Skip to content

Commit 27815b1

Browse files
committed
Adds support for multiple $in
1 parent c7503fc commit 27815b1

File tree

2 files changed

+75
-23
lines changed

2 files changed

+75
-23
lines changed

spec/ParseRelation.spec.js

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,57 @@ describe('Parse.Relation testing', () => {
237237
success: function(list) {
238238
equal(list.length, 1, "There should be only one result");
239239
equal(list[0].id, parent2.id,
240-
"Should have gotten back the right result");
240+
"Should have gotten back the right result");
241+
done();
242+
}
243+
});
244+
}
245+
});
246+
}
247+
});
248+
});
249+
250+
it("queries on relation fields with multiple ins", (done) => {
251+
var ChildObject = Parse.Object.extend("ChildObject");
252+
var childObjects = [];
253+
for (var i = 0; i < 10; i++) {
254+
childObjects.push(new ChildObject({x: i}));
255+
}
256+
257+
Parse.Object.saveAll(childObjects, {
258+
success: function() {
259+
var ParentObject = Parse.Object.extend("ParentObject");
260+
var parent = new ParentObject();
261+
parent.set("x", 4);
262+
var relation = parent.relation("child");
263+
relation.add(childObjects[0]);
264+
relation.add(childObjects[1]);
265+
relation.add(childObjects[2]);
266+
var parent2 = new ParentObject();
267+
parent2.set("x", 3);
268+
var relation2 = parent2.relation("child");
269+
relation2.add(childObjects[4]);
270+
relation2.add(childObjects[5]);
271+
relation2.add(childObjects[6]);
272+
273+
var otherChild2 = parent2.relation("otherChild");
274+
otherChild2.add(childObjects[0]);
275+
otherChild2.add(childObjects[1]);
276+
otherChild2.add(childObjects[2]);
277+
278+
var parents = [];
279+
parents.push(parent);
280+
parents.push(parent2);
281+
Parse.Object.saveAll(parents, {
282+
success: function() {
283+
var query = new Parse.Query(ParentObject);
284+
var objects = [];
285+
objects.push(childObjects[0]);
286+
query.containedIn("child", objects);
287+
query.containedIn("otherChild", [childObjects[0]]);
288+
query.find({
289+
success: function(list) {
290+
equal(list.length, 2, "There should be only one result");
241291
done();
242292
}
243293
});

src/Controllers/DatabaseController.js

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -397,31 +397,33 @@ DatabaseController.prototype.owningIds = function(className, key, relatedIds) {
397397
// Modifies query so that it no longer has $in on relation fields, or
398398
// equal-to-pointer constraints on relation fields.
399399
// Returns a promise that resolves when query is mutated
400-
// TODO: this only handles one of these at a time - make it handle more
401400
DatabaseController.prototype.reduceInRelation = function(className, query, schema) {
402401
// Search for an in-relation or equal-to-relation
403-
for (var key in query) {
404-
if (query[key] &&
405-
(query[key]['$in'] || query[key].__type == 'Pointer')) {
406-
var t = schema.getExpectedType(className, key);
407-
var match = t ? t.match(/^relation<(.*)>$/) : false;
408-
if (!match) {
409-
continue;
410-
}
411-
var relatedClassName = match[1];
412-
var relatedIds;
413-
if (query[key]['$in']) {
414-
relatedIds = query[key]['$in'].map(r => r.objectId);
415-
} else {
416-
relatedIds = [query[key].objectId];
402+
// Make it sequential for now, not sure of paralleization side effects
403+
return Object.keys(query).reduce((promise, key) => {
404+
return promise.then(() => {
405+
if (query[key] &&
406+
(query[key]['$in'] || query[key].__type == 'Pointer')) {
407+
let t = schema.getExpectedType(className, key);
408+
let match = t ? t.match(/^relation<(.*)>$/) : false;
409+
if (!match) {
410+
return;
411+
}
412+
let relatedClassName = match[1];
413+
let relatedIds;
414+
if (query[key]['$in']) {
415+
relatedIds = query[key]['$in'].map(r => r.objectId);
416+
} else {
417+
relatedIds = [query[key].objectId];
418+
}
419+
return this.owningIds(className, key, relatedIds).then((ids) => {
420+
delete query[key];
421+
query.objectId = Object.assign({'$in': []}, query.objectId);
422+
query.objectId['$in'] = query.objectId['$in'].concat(ids);
423+
});
417424
}
418-
return this.owningIds(className, key, relatedIds).then((ids) => {
419-
delete query[key];
420-
query.objectId = {'$in': ids};
421-
});
422-
}
423-
}
424-
return Promise.resolve();
425+
});
426+
}, Promise.resolve());
425427
};
426428

427429
// Modifies query so that it no longer has $relatedTo

0 commit comments

Comments
 (0)