* 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) => {
|
it('should find objects with array of pointers', (done) => {
|
||||||
var objects = [];
|
var objects = [];
|
||||||
while(objects.length != 5) {
|
while(objects.length != 5) {
|
||||||
|
|||||||
@@ -223,8 +223,9 @@ function transformQueryKeyValue(className, key, value, schema) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle query constraints
|
// Handle query constraints
|
||||||
if (transformConstraint(value, expectedTypeIsArray) !== CannotTransform) {
|
const transformedConstraint = transformConstraint(value, expectedTypeIsArray);
|
||||||
return {key, value: transformConstraint(value, expectedTypeIsArray)};
|
if (transformedConstraint !== CannotTransform) {
|
||||||
|
return {key, value: transformedConstraint};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedTypeIsArray && !(value instanceof Array)) {
|
if (expectedTypeIsArray && !(value instanceof Array)) {
|
||||||
@@ -508,7 +509,14 @@ function transformConstraint(constraint, inArray) {
|
|||||||
if (typeof constraint !== 'object' || !constraint) {
|
if (typeof constraint !== 'object' || !constraint) {
|
||||||
return CannotTransform;
|
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.
|
// keys is the constraints in reverse alphabetical order.
|
||||||
// This is a hack so that:
|
// This is a hack so that:
|
||||||
// $regex is handled before $options
|
// $regex is handled before $options
|
||||||
@@ -524,10 +532,7 @@ function transformConstraint(constraint, inArray) {
|
|||||||
case '$exists':
|
case '$exists':
|
||||||
case '$ne':
|
case '$ne':
|
||||||
case '$eq':
|
case '$eq':
|
||||||
answer[key] = inArray ? transformInteriorAtom(constraint[key]) : transformTopLevelAtom(constraint[key]);
|
answer[key] = transformer(constraint[key]);
|
||||||
if (answer[key] === CannotTransform) {
|
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${constraint[key]}`);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '$in':
|
case '$in':
|
||||||
@@ -536,12 +541,14 @@ function transformConstraint(constraint, inArray) {
|
|||||||
if (!(arr instanceof Array)) {
|
if (!(arr instanceof Array)) {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value');
|
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value');
|
||||||
}
|
}
|
||||||
answer[key] = arr.map(value => {
|
answer[key] = _.flatMap(arr, value => {
|
||||||
const result = inArray ? transformInteriorAtom(value) : transformTopLevelAtom(value);
|
return ((atom) => {
|
||||||
if (result === CannotTransform) {
|
if (Array.isArray(atom)) {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${value}`);
|
return value.map(transformer);
|
||||||
}
|
} else {
|
||||||
return result;
|
return transformer(atom);
|
||||||
|
}
|
||||||
|
})(value);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createClient } from './PostgresClient';
|
import { createClient } from './PostgresClient';
|
||||||
import Parse from 'parse/node';
|
import Parse from 'parse/node';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
const PostgresRelationDoesNotExistError = '42P01';
|
const PostgresRelationDoesNotExistError = '42P01';
|
||||||
const PostgresDuplicateRelationError = '42P07';
|
const PostgresDuplicateRelationError = '42P07';
|
||||||
@@ -296,10 +297,10 @@ const buildWhereClause = ({ schema, query, index }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fieldValue.$in) {
|
if (fieldValue.$in) {
|
||||||
createConstraint(fieldValue.$in, false);
|
createConstraint(_.flatMap(fieldValue.$in, elt => elt), false);
|
||||||
}
|
}
|
||||||
if (fieldValue.$nin) {
|
if (fieldValue.$nin) {
|
||||||
createConstraint(fieldValue.$nin, true);
|
createConstraint(_.flatMap(fieldValue.$nin, elt => elt), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user