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
@@ -5273,7 +5273,10 @@ describe('ParseGraphQLServer', () => {
|
||||
});
|
||||
|
||||
it('should support object values', async () => {
|
||||
const someFieldValue = { foo: 'bar' };
|
||||
const someFieldValue = {
|
||||
foo: { bar: 'baz' },
|
||||
number: 10,
|
||||
};
|
||||
|
||||
const createResult = await apolloClient.mutate({
|
||||
mutation: gql`
|
||||
@@ -5314,30 +5317,179 @@ describe('ParseGraphQLServer', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const getResult = await apolloClient.query({
|
||||
const where = {
|
||||
someField: {
|
||||
_eq: { _key: 'foo.bar', _value: 'baz' },
|
||||
_ne: { _key: 'foo.bar', _value: 'bat' },
|
||||
_gt: { _key: 'number', _value: 9 },
|
||||
_lt: { _key: 'number', _value: 11 },
|
||||
},
|
||||
};
|
||||
const queryResult = await apolloClient.query({
|
||||
query: gql`
|
||||
query GetSomeObject($objectId: ID!) {
|
||||
query GetSomeObject(
|
||||
$objectId: ID!
|
||||
$where: SomeClassConstraints
|
||||
$genericWhere: Object
|
||||
) {
|
||||
objects {
|
||||
get(className: "SomeClass", objectId: $objectId)
|
||||
findSomeClass(where: { someField: { _exists: true } }) {
|
||||
findSomeClass(where: $where) {
|
||||
results {
|
||||
objectId
|
||||
someField
|
||||
}
|
||||
}
|
||||
find(className: "SomeClass", where: $genericWhere) {
|
||||
results
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
objectId: createResult.data.objects.create.objectId,
|
||||
where,
|
||||
genericWhere: where, // where and genericWhere types are different
|
||||
},
|
||||
});
|
||||
|
||||
const { someField } = getResult.data.objects.get;
|
||||
const {
|
||||
get: getResult,
|
||||
findSomeClass,
|
||||
find,
|
||||
} = queryResult.data.objects;
|
||||
|
||||
const { someField } = getResult;
|
||||
expect(typeof someField).toEqual('object');
|
||||
expect(someField).toEqual(someFieldValue);
|
||||
expect(getResult.data.objects.findSomeClass.results.length).toEqual(
|
||||
2
|
||||
);
|
||||
|
||||
// Checks class query results
|
||||
expect(findSomeClass.results.length).toEqual(2);
|
||||
expect(findSomeClass.results[0].someField).toEqual(someFieldValue);
|
||||
expect(findSomeClass.results[1].someField).toEqual(someFieldValue);
|
||||
|
||||
// Checks generic query results
|
||||
expect(find.results.length).toEqual(2);
|
||||
expect(find.results[0].someField).toEqual(someFieldValue);
|
||||
expect(find.results[1].someField).toEqual(someFieldValue);
|
||||
});
|
||||
|
||||
it('should support object composed queries', async () => {
|
||||
const someFieldValue = {
|
||||
lorem: 'ipsum',
|
||||
number: 10,
|
||||
};
|
||||
const someFieldValue2 = {
|
||||
foo: {
|
||||
test: 'bar',
|
||||
},
|
||||
number: 10,
|
||||
};
|
||||
|
||||
const createResult = await apolloClient.mutate({
|
||||
mutation: gql`
|
||||
mutation CreateSomeObject($fields: Object, $fields2: Object) {
|
||||
objects {
|
||||
create1: create(className: "SomeClass", fields: $fields) {
|
||||
objectId
|
||||
}
|
||||
create2: create(className: "SomeClass", fields: $fields2) {
|
||||
objectId
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
fields: {
|
||||
someField: someFieldValue,
|
||||
},
|
||||
fields2: {
|
||||
someField: someFieldValue2,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await parseGraphQLServer.parseGraphQLSchema.databaseController.schemaCache.clear();
|
||||
|
||||
const where = {
|
||||
_and: [
|
||||
{
|
||||
someField: {
|
||||
_gt: { _key: 'number', _value: 9 },
|
||||
},
|
||||
},
|
||||
{
|
||||
someField: {
|
||||
_lt: { _key: 'number', _value: 11 },
|
||||
},
|
||||
},
|
||||
{
|
||||
_or: [
|
||||
{
|
||||
someField: {
|
||||
_eq: { _key: 'lorem', _value: 'ipsum' },
|
||||
},
|
||||
},
|
||||
{
|
||||
someField: {
|
||||
_eq: { _key: 'foo.test', _value: 'bar' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const findResult = await apolloClient.query({
|
||||
query: gql`
|
||||
query FindSomeObject(
|
||||
$where: SomeClassConstraints
|
||||
$genericWhere: Object
|
||||
) {
|
||||
objects {
|
||||
findSomeClass(where: $where) {
|
||||
results {
|
||||
objectId
|
||||
someField
|
||||
}
|
||||
}
|
||||
find(className: "SomeClass", where: $genericWhere) {
|
||||
results
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
where,
|
||||
genericWhere: where, // where and genericWhere types are different
|
||||
},
|
||||
});
|
||||
|
||||
const { create1, create2 } = createResult.data.objects;
|
||||
const { findSomeClass, find } = findResult.data.objects;
|
||||
|
||||
// Checks class query results
|
||||
const { results } = findSomeClass;
|
||||
expect(results.length).toEqual(2);
|
||||
expect(
|
||||
results.find(result => result.objectId === create1.objectId)
|
||||
.someField
|
||||
).toEqual(someFieldValue);
|
||||
expect(
|
||||
results.find(result => result.objectId === create2.objectId)
|
||||
.someField
|
||||
).toEqual(someFieldValue2);
|
||||
|
||||
// Checks generic query results
|
||||
const { results: genericResults } = find;
|
||||
expect(genericResults.length).toEqual(2);
|
||||
expect(
|
||||
genericResults.find(result => result.objectId === create1.objectId)
|
||||
.someField
|
||||
).toEqual(someFieldValue);
|
||||
expect(
|
||||
genericResults.find(result => result.objectId === create2.objectId)
|
||||
.someField
|
||||
).toEqual(someFieldValue2);
|
||||
});
|
||||
|
||||
it('should support array values', async () => {
|
||||
|
||||
Reference in New Issue
Block a user