Skip to content

Allow queries with String array for pointers containedIn #4188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions spec/ParseQuery.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down
19 changes: 12 additions & 7 deletions src/Adapters/Storage/Mongo/MongoTransform.js
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 {
Expand All @@ -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}`);
Expand Down Expand Up @@ -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)}`);
}
Expand Down