Allow queries with String array for pointers containedIn (#4188)
* Adds basic failing test * Adds ability to use [objectId] for $in/$nin pointers * makes sure to use a set field * Makes sure field is defined
This commit is contained in:
@@ -2834,6 +2834,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');
|
||||
|
||||
@@ -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)}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user