mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 13:52:10 +03:00
Revert "Optimised queries made by get helper for posts"
no-issue This was incorrectly merged - reverting until the work is complete
This commit is contained in:
parent
a309a29ef6
commit
39da5a1f88
@ -11,7 +11,6 @@ const Sentry = require('@sentry/node');
|
|||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const jsonpath = require('jsonpath');
|
const jsonpath = require('jsonpath');
|
||||||
const nqlLang = require('@tryghost/nql-lang');
|
|
||||||
|
|
||||||
const messages = {
|
const messages = {
|
||||||
mustBeCalledAsBlock: 'The {\\{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}',
|
mustBeCalledAsBlock: 'The {\\{{helperName}}} helper must be called as a block. E.g. {{#{helperName}}}...{{/{helperName}}}',
|
||||||
@ -132,54 +131,6 @@ function parseOptions(globals, data, options) {
|
|||||||
*/
|
*/
|
||||||
async function makeAPICall(resource, controllerName, action, apiOptions) {
|
async function makeAPICall(resource, controllerName, action, apiOptions) {
|
||||||
const controller = api[controllerName];
|
const controller = api[controllerName];
|
||||||
let makeRequest = () => controller[action](apiOptions);
|
|
||||||
|
|
||||||
// Only do the optimisation on posts
|
|
||||||
if (resource === 'posts' && apiOptions.filter) {
|
|
||||||
try {
|
|
||||||
const parsedFilter = nqlLang.parse(apiOptions.filter);
|
|
||||||
// Support either `id:blah` or `id:blah+other:stuff`
|
|
||||||
if (parsedFilter.$and || parsedFilter.id) {
|
|
||||||
const queries = parsedFilter.$and || [parsedFilter.id];
|
|
||||||
|
|
||||||
for (const query of queries) {
|
|
||||||
if ('id' in query) {
|
|
||||||
if ('$ne' in query.id) {
|
|
||||||
// This checks that there is only one occurence of a negative id filter
|
|
||||||
// So we know it's safe to use the `replace` method
|
|
||||||
if (apiOptions.filter.split('id:-').length === 2) {
|
|
||||||
const idToFilter = query.id.$ne;
|
|
||||||
|
|
||||||
// The default limit is 15, the addition order is to cast apiOptions.limit to a number
|
|
||||||
let limit = apiOptions.limit;
|
|
||||||
limit = apiOptions.limit && apiOptions.limit !== 'all' ? 1 + apiOptions.limit : 16;
|
|
||||||
|
|
||||||
// We replace with id:-null so we don't have to deal with leading/trailing AND operators
|
|
||||||
const filter = apiOptions.filter.replace(/id:-[a-f0-9A-F]{24}/, 'id:-null');
|
|
||||||
|
|
||||||
makeRequest = async () => {
|
|
||||||
const result = await controller[action]({
|
|
||||||
...apiOptions,
|
|
||||||
limit,
|
|
||||||
filter
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...result,
|
|
||||||
posts: result?.posts?.filter((post) => {
|
|
||||||
return post.id !== idToFilter;
|
|
||||||
}).slice(0, limit - 1) || []
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
logging.warn(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let timer;
|
let timer;
|
||||||
|
|
||||||
@ -190,7 +141,7 @@ async function makeAPICall(resource, controllerName, action, apiOptions) {
|
|||||||
const logLevel = config.get('optimization:getHelper:timeout:level') || 'error';
|
const logLevel = config.get('optimization:getHelper:timeout:level') || 'error';
|
||||||
const threshold = config.get('optimization:getHelper:timeout:threshold');
|
const threshold = config.get('optimization:getHelper:timeout:threshold');
|
||||||
|
|
||||||
const apiResponse = makeRequest();
|
const apiResponse = controller[action](apiOptions);
|
||||||
|
|
||||||
const timeout = new Promise((resolve) => {
|
const timeout = new Promise((resolve) => {
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
@ -210,7 +161,7 @@ async function makeAPICall(resource, controllerName, action, apiOptions) {
|
|||||||
response = await Promise.race([apiResponse, timeout]);
|
response = await Promise.race([apiResponse, timeout]);
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
} else {
|
} else {
|
||||||
response = await makeRequest();
|
response = await controller[action](apiOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
const assert = require('assert/strict');
|
|
||||||
const should = require('should');
|
const should = require('should');
|
||||||
const sinon = require('sinon');
|
const sinon = require('sinon');
|
||||||
const testUtils = require('../../utils');
|
const testUtils = require('../../utils');
|
||||||
@ -99,112 +98,6 @@ describe('e2e {{#get}} helper', function () {
|
|||||||
locals = {root: {_locals: {}}};
|
locals = {root: {_locals: {}}};
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Filter optimisation', function () {
|
|
||||||
it('Returns the correct posts with a solo negative filter', async function () {
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
limit: 1
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
const firstPostUsually = fn.firstCall.args[0].posts[0];
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `id:-${firstPostUsually.id}`,
|
|
||||||
limit: 5
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
assert.equal(fn.secondCall.args[0].posts.length, 5);
|
|
||||||
const foundFilteredPost = fn.secondCall.args[0].posts.find(post => post.id === firstPostUsually.id);
|
|
||||||
assert.equal(foundFilteredPost, undefined);
|
|
||||||
});
|
|
||||||
it('Returns the correct posts with a sandwiched negative filter', async function () {
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `tag:-hash-hidden+visibility:public`,
|
|
||||||
limit: 1
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
const firstPostUsually = fn.firstCall.args[0].posts[0];
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `visibility:public+id:-${firstPostUsually.id}+tag:-hash-hidden`,
|
|
||||||
limit: 5
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
assert.equal(fn.secondCall.args[0].posts.length, 5);
|
|
||||||
const foundFilteredPost = fn.secondCall.args[0].posts.find(post => post.id === firstPostUsually.id);
|
|
||||||
assert.equal(foundFilteredPost, undefined);
|
|
||||||
});
|
|
||||||
it('Returns the correct posts with a prefix negative filter', async function () {
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `tag:-hash-hidden`,
|
|
||||||
limit: 1
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
const firstPostUsually = fn.firstCall.args[0].posts[0];
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `id:-${firstPostUsually.id}+tag:-hash-hidden`,
|
|
||||||
limit: 5
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
assert.equal(fn.secondCall.args[0].posts.length, 5);
|
|
||||||
const foundFilteredPost = fn.secondCall.args[0].posts.find(post => post.id === firstPostUsually.id);
|
|
||||||
assert.equal(foundFilteredPost, undefined);
|
|
||||||
});
|
|
||||||
it('Returns the correct posts with a suffix negative filter', async function () {
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `tag:-hash-hidden`,
|
|
||||||
limit: 1
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
const firstPostUsually = fn.firstCall.args[0].posts[0];
|
|
||||||
await get.call({}, 'posts', {
|
|
||||||
hash: {
|
|
||||||
filter: `tag:-hash-hidden+id:-${firstPostUsually.id}`,
|
|
||||||
limit: 5
|
|
||||||
},
|
|
||||||
data: {},
|
|
||||||
locals,
|
|
||||||
fn,
|
|
||||||
inverse
|
|
||||||
});
|
|
||||||
assert.equal(fn.secondCall.args[0].posts.length, 5);
|
|
||||||
const foundFilteredPost = fn.secondCall.args[0].posts.find(post => post.id === firstPostUsually.id);
|
|
||||||
assert.equal(foundFilteredPost, undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('{{access}} property', function () {
|
describe('{{access}} property', function () {
|
||||||
let member;
|
let member;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user