diff --git a/spec/ParseQuery.spec.js b/spec/ParseQuery.spec.js index da53ca6292..1eec4c3a5f 100644 --- a/spec/ParseQuery.spec.js +++ b/spec/ParseQuery.spec.js @@ -2802,6 +2802,53 @@ 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('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..d745668c80 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 && 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 && 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)}`); }