Merge branch 'master' into fix/join-multi-database

This commit is contained in:
Jim LAURIE 2019-04-17 18:30:41 +02:00 committed by GitHub
commit ae943d7492
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 31 deletions

View File

@ -84,7 +84,7 @@ const buildJoinsAndFilter = (qb, model, whereClauses) => {
qb.leftJoin( qb.leftJoin(
`${originInfo.model.databaseName}.${assoc.tableCollectionName} AS ${joinTableAlias}`, `${originInfo.model.databaseName}.${assoc.tableCollectionName} AS ${joinTableAlias}`,
`${joinTableAlias}.${singular(originInfo.model.collectionName)}_${ `${joinTableAlias}.${singular(originInfo.model.globalId.toLowerCase())}_${
originInfo.model.attributes[assoc.alias].column originInfo.model.attributes[assoc.alias].column
}`, }`,
`${originInfo.alias}.${originInfo.model.primaryKey}` `${originInfo.alias}.${originInfo.model.primaryKey}`
@ -92,7 +92,7 @@ const buildJoinsAndFilter = (qb, model, whereClauses) => {
qb.leftJoin( qb.leftJoin(
`${destinationInfo.model.databaseName}.${destinationInfo.model.collectionName} AS ${destinationInfo.alias}`, `${destinationInfo.model.databaseName}.${destinationInfo.model.collectionName} AS ${destinationInfo.alias}`,
`${joinTableAlias}.${singular(destinationInfo.model.collectionName)}_${ `${joinTableAlias}.${singular(destinationInfo.model.globalId.toLowerCase())}_${
destinationInfo.model.primaryKey destinationInfo.model.primaryKey
}`, }`,
`${destinationInfo.alias}.${destinationInfo.model.primaryKey}` `${destinationInfo.alias}.${destinationInfo.model.primaryKey}`

View File

@ -20,15 +20,22 @@ module.exports = {
.filter(model => model !== 'core_store') .filter(model => model !== 'core_store')
.forEach(model => { .forEach(model => {
(strapi.models[model].associations || []).forEach(association => (strapi.models[model].associations || []).forEach(association =>
this.createLoader(association.collection || association.model, association.plugin) this.createLoader(
association.collection || association.model,
association.plugin
)
); );
}); });
// Reproduce the same pattern for each plugin. // Reproduce the same pattern for each plugin.
Object.keys(strapi.plugins).forEach(plugin => { Object.keys(strapi.plugins).forEach(plugin => {
Object.keys(strapi.plugins[plugin].models).forEach(model => { Object.keys(strapi.plugins[plugin].models).forEach(model => {
(strapi.plugins[plugin].models[model].associations || []).forEach(association => (strapi.plugins[plugin].models[model].associations || []).forEach(
this.createLoader(association.collection || association.model, association.plugin) association =>
this.createLoader(
association.collection || association.model,
association.plugin
)
); );
}); });
}); });
@ -55,9 +62,15 @@ module.exports = {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
try { try {
// Extract queries from keys and merge similar queries. // Extract queries from keys and merge similar queries.
const { queries, map } = this.extractQueries(model, _.cloneDeep(keys)); const { queries, map } = this.extractQueries(
model,
_.cloneDeep(keys)
);
// Run queries in parallel. // Run queries in parallel.
const results = await Promise.all(queries.map(query => this.makeQuery(model, query))); const results = await Promise.all(
queries.map(query => this.makeQuery(model, query))
);
// Use to match initial queries order. // Use to match initial queries order.
const data = this.mapData(model, keys, map, results); const data = this.mapData(model, keys, map, results);
@ -80,7 +93,9 @@ module.exports = {
// Use map to re-dispatch data correctly based on initial keys. // Use map to re-dispatch data correctly based on initial keys.
return originalMap.map((query, index) => { return originalMap.map((query, index) => {
// Find the index of where we should extract the results. // Find the index of where we should extract the results.
const indexResults = map.findIndex(queryMap => queryMap.indexOf(index) !== -1); const indexResults = map.findIndex(
queryMap => queryMap.indexOf(index) !== -1
);
const data = results[indexResults]; const data = results[indexResults];
// Retrieving referring model. // Retrieving referring model.
@ -90,7 +105,8 @@ module.exports = {
// Return object instead of array for one-to-many relationship. // Return object instead of array for one-to-many relationship.
return data.find( return data.find(
entry => entry =>
entry[ref.primaryKey].toString() === (query.params[ref.primaryKey] || '').toString() entry[ref.primaryKey].toString() ===
(query.params[ref.primaryKey] || '').toString()
); );
} }
@ -128,7 +144,11 @@ module.exports = {
return data return data
.filter(entry => entry !== undefined) .filter(entry => entry !== undefined)
.filter(entry => ids.map(id => id.toString()).includes(entry[ref.primaryKey].toString())) .filter(entry =>
ids
.map(id => id.toString())
.includes(entry[ref.primaryKey].toString())
)
.slice(skip, skip + limit); .slice(skip, skip + limit);
}); });
}, },
@ -170,10 +190,9 @@ module.exports = {
.value(); .value();
// Run query and remove duplicated ID. // Run query and remove duplicated ID.
const request = await strapi.plugins['content-manager'].services['contentmanager'].fetchAll( const request = await strapi.plugins['content-manager'].services[
{ model }, 'contentmanager'
params ].fetchAll({ model }, params);
);
return request && request.toJSON ? request.toJSON() : request; return request && request.toJSON ? request.toJSON() : request;
}, },
@ -196,9 +215,6 @@ module.exports = {
// Retrieving referring model. // Retrieving referring model.
const ref = this.retrieveModel(model, options.source); const ref = this.retrieveModel(model, options.source);
// Find similar query.
const indexQueries = queries.findIndex(query => _.isEqual(query.options, options));
// Generate array of IDs to fetch. // Generate array of IDs to fetch.
const ids = []; const ids = [];
@ -211,21 +227,14 @@ module.exports = {
ids.push(query[association.via]); ids.push(query[association.via]);
} }
if (indexQueries !== -1) { queries.push({
// Push to the same query the new IDs to fetch. ids,
queries[indexQueries].ids.push(...ids); options,
map[indexQueries].push(index); alias: _.first(Object.keys(query)) || ref.primaryKey,
} else { });
// Create new query in the query.
queries.push({
ids,
options,
alias: _.first(Object.keys(query)) || ref.primaryKey,
});
map[queries.length - 1 > 0 ? queries.length - 1 : 0] = []; map[queries.length - 1 > 0 ? queries.length - 1 : 0] = [];
map[queries.length - 1].push(index); map[queries.length - 1].push(index);
}
}); });
return { return {