Dirty merge. Tests are broken
This commit is contained in:
parent
e585021586
commit
fb56915371
108
lib/include.js
108
lib/include.js
|
@ -1,6 +1,7 @@
|
|||
var async = require('async');
|
||||
var utils = require('./utils');
|
||||
var List = require('./list');
|
||||
var includeUtils = require('./include_utils');
|
||||
var isPlainObject = utils.isPlainObject;
|
||||
var defineCachedRelations = utils.defineCachedRelations;
|
||||
var uniq = utils.uniq;
|
||||
|
@ -267,6 +268,11 @@ Inclusion.include = function (objects, include, options, cb) {
|
|||
if (relation.type === 'referencesMany') {
|
||||
return includeReferencesMany(cb);
|
||||
}
|
||||
|
||||
//This handles exactly hasMany. Fast and straightforward. Without parallel, each and other boilerplate.
|
||||
if(relation.type === 'hasMany' && relation.multiple && !subInclude) {
|
||||
return includeHasManySimple(cb);
|
||||
}
|
||||
//assuming all other relations with multiple=true as hasMany
|
||||
return includeHasMany(cb);
|
||||
}
|
||||
|
@ -482,6 +488,108 @@ Inclusion.include = function (objects, include, options, cb) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle inclusion of HasMany relation
|
||||
* @param callback
|
||||
*/
|
||||
function includeHasManySimple(callback) {
|
||||
//Map for Indexing objects by their id for faster retrieval
|
||||
var objIdMap = includeUtils.buildOneToOneIdentityMap(objs, relation.keyFrom);
|
||||
// all ids of primary objects to use in query
|
||||
var sourceIds = Object.keys(objIdMap);
|
||||
|
||||
filter.where[relation.keyTo] = {
|
||||
inq: uniq(sourceIds)
|
||||
};
|
||||
|
||||
relation.applyScope(null, filter);
|
||||
relation.modelTo.find(filter, options, targetFetchHandler2);
|
||||
|
||||
function targetFetchHandler2(err, targets) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var targetsIdMap = includeUtils.buildOneToManyIdentityMap(targets, relation.keyTo);
|
||||
includeUtils.join(objIdMap, targetsIdMap, function(obj1, valueToMergeIn){
|
||||
obj1[relation.name] = valueToMergeIn;
|
||||
});
|
||||
callback(err, objs);
|
||||
}
|
||||
/**
|
||||
* Process fetched related objects
|
||||
* @param err
|
||||
* @param {Array<Model>} targets
|
||||
* @returns {*}
|
||||
*/
|
||||
function targetFetchHandler(err, targets) {
|
||||
console.log("### query done. I'm in targetFetchHandler");
|
||||
console.log("### obtained: \ntargets(permission) count: " + targets.length + "\nobjs(users) count: " + objs.length);
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var modelToFKIdMap = includeUtils.buildOneToManyIdentityMap(targets, relation.keyTo);
|
||||
|
||||
var tasks = [];
|
||||
//simultaneously process subIncludes
|
||||
if (subInclude && targets) {
|
||||
tasks.push(function subIncludesTask(next) {
|
||||
relation.modelTo.include(targets, subInclude, options, next);
|
||||
});
|
||||
}
|
||||
//process each target object
|
||||
tasks.push(targetLinkingTask);
|
||||
function targetLinkingTask(next) {
|
||||
if (targets.length === 0) {
|
||||
return async.each(objs, function(obj, next) {
|
||||
processTargetObj(obj, next);
|
||||
}, next);
|
||||
}
|
||||
// TODO: show targets length
|
||||
// почему так сложно???? Не очень понимаю.
|
||||
async.each(targets, linkManyToOne, next);
|
||||
function linkManyToOne(target, next) {
|
||||
console.log("### processing target: " + JSON.stringify(target));
|
||||
//fix for bug in hasMany with referencesMany
|
||||
var targetIds = [].concat(target[relation.keyTo]);
|
||||
console.log("### targetIds: " + JSON.stringify(targetIds));
|
||||
async.each(targetIds, function (targetId, next) {
|
||||
var obj = objIdMap[targetId.toString()];
|
||||
if (!obj) return next();
|
||||
obj.__cachedRelations[relationName].push(target);
|
||||
//console.time("@@@Prepare1");
|
||||
processTargetObj(obj, next);
|
||||
//console.timeEnd("@@@Prepare1");
|
||||
}, function(err, processedTargets) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
console.time("finding object with empty ids");
|
||||
var objsWithEmptyRelation = objs.filter(function(obj) {
|
||||
return obj.__cachedRelations[relationName].length === 0;
|
||||
});
|
||||
console.timeEnd("finding object with empty ids"); // 0-1 ms
|
||||
console.log("### objs with empty relations count: " + objsWithEmptyRelation.length);
|
||||
//next(processedTargets);
|
||||
console.time("Prepare empty");
|
||||
async.each(objsWithEmptyRelation, function(obj, next) {
|
||||
console.time("Prepare one");
|
||||
processTargetObj(obj, next);
|
||||
console.timeEnd("Prepare one");
|
||||
}, function(err) {
|
||||
console.timeEnd("Prepare empty");
|
||||
next(err, processedTargets);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log("### tasks count: " + tasks.length);
|
||||
execTasksWithInterLeave(tasks, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle inclusion of HasMany relation
|
||||
* @param callback
|
||||
|
|
|
@ -56,6 +56,7 @@ describe('include', function () {
|
|||
|
||||
it('should fetch Passport - Owner - Posts', function (done) {
|
||||
Passport.find({include: {owner: 'posts'}}, function (err, passports) {
|
||||
|
||||
should.not.exist(err);
|
||||
should.exist(passports);
|
||||
passports.length.should.be.ok;
|
||||
|
|
Loading…
Reference in New Issue