Skip to content

Commit 20a70ea

Browse files
committed
🎉 fixes #1349
1 parent ca6269f commit 20a70ea

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/Controllers/DatabaseController.js

+36-2
Original file line numberDiff line numberDiff line change
@@ -444,22 +444,33 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
444444
}
445445

446446
let promises = Object.keys(query).map((key) => {
447-
if (query[key] && (query[key]['$in'] || query[key].__type == 'Pointer')) {
447+
if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) {
448448
let t = schema.getExpectedType(className, key);
449449
let match = t ? t.match(/^relation<(.*)>$/) : false;
450450
if (!match) {
451451
return Promise.resolve(query);
452452
}
453453
let relatedClassName = match[1];
454454
let relatedIds;
455+
let isNegation = false;
455456
if (query[key]['$in']) {
456457
relatedIds = query[key]['$in'].map(r => r.objectId);
458+
} else if (query[key]['$nin']) {
459+
isNegation = true;
460+
relatedIds = query[key]['$nin'].map(r => r.objectId);
461+
} else if (query[key]['$ne']) {
462+
isNegation = true;
463+
relatedIds = [query[key]['$ne'].objectId];
457464
} else {
458465
relatedIds = [query[key].objectId];
459466
}
460467
return this.owningIds(className, key, relatedIds).then((ids) => {
461468
delete query[key];
462-
this.addInObjectIdsIds(ids, query);
469+
if (isNegation) {
470+
this.addNotInObjectIdsIds(ids, query);
471+
} else {
472+
this.addInObjectIdsIds(ids, query);
473+
}
463474
return Promise.resolve(query);
464475
});
465476
}
@@ -520,6 +531,29 @@ DatabaseController.prototype.addInObjectIdsIds = function(ids = null, query) {
520531
return query;
521532
}
522533

534+
DatabaseController.prototype.addNotInObjectIdsIds = function(ids = null, query) {
535+
let idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : null;
536+
let allIds = [idsFromNin, ids].filter(list => list !== null);
537+
let totalLength = allIds.reduce((memo, list) => memo + list.length, 0);
538+
539+
let idsIntersection = [];
540+
if (totalLength > 125) {
541+
idsIntersection = intersect.big(allIds);
542+
} else {
543+
idsIntersection = intersect(allIds);
544+
}
545+
546+
// Need to make sure we don't clobber existing $lt or other constraints on objectId.
547+
// Clobbering $eq, $in and shorthand $eq (query.objectId === 'string') constraints
548+
// is expected though.
549+
if (!('objectId' in query) || typeof query.objectId === 'string') {
550+
query.objectId = {};
551+
}
552+
query.objectId['$nin'] = idsIntersection;
553+
554+
return query;
555+
}
556+
523557
// Runs a query on the database.
524558
// Returns a promise that resolves to a list of items.
525559
// Options:

src/Schema.js

+16
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,22 @@ class Schema {
648648
}
649649
return false;
650650
};
651+
652+
isRelation(className, key) {
653+
var expected = this.getExpectedType(className, key);
654+
if (expected && expected.startsWith('relation<')) {
655+
return true;
656+
}
657+
return false;
658+
};
659+
660+
classNameOnRelation(className, key) {
661+
var type = this.getExpectedType(className, key);
662+
if (type && type.startsWith('relation<')) {
663+
return type.slice('relation<'.length, type.length - 1);
664+
}
665+
return false;
666+
}
651667
}
652668

653669
// Returns a promise for a new Schema.

0 commit comments

Comments
 (0)