mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-13 19:33:55 +03:00
Remove builtin scalar types from Data Connector backend
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7167 Co-authored-by: Daniel Chambers <1214352+daniel-chambers@users.noreply.github.com> GitOrigin-RevId: 926e7282b908e3a9669ac39d625aa54971e11c37
This commit is contained in:
parent
7393c152e3
commit
a9f77acb32
@ -165,7 +165,7 @@ The `GET /capabilities` endpoint is used by `graphql-engine` to discover the cap
|
||||
The `capabilities` section describes the _capabilities_ of the service. This includes
|
||||
- `data_schema`: What sorts of features the agent supports when describing its data schema
|
||||
- `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`: scalar types and the operations they support. See [Scalar types capabilities](#scalar-type-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.
|
||||
|
||||
@ -178,23 +178,23 @@ If the agent only supports table columns that are always nullable, then it shoul
|
||||
|
||||
#### 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.
|
||||
Agents may optionally declare support for their own custom scalar types, along with custom comparison operators and aggregate functions on those types.
|
||||
The agent may optionally specify how to parse values of custom scalar types by associating them with one of the built-in GraphQL types (`Int`, `Float`, `String`, `Boolean` or `ID`)
|
||||
Agents should declare the scalar types they support, along with the comparison operators and aggregate functions on those types.
|
||||
The agent may optionally specify how to parse values of scalar type by associating it with one of the built-in GraphQL types (`Int`, `Float`, `String`, `Boolean` or `ID`)
|
||||
|
||||
Custom scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema).
|
||||
Scalar types are declared by adding a property to the `scalar_types` section of the [capabilities](#capabilities-and-configuration-schema).
|
||||
|
||||
Custom comparison types can be defined by adding a `comparison_operators` property to the scalar type capabilities object.
|
||||
Comparison operators can be defined by adding a `comparison_operators` property to the scalar type capabilities object.
|
||||
The `comparison_operators` property is an object where each key specifies a comparison operator name.
|
||||
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.
|
||||
All scalar types must also support the built-in comparison operators `eq`, `gt`, `gte`, `lt` and `lte`.
|
||||
|
||||
Custom aggregate functions can be defined by adding an `aggregate_functions` property to the scalar type capabilities object.
|
||||
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.
|
||||
Aggregate function names must be must be valid GraphQL names.
|
||||
Result types must be valid scalar types.
|
||||
|
||||
The `graphql_type` property can be used to tell Hasura GraphQL Engine to parse values of the custom scalar type as though they were one of the built-in GraphQL scalar types `Int`, `Float`, `String`, `Boolean`, or `ID`.
|
||||
The `graphql_type` property can be used to tell Hasura GraphQL Engine to parse values of the scalar type as though they were one of the built-in GraphQL scalar types `Int`, `Float`, `String`, `Boolean`, or `ID`.
|
||||
|
||||
Example:
|
||||
|
||||
@ -210,10 +210,10 @@ capabilities:
|
||||
graphql_type: String
|
||||
```
|
||||
|
||||
This example declares a custom scalar type `DateTime` which should be parsed as though it were a GraphQL `String`.
|
||||
This example declares a scalar type `DateTime` which should be parsed as though it were a GraphQL `String`.
|
||||
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 comparison operator might look like below:
|
||||
```graphql
|
||||
query MyQuery {
|
||||
Employee(where: {BirthDate: {in_year: 1962}}) {
|
||||
@ -223,7 +223,7 @@ query MyQuery {
|
||||
}
|
||||
```
|
||||
In this query we have an `Employee` field with a `BirthDate` property of type `DateTime`.
|
||||
The `in_year` custom comparison operator is being used to request all employees with a birth date in the year 1962.
|
||||
The `in_year` comparison operator is being used to request all employees with a birth date in the year 1962.
|
||||
|
||||
The example also defines two aggregate functions `min` and `max`, both of which have a result type of `DateTime`.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@hasura/dc-api-types",
|
||||
"version": "0.19.0",
|
||||
"version": "0.20.0",
|
||||
"description": "Hasura GraphQL Engine Data Connector Agent API types",
|
||||
"author": "Hasura (https://github.com/hasura/graphql-engine)",
|
||||
"license": "Apache-2.0",
|
||||
|
@ -502,20 +502,7 @@
|
||||
},
|
||||
"SubscriptionCapabilities": {},
|
||||
"ScalarType": {
|
||||
"additionalProperties": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"enum": [
|
||||
"string",
|
||||
"number",
|
||||
"bool"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
"type": "string"
|
||||
},
|
||||
"ComparisonOperators": {
|
||||
"additionalProperties": {
|
||||
|
@ -2,5 +2,4 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
|
||||
export type ScalarType = ('string' | 'number' | 'bool' | string);
|
||||
|
||||
export type ScalarType = string;
|
||||
|
10
dc-agents/package-lock.json
generated
10
dc-agents/package-lock.json
generated
@ -24,7 +24,7 @@
|
||||
},
|
||||
"dc-api-types": {
|
||||
"name": "@hasura/dc-api-types",
|
||||
"version": "0.19.0",
|
||||
"version": "0.20.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
@ -1197,7 +1197,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^7.0.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify": "^3.29.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
@ -1781,7 +1781,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify": "^4.4.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"nanoid": "^3.3.4",
|
||||
@ -3125,7 +3125,7 @@
|
||||
"version": "file:reference",
|
||||
"requires": {
|
||||
"@fastify/cors": "^7.0.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
"@types/node": "^16.11.49",
|
||||
"@types/xml2js": "^0.4.11",
|
||||
@ -3514,7 +3514,7 @@
|
||||
"version": "file:sqlite",
|
||||
"requires": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
"@types/node": "^16.11.49",
|
||||
"@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",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^7.0.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify": "^3.29.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
@ -44,7 +44,7 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@hasura/dc-api-types": {
|
||||
"version": "0.19.0",
|
||||
"version": "0.20.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^7.0.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify": "^3.29.0",
|
||||
"mathjs": "^11.0.0",
|
||||
"pino-pretty": "^8.0.0",
|
||||
|
@ -16,14 +16,32 @@ const dateTimeCapabilities: ScalarTypeCapabilities = {
|
||||
const stringCapabilities: ScalarTypeCapabilities = {
|
||||
aggregate_functions: {
|
||||
longest: 'string',
|
||||
shortest: 'string'
|
||||
shortest: 'string',
|
||||
min: 'string',
|
||||
max: 'string'
|
||||
},
|
||||
graphql_type: 'String'
|
||||
}
|
||||
|
||||
const numberCapabilities: ScalarTypeCapabilities = {
|
||||
aggregate_functions: {
|
||||
max: 'number',
|
||||
min: 'number',
|
||||
stddev: 'number',
|
||||
stddev_pop: 'number',
|
||||
stddev_samp: 'number',
|
||||
sum: 'number',
|
||||
var_pop: 'number',
|
||||
var_samp: 'number',
|
||||
variance: 'number'
|
||||
},
|
||||
graphql_type: 'Float'
|
||||
}
|
||||
|
||||
const scalarTypes: ScalarTypesCapabilities = {
|
||||
DateTime: dateTimeCapabilities,
|
||||
string: stringCapabilities
|
||||
string: stringCapabilities,
|
||||
number: numberCapabilities
|
||||
}
|
||||
|
||||
const capabilities: Capabilities = {
|
||||
|
4
dc-agents/sqlite/package-lock.json
generated
4
dc-agents/sqlite/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify": "^4.4.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"nanoid": "^3.3.4",
|
||||
@ -54,7 +54,7 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@hasura/dc-api-types": {
|
||||
"version": "0.19.0",
|
||||
"version": "0.20.0",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.3",
|
||||
|
@ -22,7 +22,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^8.1.0",
|
||||
"@hasura/dc-api-types": "0.19.0",
|
||||
"@hasura/dc-api-types": "0.20.0",
|
||||
"fastify-metrics": "^9.2.1",
|
||||
"fastify": "^4.4.0",
|
||||
"nanoid": "^3.3.4",
|
||||
|
@ -55,19 +55,33 @@ const scalar_types: Record<ScalarTypeKey, ScalarTypeCapabilities> = {
|
||||
_glob: 'string',
|
||||
// _regexp: 'string', // TODO: Detect if REGEXP is supported
|
||||
...standardOperators('string')
|
||||
},
|
||||
aggregate_functions: {
|
||||
max: 'string',
|
||||
min: 'string'
|
||||
}
|
||||
},
|
||||
// TODO: Why do we need a seperate 'decimal' type?
|
||||
decimal: {
|
||||
comparison_operators: {
|
||||
_modulus_is_zero: 'number',
|
||||
...standardOperators('number')
|
||||
_modulus_is_zero: 'decimal',
|
||||
...standardOperators('decimal')
|
||||
},
|
||||
aggregate_functions: {
|
||||
max: 'decimal',
|
||||
min: 'decimal',
|
||||
sum: 'decimal'
|
||||
}
|
||||
},
|
||||
number: {
|
||||
comparison_operators: {
|
||||
_modulus_is_zero: 'number',
|
||||
...standardOperators('number')
|
||||
},
|
||||
aggregate_functions: {
|
||||
max: 'number',
|
||||
min: 'number',
|
||||
sum: 'number'
|
||||
}
|
||||
},
|
||||
bool: {
|
||||
|
@ -162,8 +162,8 @@ tests opts = describe "Aggregate Query Tests" $ do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") API.NumberTy),
|
||||
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
|
||||
[ (API.FieldName "ArtistIds_Id", API.ColumnField (API.ColumnName "ArtistId") (API.ScalarType "number")),
|
||||
(API.FieldName "ArtistNames_Name", API.ColumnField (API.ColumnName "Name") (API.ScalarType "string")),
|
||||
( API.FieldName "nodes_Albums",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
@ -172,7 +172,7 @@ tests opts = describe "Aggregate Query Tests" $ do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") API.StringTy)
|
||||
[ (API.FieldName "nodes_Title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
|
@ -145,8 +145,8 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") (API.ScalarType "number")),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") (API.ScalarType "string"))
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
@ -207,8 +207,8 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 3,
|
||||
@ -266,7 +266,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") API.NumberTy)
|
||||
[ (API.FieldName "CustomerId", API.ColumnField (API.ColumnName "CustomerId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
@ -276,8 +276,8 @@ tests opts = do
|
||||
API.Exists (API.UnrelatedTable $ API.TableName ("Employee" :| [])) $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") API.NumberTy)
|
||||
(API.ScalarValue (Aeson.Number 1) API.NumberTy),
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
(API.ScalarValue (Aeson.Number 1) $ API.ScalarType "number"),
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
}
|
||||
|
@ -94,12 +94,12 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.CustomTy "MyInt"),
|
||||
(API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.CustomTy "MyFloat"),
|
||||
(API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.CustomTy "MyString"),
|
||||
(API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.CustomTy "MyBoolean"),
|
||||
(API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.CustomTy "MyID"),
|
||||
(API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.CustomTy "MyAnything")
|
||||
[ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.ScalarType "MyInt"),
|
||||
(API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.ScalarType "MyFloat"),
|
||||
(API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.ScalarType "MyString"),
|
||||
(API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.ScalarType "MyBoolean"),
|
||||
(API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.ScalarType "MyID"),
|
||||
(API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.ScalarType "MyAnything")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
@ -159,12 +159,12 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.CustomTy "MyInt"),
|
||||
(API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.CustomTy "MyFloat"),
|
||||
(API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.CustomTy "MyString"),
|
||||
(API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.CustomTy "MyBoolean"),
|
||||
(API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.CustomTy "MyID"),
|
||||
(API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.CustomTy "MyAnything")
|
||||
[ (API.FieldName "MyIntColumn", API.ColumnField (API.ColumnName "MyIntColumn") $ API.ScalarType "MyInt"),
|
||||
(API.FieldName "MyFloatColumn", API.ColumnField (API.ColumnName "MyFloatColumn") $ API.ScalarType "MyFloat"),
|
||||
(API.FieldName "MyStringColumn", API.ColumnField (API.ColumnName "MyStringColumn") $ API.ScalarType "MyString"),
|
||||
(API.FieldName "MyBooleanColumn", API.ColumnField (API.ColumnName "MyBooleanColumn") $ API.ScalarType "MyBoolean"),
|
||||
(API.FieldName "MyIDColumn", API.ColumnField (API.ColumnName "MyIDColumn") $ API.ScalarType "MyID"),
|
||||
(API.FieldName "MyAnythingColumn", API.ColumnField (API.ColumnName "MyAnythingColumn") $ API.ScalarType "MyAnything")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
@ -174,28 +174,28 @@ tests opts = do
|
||||
And
|
||||
[ ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyBooleanColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyBoolean"}})
|
||||
(ScalarValue (Aeson.Bool True) (CustomTy {getCustomTy = "MyBoolean"})),
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyBooleanColumn"}, _ccColumnType = ScalarType "MyBoolean"})
|
||||
(ScalarValue (Aeson.Bool True) (ScalarType "MyBoolean")),
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyFloatColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyFloat"}})
|
||||
(ScalarValue (Aeson.Number 3.14) (CustomTy {getCustomTy = "MyFloat"})),
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyFloatColumn"}, _ccColumnType = ScalarType "MyFloat"})
|
||||
(ScalarValue (Aeson.Number 3.14) (ScalarType "MyFloat")),
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyStringColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyString"}})
|
||||
(ScalarValue (Aeson.String "foo") (CustomTy {getCustomTy = "MyString"})),
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyStringColumn"}, _ccColumnType = ScalarType "MyString"})
|
||||
(ScalarValue (Aeson.String "foo") (ScalarType "MyString")),
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIDColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyID"}})
|
||||
(ScalarValue (Aeson.String "x") (CustomTy {getCustomTy = "MyID"})),
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIDColumn"}, _ccColumnType = ScalarType "MyID"})
|
||||
(ScalarValue (Aeson.String "x") (ScalarType "MyID")),
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIntColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyInt"}})
|
||||
(ScalarValue (Aeson.Number 42.0) (CustomTy {getCustomTy = "MyInt"})),
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyIntColumn"}, _ccColumnType = ScalarType "MyInt"})
|
||||
(ScalarValue (Aeson.Number 42.0) (ScalarType "MyInt")),
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyAnythingColumn"}, _ccColumnType = CustomTy {getCustomTy = "MyAnything"}})
|
||||
(ScalarValue (Aeson.Object mempty) (CustomTy {getCustomTy = "MyAnything"}))
|
||||
(ComparisonColumn {_ccPath = CurrentTable, _ccName = ColumnName {unColumnName = "MyAnythingColumn"}, _ccColumnType = ScalarType "MyAnything"})
|
||||
(ScalarValue (Aeson.Object mempty) (ScalarType "MyAnything"))
|
||||
],
|
||||
_qOrderBy = Nothing
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
|
@ -209,7 +209,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Genre",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
@ -218,7 +218,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
@ -236,7 +236,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
@ -339,7 +339,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy),
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string"),
|
||||
( API.FieldName "Album",
|
||||
API.RelField
|
||||
( API.RelationshipField
|
||||
@ -356,7 +356,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") API.StringTy)
|
||||
[ (API.FieldName "Name", API.ColumnField (API.ColumnName "Name") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Nothing,
|
||||
@ -472,7 +472,7 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") API.NumberTy)
|
||||
[ (API.FieldName "EmployeeId", API.ColumnField (API.ColumnName "EmployeeId") $ API.ScalarType "number")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
@ -482,8 +482,8 @@ tests opts = do
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRepForCustomers") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy)
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy)),
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string")),
|
||||
_qOrderBy =
|
||||
Just $
|
||||
API.OrderBy
|
||||
@ -494,8 +494,8 @@ tests opts = do
|
||||
API.Exists (API.RelatedTable $ API.RelationshipName "SupportRep") $
|
||||
API.ApplyBinaryComparisonOperator
|
||||
API.Equal
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") API.StringTy)
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") API.StringTy))
|
||||
(API.ComparisonColumn API.CurrentTable (API.ColumnName "Country") $ API.ScalarType "string")
|
||||
(API.AnotherColumn (API.ComparisonColumn API.QueryTable (API.ColumnName "Country") $ API.ScalarType "string"))
|
||||
)
|
||||
mempty
|
||||
)
|
||||
|
@ -140,8 +140,8 @@ tests opts = do
|
||||
{ _qFields =
|
||||
Just $
|
||||
HashMap.fromList
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") API.NumberTy),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") API.StringTy)
|
||||
[ (API.FieldName "id", API.ColumnField (API.ColumnName "AlbumId") $ API.ScalarType "number"),
|
||||
(API.FieldName "title", API.ColumnField (API.ColumnName "Title") $ API.ScalarType "string")
|
||||
],
|
||||
_qAggregates = Nothing,
|
||||
_qLimit = Just 1,
|
||||
|
@ -1,10 +1,8 @@
|
||||
{-# LANGUAGE DeriveAnyClass #-}
|
||||
{-# LANGUAGE OverloadedLists #-}
|
||||
|
||||
--
|
||||
module Hasura.Backends.DataConnector.API.V0.Scalar
|
||||
( ScalarType (..),
|
||||
scalarTypeToText,
|
||||
)
|
||||
where
|
||||
|
||||
@ -24,41 +22,13 @@ import Prelude
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ScalarType
|
||||
= StringTy
|
||||
| NumberTy
|
||||
| BoolTy
|
||||
| CustomTy {getCustomTy :: Text}
|
||||
newtype ScalarType = ScalarType {getScalarType :: Text}
|
||||
deriving stock (Eq, Generic, Ord, Show)
|
||||
deriving anyclass (Hashable, NFData)
|
||||
deriving newtype (FromJSONKey, ToJSONKey)
|
||||
deriving (FromJSON, ToJSON, ToSchema) via Autodocodec ScalarType
|
||||
|
||||
instance ToJSONKey ScalarType where
|
||||
toJSONKey = ToJSONKeyText (Key.fromText . scalarTypeToText) (Encoding.text . scalarTypeToText)
|
||||
|
||||
instance FromJSONKey ScalarType where
|
||||
fromJSONKey = FromJSONKeyText textToScalarType
|
||||
|
||||
scalarTypeToText :: ScalarType -> Text
|
||||
scalarTypeToText = \case
|
||||
StringTy -> "string"
|
||||
NumberTy -> "number"
|
||||
BoolTy -> "bool"
|
||||
CustomTy t -> t
|
||||
|
||||
textToScalarType :: Text -> ScalarType
|
||||
textToScalarType t
|
||||
| t == "string" = StringTy
|
||||
| t == "number" = NumberTy
|
||||
| t == "bool" = BoolTy
|
||||
| otherwise = CustomTy t
|
||||
|
||||
instance HasCodec ScalarType where
|
||||
codec =
|
||||
named "ScalarType" $
|
||||
matchChoiceCodec
|
||||
(stringConstCodec [(StringTy, "string"), (NumberTy, "number"), (BoolTy, "bool")])
|
||||
(dimapCodec CustomTy getCustomTy textCodec)
|
||||
\case
|
||||
ty@CustomTy {} -> Right ty
|
||||
ty -> Left ty
|
||||
dimapCodec ScalarType getScalarType textCodec
|
||||
|
@ -10,7 +10,7 @@ import Hasura.Backends.DataConnector.API (openApiSchema)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Servant.Client ((//))
|
||||
import System.Environment (withArgs)
|
||||
import Test.AgentClient (AgentIOClient (..), guardCapabilitiesResponse, introduceAgentClient, mkAgentClientConfig, mkAgentIOClient)
|
||||
import Test.AgentClient (AgentIOClient (..), guardCapabilitiesResponse, guardSchemaResponse, introduceAgentClient, mkAgentClientConfig, mkAgentIOClient)
|
||||
import Test.Data (TestData, mkTestData)
|
||||
import Test.DataExport (exportData)
|
||||
import Test.Sandwich (runSandwichWithCommandLineArgs)
|
||||
@ -49,9 +49,10 @@ main = do
|
||||
Test TestOptions {..} (SandwichArguments arguments) -> withArgs arguments $ do
|
||||
(AgentIOClient agentClient) <- mkAgentIOClient _toSensitiveOutputHandling _toAgentOptions
|
||||
agentCapabilities <- (agentClient // API._capabilities) >>= guardCapabilitiesResponse
|
||||
schemaResponse <- (agentClient // API._schema) testSourceName (_aoAgentConfig _toAgentOptions) >>= guardSchemaResponse
|
||||
|
||||
agentClientConfig <- mkAgentClientConfig _toSensitiveOutputHandling _toAgentOptions
|
||||
let testData = mkTestData _toTestConfig
|
||||
let testData = mkTestData schemaResponse _toTestConfig
|
||||
runSandwichWithCommandLineArgs Sandwich.defaultOptions $
|
||||
introduceAgentClient agentClientConfig $
|
||||
tests testData testSourceName (_aoAgentConfig _toAgentOptions) agentCapabilities
|
||||
|
@ -15,6 +15,7 @@ module Test.AgentClient
|
||||
guardCapabilitiesResponse,
|
||||
getHealth,
|
||||
getSchemaGuarded,
|
||||
guardSchemaResponse,
|
||||
queryGuarded,
|
||||
queryExpectError,
|
||||
explain,
|
||||
|
@ -65,7 +65,7 @@ schemaTables :: [API.TableInfo]
|
||||
schemaTables = sortOn API._tiName . either error id . eitherDecodeStrict $ schemaBS
|
||||
|
||||
numericColumns :: [API.ColumnName]
|
||||
numericColumns = schemaTables >>= (API._tiColumns >>> mapMaybe (\API.ColumnInfo {..} -> if _ciType == API.NumberTy then Just _ciName else Nothing))
|
||||
numericColumns = schemaTables >>= (API._tiColumns >>> mapMaybe (\API.ColumnInfo {..} -> if _ciType == API.ScalarType "number" then Just _ciName else Nothing))
|
||||
|
||||
chinookXmlBS :: ByteString
|
||||
chinookXmlBS = $(makeRelativeToProject "test/Test/Data/ChinookData.xml.gz" >>= embedFile)
|
||||
@ -344,19 +344,17 @@ data TestData = TestData
|
||||
_tdGenresRows :: [HashMap API.FieldName API.FieldValue],
|
||||
_tdGenresTableRelationships :: API.TableRelationships,
|
||||
-- = Scalar Types
|
||||
_tdStringType :: API.ScalarType,
|
||||
_tdIntType :: API.ScalarType,
|
||||
_tdFloatType :: API.ScalarType,
|
||||
_tdFindColumnScalarType :: API.TableName -> Text -> API.ScalarType,
|
||||
-- = Utility functions
|
||||
_tdColumnName :: Text -> API.ColumnName,
|
||||
_tdColumnField :: Text -> API.ScalarType -> API.Field,
|
||||
_tdColumnField :: API.TableName -> Text -> API.Field,
|
||||
_tdQueryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn,
|
||||
_tdCurrentComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn,
|
||||
_tdOrderByColumn :: [API.RelationshipName] -> Text -> API.OrderDirection -> API.OrderByElement
|
||||
}
|
||||
|
||||
mkTestData :: TestConfig -> TestData
|
||||
mkTestData TestConfig {..} =
|
||||
mkTestData :: API.SchemaResponse -> TestConfig -> TestData
|
||||
mkTestData schemaResponse TestConfig {..} =
|
||||
TestData
|
||||
{ _tdSchemaTables = formatTableInfo <$> schemaTables,
|
||||
_tdArtistsTableName = formatTableName artistsTableName,
|
||||
@ -395,14 +393,12 @@ mkTestData TestConfig {..} =
|
||||
_tdGenresTableName = formatTableName genresTableName,
|
||||
_tdGenresRows = genresRows,
|
||||
_tdGenresTableRelationships = formatTableRelationships genresTableRelationships,
|
||||
_tdColumnName = API.ColumnName . applyNameCasing _tcColumnNameCasing,
|
||||
_tdColumnField = columnField . applyNameCasing _tcColumnNameCasing,
|
||||
_tdStringType = API.StringTy,
|
||||
_tdIntType = API.NumberTy,
|
||||
_tdFloatType = API.NumberTy,
|
||||
_tdQueryComparisonColumn = queryComparisonColumn . applyNameCasing _tcColumnNameCasing,
|
||||
_tdCurrentComparisonColumn = currentComparisonColumn . applyNameCasing _tcColumnNameCasing,
|
||||
_tdOrderByColumn = \targetPath name -> orderByColumn targetPath (applyNameCasing _tcColumnNameCasing name)
|
||||
_tdColumnName = formatColumnName . API.ColumnName,
|
||||
_tdColumnField = columnField,
|
||||
_tdFindColumnScalarType = \tableName name -> findColumnScalarType schemaResponse tableName (formatColumnName $ API.ColumnName name),
|
||||
_tdQueryComparisonColumn = API.ComparisonColumn API.QueryTable . formatColumnName . API.ColumnName,
|
||||
_tdCurrentComparisonColumn = API.ComparisonColumn API.CurrentTable . formatColumnName . API.ColumnName,
|
||||
_tdOrderByColumn = \targetPath name -> orderByColumn targetPath (formatColumnName $ API.ColumnName name)
|
||||
}
|
||||
where
|
||||
formatTableName :: API.TableName -> API.TableName
|
||||
@ -431,6 +427,13 @@ mkTestData TestConfig {..} =
|
||||
>>> API.cColumnMapping %~ (HashMap.toList >>> fmap (bimap formatColumnName formatColumnName) >>> HashMap.fromList)
|
||||
)
|
||||
|
||||
columnField :: API.TableName -> Text -> API.Field
|
||||
columnField tableName columnName =
|
||||
API.ColumnField columnName' scalarType
|
||||
where
|
||||
columnName' = formatColumnName $ API.ColumnName columnName
|
||||
scalarType = findColumnScalarType schemaResponse tableName columnName'
|
||||
|
||||
applyTableNamePrefix :: [Text] -> API.TableName -> API.TableName
|
||||
applyTableNamePrefix prefix tableName@(API.TableName rawTableName) =
|
||||
case NonEmpty.nonEmpty prefix of
|
||||
@ -443,6 +446,13 @@ applyNameCasing casing text = case casing of
|
||||
Lowercase -> Text.toLower text
|
||||
Uppercase -> Text.toUpper text
|
||||
|
||||
findColumnScalarType :: API.SchemaResponse -> API.TableName -> API.ColumnName -> API.ScalarType
|
||||
findColumnScalarType API.SchemaResponse {..} tableName columnName =
|
||||
maybe (error $ "Can't find the scalar type of column " <> show columnName <> " in table " <> show tableName) API._ciType columnInfo
|
||||
where
|
||||
tableInfo = find (\API.TableInfo {..} -> _tiName == tableName) _srTables
|
||||
columnInfo = find (\API.ColumnInfo {..} -> _ciName == columnName) =<< API._tiColumns <$> tableInfo
|
||||
|
||||
emptyQuery :: API.Query
|
||||
emptyQuery = API.Query Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
|
||||
@ -511,15 +521,6 @@ _ColumnFieldBoolean = API._ColumnFieldValue . _Bool
|
||||
_RelationshipFieldRows :: Traversal' API.FieldValue [HashMap API.FieldName API.FieldValue]
|
||||
_RelationshipFieldRows = API._RelationshipFieldValue . API.qrRows . _Just
|
||||
|
||||
columnField :: Text -> API.ScalarType -> API.Field
|
||||
columnField name scalarType = API.ColumnField (API.ColumnName name) scalarType
|
||||
|
||||
queryComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn
|
||||
queryComparisonColumn columnName scalarType = API.ComparisonColumn API.QueryTable (API.ColumnName columnName) scalarType
|
||||
|
||||
currentComparisonColumn :: Text -> API.ScalarType -> API.ComparisonColumn
|
||||
currentComparisonColumn columnName scalarType = API.ComparisonColumn API.CurrentTable (API.ColumnName columnName) scalarType
|
||||
|
||||
orderByColumn :: [API.RelationshipName] -> Text -> API.OrderDirection -> API.OrderByElement
|
||||
orderByColumn :: [API.RelationshipName] -> API.ColumnName -> API.OrderDirection -> API.OrderByElement
|
||||
orderByColumn targetPath columnName orderDirection =
|
||||
API.OrderByElement targetPath (API.OrderByColumn $ API.ColumnName columnName) orderDirection
|
||||
API.OrderByElement targetPath (API.OrderByColumn columnName) orderDirection
|
||||
|
@ -63,7 +63,7 @@ formatDateColumnsInRow dateTimeFormatString TableInfo {..} row =
|
||||
)
|
||||
where
|
||||
dateFields = fmap (\ColumnInfo {..} -> FieldName $ unColumnName _ciName) $ filter (\ColumnInfo {..} -> _ciType == dateTimeScalarType) _tiColumns
|
||||
dateTimeScalarType = CustomTy "DateTime"
|
||||
dateTimeScalarType = ScalarType "DateTime"
|
||||
tryFormatDate fieldValue = case deserializeAsColumnFieldValue fieldValue of
|
||||
J.String value -> do
|
||||
(zonedTime :: ZonedTime) <- iso8601ParseM $ Text.unpack value
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Test.Specs.ErrorSpec (spec) where
|
||||
|
||||
import Control.Lens ((&), (?~))
|
||||
import Data.Aeson (Value (..))
|
||||
import Hasura.Backends.DataConnector.API
|
||||
import Test.AgentClient (queryExpectError)
|
||||
import Test.Data (TestData (..))
|
||||
@ -16,13 +17,15 @@ spec TestData {..} sourceName config _capabilities = describe "Error Protocol" d
|
||||
where
|
||||
brokenQueryRequest :: QueryRequest
|
||||
brokenQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
query =
|
||||
Data.emptyQuery
|
||||
& qFields ?~ fields
|
||||
& qWhere
|
||||
?~ ApplyBinaryComparisonOperator
|
||||
(CustomBinaryComparisonOperator "FOOBAR")
|
||||
(ComparisonColumn CurrentTable (ColumnName "ArtistId") NumberTy)
|
||||
(ScalarValue "1" StringTy)
|
||||
(_tdCurrentComparisonColumn "ArtistId" artistIdScalarType)
|
||||
(ScalarValue (Number 1) $ artistIdScalarType)
|
||||
in QueryRequest _tdArtistsTableName [] query
|
||||
|
||||
artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId"
|
||||
|
@ -24,6 +24,6 @@ spec TestData {..} sourceName config _ = do
|
||||
where
|
||||
artistsQueryRequest :: QueryRequest
|
||||
artistsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdArtistsTableName [] query
|
||||
|
@ -39,7 +39,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
Data.responseRows response `rowsShouldBe` []
|
||||
|
||||
it "counts all rows, after applying filters" $ do
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity" _tdStringType) (ScalarValue (String "Oslo") _tdStringType)
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCity" billingCityScalarType) (ScalarValue (String "Oslo") billingCityScalarType)
|
||||
let aggregates = Data.mkFieldsMap [("count_all", StarCount)]
|
||||
let queryRequest = invoicesQueryRequest aggregates & qrQuery . qWhere ?~ where'
|
||||
response <- queryGuarded sourceName config queryRequest
|
||||
@ -77,7 +77,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
|
||||
it "can count all rows with non-null values in a column, after applying pagination and filtering" $ do
|
||||
let limit = 50
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" invoiceIdScalarType) (ScalarValue (Number 380) invoiceIdScalarType)
|
||||
let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") False)]
|
||||
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ limit >>> qWhere ?~ where')
|
||||
response <- queryGuarded sourceName config queryRequest
|
||||
@ -107,7 +107,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
|
||||
it "can count all rows with distinct non-null values in a column, after applying pagination and filtering" $ do
|
||||
let limit = 20
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" _tdIntType) (ScalarValue (Number 380) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "InvoiceId" invoiceIdScalarType) (ScalarValue (Number 380) invoiceIdScalarType)
|
||||
-- It is important to add an explicit order by for this query as different database engines will order implicitly resulting in incorrect results
|
||||
let orderBy = OrderBy mempty $ _tdOrderByColumn [] "InvoiceId" Ascending :| []
|
||||
let aggregates = Data.mkFieldsMap [("count_cols", ColumnCount $ ColumnCountAggregate (_tdColumnName "BillingState") True)]
|
||||
@ -141,7 +141,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
|
||||
it "can get the max total from all rows, after applying pagination, filtering and ordering" $ do
|
||||
let limit = 20
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "USA") _tdStringType)
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" billingCountryScalarType) (ScalarValue (String "USA") billingCountryScalarType)
|
||||
let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingPostalCode" Descending :| [_tdOrderByColumn [] "InvoiceId" Ascending]
|
||||
let aggregates = Data.mkFieldsMap [("max", singleColumnAggregateMax (_tdColumnName "Total"))]
|
||||
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qLimit ?~ limit >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy)
|
||||
@ -180,7 +180,7 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
Data.responseRows response `rowsShouldBe` []
|
||||
|
||||
it "aggregates over empty row lists results in nulls" $ do
|
||||
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 0) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "ArtistId" artistIdScalarType) (ScalarValue (Number 0) artistIdScalarType)
|
||||
let aggregates = Data.mkFieldsMap [("min", singleColumnAggregateMin (_tdColumnName "Name"))]
|
||||
let queryRequest = artistsQueryRequest aggregates & qrQuery . qWhere ?~ where'
|
||||
response <- queryGuarded sourceName config queryRequest
|
||||
@ -240,10 +240,10 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
let limit = 30
|
||||
let fields =
|
||||
Data.mkFieldsMap
|
||||
[ ("InvoiceId", _tdColumnField "InvoiceId" _tdIntType),
|
||||
("BillingCountry", _tdColumnField "BillingCountry" _tdStringType)
|
||||
[ ("InvoiceId", _tdColumnField _tdInvoicesTableName "InvoiceId"),
|
||||
("BillingCountry", _tdColumnField _tdInvoicesTableName "BillingCountry")
|
||||
]
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" _tdStringType) (ScalarValue (String "Canada") _tdStringType)
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "BillingCountry" billingCountryScalarType) (ScalarValue (String "Canada") billingCountryScalarType)
|
||||
let orderBy = OrderBy mempty $ _tdOrderByColumn [] "BillingAddress" Ascending :| [_tdOrderByColumn [] "InvoiceId" Ascending]
|
||||
let aggregates = Data.mkFieldsMap [("min", singleColumnAggregateMin (_tdColumnName "Total"))]
|
||||
let queryRequest = invoicesQueryRequest aggregates & qrQuery %~ (qFields ?~ fields >>> qLimit ?~ limit >>> qWhere ?~ where' >>> qOrderBy ?~ orderBy)
|
||||
@ -293,8 +293,8 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
let limit = 5
|
||||
let albumFields =
|
||||
Data.mkFieldsMap
|
||||
[ ("AlbumId", _tdColumnField "AlbumId" _tdIntType),
|
||||
("Title", _tdColumnField "Title" _tdStringType)
|
||||
[ ("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"),
|
||||
("Title", _tdColumnField _tdAlbumsTableName "Title")
|
||||
]
|
||||
let query = artistsWithAlbumsQuery (qFields ?~ albumFields) & qrQuery . qLimit ?~ limit
|
||||
receivedArtists <- queryGuarded sourceName config query
|
||||
@ -494,8 +494,8 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
albumsSubquery = Data.emptyQuery & qAggregates ?~ albumAggregates & modifySubquery
|
||||
artistFields =
|
||||
Data.mkFieldsMap
|
||||
[ ("ArtistId", _tdColumnField "ArtistId" _tdIntType),
|
||||
("Name", _tdColumnField "Name" _tdStringType),
|
||||
[ ("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"),
|
||||
("Name", _tdColumnField _tdArtistsTableName "Name"),
|
||||
("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
|
||||
]
|
||||
artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "ArtistId" Ascending :| []
|
||||
@ -538,34 +538,34 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
deeplyNestedArtistsQuery =
|
||||
let invoiceLinesAggregates = Data.mkFieldsMap [("aggregate_sum_Quantity", singleColumnAggregateSum (_tdColumnName "Quantity"))]
|
||||
invoiceLinesSubquery = Data.emptyQuery & qAggregates ?~ invoiceLinesAggregates
|
||||
mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField "Name" _tdStringType)]
|
||||
mediaTypeFields = Data.mkFieldsMap [("Name", _tdColumnField _tdMediaTypesTableName "Name")]
|
||||
mediaTypeSubquery = Data.emptyQuery & qFields ?~ mediaTypeFields
|
||||
tracksFields =
|
||||
Data.mkFieldsMap
|
||||
[ ("nodes_Name", _tdColumnField "Name" _tdStringType),
|
||||
[ ("nodes_Name", _tdColumnField _tdTracksTableName "Name"),
|
||||
("nodes_MediaType", RelField $ RelationshipField _tdMediaTypeRelationshipName mediaTypeSubquery),
|
||||
("nodes_InvoiceLines_aggregate", RelField $ RelationshipField _tdInvoiceLinesRelationshipName invoiceLinesSubquery)
|
||||
]
|
||||
tracksAggregates = Data.mkFieldsMap [("aggregate_count", StarCount)]
|
||||
tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds" _tdIntType) (ScalarValue (Number 300000) _tdIntType)
|
||||
tracksWhere = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Milliseconds" millisecondsScalarType) (ScalarValue (Number 300000) millisecondsScalarType)
|
||||
tracksOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Name" Descending :| []
|
||||
tracksSubquery = Query (Just tracksFields) (Just tracksAggregates) Nothing Nothing (Just tracksWhere) (Just tracksOrderBy)
|
||||
albumsFields =
|
||||
Data.mkFieldsMap
|
||||
[ ("nodes_Title", _tdColumnField "Title" _tdStringType),
|
||||
[ ("nodes_Title", _tdColumnField _tdAlbumsTableName "Title"),
|
||||
("nodes_Tracks_aggregate", RelField $ RelationshipField _tdTracksRelationshipName tracksSubquery)
|
||||
]
|
||||
albumsOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Title" Ascending :| []
|
||||
albumsSubquery = Data.emptyQuery & qFields ?~ albumsFields & qOrderBy ?~ albumsOrderBy
|
||||
artistFields =
|
||||
Data.mkFieldsMap
|
||||
[ ("Name", _tdColumnField "Name" _tdStringType),
|
||||
[ ("Name", _tdColumnField _tdArtistsTableName "Name"),
|
||||
("Albums_aggregate", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
|
||||
]
|
||||
artistWhere =
|
||||
And
|
||||
[ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "A") _tdStringType),
|
||||
ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "B") _tdStringType)
|
||||
[ ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "A") artistNameScalarType),
|
||||
ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "B") artistNameScalarType)
|
||||
]
|
||||
artistOrderBy = OrderBy mempty $ _tdOrderByColumn [] "Name" Descending :| []
|
||||
artistQuery = Query (Just artistFields) Nothing (Just 3) (Just 1) (Just artistWhere) (Just artistOrderBy)
|
||||
@ -607,3 +607,10 @@ spec TestData {..} sourceName config relationshipCapabilities = describe "Aggreg
|
||||
|
||||
singleColumnAggregateSum :: ColumnName -> Aggregate
|
||||
singleColumnAggregateSum = SingleColumn . SingleColumnAggregate (SingleColumnAggregateFunction [G.name|sum|])
|
||||
|
||||
billingCityScalarType = _tdFindColumnScalarType _tdInvoicesTableName "BillingCity"
|
||||
billingCountryScalarType = _tdFindColumnScalarType _tdInvoicesTableName "BillingCountry"
|
||||
invoiceIdScalarType = _tdFindColumnScalarType _tdInvoicesTableName "InvoiceId"
|
||||
artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId"
|
||||
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
||||
millisecondsScalarType = _tdFindColumnScalarType _tdTracksTableName "Milliseconds"
|
||||
|
@ -24,7 +24,7 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do
|
||||
_qrAggregates receivedArtists `jsonShouldBe` Nothing
|
||||
|
||||
it "can query for a list of albums with a subset of columns" $ do
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
let query = albumsQueryRequest & qrQuery . qFields ?~ fields
|
||||
receivedAlbums <- Data.sortResponseRowsBy "Title" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -36,7 +36,7 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can project columns into fields with different names" $ do
|
||||
let fields = Data.mkFieldsMap [("Artist_Id", _tdColumnField "ArtistId" _tdIntType), ("Artist_Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("Artist_Id", _tdColumnField _tdArtistsTableName "ArtistId"), ("Artist_Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
let query = artistsQueryRequest & qrQuery . qFields ?~ fields
|
||||
receivedArtists <- Data.sortResponseRowsBy "ArtistId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -67,12 +67,12 @@ spec TestData {..} sourceName config = describe "Basic Queries" $ do
|
||||
where
|
||||
artistsQueryRequest :: QueryRequest
|
||||
artistsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdArtistsTableName [] query
|
||||
|
||||
albumsQueryRequest :: QueryRequest
|
||||
albumsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdAlbumsTableName [] query
|
||||
|
@ -34,7 +34,7 @@ spec TestData {..} sourceName config (ScalarTypesCapabilities scalarTypesCapabil
|
||||
forM_ (HashMap.toList items) \((operatorName, columnType), (columnName, tableName, argColumnName, argType)) -> do
|
||||
-- Perform a select using the operator in a where clause
|
||||
let queryRequest =
|
||||
let fields = Data.mkFieldsMap [(unColumnName columnName, _tdColumnField (unColumnName columnName) columnType)]
|
||||
let fields = Data.mkFieldsMap [(unColumnName columnName, _tdColumnField tableName (unColumnName columnName))]
|
||||
query' = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest tableName [] query'
|
||||
where' =
|
||||
@ -46,7 +46,7 @@ spec TestData {..} sourceName config (ScalarTypesCapabilities scalarTypesCapabil
|
||||
queryRequest
|
||||
& qrQuery . qWhere ?~ where'
|
||||
& qrQuery . qLimit ?~ 1 -- No need to test actual results
|
||||
it (Text.unpack $ "ComparisonOperator " <> unName operatorName <> ": " <> scalarTypeToText columnType <> " executes without an error") do
|
||||
it (Text.unpack $ "ComparisonOperator " <> unName operatorName <> ": " <> getScalarType columnType <> " executes without an error") do
|
||||
result <- queryGuarded sourceName config query
|
||||
-- Check that you get a success response
|
||||
Data.responseRows result `shouldBe` take 1 (Data.responseRows result)
|
||||
|
@ -20,7 +20,7 @@ import Prelude
|
||||
spec :: TestData -> SourceName -> Config -> Maybe ComparisonCapabilities -> AgentTestSpec
|
||||
spec TestData {..} sourceName config comparisonCapabilities = describe "Filtering in Queries" $ do
|
||||
it "can filter using an equality expression" $ do
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -31,7 +31,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter using an inequality expression" $ do
|
||||
let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType))
|
||||
let where' = Not (ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType))
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -42,7 +42,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter using an in expression" $ do
|
||||
let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType
|
||||
let where' = ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) [Number 2, Number 3] albumIdScalarType
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -53,7 +53,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can negate an in expression filter using a not expression" $ do
|
||||
let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" _tdIntType) [Number 2, Number 3] _tdIntType)
|
||||
let where' = Not (ApplyBinaryArrayComparisonOperator In (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) [Number 2, Number 3] albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -64,8 +64,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can combine filters using an and expression" $ do
|
||||
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId" _tdIntType) (ScalarValue (Number 58) _tdIntType)
|
||||
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Stormbringer") _tdStringType)
|
||||
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "ArtistId" artistIdScalarType) (ScalarValue (Number 58) artistIdScalarType)
|
||||
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "Stormbringer") albumTitleScalarType)
|
||||
let where' = And [where1, where2]
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
@ -89,8 +89,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can combine filters using an or expression" $ do
|
||||
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 2) _tdIntType)
|
||||
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 3) _tdIntType)
|
||||
let where1 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 2) albumIdScalarType)
|
||||
let where2 = ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 3) albumIdScalarType)
|
||||
let where' = Or [where1, where2]
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
@ -110,7 +110,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter by applying the greater than operator" $ do
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 300) albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -121,7 +121,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter by applying the greater than or equal operator" $ do
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 300) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 300) albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -132,7 +132,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter by applying the less than operator" $ do
|
||||
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator LessThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 100) albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -143,7 +143,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter by applying the less than or equal operator" $ do
|
||||
let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 100) _tdIntType)
|
||||
let where' = ApplyBinaryComparisonOperator LessThanOrEqual (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 100) albumIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -154,7 +154,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter using a greater than operator with a column comparison" $ do
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (AnotherColumn (_tdCurrentComparisonColumn "ArtistId" _tdIntType))
|
||||
let where' = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (AnotherColumn (_tdCurrentComparisonColumn "ArtistId" albumIdScalarType))
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -171,7 +171,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
it "returns all rows if matching rows exist" $ do
|
||||
let where' =
|
||||
Exists (UnrelatedTable _tdEmployeesTableName) $
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType)
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -183,7 +183,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
it "returns no rows if matching rows do not exist" $ do
|
||||
let where' =
|
||||
Exists (UnrelatedTable _tdEmployeesTableName) $
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 0) _tdIntType)
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 0) employeeIdScalarType)
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -195,8 +195,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
let where' =
|
||||
Exists (UnrelatedTable _tdEmployeesTableName) $
|
||||
And
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Edmonton") _tdStringType)
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" employeeCityScalarType) (ScalarValue (String "Edmonton") employeeCityScalarType)
|
||||
]
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
@ -210,8 +210,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
let where' =
|
||||
Exists (UnrelatedTable _tdEmployeesTableName) $
|
||||
And
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" _tdStringType) (ScalarValue (String "Calgary") _tdStringType)
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType) (ScalarValue (Number 1) employeeIdScalarType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "City" employeeCityScalarType) (ScalarValue (String "Calgary") employeeCityScalarType)
|
||||
]
|
||||
let query = albumsQueryRequest & qrQuery . qWhere ?~ where'
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
@ -224,7 +224,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
it "can filter by comparing against rows in a related table" $ do
|
||||
let where' =
|
||||
Exists (RelatedTable _tdArtistRelationshipName) $
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "AC/DC") _tdStringType)
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "AC/DC") artistNameScalarType)
|
||||
let query =
|
||||
albumsQueryRequest
|
||||
& qrTableRelationships .~ [Data.onlyKeepRelationships [_tdArtistRelationshipName] _tdAlbumsTableRelationships]
|
||||
@ -247,7 +247,7 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
it "can filter by comparing against rows in a deeply related table" $ do
|
||||
let where' =
|
||||
Exists (RelatedTable _tdAlbumsRelationshipName) . Exists (RelatedTable _tdTracksRelationshipName) . Exists (RelatedTable _tdGenreRelationshipName) $
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "Metal") _tdStringType)
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Name" genreNameScalarType) (ScalarValue (String "Metal") genreNameScalarType)
|
||||
let query =
|
||||
artistsQueryRequest
|
||||
& qrTableRelationships
|
||||
@ -285,8 +285,8 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
let where' =
|
||||
Exists (RelatedTable _tdAlbumsRelationshipName) $
|
||||
And
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" _tdIntType) (ScalarValue (Number 1) _tdIntType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "Let There Be Rock") _tdStringType)
|
||||
[ ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "AlbumId" albumIdScalarType) (ScalarValue (Number 1) albumIdScalarType),
|
||||
ApplyBinaryComparisonOperator Equal (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "Let There Be Rock") albumTitleScalarType)
|
||||
]
|
||||
let query =
|
||||
artistsQueryRequest
|
||||
@ -308,12 +308,20 @@ spec TestData {..} sourceName config comparisonCapabilities = describe "Filterin
|
||||
where
|
||||
artistsQueryRequest :: QueryRequest
|
||||
artistsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdArtistsTableName [] query
|
||||
|
||||
albumsQueryRequest :: QueryRequest
|
||||
albumsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdAlbumsTableName [] query
|
||||
|
||||
albumIdScalarType = _tdFindColumnScalarType _tdAlbumsTableName "AlbumId"
|
||||
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
|
||||
artistIdScalarType = _tdFindColumnScalarType _tdArtistsTableName "ArtistId"
|
||||
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
||||
employeeIdScalarType = _tdFindColumnScalarType _tdEmployeesTableName "EmployeeId"
|
||||
employeeCityScalarType = _tdFindColumnScalarType _tdEmployeesTableName "City"
|
||||
genreNameScalarType = _tdFindColumnScalarType _tdGenresTableName "Name"
|
||||
|
@ -115,7 +115,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can order results by a column in a related table where the related table is filtered" $ do
|
||||
let artistTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "N") _tdStringType)
|
||||
let artistTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "N") artistNameScalarType)
|
||||
let orderByRelations = HashMap.fromList [(_tdArtistRelationshipName, OrderByRelation (Just artistTableFilter) mempty)]
|
||||
let orderBy =
|
||||
OrderBy orderByRelations $
|
||||
@ -285,7 +285,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q
|
||||
_qrAggregates receivedArtists `jsonShouldBe` Nothing
|
||||
|
||||
it "can order results by an aggregate of a related table where the related table is filtered" $ do
|
||||
let albumTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "N") _tdStringType)
|
||||
let albumTableFilter = ApplyBinaryComparisonOperator GreaterThan (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "N") albumTitleScalarType)
|
||||
let orderByRelations = HashMap.fromList [(_tdAlbumsRelationshipName, OrderByRelation (Just albumTableFilter) mempty)]
|
||||
let orderBy =
|
||||
OrderBy orderByRelations $
|
||||
@ -360,7 +360,7 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q
|
||||
where
|
||||
albumsQuery :: Query
|
||||
albumsQuery =
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
albumsQueryRequest :: QueryRequest
|
||||
@ -369,13 +369,13 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q
|
||||
|
||||
artistsQueryRequest :: QueryRequest
|
||||
artistsQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdArtistsTableName [] query
|
||||
|
||||
tracksQuery :: Query
|
||||
tracksQuery =
|
||||
let fields = Data.mkFieldsMap [("TrackId", _tdColumnField "TrackId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("TrackId", _tdColumnField _tdTracksTableName "TrackId"), ("Name", _tdColumnField _tdTracksTableName "Name")]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
tracksQueryRequest :: QueryRequest
|
||||
@ -384,10 +384,13 @@ spec TestData {..} sourceName config Capabilities {..} = describe "Order By in Q
|
||||
|
||||
invoicesQueryRequest :: QueryRequest
|
||||
invoicesQueryRequest =
|
||||
let fields = Data.mkFieldsMap [("InvoiceId", _tdColumnField "InvoiceId" _tdIntType), ("BillingState", _tdColumnField "BillingState" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("InvoiceId", _tdColumnField _tdInvoicesTableName "InvoiceId"), ("BillingState", _tdColumnField _tdInvoicesTableName "BillingState")]
|
||||
query = Data.emptyQuery & qFields ?~ fields
|
||||
in QueryRequest _tdInvoicesTableName [] query
|
||||
|
||||
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
|
||||
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
||||
|
||||
data NullableOrdered a
|
||||
= NullFirst
|
||||
| Some a
|
||||
|
@ -67,7 +67,7 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
_qrAggregates receivedArtists `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter in object relationships" $ do
|
||||
let artistWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Name" _tdStringType) (ScalarValue (String "H") _tdStringType)
|
||||
let artistWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Name" artistNameScalarType) (ScalarValue (String "H") artistNameScalarType)
|
||||
let query = albumsWithArtistQuery (qWhere ?~ artistWhere)
|
||||
receivedAlbums <- Data.sortResponseRowsBy "AlbumId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -85,7 +85,7 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
_qrAggregates receivedAlbums `jsonShouldBe` Nothing
|
||||
|
||||
it "can filter in array relationships" $ do
|
||||
let albumsWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Title" _tdStringType) (ScalarValue (String "O") _tdStringType)
|
||||
let albumsWhere = ApplyBinaryComparisonOperator GreaterThanOrEqual (_tdCurrentComparisonColumn "Title" albumTitleScalarType) (ScalarValue (String "O") albumTitleScalarType)
|
||||
let query = artistsWithAlbumsQuery (qWhere ?~ albumsWhere)
|
||||
receivedArtists <- Data.sortResponseRowsBy "ArtistId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -114,8 +114,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
Exists (RelatedTable _tdSupportRepRelationshipName) $
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(_tdCurrentComparisonColumn "Country" _tdStringType)
|
||||
(AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType))
|
||||
(_tdCurrentComparisonColumn "Country" employeeCountryScalarType)
|
||||
(AnotherColumn (_tdQueryComparisonColumn "Country" employeeCountryScalarType))
|
||||
let query = customersWithSupportRepQuery id & qrQuery . qWhere ?~ where'
|
||||
receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -142,8 +142,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
Exists (RelatedTable _tdSupportRepForCustomersRelationshipName) $
|
||||
ApplyBinaryComparisonOperator
|
||||
Equal
|
||||
(_tdCurrentComparisonColumn "Country" _tdStringType)
|
||||
(AnotherColumn (_tdQueryComparisonColumn "Country" _tdStringType))
|
||||
(_tdCurrentComparisonColumn "Country" employeeCountryScalarType)
|
||||
(AnotherColumn (_tdQueryComparisonColumn "Country" employeeCountryScalarType))
|
||||
let query = employeesWithCustomersQuery id & qrQuery . qWhere ?~ where'
|
||||
receivedEmployees <- Data.sortResponseRowsBy "EmployeeId" <$> queryGuarded sourceName config query
|
||||
|
||||
@ -173,17 +173,17 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
And
|
||||
[ ( ApplyBinaryComparisonOperator
|
||||
GreaterThan
|
||||
(_tdCurrentComparisonColumn "FirstName" _tdStringType)
|
||||
(AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType))
|
||||
(_tdCurrentComparisonColumn "FirstName" employeeFirstNameScalarType)
|
||||
(AnotherColumn (_tdCurrentComparisonColumn "LastName" employeeLastNameScalarType))
|
||||
),
|
||||
(Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId" _tdIntType)))
|
||||
(Not (ApplyUnaryComparisonOperator IsNull (_tdCurrentComparisonColumn "EmployeeId" employeeIdScalarType)))
|
||||
]
|
||||
|
||||
let employeesWhere =
|
||||
ApplyBinaryComparisonOperator
|
||||
GreaterThan
|
||||
(_tdCurrentComparisonColumn "FirstName" _tdStringType)
|
||||
(AnotherColumn (_tdCurrentComparisonColumn "LastName" _tdStringType))
|
||||
(_tdCurrentComparisonColumn "FirstName" employeeFirstNameScalarType)
|
||||
(AnotherColumn (_tdCurrentComparisonColumn "LastName" employeeLastNameScalarType))
|
||||
|
||||
let query = customersWithSupportRepQuery (\q -> q & qWhere ?~ employeesWhere) & qrQuery . qWhere ?~ customersWhere
|
||||
receivedCustomers <- Data.sortResponseRowsBy "CustomerId" <$> queryGuarded sourceName config query
|
||||
@ -211,8 +211,8 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
let artistsSubquery = modifySubquery artistsQuery
|
||||
fields =
|
||||
Data.mkFieldsMap
|
||||
[ ("AlbumId", _tdColumnField "AlbumId" _tdIntType),
|
||||
("Title", _tdColumnField "Title" _tdStringType),
|
||||
[ ("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"),
|
||||
("Title", _tdColumnField _tdAlbumsTableName "Title"),
|
||||
("Artist", RelField $ RelationshipField _tdArtistRelationshipName artistsSubquery)
|
||||
]
|
||||
query = albumsQuery & qFields ?~ fields
|
||||
@ -220,13 +220,13 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
|
||||
artistsWithAlbumsQuery :: (Query -> Query) -> QueryRequest
|
||||
artistsWithAlbumsQuery modifySubquery =
|
||||
let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let albumFields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
albumsSort = OrderBy mempty $ _tdOrderByColumn [] "AlbumId" Ascending :| []
|
||||
albumsSubquery = albumsQuery & qFields ?~ albumFields & qOrderBy ?~ albumsSort & modifySubquery
|
||||
fields =
|
||||
Data.mkFieldsMap
|
||||
[ ("ArtistId", _tdColumnField "ArtistId" _tdIntType),
|
||||
("Name", _tdColumnField "Name" _tdStringType),
|
||||
[ ("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"),
|
||||
("Name", _tdColumnField _tdArtistsTableName "Name"),
|
||||
("Albums", RelField $ RelationshipField _tdAlbumsRelationshipName albumsSubquery)
|
||||
]
|
||||
query = artistsQuery & qFields ?~ fields
|
||||
@ -257,23 +257,23 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
|
||||
artistsQuery :: Query
|
||||
artistsQuery =
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Name", _tdColumnField "Name" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("ArtistId", _tdColumnField _tdArtistsTableName "ArtistId"), ("Name", _tdColumnField _tdArtistsTableName "Name")]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
albumsQuery :: Query
|
||||
albumsQuery =
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField "AlbumId" _tdIntType), ("ArtistId", _tdColumnField "ArtistId" _tdIntType), ("Title", _tdColumnField "Title" _tdStringType)]
|
||||
let fields = Data.mkFieldsMap [("AlbumId", _tdColumnField _tdAlbumsTableName "AlbumId"), ("ArtistId", _tdColumnField _tdAlbumsTableName "ArtistId"), ("Title", _tdColumnField _tdAlbumsTableName "Title")]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
customersQuery :: Query
|
||||
customersQuery =
|
||||
let fields =
|
||||
Data.mkFieldsMap
|
||||
[ ("CustomerId", _tdColumnField "CustomerId" _tdIntType),
|
||||
("FirstName", _tdColumnField "FirstName" _tdStringType),
|
||||
("LastName", _tdColumnField "LastName" _tdStringType),
|
||||
("Country", _tdColumnField "Country" _tdStringType),
|
||||
("SupportRepId", _tdColumnField "SupportRepId" _tdIntType)
|
||||
[ ("CustomerId", _tdColumnField _tdCustomersTableName "CustomerId"),
|
||||
("FirstName", _tdColumnField _tdCustomersTableName "FirstName"),
|
||||
("LastName", _tdColumnField _tdCustomersTableName "LastName"),
|
||||
("Country", _tdColumnField _tdCustomersTableName "Country"),
|
||||
("SupportRepId", _tdColumnField _tdCustomersTableName "SupportRepId")
|
||||
]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
@ -281,10 +281,10 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
employeesQuery =
|
||||
let fields =
|
||||
Data.mkFieldsMap
|
||||
[ ("EmployeeId", _tdColumnField "EmployeeId" _tdIntType),
|
||||
("FirstName", _tdColumnField "FirstName" _tdStringType),
|
||||
("LastName", _tdColumnField "LastName" _tdStringType),
|
||||
("Country", _tdColumnField "Country" _tdStringType)
|
||||
[ ("EmployeeId", _tdColumnField _tdEmployeesTableName "EmployeeId"),
|
||||
("FirstName", _tdColumnField _tdEmployeesTableName "FirstName"),
|
||||
("LastName", _tdColumnField _tdEmployeesTableName "LastName"),
|
||||
("Country", _tdColumnField _tdEmployeesTableName "Country")
|
||||
]
|
||||
in Data.emptyQuery & qFields ?~ fields
|
||||
|
||||
@ -294,3 +294,10 @@ spec TestData {..} sourceName config subqueryComparisonCapabilities = describe "
|
||||
|
||||
subqueryRows :: Traversal' FieldValue (HashMap FieldName FieldValue)
|
||||
subqueryRows = _RelationshipFieldValue . qrRows . _Just . traverse
|
||||
|
||||
albumTitleScalarType = _tdFindColumnScalarType _tdAlbumsTableName "Title"
|
||||
artistNameScalarType = _tdFindColumnScalarType _tdArtistsTableName "Name"
|
||||
employeeIdScalarType = _tdFindColumnScalarType _tdEmployeesTableName "EmployeeId"
|
||||
employeeCountryScalarType = _tdFindColumnScalarType _tdEmployeesTableName "Country"
|
||||
employeeFirstNameScalarType = _tdFindColumnScalarType _tdEmployeesTableName "FirstName"
|
||||
employeeLastNameScalarType = _tdFindColumnScalarType _tdEmployeesTableName "LastName"
|
||||
|
@ -44,9 +44,23 @@ backendTypeMetadata =
|
||||
max: DateTime
|
||||
min: DateTime
|
||||
graphql_type: String
|
||||
number:
|
||||
aggregate_functions:
|
||||
max: number
|
||||
min: number
|
||||
stddev: number
|
||||
stddev_pop: number
|
||||
stddev_samp: number
|
||||
sum: number
|
||||
var_pop: number
|
||||
var_samp: number
|
||||
variance: number
|
||||
graphql_type: Float
|
||||
string:
|
||||
aggregate_functions:
|
||||
longest: string
|
||||
max: string
|
||||
min: string
|
||||
shortest: string
|
||||
graphql_type: String
|
||||
|],
|
||||
|
@ -51,15 +51,22 @@ backendTypeMetadata =
|
||||
_lt: string
|
||||
_lte: string
|
||||
_neq: string
|
||||
aggregate_functions:
|
||||
min: string
|
||||
max: string
|
||||
decimal:
|
||||
comparison_operators:
|
||||
_modulus_is_zero: number
|
||||
_eq: number
|
||||
_gt: number
|
||||
_gte: number
|
||||
_lt: number
|
||||
_lte: number
|
||||
_neq: number
|
||||
_modulus_is_zero: decimal
|
||||
_eq: decimal
|
||||
_gt: decimal
|
||||
_gte: decimal
|
||||
_lt: decimal
|
||||
_lte: decimal
|
||||
_neq: decimal
|
||||
aggregate_functions:
|
||||
min: decimal
|
||||
max: decimal
|
||||
sum: decimal
|
||||
number:
|
||||
comparison_operators:
|
||||
_modulus_is_zero: number
|
||||
@ -69,6 +76,10 @@ backendTypeMetadata =
|
||||
_lt: number
|
||||
_lte: number
|
||||
_neq: number
|
||||
aggregate_functions:
|
||||
min: number
|
||||
max: number
|
||||
sum: number
|
||||
bool:
|
||||
comparison_operators:
|
||||
_and: bool
|
||||
|
@ -1,3 +1,5 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
|
||||
-- | Mock Agent Warp server backend
|
||||
module Harness.Backend.DataConnector.Mock.Server
|
||||
( MockConfig (..),
|
||||
@ -15,6 +17,7 @@ import Data.Proxy
|
||||
import Data.SOP.BasicFunctors qualified as SOP
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Prelude
|
||||
import Language.GraphQL.Draft.Syntax.QQ qualified as G
|
||||
import Network.Wai.Handler.Warp qualified as Warp
|
||||
import Servant
|
||||
|
||||
@ -79,15 +82,27 @@ capabilities =
|
||||
scalarTypesCapabilities =
|
||||
API.ScalarTypesCapabilities $
|
||||
HashMap.fromList
|
||||
[ mkScalarTypeCapability "MyInt" $ Just API.GraphQLInt,
|
||||
mkScalarTypeCapability "MyFloat" $ Just API.GraphQLFloat,
|
||||
mkScalarTypeCapability "MyString" $ Just API.GraphQLString,
|
||||
mkScalarTypeCapability "MyBoolean" $ Just API.GraphQLBoolean,
|
||||
mkScalarTypeCapability "MyID" $ Just API.GraphQLID,
|
||||
mkScalarTypeCapability "MyAnything" $ Nothing
|
||||
[ mkScalarTypeCapability "number" minMaxFunctions $ Just API.GraphQLFloat,
|
||||
mkScalarTypeCapability "string" minMaxFunctions $ Just API.GraphQLString,
|
||||
mkScalarTypeCapability "MyInt" mempty $ Just API.GraphQLInt,
|
||||
mkScalarTypeCapability "MyFloat" mempty $ Just API.GraphQLFloat,
|
||||
mkScalarTypeCapability "MyString" mempty $ Just API.GraphQLString,
|
||||
mkScalarTypeCapability "MyBoolean" mempty $ Just API.GraphQLBoolean,
|
||||
mkScalarTypeCapability "MyID" mempty $ Just API.GraphQLID,
|
||||
mkScalarTypeCapability "MyAnything" mempty Nothing
|
||||
]
|
||||
mkScalarTypeCapability :: Text -> Maybe API.GraphQLType -> (API.ScalarType, API.ScalarTypeCapabilities)
|
||||
mkScalarTypeCapability name gqlType = (API.CustomTy name, mempty {API._stcGraphQLType = gqlType})
|
||||
mkScalarTypeCapability :: Text -> (API.ScalarType -> API.AggregateFunctions) -> Maybe API.GraphQLType -> (API.ScalarType, API.ScalarTypeCapabilities)
|
||||
mkScalarTypeCapability name aggregateFunctions gqlType =
|
||||
(scalarType, API.ScalarTypeCapabilities mempty (aggregateFunctions scalarType) gqlType)
|
||||
where
|
||||
scalarType = API.ScalarType name
|
||||
|
||||
minMaxFunctions :: API.ScalarType -> API.AggregateFunctions
|
||||
minMaxFunctions resultType =
|
||||
API.AggregateFunctions $
|
||||
HashMap.fromList $
|
||||
(,resultType)
|
||||
<$> [[G.name|min|], [G.name|max|]]
|
||||
|
||||
-- | Stock Schema for a Chinook Agent
|
||||
schema :: API.SchemaResponse
|
||||
@ -100,7 +115,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "ArtistId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Artist primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -108,7 +123,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Name",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The name of the artist",
|
||||
API._ciInsertable = True,
|
||||
@ -128,7 +143,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "AlbumId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Album primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -136,7 +151,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Title",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The title of the album",
|
||||
API._ciInsertable = True,
|
||||
@ -144,7 +159,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "ArtistId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The ID of the artist that created the album",
|
||||
API._ciInsertable = True,
|
||||
@ -166,7 +181,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "CustomerId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Customer primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -174,7 +189,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "FirstName",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The customer's first name",
|
||||
API._ciInsertable = True,
|
||||
@ -182,7 +197,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "LastName",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The customer's last name",
|
||||
API._ciInsertable = True,
|
||||
@ -190,7 +205,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Company",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's company name",
|
||||
API._ciInsertable = True,
|
||||
@ -198,7 +213,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Address",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's address line (street number, street)",
|
||||
API._ciInsertable = True,
|
||||
@ -206,7 +221,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "City",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's address city",
|
||||
API._ciInsertable = True,
|
||||
@ -214,7 +229,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "State",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's address state",
|
||||
API._ciInsertable = True,
|
||||
@ -222,7 +237,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Country",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's address country",
|
||||
API._ciInsertable = True,
|
||||
@ -230,7 +245,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "PostalCode",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's address postal code",
|
||||
API._ciInsertable = True,
|
||||
@ -238,7 +253,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Phone",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's phone number",
|
||||
API._ciInsertable = True,
|
||||
@ -246,7 +261,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Fax",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The customer's fax number",
|
||||
API._ciInsertable = True,
|
||||
@ -254,7 +269,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Email",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The customer's email address",
|
||||
API._ciInsertable = True,
|
||||
@ -262,7 +277,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "SupportRepId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The ID of the Employee who is this customer's support representative",
|
||||
API._ciInsertable = True,
|
||||
@ -284,7 +299,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "EmployeeId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Employee primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -292,7 +307,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "LastName",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The employee's last name",
|
||||
API._ciInsertable = True,
|
||||
@ -300,7 +315,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "FirstName",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The employee's first name",
|
||||
API._ciInsertable = True,
|
||||
@ -308,7 +323,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Title",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's job title",
|
||||
API._ciInsertable = True,
|
||||
@ -316,7 +331,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "ReportsTo",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's report",
|
||||
API._ciInsertable = True,
|
||||
@ -324,7 +339,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BirthDate",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's birth date",
|
||||
API._ciInsertable = True,
|
||||
@ -332,7 +347,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "HireDate",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's hire date",
|
||||
API._ciInsertable = True,
|
||||
@ -340,7 +355,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Address",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's address line (street number, street)",
|
||||
API._ciInsertable = True,
|
||||
@ -348,7 +363,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "City",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's address city",
|
||||
API._ciInsertable = True,
|
||||
@ -356,7 +371,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "State",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's address state",
|
||||
API._ciInsertable = True,
|
||||
@ -364,7 +379,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Country",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's address country",
|
||||
API._ciInsertable = True,
|
||||
@ -372,7 +387,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "PostalCode",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's address postal code",
|
||||
API._ciInsertable = True,
|
||||
@ -380,7 +395,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Phone",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's phone number",
|
||||
API._ciInsertable = True,
|
||||
@ -388,7 +403,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Fax",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's fax number",
|
||||
API._ciInsertable = True,
|
||||
@ -396,7 +411,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Email",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The employee's email address",
|
||||
API._ciInsertable = True,
|
||||
@ -418,7 +433,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "GenreId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Genre primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -426,7 +441,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Name",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The name of the genre",
|
||||
API._ciInsertable = True,
|
||||
@ -446,7 +461,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "InvoiceId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Invoice primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -454,7 +469,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "CustomerId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "ID of the customer who bought the music",
|
||||
API._ciInsertable = True,
|
||||
@ -462,7 +477,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "InvoiceDate",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Date of the invoice",
|
||||
API._ciInsertable = True,
|
||||
@ -470,7 +485,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BillingAddress",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The invoice's billing address line (street number, street)",
|
||||
API._ciInsertable = True,
|
||||
@ -478,7 +493,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BillingCity",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The invoice's billing address city",
|
||||
API._ciInsertable = True,
|
||||
@ -486,7 +501,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BillingState",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The invoice's billing address state",
|
||||
API._ciInsertable = True,
|
||||
@ -494,7 +509,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BillingCountry",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The invoice's billing address country",
|
||||
API._ciInsertable = True,
|
||||
@ -502,7 +517,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "BillingPostalCode",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The invoice's billing address postal code",
|
||||
API._ciInsertable = True,
|
||||
@ -510,7 +525,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Total",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The total amount due on the invoice",
|
||||
API._ciInsertable = True,
|
||||
@ -533,7 +548,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "InvoiceLineId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Invoice Line primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -541,7 +556,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "InvoiceId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "ID of the invoice the line belongs to",
|
||||
API._ciInsertable = True,
|
||||
@ -549,7 +564,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "TrackId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "ID of the music track being purchased",
|
||||
API._ciInsertable = True,
|
||||
@ -557,7 +572,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "UnitPrice",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Price of each individual track unit",
|
||||
API._ciInsertable = True,
|
||||
@ -565,7 +580,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Quantity",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Quantity of the track purchased",
|
||||
API._ciInsertable = True,
|
||||
@ -590,7 +605,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "MediaTypeId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "Media Type primary key identifier",
|
||||
API._ciInsertable = True,
|
||||
@ -598,7 +613,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Name",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The name of the media type format",
|
||||
API._ciInsertable = True,
|
||||
@ -618,7 +633,7 @@ schema =
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "TrackId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The ID of the track",
|
||||
API._ciInsertable = True,
|
||||
@ -626,7 +641,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Name",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The name of the track",
|
||||
API._ciInsertable = True,
|
||||
@ -634,7 +649,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "AlbumId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The ID of the album the track belongs to",
|
||||
API._ciInsertable = True,
|
||||
@ -642,7 +657,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "MediaTypeId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The ID of the media type the track is encoded with",
|
||||
API._ciInsertable = True,
|
||||
@ -650,7 +665,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "GenreId",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The ID of the genre of the track",
|
||||
API._ciInsertable = True,
|
||||
@ -658,7 +673,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Composer",
|
||||
API._ciType = API.StringTy,
|
||||
API._ciType = API.ScalarType "string",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The name of the composer of the track",
|
||||
API._ciInsertable = True,
|
||||
@ -666,7 +681,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Milliseconds",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The length of the track in milliseconds",
|
||||
API._ciInsertable = True,
|
||||
@ -674,7 +689,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "Bytes",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = True,
|
||||
API._ciDescription = Just "The size of the track in bytes",
|
||||
API._ciInsertable = True,
|
||||
@ -682,7 +697,7 @@ schema =
|
||||
},
|
||||
API.ColumnInfo
|
||||
{ API._ciName = API.ColumnName "UnitPrice",
|
||||
API._ciType = API.NumberTy,
|
||||
API._ciType = API.ScalarType "number",
|
||||
API._ciNullable = False,
|
||||
API._ciDescription = Just "The price of the track",
|
||||
API._ciInsertable = True,
|
||||
@ -706,12 +721,12 @@ schema =
|
||||
{ API._tiName = mkTableName "MyCustomScalarsTable",
|
||||
API._tiType = API.Table,
|
||||
API._tiColumns =
|
||||
[ API.ColumnInfo (API.ColumnName "MyIntColumn") (API.CustomTy "MyInt") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyFloatColumn") (API.CustomTy "MyFloat") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyStringColumn") (API.CustomTy "MyString") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyBooleanColumn") (API.CustomTy "MyBoolean") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyIDColumn") (API.CustomTy "MyID") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyAnythingColumn") (API.CustomTy "MyAnything") False Nothing True True
|
||||
[ API.ColumnInfo (API.ColumnName "MyIntColumn") (API.ScalarType "MyInt") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyFloatColumn") (API.ScalarType "MyFloat") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyStringColumn") (API.ScalarType "MyString") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyBooleanColumn") (API.ScalarType "MyBoolean") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyIDColumn") (API.ScalarType "MyID") False Nothing True True,
|
||||
API.ColumnInfo (API.ColumnName "MyAnythingColumn") (API.ScalarType "MyAnything") False Nothing True True
|
||||
],
|
||||
API._tiPrimaryKey = [],
|
||||
API._tiDescription = Nothing,
|
||||
|
@ -19,6 +19,7 @@ library
|
||||
, ekg-core
|
||||
, fast-logger
|
||||
, graphql-engine
|
||||
, graphql-parser
|
||||
, haskell-src-meta
|
||||
, hasura-prelude
|
||||
, hedgehog
|
||||
|
@ -82,15 +82,10 @@ instance Backend 'DataConnector where
|
||||
type HealthCheckTest 'DataConnector = Void
|
||||
|
||||
isComparableType :: ScalarType 'DataConnector -> Bool
|
||||
isComparableType = \case
|
||||
DC.NumberTy -> True
|
||||
DC.StringTy -> True
|
||||
DC.BoolTy -> False
|
||||
DC.CustomTy _ _ -> False
|
||||
isComparableType = const False
|
||||
|
||||
isNumType :: ScalarType 'DataConnector -> Bool
|
||||
isNumType DC.NumberTy = True
|
||||
isNumType _ = False
|
||||
isNumType = const False
|
||||
|
||||
getCustomAggregateOperators :: DC.SourceConfig -> HashMap G.Name (HashMap DC.ScalarType DC.ScalarType)
|
||||
getCustomAggregateOperators DC.SourceConfig {..} =
|
||||
@ -180,10 +175,7 @@ parseValue :: DC.ScalarType -> J.Value -> J.Parser J.Value
|
||||
parseValue type' val =
|
||||
case (type', val) of
|
||||
(_, J.Null) -> pure J.Null
|
||||
(DC.StringTy, value) -> J.String <$> J.parseJSON value
|
||||
(DC.BoolTy, value) -> J.Bool <$> J.parseJSON value
|
||||
(DC.NumberTy, value) -> J.Number <$> J.parseJSON value
|
||||
(DC.CustomTy _ graphQLType, value) -> case graphQLType of
|
||||
(DC.ScalarType _ graphQLType, value) -> case graphQLType of
|
||||
Nothing -> pure value
|
||||
Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> J.parseJSON @Int value
|
||||
Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> J.parseJSON @Double value
|
||||
@ -196,4 +188,7 @@ parseValue type' val =
|
||||
columnTypeToScalarType :: ColumnType 'DataConnector -> DC.ScalarType
|
||||
columnTypeToScalarType = \case
|
||||
ColumnScalar scalarType -> scalarType
|
||||
ColumnEnumReference _ -> DC.StringTy
|
||||
-- Data connectors does not yet support enum tables.
|
||||
-- If/when we add this support, we probably want to
|
||||
-- embed the enum scalar type name within the `EnumReference` record type
|
||||
ColumnEnumReference _ -> error "columnTypeToScalarType got enum"
|
||||
|
@ -64,7 +64,11 @@ instance BackendMetadata 'DataConnector where
|
||||
parseBoolExpOperations = parseBoolExpOperations'
|
||||
parseCollectableType = parseCollectableType'
|
||||
buildComputedFieldInfo = error "buildComputedFieldInfo: not implemented for the Data Connector backend."
|
||||
|
||||
-- If/when we implement enums for Data Connector backend, we will also need to fix columnTypeToScalarType function
|
||||
-- in Hasura.Backends.DataConnector.Adapter.Backend. See note there for more information.
|
||||
fetchAndValidateEnumValues = error "fetchAndValidateEnumValues: not implemented for the Data Connector backend."
|
||||
|
||||
buildFunctionInfo = error "buildFunctionInfo: not implemented for the Data Connector backend."
|
||||
updateColumnInEventTrigger = error "updateColumnInEventTrigger: not implemented for the Data Connector backend."
|
||||
postDropSourceHook _sourceConfig _tableTriggerMap = pure ()
|
||||
|
@ -76,7 +76,13 @@ instance BackendSchema 'DataConnector where
|
||||
comparisonExps = comparisonExps'
|
||||
|
||||
countTypeInput = countTypeInput'
|
||||
aggregateOrderByCountType = DC.NumberTy
|
||||
|
||||
-- aggregateOrderByCountType is only used when generating Relay schemas, and Data Connector backends do not yet support Relay
|
||||
-- If/when we want to support this we would need to add something to Capabilities to tell HGE what (integer-like) scalar
|
||||
-- type should be used to represent the result of a count aggregate in relay order-by queries.
|
||||
aggregateOrderByCountType =
|
||||
error "aggregateOrderByCountType: not implemented for Data Connector backend"
|
||||
|
||||
computedField =
|
||||
error "computedField: not implemented for the Data Connector backend."
|
||||
|
||||
@ -173,24 +179,20 @@ columnParser' ::
|
||||
GQL.Nullability ->
|
||||
GS.C.SchemaT r m (P.Parser 'P.Both n (IR.ValueWithOrigin (RQL.ColumnValue 'DataConnector)))
|
||||
columnParser' columnType nullability = case columnType of
|
||||
RQL.ColumnScalar scalarType ->
|
||||
RQL.ColumnScalar scalarType@(DC.ScalarType name graphQLType) ->
|
||||
P.memoizeOn 'columnParser' (scalarType, nullability) $
|
||||
GS.C.peelWithOrigin . fmap (RQL.ColumnValue columnType) . possiblyNullable' scalarType nullability
|
||||
<$> case scalarType of
|
||||
DC.StringTy -> pure $ J.String <$> P.string
|
||||
DC.NumberTy -> pure $ J.Number <$> P.scientific
|
||||
DC.BoolTy -> pure $ J.Bool <$> P.boolean
|
||||
DC.CustomTy name graphQLType -> do
|
||||
gqlName <-
|
||||
GQL.mkName name
|
||||
`onNothing` throw400 ValidationFailed ("The column type name " <> name <<> " is not a valid GraphQL name")
|
||||
pure $ case graphQLType of
|
||||
Nothing -> P.jsonScalar gqlName (Just "A custom scalar type")
|
||||
Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> P.namedInt gqlName
|
||||
Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> P.namedFloat gqlName
|
||||
Just DC.GraphQLString -> J.String <$> P.namedString gqlName
|
||||
Just DC.GraphQLBoolean -> J.Bool <$> P.namedBoolean gqlName
|
||||
Just DC.GraphQLID -> J.String <$> P.namedIdentifier gqlName
|
||||
<$> do
|
||||
gqlName <-
|
||||
GQL.mkName name
|
||||
`onNothing` throw400 ValidationFailed ("The column type name " <> name <<> " is not a valid GraphQL name")
|
||||
pure $ case graphQLType of
|
||||
Nothing -> P.jsonScalar gqlName (Just "A custom scalar type")
|
||||
Just DC.GraphQLInt -> (J.Number . fromIntegral) <$> P.namedInt gqlName
|
||||
Just DC.GraphQLFloat -> (J.Number . fromFloatDigits) <$> P.namedFloat gqlName
|
||||
Just DC.GraphQLString -> J.String <$> P.namedString gqlName
|
||||
Just DC.GraphQLBoolean -> J.Bool <$> P.namedBoolean gqlName
|
||||
Just DC.GraphQLID -> J.String <$> P.namedIdentifier gqlName
|
||||
RQL.ColumnEnumReference (RQL.EnumReference tableName enumValues customTableName) ->
|
||||
case nonEmpty (Map.toList enumValues) of
|
||||
Just enumValuesList ->
|
||||
|
@ -48,7 +48,6 @@ import Data.Text.NonEmpty (NonEmptyText, mkNonEmptyTextUnsafe)
|
||||
import Hasura.Backends.DataConnector.API qualified as API
|
||||
import Hasura.Base.ErrorValue qualified as ErrorValue
|
||||
import Hasura.Base.ToErrorValue (ToErrorValue (..))
|
||||
import Hasura.GraphQL.Parser.Name.TypeSystem (_Boolean, _Float, _Int, _String)
|
||||
import Hasura.Metadata.DTO.Placeholder (placeholderCodecViaJSON)
|
||||
import Hasura.Prelude
|
||||
import Language.GraphQL.Draft.Syntax qualified as GQL
|
||||
@ -329,43 +328,28 @@ instance Witch.From OrderDirection API.OrderDirection where
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
data ScalarType
|
||||
= StringTy
|
||||
| NumberTy
|
||||
| BoolTy
|
||||
| CustomTy Text (Maybe API.GraphQLType)
|
||||
= ScalarType Text (Maybe API.GraphQLType)
|
||||
deriving stock (Eq, Generic, Ord, Show)
|
||||
deriving anyclass (FromJSON, FromJSONKey, Hashable, NFData, ToJSON, ToJSONKey)
|
||||
|
||||
instance ToTxt ScalarType where
|
||||
toTxt = tshow
|
||||
toTxt (ScalarType name _) = name
|
||||
|
||||
instance ToErrorValue ScalarType where
|
||||
toErrorValue = ErrorValue.squote . tshow
|
||||
toErrorValue = ErrorValue.squote . toTxt
|
||||
|
||||
instance Witch.From ScalarType API.ScalarType where
|
||||
from = \case
|
||||
StringTy -> API.StringTy
|
||||
NumberTy -> API.NumberTy
|
||||
BoolTy -> API.BoolTy
|
||||
CustomTy name _ -> API.CustomTy name
|
||||
from (ScalarType name _) = API.ScalarType name
|
||||
|
||||
mkScalarType :: API.Capabilities -> API.ScalarType -> ScalarType
|
||||
mkScalarType API.Capabilities {..} apiType = case apiType of
|
||||
API.StringTy -> StringTy
|
||||
API.NumberTy -> NumberTy
|
||||
API.BoolTy -> BoolTy
|
||||
API.CustomTy name -> CustomTy name graphQLType
|
||||
where
|
||||
graphQLType = HashMap.lookup apiType (API.unScalarTypesCapabilities _cScalarTypes) >>= API._stcGraphQLType
|
||||
mkScalarType API.Capabilities {..} apiType@(API.ScalarType name) =
|
||||
ScalarType name graphQLType
|
||||
where
|
||||
graphQLType = HashMap.lookup apiType (API.unScalarTypesCapabilities _cScalarTypes) >>= API._stcGraphQLType
|
||||
|
||||
fromGQLType :: GQL.Name -> API.ScalarType
|
||||
fromGQLType typeName =
|
||||
if
|
||||
| typeName == _String -> API.StringTy
|
||||
| typeName == _Int -> API.NumberTy
|
||||
| typeName == _Float -> API.NumberTy
|
||||
| typeName == _Boolean -> API.BoolTy
|
||||
| otherwise -> API.CustomTy $ GQL.unName typeName
|
||||
API.ScalarType $ GQL.unName typeName
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
@ -436,28 +436,15 @@ mkPlan session (SourceConfig {}) ir = do
|
||||
parseSessionVariable :: SessionVariable -> SessionVarType 'DataConnector -> Text -> m Literal
|
||||
parseSessionVariable varName varType varValue = do
|
||||
case varType of
|
||||
CollectableTypeScalar scalarType ->
|
||||
case scalarType of
|
||||
-- Special case for string: uses literal session variable value rather than trying to parse a JSON string
|
||||
StringTy -> pure . ValueLiteral scalarType $ J.String varValue
|
||||
NumberTy -> parseBuiltinValue (ValueLiteral scalarType . J.Number) "number value"
|
||||
BoolTy -> parseBuiltinValue (ValueLiteral scalarType . J.Bool) "boolean value"
|
||||
CustomTy customTypeName _ -> parseCustomValue scalarType (customTypeName <> " JSON value")
|
||||
CollectableTypeArray scalarType ->
|
||||
case scalarType of
|
||||
StringTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.String) "JSON array of strings"
|
||||
NumberTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.Number) "JSON array of numbers"
|
||||
BoolTy -> parseBuiltinValue (ArrayLiteral scalarType . fmap J.Bool) "JSON array of booleans"
|
||||
CustomTy customTypeName _ -> parseCustomArray scalarType ("JSON array of " <> customTypeName <> " JSON values")
|
||||
CollectableTypeScalar scalarType@(ScalarType customTypeName _) ->
|
||||
parseCustomValue scalarType (customTypeName <> " JSON value")
|
||||
CollectableTypeArray scalarType@(ScalarType customTypeName _) ->
|
||||
parseCustomArray scalarType ("JSON array of " <> customTypeName <> " JSON values")
|
||||
where
|
||||
parseBuiltinValue :: J.FromJSON a => (a -> Literal) -> Text -> m Literal
|
||||
parseBuiltinValue =
|
||||
parseValue' J.parseJSON
|
||||
|
||||
parseCustomValue :: ScalarType -> Text -> m Literal
|
||||
parseCustomValue scalarType description =
|
||||
case scalarType of
|
||||
CustomTy _ (Just GraphQLString) ->
|
||||
ScalarType _ (Just GraphQLString) ->
|
||||
-- Special case for string: uses literal session variable value rather than trying to parse a JSON string
|
||||
pure . ValueLiteral scalarType $ J.String varValue
|
||||
_ ->
|
||||
|
@ -27,11 +27,11 @@ spec = do
|
||||
(CapabilitiesResponse (defaultCapabilities {_cRelationships = Just RelationshipCapabilities {}}) emptyConfigSchemaResponse Nothing Nothing)
|
||||
[aesonQQ|{"capabilities": {"relationships": {}}, "config_schemas": {"config_schema": {}, "other_schemas": {}}}|]
|
||||
describe "ScalarTypesCapabilities" $ do
|
||||
testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton StringTy (ScalarTypeCapabilities mempty mempty Nothing))) [aesonQQ|{"string": {}}|]
|
||||
testToFromJSONToSchema (ScalarTypesCapabilities (HashMap.singleton (ScalarType "string") (ScalarTypeCapabilities mempty mempty Nothing))) [aesonQQ|{"string": {}}|]
|
||||
jsonOpenApiProperties genScalarTypesCapabilities
|
||||
describe "ScalarTypeCapabilities" $ do
|
||||
let comparisonOperators = ComparisonOperators $ HashMap.fromList [([G.name|same_day_as|], CustomTy "DateTime")]
|
||||
let aggregateFunctions = AggregateFunctions $ HashMap.fromList [([G.name|max|], CustomTy "DateTime")]
|
||||
let comparisonOperators = ComparisonOperators $ HashMap.fromList [([G.name|same_day_as|], ScalarType "DateTime")]
|
||||
let aggregateFunctions = AggregateFunctions $ HashMap.fromList [([G.name|max|], ScalarType "DateTime")]
|
||||
let graphQLType = Just GraphQLString
|
||||
let json =
|
||||
[aesonQQ|{
|
||||
|
@ -21,7 +21,7 @@ spec = do
|
||||
describe "ColumnInfo" $ do
|
||||
describe "minimal" $
|
||||
testFromJSON
|
||||
(ColumnInfo (ColumnName "my_column_name") StringTy False Nothing False False)
|
||||
(ColumnInfo (ColumnName "my_column_name") (ScalarType "string") False Nothing False False)
|
||||
[aesonQQ|
|
||||
{ "name": "my_column_name",
|
||||
"type": "string",
|
||||
@ -30,7 +30,7 @@ spec = do
|
||||
|]
|
||||
describe "non-minimal" $
|
||||
testToFromJSONToSchema
|
||||
(ColumnInfo (ColumnName "my_column_name") NumberTy True (Just "My column description") True True)
|
||||
(ColumnInfo (ColumnName "my_column_name") (ScalarType "number") True (Just "My column description") True True)
|
||||
[aesonQQ|
|
||||
{ "name": "my_column_name",
|
||||
"type": "number",
|
||||
|
@ -68,7 +68,7 @@ spec = do
|
||||
|
||||
describe "ComparisonColumn" $ do
|
||||
testToFromJSONToSchema
|
||||
(ComparisonColumn QueryTable (ColumnName "column_name") StringTy)
|
||||
(ComparisonColumn QueryTable (ColumnName "column_name") (ScalarType "string"))
|
||||
[aesonQQ|{"path": ["$"], "name": "column_name", "column_type": "string"}|]
|
||||
|
||||
jsonOpenApiProperties genComparisonColumn
|
||||
@ -83,11 +83,11 @@ spec = do
|
||||
describe "ComparisonValue" $ do
|
||||
describe "AnotherColumn" $
|
||||
testToFromJSONToSchema
|
||||
(AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy)
|
||||
(AnotherColumn $ ComparisonColumn CurrentTable (ColumnName "my_column_name") (ScalarType "string"))
|
||||
[aesonQQ|{"type": "column", "column": {"name": "my_column_name", "column_type": "string"}}|]
|
||||
describe "ScalarValue" $
|
||||
testToFromJSONToSchema
|
||||
(ScalarValue (String "scalar value") StringTy)
|
||||
(ScalarValue (String "scalar value") (ScalarType "string"))
|
||||
[aesonQQ|{"type": "scalar", "value": "scalar value", "value_type": "string"}|]
|
||||
|
||||
jsonOpenApiProperties genComparisonValue
|
||||
@ -112,8 +112,8 @@ spec = do
|
||||
jsonOpenApiProperties genExistsInTable
|
||||
|
||||
describe "Expression" $ do
|
||||
let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name") StringTy
|
||||
let scalarValue = ScalarValue (String "scalar value") StringTy
|
||||
let comparisonColumn = ComparisonColumn CurrentTable (ColumnName "my_column_name") (ScalarType "string")
|
||||
let scalarValue = ScalarValue (String "scalar value") (ScalarType "string")
|
||||
let scalarValues = [String "scalar value"]
|
||||
let unaryComparisonExpression = ApplyUnaryComparisonOperator IsNull comparisonColumn
|
||||
|
||||
@ -195,7 +195,7 @@ spec = do
|
||||
|
||||
describe "BinaryArrayComparisonOperator" $ do
|
||||
testToFromJSONToSchema
|
||||
(ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues StringTy)
|
||||
(ApplyBinaryArrayComparisonOperator In comparisonColumn scalarValues (ScalarType "string"))
|
||||
[aesonQQ|
|
||||
{
|
||||
"type": "binary_arr_op",
|
||||
|
@ -46,7 +46,7 @@ spec = do
|
||||
describe "InsertFieldSchema" $ do
|
||||
describe "ColumnInsert" $ do
|
||||
testToFromJSONToSchema
|
||||
(ColumnInsert (ColumnInsertSchema (ColumnName "my_column") NumberTy))
|
||||
(ColumnInsert (ColumnInsertSchema (ColumnName "my_column") (ScalarType "number")))
|
||||
[aesonQQ|
|
||||
{ "type": "column",
|
||||
"column": "my_column",
|
||||
@ -70,7 +70,7 @@ spec = do
|
||||
jsonOpenApiProperties genInsertFieldSchema
|
||||
|
||||
describe "MutationOperation" $ do
|
||||
let returningFields = [(FieldName "field", ColumnField (ColumnName "my_column") StringTy)]
|
||||
let returningFields = [(FieldName "field", ColumnField (ColumnName "my_column") (ScalarType "string"))]
|
||||
describe "InsertOperation" $ do
|
||||
testToFromJSONToSchema
|
||||
(InsertOperation (InsertMutationOperation (TableName ["my_table"]) [] returningFields))
|
||||
@ -172,7 +172,7 @@ spec = do
|
||||
describe "RowUpdate" $ do
|
||||
describe "IncrementColumnRowUpdate" $
|
||||
testToFromJSONToSchema
|
||||
(IncrementColumn $ RowColumnValue (ColumnName "my_column") (Number 10) NumberTy)
|
||||
(IncrementColumn $ RowColumnValue (ColumnName "my_column") (Number 10) (ScalarType "number"))
|
||||
[aesonQQ|
|
||||
{ "type": "increment",
|
||||
"column": "my_column",
|
||||
@ -181,7 +181,7 @@ spec = do
|
||||
|]
|
||||
describe "SetColumnRowUpdate" $
|
||||
testToFromJSONToSchema
|
||||
(SetColumn $ RowColumnValue (ColumnName "my_column") (Number 10) NumberTy)
|
||||
(SetColumn $ RowColumnValue (ColumnName "my_column") (Number 10) (ScalarType "number"))
|
||||
[aesonQQ|
|
||||
{ "type": "set",
|
||||
"column": "my_column",
|
||||
@ -192,7 +192,7 @@ spec = do
|
||||
|
||||
describe "RowColumnValue" $ do
|
||||
testToFromJSONToSchema
|
||||
(RowColumnValue (ColumnName "my_column") (String "a value") StringTy)
|
||||
(RowColumnValue (ColumnName "my_column") (String "a value") (ScalarType "string"))
|
||||
[aesonQQ|
|
||||
{ "column": "my_column",
|
||||
"value": "a value",
|
||||
|
@ -33,7 +33,7 @@ spec = do
|
||||
describe "Field" $ do
|
||||
describe "ColumnField" $
|
||||
testToFromJSONToSchema
|
||||
(ColumnField (ColumnName "my_column_name") StringTy)
|
||||
(ColumnField (ColumnName "my_column_name") (ScalarType "string"))
|
||||
[aesonQQ|
|
||||
{ "type": "column",
|
||||
"column": "my_column_name",
|
||||
@ -55,7 +55,7 @@ spec = do
|
||||
describe "Query" $ do
|
||||
let query =
|
||||
Query
|
||||
{ _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField (ColumnName "my_field_name") StringTy)],
|
||||
{ _qFields = Just $ HashMap.fromList [(FieldName "my_field_alias", ColumnField (ColumnName "my_field_name") (ScalarType "string"))],
|
||||
_qAggregates = Just $ HashMap.fromList [(FieldName "my_aggregate", StarCount)],
|
||||
_qLimit = Just 10,
|
||||
_qOffset = Just 20,
|
||||
|
@ -7,29 +7,16 @@ import Hasura.Backends.DataConnector.API.V0.Scalar
|
||||
import Hasura.Generator.Common (defaultRange, genArbitraryAlphaNumTextExcluding)
|
||||
import Hasura.Prelude
|
||||
import Hedgehog
|
||||
import Hedgehog.Gen qualified as Gen
|
||||
import Test.Aeson.Utils
|
||||
import Test.Hspec
|
||||
|
||||
spec :: Spec
|
||||
spec = do
|
||||
describe "ScalarType" $ do
|
||||
describe "StringTy" $
|
||||
testToFromJSONToSchema StringTy [aesonQQ|"string"|]
|
||||
describe "NumberTy" $
|
||||
testToFromJSONToSchema NumberTy [aesonQQ|"number"|]
|
||||
describe "BoolTy" $
|
||||
testToFromJSONToSchema BoolTy [aesonQQ|"bool"|]
|
||||
describe "CustomTy" $
|
||||
testToFromJSONToSchema (CustomTy "foo") [aesonQQ|"foo"|]
|
||||
testToFromJSONToSchema (ScalarType "foo") [aesonQQ|"foo"|]
|
||||
jsonOpenApiProperties genScalarType
|
||||
|
||||
genScalarType :: (MonadGen m, GenBase m ~ Identity) => m ScalarType
|
||||
genScalarType =
|
||||
Gen.choice
|
||||
[ pure StringTy,
|
||||
pure NumberTy,
|
||||
pure BoolTy,
|
||||
CustomTy
|
||||
<$> genArbitraryAlphaNumTextExcluding ["string", "number", "bool"] defaultRange
|
||||
]
|
||||
ScalarType
|
||||
<$> genArbitraryAlphaNumTextExcluding ["string", "number", "bool"] defaultRange
|
||||
|
@ -34,7 +34,7 @@ spec = do
|
||||
( TableInfo
|
||||
(TableName ["my_table_name"])
|
||||
View
|
||||
[ColumnInfo (ColumnName "id") StringTy False Nothing False False]
|
||||
[ColumnInfo (ColumnName "id") (ScalarType "string") False Nothing False False]
|
||||
[ColumnName "id"]
|
||||
(ForeignKeys mempty)
|
||||
(Just "my description")
|
||||
@ -58,7 +58,7 @@ spec = do
|
||||
( TableInfo
|
||||
(TableName ["my_table_name"])
|
||||
Table
|
||||
[ColumnInfo (ColumnName "id") StringTy False Nothing False False]
|
||||
[ColumnInfo (ColumnName "id") (ScalarType "string") False Nothing False False]
|
||||
[ColumnName "id"]
|
||||
(ForeignKeys $ HashMap.singleton (ConstraintName "Artist") (Constraint (TableName ["artist_table"]) (HashMap.singleton (ColumnName "ArtistId") (ColumnName "ArtistId"))))
|
||||
(Just "my description")
|
||||
|
Loading…
Reference in New Issue
Block a user