Skip to content

Commit 2a16893

Browse files
authored
Adds support for pointer/string pointers comparison in LiveQuery (#4231)
* Adds support for pointer/string pointers comparison in LiveQuery * nits * Makes sure needed is set * Update QueryTools.js * Update QueryTools.js
1 parent 23bffc8 commit 2a16893

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

spec/QueryTools.spec.js

+75
Original file line numberDiff line numberDiff line change
@@ -495,4 +495,79 @@ describe('matchesQuery', function() {
495495
expect(matchesQuery(message, q)).toBe(false);
496496

497497
});
498+
499+
function pointer(className, objectId) {
500+
return { __type: 'Pointer', className, objectId };
501+
}
502+
503+
it('should support containedIn with pointers', () => {
504+
var message = {
505+
id: new Id('Message', 'O1'),
506+
profile: pointer('Profile', 'abc')
507+
};
508+
var q = new Parse.Query('Message');
509+
q.containedIn('profile', [Parse.Object.fromJSON({ className: 'Profile', objectId: 'abc' }),
510+
Parse.Object.fromJSON({ className: 'Profile', objectId: 'def' })]);
511+
expect(matchesQuery(message, q)).toBe(true);
512+
513+
q = new Parse.Query('Message');
514+
q.containedIn('profile', [Parse.Object.fromJSON({ className: 'Profile', objectId: 'ghi' }),
515+
Parse.Object.fromJSON({ className: 'Profile', objectId: 'def' })]);
516+
expect(matchesQuery(message, q)).toBe(false);
517+
});
518+
519+
it('should support notContainedIn with pointers', () => {
520+
var message = {
521+
id: new Id('Message', 'O1'),
522+
profile: pointer('Profile', 'abc')
523+
};
524+
var q = new Parse.Query('Message');
525+
q.notContainedIn('profile', [Parse.Object.fromJSON({ className: 'Profile', objectId: 'def' }),
526+
Parse.Object.fromJSON({ className: 'Profile', objectId: 'ghi' })]);
527+
expect(matchesQuery(message, q)).toBe(true);
528+
529+
message = {
530+
id: new Id('Message', 'O1'),
531+
profile: pointer('Profile', 'def')
532+
};
533+
q = new Parse.Query('Message');
534+
q.notContainedIn('profile', [Parse.Object.fromJSON({ className: 'Profile', objectId: 'ghi' }),
535+
Parse.Object.fromJSON({ className: 'Profile', objectId: 'def' })]);
536+
expect(matchesQuery(message, q)).toBe(false);
537+
});
538+
539+
it('should support containedIn queries with [objectId]', () => {
540+
var message = {
541+
id: new Id('Message', 'O1'),
542+
profile: pointer('Profile', 'abc')
543+
};
544+
var q = new Parse.Query('Message');
545+
q.containedIn('profile', ['abc', 'def']);
546+
expect(matchesQuery(message, q)).toBe(true);
547+
548+
message = {
549+
id: new Id('Message', 'O1'),
550+
profile: pointer('Profile', 'ghi')
551+
};
552+
q = new Parse.Query('Message');
553+
q.containedIn('profile', ['abc', 'def']);
554+
expect(matchesQuery(message, q)).toBe(false);
555+
});
556+
557+
it('should support notContainedIn queries with [objectId]', () => {
558+
var message = {
559+
id: new Id('Message', 'O1'),
560+
profile: pointer('Profile', 'ghi')
561+
};
562+
var q = new Parse.Query('Message');
563+
q.notContainedIn('profile', ['abc', 'def']);
564+
expect(matchesQuery(message, q)).toBe(true);
565+
message = {
566+
id: new Id('Message', 'O1'),
567+
profile: pointer('Profile', 'ghi')
568+
};
569+
q = new Parse.Query('Message');
570+
q.notContainedIn('profile', ['abc', 'def', 'ghi']);
571+
expect(matchesQuery(message, q)).toBe(false);
572+
});
498573
});

src/LiveQuery/QueryTools.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,25 @@ function queryHash(query) {
8989
return query.className + ':' + sections.join('|');
9090
}
9191

92+
/**
93+
* contains -- Determines if an object is contained in a list with special handling for Parse pointers.
94+
*/
95+
function contains(haystack: Array, needle: any): boolean {
96+
if (needle && needle.__type && needle.__type === 'Pointer') {
97+
for (const i in haystack) {
98+
const ptr = haystack[i];
99+
if (typeof ptr === 'string' && ptr === needle.objectId) {
100+
return true;
101+
}
102+
if (ptr.className === needle.className &&
103+
ptr.objectId === needle.objectId) {
104+
return true;
105+
}
106+
}
107+
return false;
108+
}
109+
return haystack.indexOf(needle) > -1;
110+
}
92111
/**
93112
* matchesQuery -- Determines if an object would be returned by a Parse Query
94113
* It's a lightweight, where-clause only implementation of a full query engine.
@@ -207,12 +226,12 @@ function matchesKeyConstraints(object, key, constraints) {
207226
}
208227
break;
209228
case '$in':
210-
if (compareTo.indexOf(object[key]) < 0) {
229+
if (!contains(compareTo, object[key])) {
211230
return false;
212231
}
213232
break;
214233
case '$nin':
215-
if (compareTo.indexOf(object[key]) > -1) {
234+
if (contains(compareTo, object[key])) {
216235
return false;
217236
}
218237
break;

0 commit comments

Comments
 (0)