* Adds error reproduction * Fix transform in order to accept nested array results in $in/$nin The error originated by the nesting of 2 array in $in [["..."]], using _.flatMap with those will guarantee at the lower level that the query is properly resolved * nits * _.flatMap the $in/$nin values
This commit is contained in:
@@ -2467,6 +2467,35 @@ describe('Parse.Query testing', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should match a key in an array (#3195)", function(done) {
|
||||
var AuthorObject = Parse.Object.extend("Author");
|
||||
var GroupObject = Parse.Object.extend("Group");
|
||||
var PostObject = Parse.Object.extend("Post");
|
||||
|
||||
return new AuthorObject().save().then((user) => {
|
||||
const post = new PostObject({
|
||||
author: user
|
||||
});
|
||||
|
||||
const group = new GroupObject({
|
||||
members: [user],
|
||||
});
|
||||
|
||||
return Parse.Promise.when(post.save(), group.save());
|
||||
}).then((p) => {
|
||||
return new Parse.Query(PostObject)
|
||||
.matchesKeyInQuery("author", "members", new Parse.Query(GroupObject))
|
||||
.find()
|
||||
.then((r) => {
|
||||
expect(r.length).toEqual(1);
|
||||
if (r.length > 0) {
|
||||
expect(r[0].id).toEqual(p.id);
|
||||
}
|
||||
done();
|
||||
}, done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
it('should find objects with array of pointers', (done) => {
|
||||
var objects = [];
|
||||
while(objects.length != 5) {
|
||||
|
||||
@@ -223,8 +223,9 @@ function transformQueryKeyValue(className, key, value, schema) {
|
||||
}
|
||||
|
||||
// Handle query constraints
|
||||
if (transformConstraint(value, expectedTypeIsArray) !== CannotTransform) {
|
||||
return {key, value: transformConstraint(value, expectedTypeIsArray)};
|
||||
const transformedConstraint = transformConstraint(value, expectedTypeIsArray);
|
||||
if (transformedConstraint !== CannotTransform) {
|
||||
return {key, value: transformedConstraint};
|
||||
}
|
||||
|
||||
if (expectedTypeIsArray && !(value instanceof Array)) {
|
||||
@@ -508,7 +509,14 @@ function transformConstraint(constraint, inArray) {
|
||||
if (typeof constraint !== 'object' || !constraint) {
|
||||
return CannotTransform;
|
||||
}
|
||||
|
||||
const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom;
|
||||
const transformer = (atom) => {
|
||||
const result = transformFunction(atom);
|
||||
if (result === CannotTransform) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// keys is the constraints in reverse alphabetical order.
|
||||
// This is a hack so that:
|
||||
// $regex is handled before $options
|
||||
@@ -524,10 +532,7 @@ function transformConstraint(constraint, inArray) {
|
||||
case '$exists':
|
||||
case '$ne':
|
||||
case '$eq':
|
||||
answer[key] = inArray ? transformInteriorAtom(constraint[key]) : transformTopLevelAtom(constraint[key]);
|
||||
if (answer[key] === CannotTransform) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${constraint[key]}`);
|
||||
}
|
||||
answer[key] = transformer(constraint[key]);
|
||||
break;
|
||||
|
||||
case '$in':
|
||||
@@ -536,12 +541,14 @@ function transformConstraint(constraint, inArray) {
|
||||
if (!(arr instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value');
|
||||
}
|
||||
answer[key] = arr.map(value => {
|
||||
const result = inArray ? transformInteriorAtom(value) : transformTopLevelAtom(value);
|
||||
if (result === CannotTransform) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${value}`);
|
||||
}
|
||||
return result;
|
||||
answer[key] = _.flatMap(arr, value => {
|
||||
return ((atom) => {
|
||||
if (Array.isArray(atom)) {
|
||||
return value.map(transformer);
|
||||
} else {
|
||||
return transformer(atom);
|
||||
}
|
||||
})(value);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createClient } from './PostgresClient';
|
||||
import Parse from 'parse/node';
|
||||
import _ from 'lodash';
|
||||
|
||||
const PostgresRelationDoesNotExistError = '42P01';
|
||||
const PostgresDuplicateRelationError = '42P07';
|
||||
@@ -296,10 +297,10 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
}
|
||||
if (fieldValue.$in) {
|
||||
createConstraint(fieldValue.$in, false);
|
||||
createConstraint(_.flatMap(fieldValue.$in, elt => elt), false);
|
||||
}
|
||||
if (fieldValue.$nin) {
|
||||
createConstraint(fieldValue.$nin, true);
|
||||
createConstraint(_.flatMap(fieldValue.$nin, elt => elt), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user