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 async = require('async');
|
||||||
var utils = require('./utils');
|
var utils = require('./utils');
|
||||||
var List = require('./list');
|
var List = require('./list');
|
||||||
|
var includeUtils = require('./include_utils');
|
||||||
var isPlainObject = utils.isPlainObject;
|
var isPlainObject = utils.isPlainObject;
|
||||||
var defineCachedRelations = utils.defineCachedRelations;
|
var defineCachedRelations = utils.defineCachedRelations;
|
||||||
var uniq = utils.uniq;
|
var uniq = utils.uniq;
|
||||||
|
@ -267,6 +268,11 @@ Inclusion.include = function (objects, include, options, cb) {
|
||||||
if (relation.type === 'referencesMany') {
|
if (relation.type === 'referencesMany') {
|
||||||
return includeReferencesMany(cb);
|
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
|
//assuming all other relations with multiple=true as hasMany
|
||||||
return includeHasMany(cb);
|
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
|
* Handle inclusion of HasMany relation
|
||||||
* @param callback
|
* @param callback
|
||||||
|
|
|
@ -56,6 +56,7 @@ describe('include', function () {
|
||||||
|
|
||||||
it('should fetch Passport - Owner - Posts', function (done) {
|
it('should fetch Passport - Owner - Posts', function (done) {
|
||||||
Passport.find({include: {owner: 'posts'}}, function (err, passports) {
|
Passport.find({include: {owner: 'posts'}}, function (err, passports) {
|
||||||
|
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(passports);
|
should.exist(passports);
|
||||||
passports.length.should.be.ok;
|
passports.length.should.be.ok;
|
||||||
|
|
Loading…
Reference in New Issue