From 0f4400c5d8baa06467dada471017e09be27f336d Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Sep 2017 13:31:31 -0400 Subject: [PATCH 1/4] Adds basic failing test --- spec/ParseQuery.spec.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index da53ca6292..0418dc91cd 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -2802,6 +2802,27 @@ describe('Parse.Query testing', () => { }); }); + it('containedIn with pointers should work with string array', done => { + const obj = new Parse.Object('MyClass'); + const child = new Parse.Object('Child'); + child.save().then(() => { + obj.set('child', child); + return obj.save(); + }).then(() => { + const objs = []; + for(let i = 0; i < 10; i++) { + objs.push(new Parse.Object('MyClass')); + } + return Parse.Object.saveAll(objs); + }).then(() => { + const query = new Parse.Query('MyClass'); + query.containedIn('child', [child.id]); + return query.find(); + }).then((results) => { + expect(results.length).toBe(1); + }).then(done).catch(done.fail); + }); + it('include for specific object', function(done){ var child = new Parse.Object('Child'); var parent = new Parse.Object('Parent'); From b41058c47587fc0154ff398b4592a58fa488c2f5 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Sep 2017 14:10:44 -0400 Subject: [PATCH 2/4] Adds ability to use [objectId] for $in/$nin pointers --- spec/ParseQuery.spec.js | 26 ++++++++++++++++++++ src/Adapters/Storage/Mongo/MongoTransform.js | 19 ++++++++------ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index 0418dc91cd..1eec4c3a5f 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -2823,6 +2823,32 @@ describe('Parse.Query testing', () => { }).then(done).catch(done.fail); }); + it('containedIn with pointers should work with string array, with many objects', done => { + const objs = []; + const children = []; + for(let i = 0; i < 10; i++) { + const obj = new Parse.Object('MyClass'); + const child = new Parse.Object('Child'); + objs.push(obj); + children.push(child); + } + Parse.Object.saveAll(children).then(() => { + return Parse.Object.saveAll(objs.map((obj, i) => { + obj.set('child', children[i]); + return obj; + })); + }).then(() => { + const query = new Parse.Query('MyClass'); + const subset = children.slice(0, 5).map((child) => { + return child.id; + }); + query.containedIn('child', subset); + return query.find(); + }).then((results) => { + expect(results.length).toBe(5); + }).then(done).catch(done.fail); + }); + it('include for specific object', function(done){ var child = new Parse.Object('Child'); var parent = new Parse.Object('Parent'); diff --git a/src/Adapters/Storage/Mongo/MongoTransform.js b/src/Adapters/Storage/Mongo/MongoTransform.js index 143df5584a..cd6d250df1 100644 --- a/src/Adapters/Storage/Mongo/MongoTransform.js +++ b/src/Adapters/Storage/Mongo/MongoTransform.js @@ -241,12 +241,13 @@ function transformQueryKeyValue(className, key, value, schema) { schema.fields[key] && schema.fields[key].type === 'Pointer'; + const field = schema && schema.fields[key]; if (expectedTypeIsPointer || !schema && value && value.__type === 'Pointer') { key = '_p_' + key; } // Handle query constraints - const transformedConstraint = transformConstraint(value, expectedTypeIsArray); + const transformedConstraint = transformConstraint(value, field); if (transformedConstraint !== CannotTransform) { if (transformedConstraint.$text) { return {key: '$text', value: transformedConstraint.$text}; @@ -454,7 +455,7 @@ const addLegacyACL = restObject => { // cannot perform a transformation function CannotTransform() {} -const transformInteriorAtom = atom => { +const transformInteriorAtom = (atom) => { // TODO: check validity harder for the __type-defined types if (typeof atom === 'object' && atom && !(atom instanceof Date) && atom.__type === 'Pointer') { return { @@ -480,14 +481,17 @@ const transformInteriorAtom = atom => { // or arrays with generic stuff inside. // Raises an error if this cannot possibly be valid REST format. // Returns CannotTransform if it's just not an atom -function transformTopLevelAtom(atom) { +function transformTopLevelAtom(atom, field) { switch(typeof atom) { - case 'string': case 'number': case 'boolean': - return atom; case 'undefined': return atom; + case 'string': + if (field.type === 'Pointer') { + return `${field.targetClass}$${atom}`; + } + return atom; case 'symbol': case 'function': throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); @@ -534,13 +538,14 @@ function transformTopLevelAtom(atom) { // If it is not a valid constraint but it could be a valid something // else, return CannotTransform. // inArray is whether this is an array field. -function transformConstraint(constraint, inArray) { +function transformConstraint(constraint, field) { + const inArray = field.type && field.type === 'Array'; if (typeof constraint !== 'object' || !constraint) { return CannotTransform; } const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom; const transformer = (atom) => { - const result = transformFunction(atom); + const result = transformFunction(atom, field); if (result === CannotTransform) { throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`); } From 31ed3f1d7a46e3cef855e040b643ec657ca740dd Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Sep 2017 14:35:22 -0400 Subject: [PATCH 3/4] makes sure to use a set field --- src/Adapters/Storage/Mongo/MongoTransform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Mongo/MongoTransform.js b/src/Adapters/Storage/Mongo/MongoTransform.js index cd6d250df1..fbdefb16fa 100644 --- a/src/Adapters/Storage/Mongo/MongoTransform.js +++ b/src/Adapters/Storage/Mongo/MongoTransform.js @@ -488,7 +488,7 @@ function transformTopLevelAtom(atom, field) { case 'undefined': return atom; case 'string': - if (field.type === 'Pointer') { + if (field && field.type === 'Pointer') { return `${field.targetClass}$${atom}`; } return atom; From be0301532e47256ee29dd320fbc5a3f189e15550 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 19 Sep 2017 15:10:11 -0400 Subject: [PATCH 4/4] Makes sure field is defined --- src/Adapters/Storage/Mongo/MongoTransform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Mongo/MongoTransform.js b/src/Adapters/Storage/Mongo/MongoTransform.js index fbdefb16fa..d745668c80 100644 --- a/src/Adapters/Storage/Mongo/MongoTransform.js +++ b/src/Adapters/Storage/Mongo/MongoTransform.js @@ -539,7 +539,7 @@ function transformTopLevelAtom(atom, field) { // else, return CannotTransform. // inArray is whether this is an array field. function transformConstraint(constraint, field) { - const inArray = field.type && field.type === 'Array'; + const inArray = field && field.type && field.type === 'Array'; if (typeof constraint !== 'object' || !constraint) { return CannotTransform; }