mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
Use JSON instead of GraphQL for comparison operators
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6563 GitOrigin-RevId: 0819414df199292e0146ce3009295ce3e49f2439
This commit is contained in:
parent
72dbafc319
commit
87bcdb97c7
@ -133,9 +133,8 @@ The `GET /capabilities` endpoint is used by `graphql-engine` to discover the cap
|
|||||||
"column_nullability": "nullable_and_non_nullable"
|
"column_nullability": "nullable_and_non_nullable"
|
||||||
},
|
},
|
||||||
"relationships": {},
|
"relationships": {},
|
||||||
"graphql_schema": "scalar DateTime\n\ninput DateTimeComparisons {\n in_year: Number\n}",
|
|
||||||
"scalar_types": {
|
"scalar_types": {
|
||||||
"DateTime": {"comparisonType": "DateTimeComparisons"}
|
"DateTime": {"comparison_operators": {"DateTime": {"in_year": "Number"}}}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"config_schemas": {
|
"config_schemas": {
|
||||||
@ -166,7 +165,6 @@ The `capabilities` section describes the _capabilities_ of the service. This inc
|
|||||||
- `data_schema`: What sorts of features the agent supports when describing its data schema
|
- `data_schema`: What sorts of features the agent supports when describing its data schema
|
||||||
- `relationships`: whether or not the agent supports relationships
|
- `relationships`: whether or not the agent supports relationships
|
||||||
- `scalar_types`: custom scalar types and the operations they support. See [Scalar types capabilities](#scalar-type-capabilities).
|
- `scalar_types`: custom scalar types and the operations they support. See [Scalar types capabilities](#scalar-type-capabilities).
|
||||||
- `graphql_schema`: a GraphQL schema document containing type definitions referenced by the `scalar_types` capabilities.
|
|
||||||
|
|
||||||
The `config_schema` property contains an [OpenAPI 3 Schema](https://swagger.io/specification/#schema-object) object that represents the schema of the configuration object. It can use references (`$ref`) to refer to other schemas defined in the `other_schemas` object by name.
|
The `config_schema` property contains an [OpenAPI 3 Schema](https://swagger.io/specification/#schema-object) object that represents the schema of the configuration object. It can use references (`$ref`) to refer to other schemas defined in the `other_schemas` object by name.
|
||||||
|
|
||||||
@ -180,7 +178,7 @@ If the agent only supports table columns that are always nullable, then it shoul
|
|||||||
#### Scalar type capabilities
|
#### Scalar type capabilities
|
||||||
|
|
||||||
The agent is expected to support a default set of scalar types (`Number`, `String`, `Bool`) and a default set of [comparison operators](#filters) on these types.
|
The agent is expected to support a default set of scalar types (`Number`, `String`, `Bool`) and a default set of [comparison operators](#filters) on these types.
|
||||||
Agents may optionally declare support for their own custom scalar types and custom comparison operators on those types.
|
Agents may optionally declare support for their own custom scalar types, along with custom comparison operators and aggregate functions on those types.
|
||||||
Hasura GraphQL Engine does not validate the JSON format for values of custom scalar types.
|
Hasura GraphQL Engine does not validate the JSON format for values of custom scalar types.
|
||||||
It passes them through transparently to the agent when they are used as GraphQL input values and returns them transparently when they are produced by the agent.
|
It passes them through transparently to the agent when they are used as GraphQL input values and returns them transparently when they are produced by the agent.
|
||||||
It is the agent's responsibility to validate the values provided as GraphQL inputs.
|
It is the agent's responsibility to validate the values provided as GraphQL inputs.
|
||||||
@ -188,33 +186,31 @@ It is the agent's responsibility to validate the values provided as GraphQL inpu
|
|||||||
Custom scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema) and
|
Custom scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema) and
|
||||||
by adding scalar type declaration with the same name in the `graphql_schema` capabilities property.
|
by adding scalar type declaration with the same name in the `graphql_schema` capabilities property.
|
||||||
|
|
||||||
Custom comparison types can be defined by adding a `comparisonType` property to the scalar type capabilities object.
|
Custom comparison types can be defined by adding a `comparison_operators` property to the scalar type capabilities object.
|
||||||
The `comparisonType` property gives the name of a GraphQL input object type, which must be defined in the `graphql_schema` capabilities property.
|
The `comparison_operators` property is an object where each key specifies a comparison operator name.
|
||||||
The input object type will be spliced into the `where` argument for any columns of the scalar type in the GraphQL schema.
|
The operator name must be a valid GraphQL name.
|
||||||
|
The value associated with each key should be a string specifying the argument type, which must be a valid scalar type.
|
||||||
|
|
||||||
Custom aggregate functions can be defined by adding a `aggregate_functions` property to the scalar type capabilities object.
|
Custom aggregate functions can be defined by adding an `aggregate_functions` property to the scalar type capabilities object.
|
||||||
The `aggregate_functions` property must be an object mapping aggregate function names to their result types.
|
The `aggregate_functions` property must be an object mapping aggregate function names to their result types.
|
||||||
|
Aggregate function names must be must be valid GraphQL names.
|
||||||
|
Result types must be valid scalar types.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
capabilities:
|
capabilities:
|
||||||
graphql_schema: |
|
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
input DateTimeComparisons {
|
|
||||||
in_year: Number
|
|
||||||
}
|
|
||||||
scalar_types:
|
scalar_types:
|
||||||
DateTime:
|
DateTime:
|
||||||
comparisonType: DateTimeComparisons
|
comparison_operators:
|
||||||
|
in_year: Number
|
||||||
aggregate_functions:
|
aggregate_functions:
|
||||||
max: 'DateTime'
|
max: 'DateTime'
|
||||||
min: 'DateTime'
|
min: 'DateTime'
|
||||||
```
|
```
|
||||||
|
|
||||||
This example declares a custom scalar type `DateTime`, with comparison operators defined by the GraphQL input object type `DateTimeComparisons`.
|
This example declares a custom scalar type `DateTime`.
|
||||||
The input type `DateTimeComparisons` defines one comparison operator `in_year` which takes a `Number` argument
|
The type supports a comparison operator `in_year`, which takes an argument of type `Number`.
|
||||||
|
|
||||||
An example GraphQL query using the custom comparison operator might look like below:
|
An example GraphQL query using the custom comparison operator might look like below:
|
||||||
```graphql
|
```graphql
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hasura/dc-api-types",
|
"name": "@hasura/dc-api-types",
|
||||||
"version": "0.13.0",
|
"version": "0.14.0",
|
||||||
"description": "Hasura GraphQL Engine Data Connector Agent API types",
|
"description": "Hasura GraphQL Engine Data Connector Agent API types",
|
||||||
"author": "Hasura (https://github.com/hasura/graphql-engine)",
|
"author": "Hasura (https://github.com/hasura/graphql-engine)",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
@ -312,9 +312,6 @@
|
|||||||
"explain": {
|
"explain": {
|
||||||
"$ref": "#/components/schemas/ExplainCapabilities"
|
"$ref": "#/components/schemas/ExplainCapabilities"
|
||||||
},
|
},
|
||||||
"graphql_schema": {
|
|
||||||
"$ref": "#/components/schemas/GraphQLTypeDefinitions"
|
|
||||||
},
|
|
||||||
"metrics": {
|
"metrics": {
|
||||||
"$ref": "#/components/schemas/MetricsCapabilities"
|
"$ref": "#/components/schemas/MetricsCapabilities"
|
||||||
},
|
},
|
||||||
@ -367,10 +364,6 @@
|
|||||||
"QueryCapabilities": {},
|
"QueryCapabilities": {},
|
||||||
"MutationCapabilities": {},
|
"MutationCapabilities": {},
|
||||||
"SubscriptionCapabilities": {},
|
"SubscriptionCapabilities": {},
|
||||||
"GraphQLName": {
|
|
||||||
"description": "A valid GraphQL name",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"ScalarType": {
|
"ScalarType": {
|
||||||
"additionalProperties": true,
|
"additionalProperties": true,
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -387,6 +380,13 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ComparisonOperators": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/ScalarType"
|
||||||
|
},
|
||||||
|
"description": "A map from comparison operator names to their argument types.\nOperator and argument type names must be valid GraphQL names.\nResult type names must be defined scalar types - either builtin or declared in ScalarTypesCapabilities.\n",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"AggregateFunctions": {
|
"AggregateFunctions": {
|
||||||
"additionalProperties": {
|
"additionalProperties": {
|
||||||
"$ref": "#/components/schemas/ScalarType"
|
"$ref": "#/components/schemas/ScalarType"
|
||||||
@ -395,13 +395,13 @@
|
|||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"ScalarTypeCapabilities": {
|
"ScalarTypeCapabilities": {
|
||||||
"description": "Capabilities of a scalar type.\ncomparison_type: Name of the GraphQL input object to be used for comparison operations on the scalar type. The input object type must be defined in the `graphql_schema`.\naggregate_functions: The aggregate functions supported by the scalar type.\n",
|
"description": "Capabilities of a scalar type.\ncomparison_operators: The comparison operators supported by the scalar type.\naggregate_functions: The aggregate functions supported by the scalar type.\n",
|
||||||
"properties": {
|
"properties": {
|
||||||
"aggregate_functions": {
|
"aggregate_functions": {
|
||||||
"$ref": "#/components/schemas/AggregateFunctions"
|
"$ref": "#/components/schemas/AggregateFunctions"
|
||||||
},
|
},
|
||||||
"comparison_type": {
|
"comparison_operators": {
|
||||||
"$ref": "#/components/schemas/GraphQLName"
|
"$ref": "#/components/schemas/ComparisonOperators"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
@ -413,10 +413,6 @@
|
|||||||
"description": "A map from scalar type names to their capabilities.\nKeys must be valid GraphQL names and must be defined as scalar types in the `graphql_schema`\n",
|
"description": "A map from scalar type names to their capabilities.\nKeys must be valid GraphQL names and must be defined as scalar types in the `graphql_schema`\n",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"GraphQLTypeDefinitions": {
|
|
||||||
"description": "A valid GraphQL schema document containing type definitions",
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"RelationshipCapabilities": {},
|
"RelationshipCapabilities": {},
|
||||||
"SubqueryComparisonCapabilities": {
|
"SubqueryComparisonCapabilities": {
|
||||||
"nullable": true,
|
"nullable": true,
|
||||||
|
@ -20,6 +20,7 @@ export type { ColumnInfo } from './models/ColumnInfo';
|
|||||||
export type { ColumnNullability } from './models/ColumnNullability';
|
export type { ColumnNullability } from './models/ColumnNullability';
|
||||||
export type { ComparisonCapabilities } from './models/ComparisonCapabilities';
|
export type { ComparisonCapabilities } from './models/ComparisonCapabilities';
|
||||||
export type { ComparisonColumn } from './models/ComparisonColumn';
|
export type { ComparisonColumn } from './models/ComparisonColumn';
|
||||||
|
export type { ComparisonOperators } from './models/ComparisonOperators';
|
||||||
export type { ComparisonValue } from './models/ComparisonValue';
|
export type { ComparisonValue } from './models/ComparisonValue';
|
||||||
export type { ConfigSchemaResponse } from './models/ConfigSchemaResponse';
|
export type { ConfigSchemaResponse } from './models/ConfigSchemaResponse';
|
||||||
export type { Constraint } from './models/Constraint';
|
export type { Constraint } from './models/Constraint';
|
||||||
@ -32,8 +33,6 @@ export type { ExplainCapabilities } from './models/ExplainCapabilities';
|
|||||||
export type { ExplainResponse } from './models/ExplainResponse';
|
export type { ExplainResponse } from './models/ExplainResponse';
|
||||||
export type { Expression } from './models/Expression';
|
export type { Expression } from './models/Expression';
|
||||||
export type { Field } from './models/Field';
|
export type { Field } from './models/Field';
|
||||||
export type { GraphQLName } from './models/GraphQLName';
|
|
||||||
export type { GraphQLTypeDefinitions } from './models/GraphQLTypeDefinitions';
|
|
||||||
export type { MetricsCapabilities } from './models/MetricsCapabilities';
|
export type { MetricsCapabilities } from './models/MetricsCapabilities';
|
||||||
export type { MutationCapabilities } from './models/MutationCapabilities';
|
export type { MutationCapabilities } from './models/MutationCapabilities';
|
||||||
export type { NotExpression } from './models/NotExpression';
|
export type { NotExpression } from './models/NotExpression';
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import type { ComparisonCapabilities } from './ComparisonCapabilities';
|
import type { ComparisonCapabilities } from './ComparisonCapabilities';
|
||||||
import type { DataSchemaCapabilities } from './DataSchemaCapabilities';
|
import type { DataSchemaCapabilities } from './DataSchemaCapabilities';
|
||||||
import type { ExplainCapabilities } from './ExplainCapabilities';
|
import type { ExplainCapabilities } from './ExplainCapabilities';
|
||||||
import type { GraphQLTypeDefinitions } from './GraphQLTypeDefinitions';
|
|
||||||
import type { MetricsCapabilities } from './MetricsCapabilities';
|
import type { MetricsCapabilities } from './MetricsCapabilities';
|
||||||
import type { MutationCapabilities } from './MutationCapabilities';
|
import type { MutationCapabilities } from './MutationCapabilities';
|
||||||
import type { QueryCapabilities } from './QueryCapabilities';
|
import type { QueryCapabilities } from './QueryCapabilities';
|
||||||
@ -18,7 +17,6 @@ export type Capabilities = {
|
|||||||
comparisons?: ComparisonCapabilities;
|
comparisons?: ComparisonCapabilities;
|
||||||
data_schema?: DataSchemaCapabilities;
|
data_schema?: DataSchemaCapabilities;
|
||||||
explain?: ExplainCapabilities;
|
explain?: ExplainCapabilities;
|
||||||
graphql_schema?: GraphQLTypeDefinitions;
|
|
||||||
metrics?: MetricsCapabilities;
|
metrics?: MetricsCapabilities;
|
||||||
mutations?: MutationCapabilities;
|
mutations?: MutationCapabilities;
|
||||||
queries?: QueryCapabilities;
|
queries?: QueryCapabilities;
|
||||||
|
13
dc-agents/dc-api-types/src/models/ComparisonOperators.ts
Normal file
13
dc-agents/dc-api-types/src/models/ComparisonOperators.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
|
||||||
|
import type { ScalarType } from './ScalarType';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map from comparison operator names to their argument types.
|
||||||
|
* Operator and argument type names must be valid GraphQL names.
|
||||||
|
* Result type names must be defined scalar types - either builtin or declared in ScalarTypesCapabilities.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export type ComparisonOperators = Record<string, ScalarType>;
|
@ -1,8 +0,0 @@
|
|||||||
/* istanbul ignore file */
|
|
||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A valid GraphQL name
|
|
||||||
*/
|
|
||||||
export type GraphQLName = string;
|
|
@ -1,8 +0,0 @@
|
|||||||
/* istanbul ignore file */
|
|
||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A valid GraphQL schema document containing type definitions
|
|
||||||
*/
|
|
||||||
export type GraphQLTypeDefinitions = string;
|
|
@ -3,16 +3,16 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
import type { AggregateFunctions } from './AggregateFunctions';
|
import type { AggregateFunctions } from './AggregateFunctions';
|
||||||
import type { GraphQLName } from './GraphQLName';
|
import type { ComparisonOperators } from './ComparisonOperators';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Capabilities of a scalar type.
|
* Capabilities of a scalar type.
|
||||||
* comparison_type: Name of the GraphQL input object to be used for comparison operations on the scalar type. The input object type must be defined in the `graphql_schema`.
|
* comparison_operators: The comparison operators supported by the scalar type.
|
||||||
* aggregate_functions: The aggregate functions supported by the scalar type.
|
* aggregate_functions: The aggregate functions supported by the scalar type.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type ScalarTypeCapabilities = {
|
export type ScalarTypeCapabilities = {
|
||||||
aggregate_functions?: AggregateFunctions;
|
aggregate_functions?: AggregateFunctions;
|
||||||
comparison_type?: GraphQLName;
|
comparison_operators?: ComparisonOperators;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
10
dc-agents/package-lock.json
generated
10
dc-agents/package-lock.json
generated
@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"dc-api-types": {
|
"dc-api-types": {
|
||||||
"name": "@hasura/dc-api-types",
|
"name": "@hasura/dc-api-types",
|
||||||
"version": "0.13.0",
|
"version": "0.14.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node16": "^1.0.3",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
@ -631,7 +631,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^7.0.0",
|
"@fastify/cors": "^7.0.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify": "^3.29.0",
|
"fastify": "^3.29.0",
|
||||||
"mathjs": "^11.0.0",
|
"mathjs": "^11.0.0",
|
||||||
"pino-pretty": "^8.0.0",
|
"pino-pretty": "^8.0.0",
|
||||||
@ -1389,7 +1389,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^8.1.0",
|
"@fastify/cors": "^8.1.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify": "^4.4.0",
|
"fastify": "^4.4.0",
|
||||||
"fastify-metrics": "^9.2.1",
|
"fastify-metrics": "^9.2.1",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
@ -3122,7 +3122,7 @@
|
|||||||
"version": "file:reference",
|
"version": "file:reference",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@fastify/cors": "^7.0.0",
|
"@fastify/cors": "^7.0.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"@tsconfig/node16": "^1.0.3",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
"@types/node": "^16.11.49",
|
"@types/node": "^16.11.49",
|
||||||
"@types/xml2js": "^0.4.11",
|
"@types/xml2js": "^0.4.11",
|
||||||
@ -3613,7 +3613,7 @@
|
|||||||
"version": "file:sqlite",
|
"version": "file:sqlite",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@fastify/cors": "^8.1.0",
|
"@fastify/cors": "^8.1.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"@tsconfig/node16": "^1.0.3",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
"@types/node": "^16.11.49",
|
"@types/node": "^16.11.49",
|
||||||
"@types/sqlite3": "^3.1.8",
|
"@types/sqlite3": "^3.1.8",
|
||||||
|
4
dc-agents/reference/package-lock.json
generated
4
dc-agents/reference/package-lock.json
generated
@ -10,7 +10,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^7.0.0",
|
"@fastify/cors": "^7.0.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify": "^3.29.0",
|
"fastify": "^3.29.0",
|
||||||
"mathjs": "^11.0.0",
|
"mathjs": "^11.0.0",
|
||||||
"pino-pretty": "^8.0.0",
|
"pino-pretty": "^8.0.0",
|
||||||
@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@hasura/dc-api-types": {
|
"node_modules/@hasura/dc-api-types": {
|
||||||
"version": "0.13.0",
|
"version": "0.14.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node16": "^1.0.3",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^7.0.0",
|
"@fastify/cors": "^7.0.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify": "^3.29.0",
|
"fastify": "^3.29.0",
|
||||||
"mathjs": "^11.0.0",
|
"mathjs": "^11.0.0",
|
||||||
"pino-pretty": "^8.0.0",
|
"pino-pretty": "^8.0.0",
|
||||||
|
@ -1,17 +1,11 @@
|
|||||||
import { configSchema } from "./config"
|
import { configSchema } from "./config"
|
||||||
import { Capabilities, CapabilitiesResponse, ScalarTypeCapabilities, ScalarTypesCapabilities } from "@hasura/dc-api-types"
|
import { Capabilities, CapabilitiesResponse, ScalarTypeCapabilities, ScalarTypesCapabilities } from "@hasura/dc-api-types"
|
||||||
|
|
||||||
const schemaDoc: string =
|
|
||||||
`scalar DateTime
|
|
||||||
|
|
||||||
input DateTimeComparisons {
|
|
||||||
same_day_as: DateTime
|
|
||||||
in_year: Int
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const dateTimeCapabilities: ScalarTypeCapabilities = {
|
const dateTimeCapabilities: ScalarTypeCapabilities = {
|
||||||
comparison_type: 'DateTimeComparisons',
|
comparison_operators: {
|
||||||
|
same_day_as: 'DateTime',
|
||||||
|
in_year: 'Int'
|
||||||
|
},
|
||||||
aggregate_functions: {
|
aggregate_functions: {
|
||||||
max: 'DateTime',
|
max: 'DateTime',
|
||||||
min: 'DateTime'
|
min: 'DateTime'
|
||||||
@ -43,7 +37,6 @@ const capabilities: Capabilities = {
|
|||||||
supports_relations: true
|
supports_relations: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
graphql_schema: schemaDoc,
|
|
||||||
scalar_types: scalarTypes
|
scalar_types: scalarTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
dc-agents/sqlite/package-lock.json
generated
4
dc-agents/sqlite/package-lock.json
generated
@ -10,7 +10,7 @@
|
|||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^8.1.0",
|
"@fastify/cors": "^8.1.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify": "^4.4.0",
|
"fastify": "^4.4.0",
|
||||||
"fastify-metrics": "^9.2.1",
|
"fastify-metrics": "^9.2.1",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
@ -54,7 +54,7 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@hasura/dc-api-types": {
|
"node_modules/@hasura/dc-api-types": {
|
||||||
"version": "0.13.0",
|
"version": "0.14.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node16": "^1.0.3",
|
"@tsconfig/node16": "^1.0.3",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/cors": "^8.1.0",
|
"@fastify/cors": "^8.1.0",
|
||||||
"@hasura/dc-api-types": "0.13.0",
|
"@hasura/dc-api-types": "0.14.0",
|
||||||
"fastify-metrics": "^9.2.1",
|
"fastify-metrics": "^9.2.1",
|
||||||
"fastify": "^4.4.0",
|
"fastify": "^4.4.0",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
|
@ -10,7 +10,6 @@ export const capabilitiesResponse: CapabilitiesResponse = {
|
|||||||
supports_foreign_keys: true,
|
supports_foreign_keys: true,
|
||||||
column_nullability: "nullable_and_non_nullable",
|
column_nullability: "nullable_and_non_nullable",
|
||||||
},
|
},
|
||||||
graphql_schema: "scalar DateTime",
|
|
||||||
scalar_types: {
|
scalar_types: {
|
||||||
DateTime: {}
|
DateTime: {}
|
||||||
},
|
},
|
||||||
|
@ -13,10 +13,10 @@ module Hasura.Backends.DataConnector.API.V0.Capabilities
|
|||||||
QueryCapabilities (..),
|
QueryCapabilities (..),
|
||||||
MutationCapabilities (..),
|
MutationCapabilities (..),
|
||||||
SubscriptionCapabilities (..),
|
SubscriptionCapabilities (..),
|
||||||
|
ComparisonOperators (..),
|
||||||
AggregateFunctions (..),
|
AggregateFunctions (..),
|
||||||
ScalarTypeCapabilities (..),
|
ScalarTypeCapabilities (..),
|
||||||
ScalarTypesCapabilities (..),
|
ScalarTypesCapabilities (..),
|
||||||
GraphQLTypeDefinitions,
|
|
||||||
RelationshipCapabilities (..),
|
RelationshipCapabilities (..),
|
||||||
ComparisonCapabilities (..),
|
ComparisonCapabilities (..),
|
||||||
SubqueryComparisonCapabilities (..),
|
SubqueryComparisonCapabilities (..),
|
||||||
@ -24,8 +24,6 @@ module Hasura.Backends.DataConnector.API.V0.Capabilities
|
|||||||
ExplainCapabilities (..),
|
ExplainCapabilities (..),
|
||||||
RawCapabilities (..),
|
RawCapabilities (..),
|
||||||
CapabilitiesResponse (..),
|
CapabilitiesResponse (..),
|
||||||
lookupComparisonInputObjectDefinition,
|
|
||||||
mkGraphQLTypeDefinitions,
|
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -70,8 +68,7 @@ data Capabilities = Capabilities
|
|||||||
_cQueries :: Maybe QueryCapabilities,
|
_cQueries :: Maybe QueryCapabilities,
|
||||||
_cMutations :: Maybe MutationCapabilities,
|
_cMutations :: Maybe MutationCapabilities,
|
||||||
_cSubscriptions :: Maybe SubscriptionCapabilities,
|
_cSubscriptions :: Maybe SubscriptionCapabilities,
|
||||||
_cScalarTypes :: Maybe ScalarTypesCapabilities,
|
_cScalarTypes :: ScalarTypesCapabilities,
|
||||||
_cGraphQLTypeDefinitions :: Maybe GraphQLTypeDefinitions,
|
|
||||||
_cRelationships :: Maybe RelationshipCapabilities,
|
_cRelationships :: Maybe RelationshipCapabilities,
|
||||||
_cComparisons :: Maybe ComparisonCapabilities,
|
_cComparisons :: Maybe ComparisonCapabilities,
|
||||||
_cMetrics :: Maybe MetricsCapabilities,
|
_cMetrics :: Maybe MetricsCapabilities,
|
||||||
@ -83,7 +80,7 @@ data Capabilities = Capabilities
|
|||||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec Capabilities
|
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec Capabilities
|
||||||
|
|
||||||
defaultCapabilities :: Capabilities
|
defaultCapabilities :: Capabilities
|
||||||
defaultCapabilities = Capabilities defaultDataSchemaCapabilities Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
defaultCapabilities = Capabilities defaultDataSchemaCapabilities Nothing Nothing Nothing mempty Nothing Nothing Nothing Nothing Nothing
|
||||||
|
|
||||||
instance HasCodec Capabilities where
|
instance HasCodec Capabilities where
|
||||||
codec =
|
codec =
|
||||||
@ -93,8 +90,7 @@ instance HasCodec Capabilities where
|
|||||||
<*> optionalField "queries" "The agent's query capabilities" .= _cQueries
|
<*> optionalField "queries" "The agent's query capabilities" .= _cQueries
|
||||||
<*> optionalField "mutations" "The agent's mutation capabilities" .= _cMutations
|
<*> optionalField "mutations" "The agent's mutation capabilities" .= _cMutations
|
||||||
<*> optionalField "subscriptions" "The agent's subscription capabilities" .= _cSubscriptions
|
<*> optionalField "subscriptions" "The agent's subscription capabilities" .= _cSubscriptions
|
||||||
<*> optionalField "scalar_types" "The agent's scalar types and their capabilities" .= _cScalarTypes
|
<*> optionalFieldWithOmittedDefault "scalar_types" mempty "The agent's scalar types and their capabilities" .= _cScalarTypes
|
||||||
<*> optionalField "graphql_schema" "A GraphQL Schema Document describing the agent's scalar types and input object types for comparison operators" .= _cGraphQLTypeDefinitions
|
|
||||||
<*> optionalField "relationships" "The agent's relationship capabilities" .= _cRelationships
|
<*> optionalField "relationships" "The agent's relationship capabilities" .= _cRelationships
|
||||||
<*> optionalField "comparisons" "The agent's comparison capabilities" .= _cComparisons
|
<*> optionalField "comparisons" "The agent's comparison capabilities" .= _cComparisons
|
||||||
<*> optionalField "metrics" "The agent's metrics capabilities" .= _cMetrics
|
<*> optionalField "metrics" "The agent's metrics capabilities" .= _cMetrics
|
||||||
@ -170,11 +166,29 @@ data RelationshipCapabilities = RelationshipCapabilities {}
|
|||||||
instance HasCodec RelationshipCapabilities where
|
instance HasCodec RelationshipCapabilities where
|
||||||
codec = object "RelationshipCapabilities" $ pure RelationshipCapabilities
|
codec = object "RelationshipCapabilities" $ pure RelationshipCapabilities
|
||||||
|
|
||||||
|
newtype ComparisonOperators = ComparisonOperators
|
||||||
|
{ unComparisonOperators :: HashMap GQL.Syntax.Name ScalarType
|
||||||
|
}
|
||||||
|
deriving stock (Eq, Ord, Show, Generic)
|
||||||
|
deriving anyclass (NFData, Hashable)
|
||||||
|
deriving newtype (Semigroup, Monoid)
|
||||||
|
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ComparisonOperators
|
||||||
|
|
||||||
|
instance HasCodec ComparisonOperators where
|
||||||
|
codec =
|
||||||
|
named "ComparisonOperators" $
|
||||||
|
dimapCodec ComparisonOperators unComparisonOperators (hashMapCodec codec)
|
||||||
|
<??> [ "A map from comparison operator names to their argument types.",
|
||||||
|
"Operator and argument type names must be valid GraphQL names.",
|
||||||
|
"Result type names must be defined scalar types - either builtin or declared in ScalarTypesCapabilities."
|
||||||
|
]
|
||||||
|
|
||||||
newtype AggregateFunctions = AggregateFunctions
|
newtype AggregateFunctions = AggregateFunctions
|
||||||
{ unAggregateFunctions :: HashMap GQL.Syntax.Name ScalarType
|
{ unAggregateFunctions :: HashMap GQL.Syntax.Name ScalarType
|
||||||
}
|
}
|
||||||
deriving stock (Eq, Ord, Show, Generic)
|
deriving stock (Eq, Ord, Show, Generic)
|
||||||
deriving anyclass (NFData, Hashable)
|
deriving anyclass (NFData, Hashable)
|
||||||
|
deriving newtype (Semigroup, Monoid)
|
||||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec AggregateFunctions
|
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec AggregateFunctions
|
||||||
|
|
||||||
instance HasCodec AggregateFunctions where
|
instance HasCodec AggregateFunctions where
|
||||||
@ -187,8 +201,8 @@ instance HasCodec AggregateFunctions where
|
|||||||
]
|
]
|
||||||
|
|
||||||
data ScalarTypeCapabilities = ScalarTypeCapabilities
|
data ScalarTypeCapabilities = ScalarTypeCapabilities
|
||||||
{ _stcComparisonInputObject :: Maybe GQL.Syntax.Name,
|
{ _stcComparisonOperators :: ComparisonOperators,
|
||||||
_stcAggregateFunctions :: Maybe AggregateFunctions
|
_stcAggregateFunctions :: AggregateFunctions
|
||||||
}
|
}
|
||||||
deriving stock (Eq, Ord, Show, Generic)
|
deriving stock (Eq, Ord, Show, Generic)
|
||||||
deriving anyclass (NFData, Hashable)
|
deriving anyclass (NFData, Hashable)
|
||||||
@ -199,11 +213,11 @@ instance HasCodec ScalarTypeCapabilities where
|
|||||||
object
|
object
|
||||||
"ScalarTypeCapabilities"
|
"ScalarTypeCapabilities"
|
||||||
( ScalarTypeCapabilities
|
( ScalarTypeCapabilities
|
||||||
<$> optionalFieldWith' "comparison_type" nameCodec .= _stcComparisonInputObject
|
<$> optionalFieldWithOmittedDefault' "comparison_operators" mempty .= _stcComparisonOperators
|
||||||
<*> optionalField' "aggregate_functions" .= _stcAggregateFunctions
|
<*> optionalFieldWithOmittedDefault' "aggregate_functions" mempty .= _stcAggregateFunctions
|
||||||
)
|
)
|
||||||
<??> [ "Capabilities of a scalar type.",
|
<??> [ "Capabilities of a scalar type.",
|
||||||
"comparison_type: Name of the GraphQL input object to be used for comparison operations on the scalar type. The input object type must be defined in the `graphql_schema`.",
|
"comparison_operators: The comparison operators supported by the scalar type.",
|
||||||
"aggregate_functions: The aggregate functions supported by the scalar type."
|
"aggregate_functions: The aggregate functions supported by the scalar type."
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -223,63 +237,6 @@ instance HasCodec ScalarTypesCapabilities where
|
|||||||
"Keys must be valid GraphQL names and must be defined as scalar types in the `graphql_schema`"
|
"Keys must be valid GraphQL names and must be defined as scalar types in the `graphql_schema`"
|
||||||
]
|
]
|
||||||
|
|
||||||
type TypeDefinition = GQL.Syntax.TypeDefinition () GQL.Syntax.InputValueDefinition
|
|
||||||
|
|
||||||
mkGraphQLTypeDefinitions :: NonEmpty TypeDefinition -> GraphQLTypeDefinitions
|
|
||||||
mkGraphQLTypeDefinitions =
|
|
||||||
GraphQLTypeDefinitions
|
|
||||||
. InsOrdHashMap.fromList
|
|
||||||
. toList
|
|
||||||
. fmap (\td -> (getName td, td))
|
|
||||||
where
|
|
||||||
getName :: TypeDefinition -> GQL.Syntax.Name
|
|
||||||
getName = \case
|
|
||||||
GQL.Syntax.TypeDefinitionScalar GQL.Syntax.ScalarTypeDefinition {..} -> _stdName
|
|
||||||
GQL.Syntax.TypeDefinitionObject GQL.Syntax.ObjectTypeDefinition {..} -> _otdName
|
|
||||||
GQL.Syntax.TypeDefinitionInterface GQL.Syntax.InterfaceTypeDefinition {..} -> _itdName
|
|
||||||
GQL.Syntax.TypeDefinitionUnion GQL.Syntax.UnionTypeDefinition {..} -> _utdName
|
|
||||||
GQL.Syntax.TypeDefinitionEnum GQL.Syntax.EnumTypeDefinition {..} -> _etdName
|
|
||||||
GQL.Syntax.TypeDefinitionInputObject GQL.Syntax.InputObjectTypeDefinition {..} -> _iotdName
|
|
||||||
|
|
||||||
newtype GraphQLTypeDefinitions = GraphQLTypeDefinitions
|
|
||||||
{ _gtdTypeDefinitions :: InsOrdHashMap GQL.Syntax.Name TypeDefinition
|
|
||||||
}
|
|
||||||
deriving stock (Eq, Show, Generic)
|
|
||||||
deriving anyclass (NFData, Hashable)
|
|
||||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec GraphQLTypeDefinitions
|
|
||||||
|
|
||||||
instance HasCodec GraphQLTypeDefinitions where
|
|
||||||
codec =
|
|
||||||
bimapCodec parseTypeDefinitions printTypeDefinitions (StringCodec (Just "GraphQLTypeDefinitions"))
|
|
||||||
<?> "A valid GraphQL schema document containing type definitions"
|
|
||||||
where
|
|
||||||
-- Note: any `SchemaDefinition`s in the parsed `SchemaDocument` will be ignored.
|
|
||||||
-- We don't need them, we're only interested in the `TypeDefinition`s defined in the document.
|
|
||||||
getTypeDefinition :: GQL.Syntax.TypeSystemDefinition -> Maybe TypeDefinition
|
|
||||||
getTypeDefinition = \case
|
|
||||||
GQL.Syntax.TypeSystemDefinitionSchema _ -> Nothing
|
|
||||||
GQL.Syntax.TypeSystemDefinitionType td -> Just td
|
|
||||||
|
|
||||||
fromSchemaDocument :: GQL.Syntax.SchemaDocument -> Either String GraphQLTypeDefinitions
|
|
||||||
fromSchemaDocument (GQL.Syntax.SchemaDocument typeSystemDefinitions) =
|
|
||||||
case nonEmpty $ mapMaybe getTypeDefinition typeSystemDefinitions of
|
|
||||||
Nothing -> Left "No type definitions found in schema document"
|
|
||||||
Just typeDefinitions -> Right $ mkGraphQLTypeDefinitions typeDefinitions
|
|
||||||
|
|
||||||
parseTypeDefinitions :: Text -> Either String GraphQLTypeDefinitions
|
|
||||||
parseTypeDefinitions =
|
|
||||||
fromSchemaDocument <=< first Text.unpack . GQL.Parser.parseSchemaDocument
|
|
||||||
|
|
||||||
printTypeDefinitions :: GraphQLTypeDefinitions -> Text
|
|
||||||
printTypeDefinitions =
|
|
||||||
toStrict
|
|
||||||
. Builder.toLazyText
|
|
||||||
. GQL.Printer.schemaDocument
|
|
||||||
. GQL.Syntax.SchemaDocument
|
|
||||||
. fmap GQL.Syntax.TypeSystemDefinitionType
|
|
||||||
. toList
|
|
||||||
. _gtdTypeDefinitions
|
|
||||||
|
|
||||||
data ComparisonCapabilities = ComparisonCapabilities
|
data ComparisonCapabilities = ComparisonCapabilities
|
||||||
{_ccSubqueryComparisonCapabilities :: Maybe SubqueryComparisonCapabilities}
|
{_ccSubqueryComparisonCapabilities :: Maybe SubqueryComparisonCapabilities}
|
||||||
deriving stock (Eq, Ord, Show, Generic, Data)
|
deriving stock (Eq, Ord, Show, Generic, Data)
|
||||||
@ -365,14 +322,3 @@ instance ToSchema CapabilitiesResponse where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pure $ NamedSchema (Just "CapabilitiesResponse") schema
|
pure $ NamedSchema (Just "CapabilitiesResponse") schema
|
||||||
|
|
||||||
lookupComparisonInputObjectDefinition :: Capabilities -> ScalarType -> Maybe (GQL.Syntax.InputObjectTypeDefinition GQL.Syntax.InputValueDefinition)
|
|
||||||
lookupComparisonInputObjectDefinition Capabilities {..} typeName = do
|
|
||||||
scalarTypesMap <- _cScalarTypes
|
|
||||||
ScalarTypeCapabilities {..} <- HashMap.lookup typeName $ unScalarTypesCapabilities scalarTypesMap
|
|
||||||
comparisonTypeName <- _stcComparisonInputObject
|
|
||||||
typeDefinitions <- _cGraphQLTypeDefinitions
|
|
||||||
typeDefinition <- InsOrdHashMap.lookup comparisonTypeName $ _gtdTypeDefinitions typeDefinitions
|
|
||||||
case typeDefinition of
|
|
||||||
GQL.Syntax.TypeDefinitionInputObject inputObjectTypeDefinition -> Just inputObjectTypeDefinition
|
|
||||||
_ -> Nothing
|
|
||||||
|
@ -42,8 +42,7 @@ capabilities =
|
|||||||
API._cQueries = Just API.QueryCapabilities,
|
API._cQueries = Just API.QueryCapabilities,
|
||||||
API._cMutations = Nothing,
|
API._cMutations = Nothing,
|
||||||
API._cSubscriptions = Nothing,
|
API._cSubscriptions = Nothing,
|
||||||
API._cScalarTypes = Nothing,
|
API._cScalarTypes = mempty,
|
||||||
API._cGraphQLTypeDefinitions = Nothing,
|
|
||||||
API._cRelationships = Just API.RelationshipCapabilities {},
|
API._cRelationships = Just API.RelationshipCapabilities {},
|
||||||
API._cComparisons =
|
API._cComparisons =
|
||||||
Just
|
Just
|
||||||
|
@ -56,8 +56,6 @@ defaultBackendCapabilities = \case
|
|||||||
supports_foreign_keys: true
|
supports_foreign_keys: true
|
||||||
scalar_types:
|
scalar_types:
|
||||||
DateTime: {}
|
DateTime: {}
|
||||||
graphql_schema: |-
|
|
||||||
scalar DateTime
|
|
||||||
queries: {}
|
queries: {}
|
||||||
relationships: {}
|
relationships: {}
|
||||||
comparisons:
|
comparisons:
|
||||||
@ -74,19 +72,15 @@ defaultBackendCapabilities = \case
|
|||||||
supports_primary_keys: true
|
supports_primary_keys: true
|
||||||
supports_foreign_keys: true
|
supports_foreign_keys: true
|
||||||
queries: {}
|
queries: {}
|
||||||
graphql_schema: |-
|
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
input DateTimeComparisons {in_year: Int
|
|
||||||
same_day_as: DateTime
|
|
||||||
}
|
|
||||||
relationships: {}
|
relationships: {}
|
||||||
comparisons:
|
comparisons:
|
||||||
subquery:
|
subquery:
|
||||||
supports_relations: true
|
supports_relations: true
|
||||||
scalar_types:
|
scalar_types:
|
||||||
DateTime:
|
DateTime:
|
||||||
comparison_type: DateTimeComparisons
|
comparison_operators:
|
||||||
|
same_day_as: DateTime
|
||||||
|
in_year: Int
|
||||||
aggregate_functions:
|
aggregate_functions:
|
||||||
max: DateTime
|
max: DateTime
|
||||||
min: DateTime
|
min: DateTime
|
||||||
|
@ -92,10 +92,10 @@ instance Backend 'DataConnector where
|
|||||||
getCustomAggregateOperators Adapter.SourceConfig {..} =
|
getCustomAggregateOperators Adapter.SourceConfig {..} =
|
||||||
HashMap.foldrWithKey insertOps mempty scalarTypesCapabilities
|
HashMap.foldrWithKey insertOps mempty scalarTypesCapabilities
|
||||||
where
|
where
|
||||||
scalarTypesCapabilities = maybe mempty API.unScalarTypesCapabilities $ API._cScalarTypes _scCapabilities
|
scalarTypesCapabilities = API.unScalarTypesCapabilities $ API._cScalarTypes _scCapabilities
|
||||||
insertOps typeName API.ScalarTypeCapabilities {..} m =
|
insertOps typeName API.ScalarTypeCapabilities {..} m =
|
||||||
HashMap.foldrWithKey insertOp m $
|
HashMap.foldrWithKey insertOp m $
|
||||||
maybe mempty API.unAggregateFunctions _stcAggregateFunctions
|
API.unAggregateFunctions _stcAggregateFunctions
|
||||||
where
|
where
|
||||||
insertOp funtionName resultTypeName =
|
insertOp funtionName resultTypeName =
|
||||||
HashMap.insertWith HashMap.union funtionName $
|
HashMap.insertWith HashMap.union funtionName $
|
||||||
|
@ -12,7 +12,7 @@ import Data.HashMap.Strict qualified as Map
|
|||||||
import Data.List.NonEmpty qualified as NE
|
import Data.List.NonEmpty qualified as NE
|
||||||
import Data.Text.Casing (GQLNameIdentifier, fromCustomName)
|
import Data.Text.Casing (GQLNameIdentifier, fromCustomName)
|
||||||
import Data.Text.Extended ((<<>))
|
import Data.Text.Extended ((<<>))
|
||||||
import Hasura.Backends.DataConnector.API.V0.Capabilities (lookupComparisonInputObjectDefinition)
|
import Hasura.Backends.DataConnector.API qualified as API
|
||||||
import Hasura.Backends.DataConnector.Adapter.Backend (CustomBooleanOperator (..), columnTypeToScalarType)
|
import Hasura.Backends.DataConnector.Adapter.Backend (CustomBooleanOperator (..), columnTypeToScalarType)
|
||||||
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
|
import Hasura.Backends.DataConnector.Adapter.Types qualified as DC
|
||||||
import Hasura.Base.Error
|
import Hasura.Base.Error
|
||||||
@ -204,28 +204,28 @@ comparisonExps' sourceInfo columnType = P.memoizeOn 'comparisonExps' (dataConnec
|
|||||||
GS.C.SchemaT r m [P.InputFieldsParser n (Maybe (CustomBooleanOperator (IR.UnpreparedValue 'DataConnector)))]
|
GS.C.SchemaT r m [P.InputFieldsParser n (Maybe (CustomBooleanOperator (IR.UnpreparedValue 'DataConnector)))]
|
||||||
mkCustomOperators tCase collapseIfNull typeName = do
|
mkCustomOperators tCase collapseIfNull typeName = do
|
||||||
let capabilities = sourceInfo ^. RQL.siConfiguration . DC.scCapabilities
|
let capabilities = sourceInfo ^. RQL.siConfiguration . DC.scCapabilities
|
||||||
case lookupComparisonInputObjectDefinition capabilities (Witch.from $ DC.fromGQLType typeName) of
|
case Map.lookup (Witch.from $ DC.fromGQLType typeName) (API.unScalarTypesCapabilities $ API._cScalarTypes capabilities) of
|
||||||
Nothing -> pure []
|
Nothing -> pure []
|
||||||
Just GQL.InputObjectTypeDefinition {..} -> do
|
Just API.ScalarTypeCapabilities {..} -> do
|
||||||
traverse (mkCustomOperator tCase collapseIfNull) _iotdValueDefinitions
|
traverse (mkCustomOperator tCase collapseIfNull) $ Map.toList $ fmap Witch.from $ API.unComparisonOperators $ _stcComparisonOperators
|
||||||
|
|
||||||
mkCustomOperator ::
|
mkCustomOperator ::
|
||||||
NamingCase ->
|
NamingCase ->
|
||||||
Options.DangerouslyCollapseBooleans ->
|
Options.DangerouslyCollapseBooleans ->
|
||||||
GQL.InputValueDefinition ->
|
(GQL.Name, DC.ScalarType) ->
|
||||||
GS.C.SchemaT r m (P.InputFieldsParser n (Maybe (CustomBooleanOperator (IR.UnpreparedValue 'DataConnector))))
|
GS.C.SchemaT r m (P.InputFieldsParser n (Maybe (CustomBooleanOperator (IR.UnpreparedValue 'DataConnector))))
|
||||||
mkCustomOperator tCase collapseIfNull GQL.InputValueDefinition {..} = do
|
mkCustomOperator tCase collapseIfNull (operatorName, argType) = do
|
||||||
argParser <- mkArgParser _ivdType
|
argParser <- mkArgParser argType
|
||||||
pure $
|
pure $
|
||||||
GS.BE.mkBoolOperator tCase collapseIfNull (fromCustomName _ivdName) _ivdDescription $
|
GS.BE.mkBoolOperator tCase collapseIfNull (fromCustomName operatorName) Nothing $
|
||||||
CustomBooleanOperator (GQL.unName _ivdName) . Just . Right <$> argParser
|
CustomBooleanOperator (GQL.unName operatorName) . Just . Right <$> argParser
|
||||||
|
|
||||||
mkArgParser :: GQL.GType -> GS.C.SchemaT r m (P.Parser 'P.Both n (IR.UnpreparedValue 'DataConnector))
|
mkArgParser :: DC.ScalarType -> GS.C.SchemaT r m (P.Parser 'P.Both n (IR.UnpreparedValue 'DataConnector))
|
||||||
mkArgParser argType =
|
mkArgParser argType =
|
||||||
fmap IR.mkParameter
|
fmap IR.mkParameter
|
||||||
<$> columnParser'
|
<$> columnParser'
|
||||||
(RQL.ColumnScalar $ DC.fromGQLType $ GQL.getBaseType argType)
|
(RQL.ColumnScalar argType)
|
||||||
(GQL.Nullability $ GQL.isNotNull argType)
|
(GQL.Nullability True)
|
||||||
|
|
||||||
tableArgs' ::
|
tableArgs' ::
|
||||||
forall r m n.
|
forall r m n.
|
||||||
|
@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
module Hasura.Backends.DataConnector.API.V0.CapabilitiesSpec (spec) where
|
module Hasura.Backends.DataConnector.API.V0.CapabilitiesSpec (spec) where
|
||||||
|
|
||||||
import Data.Aeson (Value (..))
|
|
||||||
import Data.Aeson.QQ.Simple (aesonQQ)
|
import Data.Aeson.QQ.Simple (aesonQQ)
|
||||||
import Data.HashMap.Strict qualified as HashMap
|
import Data.HashMap.Strict qualified as HashMap
|
||||||
import Data.Text.RawString (raw)
|
|
||||||
import Hasura.Backends.DataConnector.API.V0.Capabilities
|
import Hasura.Backends.DataConnector.API.V0.Capabilities
|
||||||
import Hasura.Backends.DataConnector.API.V0.ConfigSchema
|
import Hasura.Backends.DataConnector.API.V0.ConfigSchema
|
||||||
import Hasura.Backends.DataConnector.API.V0.Scalar (ScalarType (..))
|
import Hasura.Backends.DataConnector.API.V0.Scalar (ScalarType (..))
|
||||||
@ -15,8 +13,6 @@ import Hasura.Generator.Common
|
|||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
import Hedgehog
|
import Hedgehog
|
||||||
import Hedgehog.Gen qualified as Gen
|
import Hedgehog.Gen qualified as Gen
|
||||||
import Language.GraphQL.Draft.Generator (genTypeDefinition)
|
|
||||||
import Language.GraphQL.Draft.Syntax qualified as G
|
|
||||||
import Language.GraphQL.Draft.Syntax.QQ qualified as G
|
import Language.GraphQL.Draft.Syntax.QQ qualified as G
|
||||||
import Test.Aeson.Utils
|
import Test.Aeson.Utils
|
||||||
import Test.Hspec
|
import Test.Hspec
|
||||||
@ -31,36 +27,21 @@ spec = do
|
|||||||
(CapabilitiesResponse (defaultCapabilities {_cRelationships = Just RelationshipCapabilities {}}) emptyConfigSchemaResponse)
|
(CapabilitiesResponse (defaultCapabilities {_cRelationships = Just RelationshipCapabilities {}}) emptyConfigSchemaResponse)
|
||||||
[aesonQQ|{"capabilities": {"relationships": {}}, "config_schemas": {"config_schema": {}, "other_schemas": {}}}|]
|
[aesonQQ|{"capabilities": {"relationships": {}}, "config_schemas": {"config_schema": {}, "other_schemas": {}}}|]
|
||||||
describe "ScalarTypesCapabilities" $ do
|
describe "ScalarTypesCapabilities" $ do
|
||||||
testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton StringTy (ScalarTypeCapabilities Nothing Nothing))) [aesonQQ|{"string": {}}|]
|
testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton StringTy (ScalarTypeCapabilities mempty mempty))) [aesonQQ|{"string": {}}|]
|
||||||
jsonOpenApiProperties genScalarTypesCapabilities
|
jsonOpenApiProperties genScalarTypesCapabilities
|
||||||
describe "ScalarTypeCapabilities" $ do
|
describe "ScalarTypeCapabilities" $ do
|
||||||
testToFromJSONToSchema (ScalarTypeCapabilities (Just [G.name|DateTimeComparisons|]) Nothing) [aesonQQ|{"comparison_type": "DateTimeComparisons"}|]
|
let comparisonOperators = ComparisonOperators $ HashMap.fromList [([G.name|same_day_as|], CustomTy "DateTime")]
|
||||||
describe "GraphQLTypeDefinitions" $ do
|
let aggregateFunctions = AggregateFunctions $ HashMap.fromList [([G.name|max|], CustomTy "DateTime")]
|
||||||
testToFromJSONToSchema sampleGraphQLTypeDefinitions sampleGraphQLTypeDefinitionsJSON
|
let json =
|
||||||
|
[aesonQQ|{
|
||||||
sampleGraphQLTypeDefinitions :: GraphQLTypeDefinitions
|
"comparison_operators": {
|
||||||
sampleGraphQLTypeDefinitions =
|
"same_day_as": "DateTime"
|
||||||
mkGraphQLTypeDefinitions
|
},
|
||||||
[ G.TypeDefinitionScalar $ G.ScalarTypeDefinition Nothing [G.name|DateTime|] [],
|
"aggregate_functions": {
|
||||||
G.TypeDefinitionInputObject $
|
"max": "DateTime"
|
||||||
G.InputObjectTypeDefinition
|
}
|
||||||
Nothing
|
}|]
|
||||||
[G.name|DateTimeComparisons|]
|
testToFromJSONToSchema (ScalarTypeCapabilities comparisonOperators aggregateFunctions) json
|
||||||
[]
|
|
||||||
[ G.InputValueDefinition Nothing [G.name|after|] (G.TypeNamed (G.Nullability True) [G.name|DateTime|]) Nothing [],
|
|
||||||
G.InputValueDefinition Nothing [G.name|before|] (G.TypeNamed (G.Nullability True) [G.name|DateTime|]) Nothing [],
|
|
||||||
G.InputValueDefinition Nothing [G.name|in_year|] (G.TypeNamed (G.Nullability True) [G.name|Int|]) Nothing []
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
sampleGraphQLTypeDefinitionsJSON :: Value
|
|
||||||
sampleGraphQLTypeDefinitionsJSON =
|
|
||||||
[raw|scalar DateTime
|
|
||||||
|
|
||||||
input DateTimeComparisons {after: DateTime
|
|
||||||
before: DateTime
|
|
||||||
in_year: Int
|
|
||||||
}|]
|
|
||||||
|
|
||||||
genDataSchemaCapabilities :: MonadGen m => m DataSchemaCapabilities
|
genDataSchemaCapabilities :: MonadGen m => m DataSchemaCapabilities
|
||||||
genDataSchemaCapabilities =
|
genDataSchemaCapabilities =
|
||||||
@ -82,6 +63,10 @@ genMutationCapabilities = pure MutationCapabilities {}
|
|||||||
genSubscriptionCapabilities :: MonadGen m => m SubscriptionCapabilities
|
genSubscriptionCapabilities :: MonadGen m => m SubscriptionCapabilities
|
||||||
genSubscriptionCapabilities = pure SubscriptionCapabilities {}
|
genSubscriptionCapabilities = pure SubscriptionCapabilities {}
|
||||||
|
|
||||||
|
genComparisonOperators :: MonadGen m => m ComparisonOperators
|
||||||
|
genComparisonOperators =
|
||||||
|
ComparisonOperators <$> genHashMap (genGName defaultRange) genScalarType defaultRange
|
||||||
|
|
||||||
genAggregateFunctions :: MonadGen m => m AggregateFunctions
|
genAggregateFunctions :: MonadGen m => m AggregateFunctions
|
||||||
genAggregateFunctions =
|
genAggregateFunctions =
|
||||||
AggregateFunctions <$> genHashMap (genGName defaultRange) genScalarType defaultRange
|
AggregateFunctions <$> genHashMap (genGName defaultRange) genScalarType defaultRange
|
||||||
@ -89,55 +74,13 @@ genAggregateFunctions =
|
|||||||
genScalarTypeCapabilities :: MonadGen m => m ScalarTypeCapabilities
|
genScalarTypeCapabilities :: MonadGen m => m ScalarTypeCapabilities
|
||||||
genScalarTypeCapabilities =
|
genScalarTypeCapabilities =
|
||||||
ScalarTypeCapabilities
|
ScalarTypeCapabilities
|
||||||
<$> Gen.maybe (genGName defaultRange)
|
<$> genComparisonOperators
|
||||||
<*> Gen.maybe genAggregateFunctions
|
<*> genAggregateFunctions
|
||||||
|
|
||||||
genScalarTypesCapabilities :: MonadGen m => m ScalarTypesCapabilities
|
genScalarTypesCapabilities :: MonadGen m => m ScalarTypesCapabilities
|
||||||
genScalarTypesCapabilities =
|
genScalarTypesCapabilities =
|
||||||
ScalarTypesCapabilities <$> genHashMap genScalarType genScalarTypeCapabilities defaultRange
|
ScalarTypesCapabilities <$> genHashMap genScalarType genScalarTypeCapabilities defaultRange
|
||||||
|
|
||||||
-- | 'genTypeDefinition' generates invalid type definitions so we need to filter them out.
|
|
||||||
-- The printers also sort various lists upon printing, so we need to pre-sort them for round-tripping to work.
|
|
||||||
-- The printer for 'ObjectTypeDefinition' prints directives in the wrong place so we only allow
|
|
||||||
-- definitions with no directives.
|
|
||||||
-- TODO: fix this in `graphql-parser-hs`.
|
|
||||||
isValidTypeDefinition :: Ord inputType => G.TypeDefinition possibleTypes inputType -> Maybe (G.TypeDefinition possibleTypes inputType)
|
|
||||||
isValidTypeDefinition = \case
|
|
||||||
t@(G.TypeDefinitionScalar G.ScalarTypeDefinition {}) -> Just t
|
|
||||||
G.TypeDefinitionObject G.ObjectTypeDefinition {..} -> do
|
|
||||||
guard $ not $ null _otdFieldsDefinition
|
|
||||||
Just $
|
|
||||||
G.TypeDefinitionObject
|
|
||||||
G.ObjectTypeDefinition
|
|
||||||
{ _otdFieldsDefinition = sort _otdFieldsDefinition,
|
|
||||||
_otdDirectives = [],
|
|
||||||
..
|
|
||||||
}
|
|
||||||
G.TypeDefinitionInterface G.InterfaceTypeDefinition {..} -> do
|
|
||||||
guard $ not $ null _itdFieldsDefinition
|
|
||||||
Just $
|
|
||||||
G.TypeDefinitionInterface
|
|
||||||
G.InterfaceTypeDefinition {_itdFieldsDefinition = sort _itdFieldsDefinition, ..}
|
|
||||||
G.TypeDefinitionUnion G.UnionTypeDefinition {..} -> do
|
|
||||||
guard $ not $ null _utdMemberTypes
|
|
||||||
Just $
|
|
||||||
G.TypeDefinitionUnion
|
|
||||||
G.UnionTypeDefinition {_utdMemberTypes = sort _utdMemberTypes, ..}
|
|
||||||
G.TypeDefinitionEnum G.EnumTypeDefinition {..} -> do
|
|
||||||
guard $ not $ null _etdValueDefinitions
|
|
||||||
Just $
|
|
||||||
G.TypeDefinitionEnum
|
|
||||||
G.EnumTypeDefinition {_etdValueDefinitions = sort _etdValueDefinitions, ..}
|
|
||||||
G.TypeDefinitionInputObject G.InputObjectTypeDefinition {..} -> do
|
|
||||||
guard $ not $ null _iotdValueDefinitions
|
|
||||||
Just $
|
|
||||||
G.TypeDefinitionInputObject
|
|
||||||
G.InputObjectTypeDefinition {_iotdValueDefinitions = sort _iotdValueDefinitions, ..}
|
|
||||||
|
|
||||||
genGraphQLTypeDefinitions :: Gen GraphQLTypeDefinitions
|
|
||||||
genGraphQLTypeDefinitions =
|
|
||||||
mkGraphQLTypeDefinitions <$> Gen.nonEmpty defaultRange (Gen.mapMaybe isValidTypeDefinition genTypeDefinition)
|
|
||||||
|
|
||||||
genRelationshipCapabilities :: MonadGen m => m RelationshipCapabilities
|
genRelationshipCapabilities :: MonadGen m => m RelationshipCapabilities
|
||||||
genRelationshipCapabilities = pure RelationshipCapabilities {}
|
genRelationshipCapabilities = pure RelationshipCapabilities {}
|
||||||
|
|
||||||
@ -167,8 +110,7 @@ genCapabilities =
|
|||||||
<*> Gen.maybe genQueryCapabilities
|
<*> Gen.maybe genQueryCapabilities
|
||||||
<*> Gen.maybe genMutationCapabilities
|
<*> Gen.maybe genMutationCapabilities
|
||||||
<*> Gen.maybe genSubscriptionCapabilities
|
<*> Gen.maybe genSubscriptionCapabilities
|
||||||
<*> Gen.maybe genScalarTypesCapabilities
|
<*> genScalarTypesCapabilities
|
||||||
<*> Gen.maybe genGraphQLTypeDefinitions
|
|
||||||
<*> Gen.maybe genRelationshipCapabilities
|
<*> Gen.maybe genRelationshipCapabilities
|
||||||
<*> Gen.maybe genComparisonCapabilities
|
<*> Gen.maybe genComparisonCapabilities
|
||||||
<*> Gen.maybe genMetricsCapabilities
|
<*> Gen.maybe genMetricsCapabilities
|
||||||
|
Loading…
Reference in New Issue
Block a user