GraphQL Object constraints (#5715)
* GraphQL Object constraints
Implements the GraphQL Object constraints, which allows us to filter queries results using the `$eq`, `$lt`, `$gt`, `$in`, and other Parse supported constraints.
Example:
```
query objects {
findMyClass(where: {
objField: {
_eq: {
key: 'foo.bar',
value: 'hello'
},
_gt: {
key: 'foo.number',
value: 10
},
_lt: {
key: 'anotherNumber',
value: 5
}
}
}) {
results {
objectId
}
}
}
```
In the example above, we have the `findMyClass` query (automatically generated for the `MyClass` class), and a field named `objField` whose type is Object. The object below represents a valid `objField` value and would satisfy all constraints:
```
{
"foo": {
"bar": "hello",
"number": 11
},
"anotherNumber": 4
}
```
The Object constraint is applied only when using Parse class object type queries. When using "generic" queries such as `get` and `find`, this type of constraint is not available.
* Objects constraints not working on Postgres
Fixes the $eq, $ne, $gt, and $lt constraints when applied on an Object type field.
* Fix object constraint field name
* Fix Postgres constraints indexes
* fix: Object type composed constraints not working
* fix: Rename key and value fields
* refactor: Object constraints for generic queries
* fix: Object constraints not working on Postgres
This commit is contained in:
committed by
Antonio Davi Macedo Coelho de Castro
parent
e0690d0c56
commit
ef14ca530d
@@ -846,15 +846,34 @@ const ARRAY_CONSTRAINT = new GraphQLInputObjectType({
|
||||
},
|
||||
});
|
||||
|
||||
const KEY_VALUE = new GraphQLInputObjectType({
|
||||
name: 'KeyValue',
|
||||
description: 'An entry from an object, i.e., a pair of key and value.',
|
||||
fields: {
|
||||
_key: {
|
||||
description: 'The key used to retrieve the value of this entry.',
|
||||
type: new GraphQLNonNull(GraphQLString),
|
||||
},
|
||||
_value: {
|
||||
description: 'The value of the entry. Could be any type of scalar data.',
|
||||
type: new GraphQLNonNull(ANY),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const OBJECT_CONSTRAINT = new GraphQLInputObjectType({
|
||||
name: 'ObjectConstraint',
|
||||
description:
|
||||
'The ObjectConstraint input type is used in operations that involve filtering objects by a field of type Object.',
|
||||
'The ObjectConstraint input type is used in operations that involve filtering result by a field of type Object.',
|
||||
fields: {
|
||||
_eq: _eq(OBJECT),
|
||||
_ne: _ne(OBJECT),
|
||||
_in: _in(OBJECT),
|
||||
_nin: _nin(OBJECT),
|
||||
_eq: _eq(KEY_VALUE),
|
||||
_ne: _ne(KEY_VALUE),
|
||||
_in: _in(KEY_VALUE),
|
||||
_nin: _nin(KEY_VALUE),
|
||||
_lt: _lt(KEY_VALUE),
|
||||
_lte: _lte(KEY_VALUE),
|
||||
_gt: _gt(KEY_VALUE),
|
||||
_gte: _gte(KEY_VALUE),
|
||||
_exists,
|
||||
_select,
|
||||
_dontSelect,
|
||||
|
||||
@@ -96,13 +96,51 @@ const parseMap = {
|
||||
_point: '$point',
|
||||
};
|
||||
|
||||
const transformToParse = constraints => {
|
||||
const transformToParse = (constraints, parentFieldName, parentConstraints) => {
|
||||
if (!constraints || typeof constraints !== 'object') {
|
||||
return;
|
||||
}
|
||||
Object.keys(constraints).forEach(fieldName => {
|
||||
let fieldValue = constraints[fieldName];
|
||||
if (parseMap[fieldName]) {
|
||||
|
||||
/**
|
||||
* If we have a key-value pair, we need to change the way the constraint is structured.
|
||||
*
|
||||
* Example:
|
||||
* From:
|
||||
* {
|
||||
* "someField": {
|
||||
* "_lt": {
|
||||
* "_key":"foo.bar",
|
||||
* "_value": 100
|
||||
* },
|
||||
* "_gt": {
|
||||
* "_key":"foo.bar",
|
||||
* "_value": 10
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* To:
|
||||
* {
|
||||
* "someField.foo.bar": {
|
||||
* "$lt": 100,
|
||||
* "$gt": 10
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
if (
|
||||
fieldValue._key &&
|
||||
fieldValue._value &&
|
||||
parentConstraints &&
|
||||
parentFieldName
|
||||
) {
|
||||
delete parentConstraints[parentFieldName];
|
||||
parentConstraints[`${parentFieldName}.${fieldValue._key}`] = {
|
||||
...parentConstraints[`${parentFieldName}.${fieldValue._key}`],
|
||||
[parseMap[fieldName]]: fieldValue._value,
|
||||
};
|
||||
} else if (parseMap[fieldName]) {
|
||||
delete constraints[fieldName];
|
||||
fieldName = parseMap[fieldName];
|
||||
constraints[fieldName] = fieldValue;
|
||||
@@ -160,7 +198,7 @@ const transformToParse = constraints => {
|
||||
break;
|
||||
}
|
||||
if (typeof fieldValue === 'object') {
|
||||
transformToParse(fieldValue);
|
||||
transformToParse(fieldValue, fieldName, constraints);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user