Dirty merge. Tests are broken

This commit is contained in:
Wert_Lex 2015-08-24 16:07:43 +03:00
parent e585021586
commit fb56915371
2 changed files with 109 additions and 0 deletions

View File

@ -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

View File

@ -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;