mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-09-17 13:37:26 +03:00
chore(server): metadata changes for array relationships for Native Queries
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/8670 GitOrigin-RevId: c23e23e3cf48013ab76fc2fa98c8b8b800c6cee6
This commit is contained in:
parent
e95259e1f4
commit
2fd3f91398
@ -672,7 +672,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -820,6 +821,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig__BigQuery"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -1401,7 +1409,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -1652,6 +1661,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig___Postgres__Citus_"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -2268,7 +2284,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -2519,6 +2536,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig___Postgres__Cockroach_"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -3389,7 +3413,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -3541,6 +3566,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig__DataConnector"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -4790,7 +4822,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -5033,6 +5066,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig__MSSQL"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -5714,7 +5754,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -5863,6 +5904,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig__MySQL"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -6379,32 +6427,6 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"NullableScalarType": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"description": "Optional description text which appears in the GraphQL Schema",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name",
|
||||
"type": "string"
|
||||
},
|
||||
"nullable": {
|
||||
"default": false,
|
||||
"description": "Whether the type is nullable",
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"description": "The base scalar type\nPostgres Scalar Types",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ObjectFieldDefinition_GraphQLType": {
|
||||
"properties": {
|
||||
"arguments": {
|
||||
@ -6743,7 +6765,8 @@
|
||||
"fields": {
|
||||
"description": "Return types for the custom return type",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NullableScalarType"
|
||||
"additionalProperties": true,
|
||||
"description": "A scalar type or reference to another custom return type\nvalue with unspecified type - this is a placeholder that will eventually be replaced with a more detailed description"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
@ -6994,6 +7017,13 @@
|
||||
"description": "Free variables in the expression and their types",
|
||||
"type": "object"
|
||||
},
|
||||
"array_relationships": {
|
||||
"default": [],
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RelDef_RelManualConfig___Postgres__Vanilla_"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"code": {
|
||||
"description": "Native code expression (SQL) to run\nAn interpolated query expressed in native code (SQL)",
|
||||
"type": "string"
|
||||
@ -8027,6 +8057,132 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig__BigQuery": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/BigqueryRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig__DataConnector": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/DataconnectorRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig__MSSQL": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/MssqlRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig__MySQL": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/MysqlRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig___Postgres__Citus_": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/CitusRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig___Postgres__Cockroach_": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/CockroachRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelManualConfig___Postgres__Vanilla_": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"using": {
|
||||
"$ref": "#/components/schemas/PostgresRelManualConfig"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"using"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"RelDef_RelUsing__BigQuery__ArrRelUsingFKeyOn__BigQuery_": {
|
||||
"properties": {
|
||||
"comment": {
|
||||
|
@ -97,7 +97,7 @@ library
|
||||
Test.API.GraphQL.ContentLengthSpec
|
||||
Test.API.Metadata.BulkKeepGoingSpec
|
||||
Test.API.Metadata.ComputedFieldsSpec
|
||||
Test.API.Metadata.CustomTypeSpec
|
||||
Test.API.Metadata.CustomReturnTypeSpec
|
||||
Test.API.Metadata.InconsistentSpec
|
||||
Test.API.Metadata.NativeQueriesSpec
|
||||
Test.API.Metadata.NativeQueries.TypeCheckingSpec
|
||||
|
@ -1,7 +1,8 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
|
||||
|
||||
-- | Tests of the newly separated Custom Return Types feature
|
||||
module Test.API.Metadata.CustomTypeSpec (spec) where
|
||||
module Test.API.Metadata.CustomReturnTypeSpec (spec) where
|
||||
|
||||
import Control.Lens
|
||||
import Data.Aeson (Value)
|
||||
@ -53,13 +54,13 @@ schema = []
|
||||
|
||||
testImplementation :: SpecWith TestEnvironment
|
||||
testImplementation = do
|
||||
let myCustomType :: Schema.CustomType
|
||||
myCustomType =
|
||||
let myCustomReturnType :: Schema.CustomReturnType
|
||||
myCustomReturnType =
|
||||
(Schema.customType "nice")
|
||||
{ Schema.customTypeDescription = Just "hello",
|
||||
Schema.customTypeColumns =
|
||||
[ (Schema.nativeQueryColumn "divided" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "a divided thing"
|
||||
[ (Schema.customReturnTypeScalar "divided" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "a divided thing"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -109,7 +110,24 @@ testImplementation = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName myCustomType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
|
||||
it "Adds a custom type with a nested custom type and returns a 200" $ \testEnvironment -> do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
nestedCustomReturnType :: Schema.CustomReturnType
|
||||
nestedCustomReturnType =
|
||||
(Schema.customType "nested")
|
||||
{ Schema.customTypeDescription = Just "hello",
|
||||
Schema.customTypeColumns =
|
||||
[ Schema.customReturnTypeScalar "name" Schema.TStr,
|
||||
Schema.customReturnTypeReference "nices" "nice"
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName nestedCustomReturnType testEnvironment
|
||||
|
||||
it "Checks for the custom type" $ \testEnvironment -> do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
@ -117,7 +135,7 @@ testImplementation = do
|
||||
backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
getRequestType = backendType <> "_get_custom_return_type"
|
||||
|
||||
Schema.trackCustomType sourceName myCustomType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -145,9 +163,9 @@ testImplementation = do
|
||||
backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
getRequestType = backendType <> "_get_custom_return_type"
|
||||
|
||||
Schema.trackCustomType sourceName myCustomType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
|
||||
Schema.untrackCustomType sourceName myCustomType testEnvironment
|
||||
Schema.untrackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -171,13 +189,13 @@ testImplementation = do
|
||||
nativeQuery =
|
||||
(Schema.nativeQuery "native_query" "SELECT 1 as divided" "nice")
|
||||
|
||||
Schema.trackCustomType sourceName myCustomType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName myCustomReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName nativeQuery testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
( GraphqlEngine.postMetadataWithStatus 400 testEnvironment $
|
||||
Schema.untrackCustomTypeCommand sourceName backendTypeMetadata myCustomType
|
||||
Schema.untrackCustomReturnTypeCommand sourceName backendTypeMetadata myCustomReturnType
|
||||
)
|
||||
[yaml|
|
||||
code: constraint-violation
|
||||
@ -191,12 +209,12 @@ testImplementation = do
|
||||
|
||||
testPermissions :: SpecWith TestEnvironment
|
||||
testPermissions = do
|
||||
let customReturnType :: Schema.CustomType
|
||||
let customReturnType :: Schema.CustomReturnType
|
||||
customReturnType =
|
||||
(Schema.customType "divided_stuff")
|
||||
{ Schema.customTypeColumns =
|
||||
[ (Schema.nativeQueryColumn "divided" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "a divided thing"
|
||||
[ (Schema.customReturnTypeScalar "divided" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "a divided thing"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -207,7 +225,7 @@ testPermissions = do
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName customReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName customReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -262,7 +280,7 @@ testPermissions = do
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName customReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName customReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
@ -78,11 +78,11 @@ schema =
|
||||
)
|
||||
types
|
||||
|
||||
allTypesReturnType :: Schema.CustomType
|
||||
allTypesReturnType :: Schema.CustomReturnType
|
||||
allTypesReturnType =
|
||||
(Schema.customType "stuff_type")
|
||||
{ Schema.customTypeColumns =
|
||||
(\t -> Schema.nativeQueryColumn t (customType t)) <$> types
|
||||
(\t -> Schema.customReturnTypeScalar t (customType t)) <$> types
|
||||
}
|
||||
|
||||
types :: [Text]
|
||||
@ -125,7 +125,7 @@ tests BackendDifferences {..} = do
|
||||
nativeQuery =
|
||||
(Schema.nativeQuery "typed_model" simpleQuery "stuff_type")
|
||||
|
||||
Schema.trackCustomType sourceName allTypesReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName allTypesReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -153,8 +153,8 @@ tests BackendDifferences {..} = do
|
||||
|
||||
-- Possible cleanup after last test that may have tracked this custom type
|
||||
_ <- Schema.untrackNativeQuery sourceName nativeQuery testEnvironment `catch` \(_ :: SomeException) -> pure ()
|
||||
_ <- Schema.untrackCustomType sourceName (mkCustomType customtypeType) testEnvironment `catch` \(_ :: SomeException) -> pure ()
|
||||
Schema.trackCustomType sourceName (mkCustomType customtypeType) testEnvironment
|
||||
_ <- Schema.untrackCustomReturnType sourceName (mkCustomReturnType customtypeType) testEnvironment `catch` \(_ :: SomeException) -> pure ()
|
||||
Schema.trackCustomReturnType sourceName (mkCustomReturnType customtypeType) testEnvironment
|
||||
|
||||
let message :: Text
|
||||
message =
|
||||
@ -181,11 +181,11 @@ tests BackendDifferences {..} = do
|
||||
|
||||
-- ** Utils
|
||||
|
||||
mkCustomType :: Text -> Schema.CustomType
|
||||
mkCustomType typ =
|
||||
mkCustomReturnType :: Text -> Schema.CustomReturnType
|
||||
mkCustomReturnType typ =
|
||||
(Schema.customType ("stuff_type_" <> typ))
|
||||
{ Schema.customTypeColumns =
|
||||
[Schema.nativeQueryColumn typ (customType typ)]
|
||||
[Schema.customReturnTypeScalar typ (customType typ)]
|
||||
}
|
||||
|
||||
-- | Match a column from a table type and the custom type.
|
||||
|
@ -60,20 +60,20 @@ tests = do
|
||||
let simpleQuery :: Text
|
||||
simpleQuery = "SELECT (thing / 2)::integer AS divided FROM stuff"
|
||||
|
||||
conflictingReturnType :: Schema.CustomType
|
||||
conflictingReturnType :: Schema.CustomReturnType
|
||||
conflictingReturnType =
|
||||
(Schema.customType "conflicting")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "thing" Schema.TInt,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "thing" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
dividedReturnType :: Schema.CustomType
|
||||
dividedReturnType :: Schema.CustomReturnType
|
||||
dividedReturnType =
|
||||
(Schema.customType "divided_stuff")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "divided" Schema.TInt
|
||||
[ Schema.customReturnTypeScalar "divided" Schema.TInt
|
||||
]
|
||||
}
|
||||
|
||||
@ -126,7 +126,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedReturnType testEnvironment
|
||||
|
||||
actual <-
|
||||
GraphqlEngine.postMetadataWithStatus
|
||||
@ -163,7 +163,7 @@ tests = do
|
||||
status_code: "42P01"
|
||||
|]
|
||||
|
||||
Schema.trackCustomType sourceName dividedReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedReturnType testEnvironment
|
||||
|
||||
actual <-
|
||||
GraphqlEngine.postMetadataWithStatus
|
||||
@ -193,7 +193,7 @@ tests = do
|
||||
|
||||
expectedError = "Encountered conflicting definitions in the selection set for 'subscription_root' for field 'hasura_stuff' defined in [table hasura.stuff in source " <> sourceName <> ", native_query hasura_stuff in source " <> sourceName <> "]. Fields must not be defined more than once across all sources."
|
||||
|
||||
Schema.trackCustomType sourceName conflictingReturnType testEnv
|
||||
Schema.trackCustomReturnType sourceName conflictingReturnType testEnv
|
||||
|
||||
shouldReturnYaml
|
||||
testEnv
|
||||
@ -226,7 +226,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source conflictingReturnType testEnv
|
||||
Schema.trackCustomReturnType source conflictingReturnType testEnv
|
||||
|
||||
shouldReturnYaml
|
||||
testEnv
|
||||
@ -272,7 +272,7 @@ tests = do
|
||||
error: Failed to validate query
|
||||
|]
|
||||
|
||||
Schema.trackCustomType sourceName dividedReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedReturnType testEnvironment
|
||||
|
||||
actual <-
|
||||
GraphqlEngine.postMetadataWithStatus
|
||||
@ -298,11 +298,11 @@ tests = do
|
||||
|
||||
query = "SELECT {{text}} AS not_text"
|
||||
|
||||
brokenColumnsReturn :: Schema.CustomType
|
||||
brokenColumnsReturn :: Schema.CustomReturnType
|
||||
brokenColumnsReturn =
|
||||
(Schema.customType "failing")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "text" Schema.TStr
|
||||
[ Schema.customReturnTypeScalar "text" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName brokenColumnsReturn testEnvironment
|
||||
Schema.trackCustomReturnType sourceName brokenColumnsReturn testEnvironment
|
||||
|
||||
actual <-
|
||||
GraphqlEngine.postMetadataWithStatus
|
||||
@ -335,7 +335,7 @@ tests = do
|
||||
missingArgsNativeQuery =
|
||||
(Schema.nativeQuery "divided_falling" query "divided_stuff")
|
||||
|
||||
Schema.trackCustomType sourceName dividedReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -365,7 +365,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
|
||||
|
||||
-- | Tests of the Native Queries feature.
|
||||
module Test.API.Metadata.NativeQueriesSpec (spec) where
|
||||
|
||||
import Control.Lens
|
||||
import Data.Aeson qualified as A
|
||||
import Data.Aeson.Key qualified as Key
|
||||
import Data.Aeson.Lens
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Harness.Backend.BigQuery qualified as BigQuery
|
||||
@ -70,6 +72,7 @@ spec = do
|
||||
traverse_
|
||||
(Fixture.runClean fixtures)
|
||||
[ testAdminAccess,
|
||||
testRelationships,
|
||||
testImplementation
|
||||
]
|
||||
|
||||
@ -84,15 +87,23 @@ schema =
|
||||
[ Schema.column "thing" Schema.TInt,
|
||||
Schema.column "date" Schema.TUTCTime
|
||||
]
|
||||
},
|
||||
(Schema.table "articles")
|
||||
{ Schema.tableColumns =
|
||||
[ Schema.column "id" Schema.TInt,
|
||||
Schema.column "author_id" Schema.TInt,
|
||||
Schema.column "title" Schema.TStr,
|
||||
Schema.column "content" Schema.TStr
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
dividedStuffReturnType :: Schema.CustomType
|
||||
dividedStuffReturnType :: Schema.CustomReturnType
|
||||
dividedStuffReturnType =
|
||||
(Schema.customType "divided_stuff")
|
||||
{ Schema.customTypeColumns =
|
||||
[ (Schema.nativeQueryColumn "divided" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "a divided thing"
|
||||
[ (Schema.customReturnTypeScalar "divided" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "a divided thing"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -117,7 +128,7 @@ testAdminAccess = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -139,7 +150,7 @@ testAdminAccess = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -182,6 +193,75 @@ testAdminAccess = do
|
||||
path: "$.args"
|
||||
|]
|
||||
|
||||
-------------------------
|
||||
-- Test relationshis --
|
||||
-------------------------
|
||||
|
||||
testRelationships :: SpecWith TestEnvironment
|
||||
testRelationships = do
|
||||
let query :: Text
|
||||
query = "SELECT * FROM (VALUES (1, 'Marenghi'), (2, 'other')) as t(\"id\", \"name\")"
|
||||
|
||||
articleCustomReturnType :: Schema.CustomReturnType
|
||||
articleCustomReturnType =
|
||||
(Schema.customType "article")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "author_id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "content" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
-- we'll need to add the `articles` relationship row later
|
||||
relationshipCustomReturnType :: Schema.CustomReturnType
|
||||
relationshipCustomReturnType =
|
||||
(Schema.customType "author")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "name" Schema.TStr,
|
||||
Schema.customReturnTypeReference "articles" "article"
|
||||
]
|
||||
}
|
||||
|
||||
-- broadly, a 'SELECT * FROM authors' type query
|
||||
relationshipNativeQuery :: Schema.NativeQuery
|
||||
relationshipNativeQuery =
|
||||
Schema.nativeQuery "relationship_test" query "author"
|
||||
|
||||
describe "Relationships" $ do
|
||||
it "Adding a logical model with a valid array relationship returns a 200" $ \testEnvironment -> do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
schemaKeyword :: String
|
||||
schemaKeyword = Key.toString $ Fixture.backendSchemaKeyword backendTypeMetadata
|
||||
|
||||
arrayRel =
|
||||
[interpolateYaml|
|
||||
name: model_to_articles
|
||||
using:
|
||||
column_mapping: {}
|
||||
insertion_order: null
|
||||
remote_table:
|
||||
name: article
|
||||
#{schemaKeyword}: #{schemaName}
|
||||
|]
|
||||
|
||||
nativeQueryWithRelationship =
|
||||
relationshipNativeQuery
|
||||
{ Schema.nativeQueryArrayRelationships = [arrayRel]
|
||||
}
|
||||
|
||||
Schema.trackCustomReturnType sourceName articleCustomReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName relationshipCustomReturnType testEnvironment
|
||||
let nativeQueryMetadata = Schema.trackNativeQueryCommand sourceName backendTypeMetadata nativeQueryWithRelationship
|
||||
|
||||
GraphqlEngine.postMetadata_
|
||||
testEnvironment
|
||||
nativeQueryMetadata
|
||||
|
||||
-------------------------
|
||||
-- Test implementation --
|
||||
-------------------------
|
||||
@ -206,7 +286,7 @@ testImplementation = do
|
||||
[Schema.nativeQueryColumn "unused" Schema.TInt]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
|
||||
it "Adding a native query of a function with broken SQL returns a 400" $ \testEnvironment -> do
|
||||
@ -252,7 +332,7 @@ testImplementation = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
@ -291,7 +371,7 @@ testImplementation = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
Schema.untrackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
@ -311,7 +391,7 @@ testImplementation = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
|
||||
Schema.untrackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
@ -376,7 +456,7 @@ testImplementation = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
testEnvironment
|
||||
@ -403,7 +483,7 @@ testImplementation = do
|
||||
[Schema.nativeQueryColumn "unused" Schema.TInt]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName dividedStuffReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName dividedStuffNativeQuery testEnvironment
|
||||
|
||||
metadata <-
|
||||
@ -464,7 +544,7 @@ metadataHandlingWhenDisabledSpec = do
|
||||
$ withPostgresSource "default"
|
||||
$ do
|
||||
it "`replace_metadata` does not report any inconsistent objects" $ \env -> do
|
||||
let command = Schema.trackCustomTypeCommand "default" Postgres.backendTypeMetadata dividedStuffReturnType
|
||||
let command = Schema.trackCustomReturnTypeCommand "default" Postgres.backendTypeMetadata dividedStuffReturnType
|
||||
_ <- hgePost env 200 "/v1/metadata" [] command
|
||||
|
||||
currentMetadata <- export_metadata env
|
||||
@ -477,7 +557,7 @@ metadataHandlingWhenDisabledSpec = do
|
||||
|]
|
||||
|
||||
it "They do appear in the schema" $ \env -> do
|
||||
let command = Schema.trackCustomTypeCommand "default" Postgres.backendTypeMetadata dividedStuffReturnType
|
||||
let command = Schema.trackCustomReturnTypeCommand "default" Postgres.backendTypeMetadata dividedStuffReturnType
|
||||
_ <- hgePost env 200 "/v1/metadata" [] command
|
||||
|
||||
currentMetadata <- export_metadata env
|
||||
|
@ -1,4 +1,5 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
|
||||
|
||||
-- | Access to the SQL
|
||||
module Test.Databases.BigQuery.NativeQueriesSpec (spec) where
|
||||
@ -79,23 +80,23 @@ tests = do
|
||||
helloWorldNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_function" query "hello_world_function")
|
||||
|
||||
helloWorldReturnType :: Schema.CustomType
|
||||
helloWorldReturnType :: Schema.CustomReturnType
|
||||
helloWorldReturnType =
|
||||
(Schema.customType "hello_world_function")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "one" Schema.TStr,
|
||||
Schema.nativeQueryColumn "two" Schema.TStr
|
||||
[ Schema.customReturnTypeScalar "one" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "two" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
articleWithExcerptReturnType :: Schema.CustomType
|
||||
articleWithExcerptReturnType :: Schema.CustomReturnType
|
||||
articleWithExcerptReturnType =
|
||||
(Schema.customType "article_with_excerpt")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "id" Schema.TInt,
|
||||
Schema.nativeQueryColumn "title" Schema.TStr,
|
||||
Schema.nativeQueryColumn "excerpt" Schema.TStr,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "excerpt" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
@ -106,16 +107,16 @@ tests = do
|
||||
|
||||
nullableQuery = "SELECT thing / 2 AS divided, null as something_nullable FROM stuff"
|
||||
|
||||
descriptionsAndNullableReturnType :: Schema.CustomType
|
||||
descriptionsAndNullableReturnType :: Schema.CustomReturnType
|
||||
descriptionsAndNullableReturnType =
|
||||
(Schema.customType "divided_stuff")
|
||||
{ Schema.customTypeColumns =
|
||||
[ (Schema.nativeQueryColumn "divided" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "A divided thing"
|
||||
[ (Schema.customReturnTypeScalar "divided" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "A divided thing"
|
||||
},
|
||||
(Schema.nativeQueryColumn "something_nullable" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "Something nullable",
|
||||
Schema.nativeQueryColumnNullable = True
|
||||
(Schema.customReturnTypeScalar "something_nullable" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "Something nullable",
|
||||
Schema.customReturnTypeColumnNullable = True
|
||||
}
|
||||
],
|
||||
Schema.customTypeDescription = Just "Return type description"
|
||||
@ -129,7 +130,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName descriptionsAndNullableReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName descriptionsAndNullableReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName descriptionsAndNullableNativeQuery testEnvironment
|
||||
|
||||
let queryTypesIntrospection :: Value
|
||||
@ -196,7 +197,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
Schema.trackNativeQuery source helloWorldNativeQuery testEnvironment
|
||||
|
||||
let expected =
|
||||
@ -228,7 +229,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldNativeQuery testEnvironment
|
||||
|
||||
@ -266,7 +267,7 @@ tests = do
|
||||
helloWorldNativeQueryWithDuplicates =
|
||||
(Schema.nativeQuery "hello_world_function" queryWithDuplicates "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldNativeQueryWithDuplicates testEnvironment
|
||||
|
||||
@ -300,7 +301,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName helloWorldNativeQuery testEnvironment
|
||||
|
||||
@ -339,7 +340,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldNativeQueryWithDummyArgument testEnvironment
|
||||
|
||||
@ -376,7 +377,7 @@ tests = do
|
||||
helloCommentNativeQuery =
|
||||
(Schema.nativeQuery "hello_comment_function" spicyQuery "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloCommentNativeQuery testEnvironment
|
||||
|
||||
@ -415,7 +416,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_perms" query "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
@ -474,7 +475,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_perms" query "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
@ -534,7 +535,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_perms" query "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
@ -616,7 +617,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source articleWithExcerptNativeQuery testEnvironment
|
||||
|
||||
@ -662,7 +663,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -715,7 +716,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source articleWithExcerptNativeQuery testEnvironment
|
||||
|
||||
@ -760,7 +761,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source articleWithExcerptNativeQuery testEnvironment
|
||||
|
||||
|
@ -88,14 +88,14 @@ tests = do
|
||||
|]
|
||||
|
||||
describe "Testing Native Queries" $ do
|
||||
let articleWithExcerptReturnType :: Schema.CustomType
|
||||
let articleWithExcerptReturnType :: Schema.CustomReturnType
|
||||
articleWithExcerptReturnType =
|
||||
(Schema.customType "article_with_excerpt")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "id" Schema.TInt,
|
||||
Schema.nativeQueryColumn "title" Schema.TStr,
|
||||
Schema.nativeQueryColumn "excerpt" Schema.TStr,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "excerpt" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -149,7 +149,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -191,7 +191,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -228,7 +228,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -269,12 +269,12 @@ tests = do
|
||||
queryWithDuplicates :: Text
|
||||
queryWithDuplicates = "SELECT * FROM (VALUES ('hello', 'world'), ('hello', 'friend')) as t(\"one\", \"two\")"
|
||||
|
||||
helloWorldReturnType :: Schema.CustomType
|
||||
helloWorldReturnType :: Schema.CustomReturnType
|
||||
helloWorldReturnType =
|
||||
(Schema.customType "hello_world_function")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "one" Schema.TStr,
|
||||
Schema.nativeQueryColumn "two" Schema.TStr
|
||||
[ Schema.customReturnTypeScalar "one" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "two" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
@ -282,7 +282,7 @@ tests = do
|
||||
helloWorldNativeQueryWithDuplicates =
|
||||
(Schema.nativeQuery "hello_world_function" queryWithDuplicates "hello_world_function")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldNativeQueryWithDuplicates testEnvironment
|
||||
|
||||
|
@ -66,14 +66,14 @@ tests = do
|
||||
articleQuery schemaName =
|
||||
"select id, title,(substring(content, 1, {{length}}) + (case when len(content) < {{length}} then '' else '...' end)) as excerpt,date from [" <> Schema.unSchemaName schemaName <> "].[article]"
|
||||
|
||||
articleWithExcerptReturnType :: Schema.CustomType
|
||||
articleWithExcerptReturnType :: Schema.CustomReturnType
|
||||
articleWithExcerptReturnType =
|
||||
(Schema.customType "article_with_excerpt")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "id" Schema.TInt,
|
||||
Schema.nativeQueryColumn "title" Schema.TStr,
|
||||
Schema.nativeQueryColumn "excerpt" Schema.TStr,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "excerpt" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ tests = do
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source (articleWithExcerptNativeQuery "article_with_excerpt" schemaName) testEnvironment
|
||||
|
||||
@ -127,7 +127,7 @@ tests = do
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery
|
||||
source
|
||||
@ -170,7 +170,7 @@ tests = do
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source (articleWithExcerptNativeQuery "article_with_excerpt" schemaName) testEnvironment
|
||||
|
||||
@ -205,7 +205,7 @@ tests = do
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
Schema.trackCustomType source articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source (articleWithExcerptNativeQuery "article_with_excerpt" schemaName) testEnvironment
|
||||
|
||||
@ -242,13 +242,13 @@ tests = do
|
||||
|
||||
goodQuery = "EXEC sp_databases"
|
||||
|
||||
storedProcedureReturnType :: Schema.CustomType
|
||||
storedProcedureReturnType :: Schema.CustomReturnType
|
||||
storedProcedureReturnType =
|
||||
(Schema.customType "stored_procedure")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "database_name" Schema.TStr,
|
||||
Schema.nativeQueryColumn "database_size" Schema.TInt,
|
||||
Schema.nativeQueryColumn "remarks" Schema.TStr
|
||||
[ Schema.customReturnTypeScalar "database_name" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "database_size" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "remarks" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ tests = do
|
||||
useStoredProcedure =
|
||||
(Schema.nativeQuery "use_stored_procedure" goodQuery "stored_procedure")
|
||||
|
||||
Schema.trackCustomType source storedProcedureReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source storedProcedureReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source useStoredProcedure testEnvironment
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
|
||||
|
||||
-- | Access to the SQL
|
||||
module Test.Queries.NativeQueries.NativeQueriesSpec (spec) where
|
||||
@ -74,12 +75,12 @@ tests = do
|
||||
let query :: Text
|
||||
query = "SELECT * FROM (VALUES ('hello', 'world'), ('welcome', 'friend')) as t(\"one\", \"two\")"
|
||||
|
||||
helloWorldReturnType :: Schema.CustomType
|
||||
helloWorldReturnType :: Schema.CustomReturnType
|
||||
helloWorldReturnType =
|
||||
(Schema.customType "hello_world_return_type")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "one" Schema.TStr,
|
||||
Schema.nativeQueryColumn "two" Schema.TStr
|
||||
[ Schema.customReturnTypeScalar "one" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "two" Schema.TStr
|
||||
]
|
||||
}
|
||||
|
||||
@ -92,7 +93,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName helloWorldNativeQuery testEnvironment
|
||||
|
||||
@ -124,16 +125,16 @@ tests = do
|
||||
|
||||
nullableQuery = "SELECT (thing / 2)::integer AS divided, null::text as something_nullable FROM stuff"
|
||||
|
||||
descriptionsAndNullableReturnType :: Schema.CustomType
|
||||
descriptionsAndNullableReturnType :: Schema.CustomReturnType
|
||||
descriptionsAndNullableReturnType =
|
||||
(Schema.customType "divided_stuff")
|
||||
{ Schema.customTypeColumns =
|
||||
[ (Schema.nativeQueryColumn "divided" Schema.TInt)
|
||||
{ Schema.nativeQueryColumnDescription = Just "A divided thing"
|
||||
[ (Schema.customReturnTypeScalar "divided" Schema.TInt)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "A divided thing"
|
||||
},
|
||||
(Schema.nativeQueryColumn "something_nullable" Schema.TStr)
|
||||
{ Schema.nativeQueryColumnDescription = Just "Something nullable",
|
||||
Schema.nativeQueryColumnNullable = True
|
||||
(Schema.customReturnTypeScalar "something_nullable" Schema.TStr)
|
||||
{ Schema.customReturnTypeColumnDescription = Just "Something nullable",
|
||||
Schema.customReturnTypeColumnNullable = True
|
||||
}
|
||||
],
|
||||
Schema.customTypeDescription = Just "Return type description"
|
||||
@ -147,7 +148,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName descriptionsAndNullableReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName descriptionsAndNullableReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName descriptionsAndNullableNativeQuery testEnvironment
|
||||
|
||||
@ -215,7 +216,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
Schema.trackNativeQuery source helloWorldNativeQuery testEnvironment
|
||||
|
||||
let expected =
|
||||
@ -247,7 +248,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
Schema.trackNativeQuery source helloWorldNativeQuery testEnvironment
|
||||
|
||||
let expected =
|
||||
@ -277,7 +278,7 @@ tests = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
sourceName = BackendType.backendSourceName backendTypeMetadata
|
||||
|
||||
Schema.trackCustomType sourceName helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName helloWorldReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName helloWorldNativeQuery testEnvironment
|
||||
|
||||
let expected =
|
||||
@ -315,7 +316,7 @@ tests = do
|
||||
]
|
||||
}
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldNativeQueryWithDummyArgument testEnvironment
|
||||
|
||||
@ -352,7 +353,7 @@ tests = do
|
||||
helloCommentNativeQuery =
|
||||
(Schema.nativeQuery "hello_comment_function" spicyQuery "hello_world_return_type")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloCommentNativeQuery testEnvironment
|
||||
|
||||
@ -391,7 +392,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_with_permissions" query "hello_world_return_type")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
@ -450,7 +451,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_with_permissions" query "hello_world_return_type")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
@ -510,7 +511,7 @@ tests = do
|
||||
helloWorldPermNativeQuery =
|
||||
(Schema.nativeQuery "hello_world_with_permissions" query "hello_world_return_type")
|
||||
|
||||
Schema.trackCustomType source helloWorldReturnType testEnvironment
|
||||
Schema.trackCustomReturnType source helloWorldReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery source helloWorldPermNativeQuery testEnvironment
|
||||
|
||||
|
@ -95,14 +95,14 @@ tests = do
|
||||
from article
|
||||
|]
|
||||
|
||||
articleWithExcerptReturnType :: Schema.CustomType
|
||||
articleWithExcerptReturnType :: Schema.CustomReturnType
|
||||
articleWithExcerptReturnType =
|
||||
(Schema.customType "article_with_excerpt")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "id" Schema.TInt,
|
||||
Schema.nativeQueryColumn "title" Schema.TStr,
|
||||
Schema.nativeQueryColumn "excerpt" Schema.TStr,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "excerpt" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ tests = do
|
||||
[Schema.nativeQueryColumn "length" Schema.TInt]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName articleWithExcerptReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName articleWithExcerptReturnType testEnvironment
|
||||
|
||||
Schema.trackNativeQuery sourceName articleWithExcerptNativeQuery testEnvironment
|
||||
|
||||
@ -233,14 +233,14 @@ tests = do
|
||||
shouldBe :: IO Value -> Value -> IO ()
|
||||
shouldBe = shouldReturnYaml testEnvironment
|
||||
|
||||
customReturnType :: Schema.CustomType
|
||||
customReturnType :: Schema.CustomReturnType
|
||||
customReturnType =
|
||||
(Schema.customType "crt")
|
||||
{ Schema.customTypeColumns =
|
||||
[ Schema.nativeQueryColumn "id" Schema.TInt,
|
||||
Schema.nativeQueryColumn "title" Schema.TStr,
|
||||
Schema.nativeQueryColumn "content" Schema.TStr,
|
||||
Schema.nativeQueryColumn "date" Schema.TUTCTime
|
||||
[ Schema.customReturnTypeScalar "id" Schema.TInt,
|
||||
Schema.customReturnTypeScalar "title" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "content" Schema.TStr,
|
||||
Schema.customReturnTypeScalar "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ tests = do
|
||||
[Schema.nativeQueryColumn "pattern" Schema.TStr]
|
||||
}
|
||||
|
||||
Schema.trackCustomType sourceName customReturnType testEnvironment
|
||||
Schema.trackCustomReturnType sourceName customReturnType testEnvironment
|
||||
Schema.trackNativeQuery sourceName nativeQuery testEnvironment
|
||||
|
||||
one <- mkSubscription [graphql| subscription { filtered_article(args: { pattern: "%native%" }) { id, title } } |] []
|
||||
|
@ -17,11 +17,6 @@ module Harness.Schema
|
||||
NativeQueryColumn (..),
|
||||
trackNativeQueryCommand,
|
||||
untrackNativeQueryCommand,
|
||||
CustomType (..),
|
||||
trackCustomType,
|
||||
trackCustomTypeCommand,
|
||||
untrackCustomType,
|
||||
untrackCustomTypeCommand,
|
||||
resolveTableSchema,
|
||||
trackTable,
|
||||
untrackTable,
|
||||
@ -39,9 +34,10 @@ module Harness.Schema
|
||||
addSource,
|
||||
trackNativeQuery,
|
||||
untrackNativeQuery,
|
||||
getSchemaName,
|
||||
module Harness.Schema.Table,
|
||||
module Harness.Schema.Name,
|
||||
getSchemaName,
|
||||
module Harness.Schema.CustomReturnType,
|
||||
)
|
||||
where
|
||||
|
||||
@ -53,6 +49,7 @@ import Data.Vector qualified as V
|
||||
import Harness.Exceptions
|
||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||
import Harness.Quoter.Yaml (interpolateYaml, yaml)
|
||||
import Harness.Schema.CustomReturnType
|
||||
import Harness.Schema.Name
|
||||
import Harness.Schema.Table
|
||||
import Harness.Test.BackendType (BackendTypeConfig)
|
||||
@ -423,7 +420,7 @@ addSource sourceName sourceConfig testEnvironment = do
|
||||
|]
|
||||
|
||||
trackNativeQueryCommand :: String -> BackendTypeConfig -> NativeQuery -> Value
|
||||
trackNativeQueryCommand sourceName backendTypeConfig (NativeQuery {nativeQueryName, nativeQueryArguments, nativeQueryQuery, nativeQueryReturnType}) =
|
||||
trackNativeQueryCommand sourceName backendTypeConfig (NativeQuery {nativeQueryArrayRelationships, nativeQueryName, nativeQueryArguments, nativeQueryQuery, nativeQueryReturnType}) =
|
||||
-- arguments are a map from name to type details
|
||||
let argsToJson =
|
||||
Aeson.object
|
||||
@ -431,13 +428,13 @@ trackNativeQueryCommand sourceName backendTypeConfig (NativeQuery {nativeQueryNa
|
||||
( \NativeQueryColumn {..} ->
|
||||
let key = K.fromText nativeQueryColumnName
|
||||
descriptionPair = case nativeQueryColumnDescription of
|
||||
Just desc -> [(K.fromText "description", Aeson.String desc)]
|
||||
Just desc -> ["description" .= desc]
|
||||
Nothing -> []
|
||||
|
||||
value =
|
||||
Aeson.object $
|
||||
[ (K.fromText "type", Aeson.String ((BackendType.backendScalarType backendTypeConfig) nativeQueryColumnType)),
|
||||
(K.fromText "nullable", Aeson.Bool nativeQueryColumnNullable)
|
||||
[ ("type" .= (BackendType.backendScalarType backendTypeConfig) nativeQueryColumnType),
|
||||
("nullable" .= nativeQueryColumnNullable)
|
||||
]
|
||||
<> descriptionPair
|
||||
in (key, value)
|
||||
@ -456,6 +453,7 @@ trackNativeQueryCommand sourceName backendTypeConfig (NativeQuery {nativeQueryNa
|
||||
root_field_name: *nativeQueryName
|
||||
code: *nativeQueryQuery
|
||||
arguments: *arguments
|
||||
array_relationships: *nativeQueryArrayRelationships
|
||||
returns: *nativeQueryReturnType
|
||||
|]
|
||||
|
||||
@ -487,69 +485,3 @@ untrackNativeQuery source logMod testEnvironment = do
|
||||
GraphqlEngine.postMetadata_
|
||||
testEnvironment
|
||||
command
|
||||
|
||||
trackCustomTypeCommand :: String -> BackendTypeConfig -> CustomType -> Value
|
||||
trackCustomTypeCommand sourceName backendTypeConfig (CustomType {customTypeDescription, customTypeName, customTypeColumns}) =
|
||||
-- return type is an array of items
|
||||
let returnTypeToJson =
|
||||
Aeson.Array
|
||||
. V.fromList
|
||||
. fmap
|
||||
( \NativeQueryColumn {..} ->
|
||||
let descriptionPair = case nativeQueryColumnDescription of
|
||||
Just desc -> [(K.fromText "description", Aeson.String desc)]
|
||||
Nothing -> []
|
||||
in Aeson.object $
|
||||
[ (K.fromText "name", Aeson.String nativeQueryColumnName),
|
||||
(K.fromText "type", Aeson.String ((BackendType.backendScalarType backendTypeConfig) nativeQueryColumnType)),
|
||||
(K.fromText "nullable", Aeson.Bool nativeQueryColumnNullable)
|
||||
]
|
||||
<> descriptionPair
|
||||
)
|
||||
|
||||
columns = returnTypeToJson customTypeColumns
|
||||
|
||||
-- need to make this only appear if it's Just, for now fall back to empty
|
||||
-- string for lols
|
||||
description = fromMaybe "" customTypeDescription
|
||||
|
||||
backendType = BackendType.backendTypeString backendTypeConfig
|
||||
|
||||
requestType = backendType <> "_track_custom_return_type"
|
||||
in [yaml|
|
||||
type: *requestType
|
||||
args:
|
||||
source: *sourceName
|
||||
description: *description
|
||||
name: *customTypeName
|
||||
fields: *columns
|
||||
|]
|
||||
|
||||
trackCustomType :: HasCallStack => String -> CustomType -> TestEnvironment -> IO ()
|
||||
trackCustomType sourceName ctmType testEnvironment = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
|
||||
let command = trackCustomTypeCommand sourceName backendTypeMetadata ctmType
|
||||
|
||||
GraphqlEngine.postMetadata_ testEnvironment command
|
||||
|
||||
untrackCustomTypeCommand :: String -> BackendTypeConfig -> CustomType -> Value
|
||||
untrackCustomTypeCommand source backendTypeMetadata CustomType {customTypeName} =
|
||||
let backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
requestType = backendType <> "_untrack_custom_return_type"
|
||||
in [yaml|
|
||||
type: *requestType
|
||||
args:
|
||||
source: *source
|
||||
name: *customTypeName
|
||||
|]
|
||||
|
||||
untrackCustomType :: HasCallStack => String -> CustomType -> TestEnvironment -> IO ()
|
||||
untrackCustomType source ctmType testEnvironment = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
|
||||
let command = untrackCustomTypeCommand source backendTypeMetadata ctmType
|
||||
|
||||
GraphqlEngine.postMetadata_
|
||||
testEnvironment
|
||||
command
|
||||
|
144
server/lib/test-harness/src/Harness/Schema/CustomReturnType.hs
Normal file
144
server/lib/test-harness/src/Harness/Schema/CustomReturnType.hs
Normal file
@ -0,0 +1,144 @@
|
||||
{-# LANGUAGE QuasiQuotes #-}
|
||||
{-# OPTIONS_GHC -Wno-partial-fields #-}
|
||||
|
||||
-- | Common interface for custom return types across backends
|
||||
module Harness.Schema.CustomReturnType
|
||||
( CustomReturnType (..),
|
||||
CustomReturnTypeColumn (..),
|
||||
customType,
|
||||
customReturnTypeScalar,
|
||||
customReturnTypeReference,
|
||||
trackCustomReturnType,
|
||||
trackCustomReturnTypeCommand,
|
||||
untrackCustomReturnType,
|
||||
untrackCustomReturnTypeCommand,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson (Value, (.=))
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.Vector qualified as V
|
||||
import Harness.Exceptions
|
||||
import Harness.GraphqlEngine qualified as GraphqlEngine
|
||||
import Harness.Quoter.Yaml (yaml)
|
||||
import Harness.Test.BackendType (BackendTypeConfig)
|
||||
import Harness.Test.BackendType qualified as BackendType
|
||||
import Harness.Test.ScalarType
|
||||
import Harness.TestEnvironment (TestEnvironment, getBackendTypeConfig)
|
||||
import Hasura.Prelude
|
||||
|
||||
data CustomReturnTypeColumn
|
||||
= CustomReturnTypeScalar
|
||||
{ customReturnTypeColumnName :: Text,
|
||||
customReturnTypeColumnType :: ScalarType,
|
||||
customReturnTypeColumnNullable :: Bool,
|
||||
customReturnTypeColumnDescription :: Maybe Text
|
||||
}
|
||||
| CustomReturnTypeReference
|
||||
{ customReturnTypeColumnName :: Text,
|
||||
customReturnTypeColumnReference :: Text
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
customReturnTypeScalar :: Text -> ScalarType -> CustomReturnTypeColumn
|
||||
customReturnTypeScalar name colType =
|
||||
CustomReturnTypeScalar
|
||||
{ customReturnTypeColumnName = name,
|
||||
customReturnTypeColumnType = colType,
|
||||
customReturnTypeColumnNullable = False,
|
||||
customReturnTypeColumnDescription = Nothing
|
||||
}
|
||||
|
||||
customReturnTypeReference :: Text -> Text -> CustomReturnTypeColumn
|
||||
customReturnTypeReference name ref =
|
||||
CustomReturnTypeReference
|
||||
{ customReturnTypeColumnName = name,
|
||||
customReturnTypeColumnReference = ref
|
||||
}
|
||||
|
||||
data CustomReturnType = CustomReturnType
|
||||
{ customTypeName :: Text,
|
||||
customTypeColumns :: [CustomReturnTypeColumn],
|
||||
customTypeDescription :: Maybe Text
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
customType :: Text -> CustomReturnType
|
||||
customType customTypeName =
|
||||
CustomReturnType
|
||||
{ customTypeName,
|
||||
customTypeColumns = mempty,
|
||||
customTypeDescription = Nothing
|
||||
}
|
||||
|
||||
trackCustomReturnTypeCommand :: String -> BackendTypeConfig -> CustomReturnType -> Value
|
||||
trackCustomReturnTypeCommand sourceName backendTypeConfig (CustomReturnType {customTypeDescription, customTypeName, customTypeColumns}) =
|
||||
-- return type is an array of items
|
||||
let returnTypeToJson =
|
||||
Aeson.Array
|
||||
. V.fromList
|
||||
. fmap
|
||||
( \case
|
||||
CustomReturnTypeReference {..} ->
|
||||
Aeson.object $
|
||||
[ ("custom_return_type" .= customReturnTypeColumnReference),
|
||||
("name" .= customReturnTypeColumnName)
|
||||
]
|
||||
CustomReturnTypeScalar {..} ->
|
||||
let descriptionPair = case customReturnTypeColumnDescription of
|
||||
Just desc -> [("description" .= desc)]
|
||||
Nothing -> []
|
||||
in Aeson.object $
|
||||
[ ("name" .= customReturnTypeColumnName),
|
||||
("type" .= (BackendType.backendScalarType backendTypeConfig) customReturnTypeColumnType),
|
||||
("nullable" .= customReturnTypeColumnNullable)
|
||||
]
|
||||
<> descriptionPair
|
||||
)
|
||||
|
||||
columns = returnTypeToJson customTypeColumns
|
||||
|
||||
-- need to make this only appear if it's Just, for now fall back to empty
|
||||
-- string for lols
|
||||
description = fromMaybe "" customTypeDescription
|
||||
|
||||
backendType = BackendType.backendTypeString backendTypeConfig
|
||||
|
||||
requestType = backendType <> "_track_custom_return_type"
|
||||
in [yaml|
|
||||
type: *requestType
|
||||
args:
|
||||
source: *sourceName
|
||||
description: *description
|
||||
name: *customTypeName
|
||||
fields: *columns
|
||||
|]
|
||||
|
||||
trackCustomReturnType :: HasCallStack => String -> CustomReturnType -> TestEnvironment -> IO ()
|
||||
trackCustomReturnType sourceName ctmType testEnvironment = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
|
||||
let command = trackCustomReturnTypeCommand sourceName backendTypeMetadata ctmType
|
||||
|
||||
GraphqlEngine.postMetadata_ testEnvironment command
|
||||
|
||||
untrackCustomReturnTypeCommand :: String -> BackendTypeConfig -> CustomReturnType -> Value
|
||||
untrackCustomReturnTypeCommand source backendTypeMetadata CustomReturnType {customTypeName} =
|
||||
let backendType = BackendType.backendTypeString backendTypeMetadata
|
||||
requestType = backendType <> "_untrack_custom_return_type"
|
||||
in [yaml|
|
||||
type: *requestType
|
||||
args:
|
||||
source: *source
|
||||
name: *customTypeName
|
||||
|]
|
||||
|
||||
untrackCustomReturnType :: HasCallStack => String -> CustomReturnType -> TestEnvironment -> IO ()
|
||||
untrackCustomReturnType source ctmType testEnvironment = do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
|
||||
let command = untrackCustomReturnTypeCommand source backendTypeMetadata ctmType
|
||||
|
||||
GraphqlEngine.postMetadata_
|
||||
testEnvironment
|
||||
command
|
@ -1,3 +1,5 @@
|
||||
{-# OPTIONS_GHC -Wno-partial-fields #-}
|
||||
|
||||
-- | Common interface for setup/teardown for all backends - schema and data
|
||||
module Harness.Schema.Table
|
||||
( Table (..),
|
||||
@ -21,8 +23,6 @@ module Harness.Schema.Table
|
||||
nativeQuery,
|
||||
NativeQueryColumn (..),
|
||||
nativeQueryColumn,
|
||||
CustomType (..),
|
||||
customType,
|
||||
quotedValue,
|
||||
unquotedValue,
|
||||
backendScalarValue,
|
||||
@ -36,6 +36,7 @@ module Harness.Schema.Table
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.Time (defaultTimeLocale)
|
||||
import Data.Time.Format (parseTimeOrError)
|
||||
import Harness.Test.ScalarType
|
||||
@ -115,7 +116,8 @@ data NativeQuery = NativeQuery
|
||||
{ nativeQueryName :: Text,
|
||||
nativeQueryReturnType :: Text,
|
||||
nativeQueryQuery :: Text,
|
||||
nativeQueryArguments :: [NativeQueryColumn]
|
||||
nativeQueryArguments :: [NativeQueryColumn],
|
||||
nativeQueryArrayRelationships :: [Aeson.Value]
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
@ -125,7 +127,8 @@ nativeQuery nativeQueryName query returnType =
|
||||
{ nativeQueryName,
|
||||
nativeQueryReturnType = returnType,
|
||||
nativeQueryQuery = query,
|
||||
nativeQueryArguments = mempty
|
||||
nativeQueryArguments = mempty,
|
||||
nativeQueryArrayRelationships = mempty
|
||||
}
|
||||
|
||||
-- | Foreign keys for backends that support it.
|
||||
@ -178,18 +181,3 @@ columnNull name typ = (column name typ) {columnNullable = True}
|
||||
-- | Helper to construct UTCTime using @%F %T@ format. For e.g. @YYYY-MM-DD HH:MM:SS@
|
||||
parseUTCTimeOrError :: String -> ScalarValue
|
||||
parseUTCTimeOrError = VUTCTime . parseTimeOrError True defaultTimeLocale "%F %T"
|
||||
|
||||
data CustomType = CustomType
|
||||
{ customTypeName :: Text,
|
||||
customTypeColumns :: [NativeQueryColumn],
|
||||
customTypeDescription :: Maybe Text
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
customType :: Text -> CustomType
|
||||
customType customTypeName =
|
||||
CustomType
|
||||
{ customTypeName,
|
||||
customTypeColumns = mempty,
|
||||
customTypeDescription = Nothing
|
||||
}
|
||||
|
@ -146,6 +146,7 @@ library
|
||||
Harness.Quoter.Yaml.InterpolateYaml
|
||||
Harness.RemoteServer
|
||||
Harness.Schema
|
||||
Harness.Schema.CustomReturnType
|
||||
Harness.Schema.Name
|
||||
Harness.Schema.Table
|
||||
Harness.Services.Composed
|
||||
|
@ -622,7 +622,8 @@ data ScalarType
|
||||
| JsonScalarType
|
||||
| StructScalarType
|
||||
deriving stock (Show, Eq, Ord, Bounded, Enum, Generic, Data, Lift)
|
||||
deriving anyclass (FromJSON, Hashable, NFData, ToJSON, ToJSONKey)
|
||||
deriving anyclass (Hashable, NFData, ToJSONKey)
|
||||
deriving (FromJSON, ToJSON) via AC.Autodocodec ScalarType
|
||||
|
||||
instance HasCodec ScalarType where
|
||||
codec = AC.named "ScalarType" $
|
||||
|
@ -34,6 +34,7 @@ import Hasura.Backends.MSSQL.FromIr.Constants
|
||||
import Hasura.Backends.MSSQL.FromIr.Expression
|
||||
import Hasura.Backends.MSSQL.Instances.Types ()
|
||||
import Hasura.Backends.MSSQL.Types.Internal as TSQL
|
||||
import Hasura.CustomReturnType.Common (columnsFromFields)
|
||||
import Hasura.CustomReturnType.IR (CustomReturnType (..))
|
||||
import Hasura.NativeQuery.IR qualified as IR
|
||||
import Hasura.NativeQuery.Types (NativeQueryName (..), NullableScalarType (..))
|
||||
@ -347,7 +348,7 @@ fromNativeQuery nativeQuery = do
|
||||
type' = (nstType ty)
|
||||
}
|
||||
)
|
||||
<$> InsOrd.toList (crtFields nativeQueryReturnType)
|
||||
<$> InsOrd.toList (columnsFromFields $ crtFields nativeQueryReturnType)
|
||||
|
||||
-- \| add create temp table to "the environment"
|
||||
tellBefore (CreateTemp (TempTableName rawTempTableName) columns)
|
||||
|
@ -26,6 +26,7 @@ import Hasura.Backends.Postgres.Connection.Connect (withPostgresDB)
|
||||
import Hasura.Backends.Postgres.Instances.Types ()
|
||||
import Hasura.Backends.Postgres.SQL.Types (PGScalarType (..), pgScalarTypeToText)
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Common (columnsFromFields)
|
||||
import Hasura.CustomReturnType.Metadata (CustomReturnTypeMetadata (..))
|
||||
import Hasura.NativeQuery.Metadata
|
||||
( InterpolatedItem (..),
|
||||
@ -50,7 +51,8 @@ validateNativeQuery ::
|
||||
validateNativeQuery pgTypeOidMapping env connConf customReturnType model = do
|
||||
(prepname, preparedQuery) <- nativeQueryToPreparedStatement customReturnType model
|
||||
description <- runCheck prepname (PG.fromText preparedQuery)
|
||||
let returnColumns = bimap toTxt nstType <$> InsOrd.toList (_crtmFields customReturnType)
|
||||
let returnColumns = bimap toTxt nstType <$> InsOrd.toList (columnsFromFields $ _crtmFields customReturnType)
|
||||
|
||||
for_ (toList returnColumns) (matchTypes description)
|
||||
where
|
||||
-- Run stuff against the database.
|
||||
@ -223,7 +225,7 @@ nativeQueryToPreparedStatement customReturnType model = do
|
||||
|
||||
returnedColumnNames :: Text
|
||||
returnedColumnNames =
|
||||
commaSeparated $ InsOrd.keys (_crtmFields customReturnType)
|
||||
commaSeparated $ InsOrd.keys (columnsFromFields $ _crtmFields customReturnType)
|
||||
|
||||
wrapInCTE :: Text -> Text
|
||||
wrapInCTE query =
|
||||
|
@ -27,11 +27,10 @@ import Data.HashMap.Strict.InsOrd.Extended qualified as OMap
|
||||
import Data.Text.Extended (toTxt, (<<>))
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Metadata (CustomReturnTypeMetadata (..), crtmSelectPermissions)
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeName)
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeField, CustomReturnTypeName, customReturnTypeFieldMapCodec)
|
||||
import Hasura.EncJSON
|
||||
import Hasura.Metadata.DTO.Utils (codecNamePrefix)
|
||||
import Hasura.NativeQuery.Metadata (NativeQueryMetadata (..))
|
||||
import Hasura.NativeQuery.Types (NullableScalarType, nullableScalarTypeMapCodec)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.Common (SourceName, defaultSource, sourceNameToText, successMsg)
|
||||
@ -51,7 +50,7 @@ data TrackCustomReturnType (b :: BackendType) = TrackCustomReturnType
|
||||
{ tctSource :: SourceName,
|
||||
tctName :: CustomReturnTypeName,
|
||||
tctDescription :: Maybe Text,
|
||||
tctFields :: InsOrd.InsOrdHashMap (Column b) (NullableScalarType b)
|
||||
tctFields :: InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b)
|
||||
}
|
||||
|
||||
instance (Backend b) => HasCodec (TrackCustomReturnType b) where
|
||||
@ -66,7 +65,7 @@ instance (Backend b) => HasCodec (TrackCustomReturnType b) where
|
||||
AC..= tctName
|
||||
<*> AC.optionalField "description" descriptionDoc
|
||||
AC..= tctDescription
|
||||
<*> AC.requiredFieldWith "fields" nullableScalarTypeMapCodec fieldsDoc
|
||||
<*> AC.requiredFieldWith "fields" customReturnTypeFieldMapCodec fieldsDoc
|
||||
AC..= tctFields
|
||||
where
|
||||
sourceDoc = "The source in which this custom return type should be tracked"
|
||||
|
@ -14,8 +14,7 @@ where
|
||||
import Control.Lens (makeLenses)
|
||||
import Data.Aeson (ToJSON (..), genericToJSON)
|
||||
import Data.HashMap.Strict.InsOrd qualified as InsOrd
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeName)
|
||||
import Hasura.NativeQuery.Types (NullableScalarType (..))
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeField, CustomReturnTypeName)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.Table (RolePermInfoMap)
|
||||
@ -23,10 +22,10 @@ import Hasura.SQL.Backend (BackendType)
|
||||
|
||||
type CustomReturnTypeCache b = HashMap CustomReturnTypeName (CustomReturnTypeInfo b)
|
||||
|
||||
-- | Description of a custom return type for use in metadata (before schema cache)
|
||||
-- | Description of a custom return type for use in metadata (after schema cache)
|
||||
data CustomReturnTypeInfo (b :: BackendType) = CustomReturnTypeInfo
|
||||
{ _crtiName :: CustomReturnTypeName,
|
||||
_crtiFields :: InsOrd.InsOrdHashMap (Column b) (NullableScalarType b),
|
||||
_crtiFields :: InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b),
|
||||
_crtiDescription :: Maybe Text,
|
||||
_crtiPermissions :: RolePermInfoMap b
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
module Hasura.CustomReturnType.Common
|
||||
( toFieldInfo,
|
||||
columnsFromFields,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.HashMap.Strict.InsOrd qualified as InsOrd
|
||||
import Data.Text.Extended (ToTxt (toTxt))
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeField (..))
|
||||
import Hasura.NativeQuery.Types (NullableScalarType (..))
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
@ -12,6 +14,21 @@ import Hasura.RQL.Types.Column (ColumnInfo (..), ColumnMutability (..), ColumnTy
|
||||
import Hasura.RQL.Types.Table (FieldInfo (..))
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
|
||||
columnsFromFields ::
|
||||
InsOrd.InsOrdHashMap k (CustomReturnTypeField b) ->
|
||||
InsOrd.InsOrdHashMap k (NullableScalarType b)
|
||||
columnsFromFields =
|
||||
InsOrd.mapMaybe
|
||||
( \case
|
||||
CustomReturnTypeScalarField
|
||||
{ crtfType = nstType,
|
||||
crtfNullable = nstNullable,
|
||||
crtfDescription = nstDescription
|
||||
} ->
|
||||
Just (NullableScalarType {..})
|
||||
_ -> Nothing
|
||||
)
|
||||
|
||||
toFieldInfo :: forall b. (Backend b) => InsOrd.InsOrdHashMap (Column b) (NullableScalarType b) -> Maybe [FieldInfo b]
|
||||
toFieldInfo fields =
|
||||
traverseWithIndex
|
||||
|
@ -6,8 +6,7 @@ module Hasura.CustomReturnType.IR
|
||||
where
|
||||
|
||||
import Data.HashMap.Strict.InsOrd qualified as InsOrd
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeName)
|
||||
import Hasura.NativeQuery.Types (NullableScalarType (..))
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeField, CustomReturnTypeName)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.SQL.Backend (BackendType)
|
||||
@ -15,7 +14,7 @@ import Hasura.SQL.Backend (BackendType)
|
||||
-- | Description of a custom return type for use in IR
|
||||
data CustomReturnType (b :: BackendType) = CustomReturnType
|
||||
{ crtName :: CustomReturnTypeName,
|
||||
crtFields :: InsOrd.InsOrdHashMap (Column b) (NullableScalarType b)
|
||||
crtFields :: InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b)
|
||||
}
|
||||
deriving (Generic)
|
||||
|
||||
|
@ -21,7 +21,6 @@ import Data.HashMap.Strict.InsOrd qualified as InsOrd
|
||||
import Data.HashMap.Strict.InsOrd.Autodocodec (sortedElemsCodec)
|
||||
import Hasura.CustomReturnType.Types
|
||||
import Hasura.Metadata.DTO.Utils (codecNamePrefix)
|
||||
import Hasura.NativeQuery.Types (NullableScalarType (..), nullableScalarTypeMapCodec)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.Common (SourceName, ToAesonPairs (toAesonPairs), defaultSource)
|
||||
@ -32,7 +31,7 @@ import Hasura.Session (RoleName)
|
||||
-- | Description of a custom return type for use in metadata (before schema cache)
|
||||
data CustomReturnTypeMetadata (b :: BackendType) = CustomReturnTypeMetadata
|
||||
{ _crtmName :: CustomReturnTypeName,
|
||||
_crtmFields :: InsOrd.InsOrdHashMap (Column b) (NullableScalarType b),
|
||||
_crtmFields :: InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b),
|
||||
_crtmDescription :: Maybe Text,
|
||||
_crtmSelectPermissions :: InsOrdHashMap RoleName (SelPermDef b)
|
||||
}
|
||||
@ -48,7 +47,7 @@ instance (Backend b) => HasCodec (CustomReturnTypeMetadata b) where
|
||||
$ CustomReturnTypeMetadata
|
||||
<$> AC.requiredField "name" nameDoc
|
||||
AC..= _crtmName
|
||||
<*> AC.requiredFieldWith "fields" nullableScalarTypeMapCodec fieldsDoc
|
||||
<*> AC.requiredFieldWith "fields" customReturnTypeFieldMapCodec fieldsDoc
|
||||
AC..= _crtmFields
|
||||
<*> AC.optionalField "description" descriptionDoc
|
||||
AC..= _crtmDescription
|
||||
|
@ -1,13 +1,22 @@
|
||||
-- | A name for a custom return type as it is recognized by the graphql schema.
|
||||
module Hasura.CustomReturnType.Types
|
||||
( CustomReturnTypeName (..),
|
||||
CustomReturnTypeField (..),
|
||||
customReturnTypeFieldMapCodec,
|
||||
)
|
||||
where
|
||||
|
||||
import Autodocodec (HasCodec (codec), dimapCodec)
|
||||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
||||
import Autodocodec
|
||||
( HasCodec (codec),
|
||||
dimapCodec,
|
||||
)
|
||||
import Autodocodec qualified as AC
|
||||
import Data.Aeson (FromJSON (..), FromJSONKey, ToJSON (..), ToJSONKey, Value, object, withObject, (.!=), (.:), (.:?), (.=))
|
||||
import Data.HashMap.Strict.InsOrd qualified as InsOrd
|
||||
import Data.Text.Extended (ToTxt)
|
||||
import Hasura.Metadata.DTO.Placeholder (placeholderCodecViaJSON)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
import Language.Haskell.TH.Syntax (Lift)
|
||||
|
||||
@ -22,3 +31,83 @@ instance HasCodec CustomReturnTypeName where
|
||||
instance FromJSONKey CustomReturnTypeName
|
||||
|
||||
instance ToJSONKey CustomReturnTypeName
|
||||
|
||||
----
|
||||
|
||||
-- | either a scalar type or a reference to another custom return type
|
||||
data CustomReturnTypeField b
|
||||
= CustomReturnTypeScalarField
|
||||
{ crtfName :: Column b,
|
||||
crtfType :: ScalarType b, -- int, string, blah
|
||||
crtfNullable :: Bool,
|
||||
crtfDescription :: Maybe Text
|
||||
}
|
||||
| CustomReturnTypeArrayReference
|
||||
{ crtfName :: Column b,
|
||||
crtfCustomReturnType :: CustomReturnTypeName -- name of another custom return type
|
||||
}
|
||||
deriving (Generic)
|
||||
|
||||
instance (Backend b) => HasCodec (CustomReturnTypeField b) where
|
||||
codec =
|
||||
AC.CommentCodec
|
||||
("A scalar type or reference to another custom return type")
|
||||
$ placeholderCodecViaJSON
|
||||
|
||||
instance (Backend b) => FromJSON (CustomReturnTypeField b) where
|
||||
parseJSON = withObject "CustomReturnTypeField" \o ->
|
||||
parseReference o <|> parseScalar o
|
||||
where
|
||||
parseScalar obj = do
|
||||
crtfName <- obj .: "name"
|
||||
crtfType <- obj .: "type"
|
||||
crtfNullable <- obj .:? "nullable" .!= False
|
||||
crtfDescription <- obj .:? "description"
|
||||
pure (CustomReturnTypeScalarField {..})
|
||||
parseReference obj = do
|
||||
crtfCustomReturnType <- obj .: "custom_return_type"
|
||||
crtfName <- obj .: "name"
|
||||
pure (CustomReturnTypeArrayReference {..})
|
||||
|
||||
instance (Backend b) => ToJSON (CustomReturnTypeField b) where
|
||||
toJSON (CustomReturnTypeScalarField {..}) =
|
||||
object $
|
||||
[ "name" .= crtfName,
|
||||
"type" .= crtfType,
|
||||
"nullable" .= crtfNullable
|
||||
]
|
||||
<> maybeDescription
|
||||
where
|
||||
maybeDescription = case crtfDescription of
|
||||
Just desc -> ["description" .= desc]
|
||||
Nothing -> []
|
||||
toJSON (CustomReturnTypeArrayReference {..}) =
|
||||
object ["name" .= crtfName, "custom_return_type" .= crtfCustomReturnType]
|
||||
|
||||
deriving stock instance (Backend b) => Eq (CustomReturnTypeField b)
|
||||
|
||||
deriving stock instance (Backend b) => Show (CustomReturnTypeField b)
|
||||
|
||||
instance (Backend b) => Hashable (CustomReturnTypeField b)
|
||||
|
||||
instance (Backend b) => NFData (CustomReturnTypeField b)
|
||||
|
||||
-- we parse in as an array of NullableScalarTypeFromArray and then turn into
|
||||
-- InsOrdHashMap because JSON objects cannot be depended on for ordering
|
||||
customReturnTypeFieldMapCodec ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
AC.Codec
|
||||
Value
|
||||
(InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b))
|
||||
(InsOrd.InsOrdHashMap (Column b) (CustomReturnTypeField b))
|
||||
customReturnTypeFieldMapCodec =
|
||||
AC.dimapCodec
|
||||
( InsOrd.fromList
|
||||
. fmap
|
||||
( \crtf -> (crtfName crtf, crtf)
|
||||
)
|
||||
)
|
||||
( fmap snd . InsOrd.toList
|
||||
)
|
||||
(AC.codec @[CustomReturnTypeField b])
|
||||
|
@ -181,7 +181,7 @@ customReturnTypeBoolExp ::
|
||||
CustomReturnTypeInfo b ->
|
||||
SchemaT r m (Parser 'Input n (AnnBoolExp b (UnpreparedValue b)))
|
||||
customReturnTypeBoolExp customReturnType =
|
||||
case toFieldInfo (_crtiFields customReturnType) of
|
||||
case toFieldInfo (columnsFromFields $ _crtiFields customReturnType) of
|
||||
Nothing -> throw500 $ "Error creating fields for custom type " <> tshow (_crtiName customReturnType)
|
||||
Just fieldInfo -> do
|
||||
let name = getCustomReturnTypeName (_crtiName customReturnType)
|
||||
|
@ -13,7 +13,7 @@ import Data.Text.Casing qualified as C
|
||||
import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Cache (CustomReturnTypeInfo (_crtiFields, _crtiName))
|
||||
import Hasura.CustomReturnType.Common (toFieldInfo)
|
||||
import Hasura.CustomReturnType.Common (columnsFromFields, toFieldInfo)
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeName (..))
|
||||
import Hasura.Function.Cache
|
||||
import Hasura.GraphQL.Parser.Class
|
||||
@ -74,7 +74,7 @@ customReturnTypeOrderByExp ::
|
||||
SchemaT r m (Parser 'Input n [IR.AnnotatedOrderByItemG b (IR.UnpreparedValue b)])
|
||||
customReturnTypeOrderByExp customReturnType =
|
||||
let name = getCustomReturnTypeName (_crtiName customReturnType)
|
||||
in case toFieldInfo (_crtiFields customReturnType) of
|
||||
in case toFieldInfo (columnsFromFields $ _crtiFields customReturnType) of
|
||||
Nothing -> throw500 $ "Error creating fields for custom type " <> tshow name
|
||||
Just tableFields -> do
|
||||
let description =
|
||||
|
@ -48,6 +48,7 @@ import Hasura.Backends.Postgres.SQL.Types qualified as Postgres
|
||||
import Hasura.Base.Error
|
||||
import Hasura.Base.ErrorMessage (toErrorMessage)
|
||||
import Hasura.CustomReturnType.Cache (CustomReturnTypeInfo (..))
|
||||
import Hasura.CustomReturnType.Common (columnsFromFields)
|
||||
import Hasura.CustomReturnType.Types (CustomReturnTypeName (..))
|
||||
import Hasura.GraphQL.Parser.Class
|
||||
import Hasura.GraphQL.Parser.Internal.Parser qualified as IP
|
||||
@ -526,7 +527,7 @@ defaultCustomReturnTypeSelectionSet customReturnType = runMaybeT $ do
|
||||
let allowedColumns =
|
||||
filter
|
||||
(isSelectable . fst)
|
||||
(InsOrd.toList (_crtiFields customReturnType))
|
||||
(InsOrd.toList (columnsFromFields $ _crtiFields customReturnType))
|
||||
|
||||
parsers <- traverse parseField allowedColumns
|
||||
|
||||
|
@ -16,7 +16,17 @@ module Hasura.Metadata.DTO.Placeholder
|
||||
)
|
||||
where
|
||||
|
||||
import Autodocodec (Autodocodec, HasCodec (codec), JSONCodec, bimapCodec, codecViaAeson, dimapCodec, valueCodec, vectorCodec, (<?>))
|
||||
import Autodocodec
|
||||
( Autodocodec,
|
||||
HasCodec (codec),
|
||||
JSONCodec,
|
||||
bimapCodec,
|
||||
codecViaAeson,
|
||||
dimapCodec,
|
||||
valueCodec,
|
||||
vectorCodec,
|
||||
(<?>),
|
||||
)
|
||||
import Autodocodec.OpenAPI ()
|
||||
import Data.Aeson (FromJSON, ToJSON)
|
||||
import Data.Aeson qualified as JSON
|
||||
|
@ -18,7 +18,7 @@ import Autodocodec qualified as AC
|
||||
import Control.Lens (Traversal', has, preview, (^?))
|
||||
import Data.Aeson
|
||||
import Data.Environment qualified as Env
|
||||
import Data.HashMap.Strict.InsOrd.Extended qualified as OMap
|
||||
import Data.HashMap.Strict.InsOrd.Extended qualified as InsOrd
|
||||
import Data.Text.Extended (toTxt, (<<>))
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.API (getCustomTypes)
|
||||
@ -26,13 +26,19 @@ import Hasura.CustomReturnType.Metadata (CustomReturnTypeName)
|
||||
import Hasura.EncJSON
|
||||
import Hasura.Metadata.DTO.Utils (codecNamePrefix)
|
||||
import Hasura.NativeQuery.Metadata (NativeQueryArgumentName, NativeQueryMetadata (..), parseInterpolatedQuery)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName, NullableScalarType)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName, NullableScalarType, nativeQueryArrayRelationshipsCodec)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend, SourceConnConfiguration)
|
||||
import Hasura.RQL.Types.Common (SourceName, sourceNameToText, successMsg)
|
||||
import Hasura.RQL.Types.Common
|
||||
( RelName,
|
||||
SourceName,
|
||||
sourceNameToText,
|
||||
successMsg,
|
||||
)
|
||||
import Hasura.RQL.Types.Metadata
|
||||
import Hasura.RQL.Types.Metadata.Backend
|
||||
import Hasura.RQL.Types.Metadata.Object
|
||||
import Hasura.RQL.Types.Relationships.Local (RelDef, RelManualConfig)
|
||||
import Hasura.RQL.Types.SchemaCache.Build
|
||||
import Hasura.SQL.AnyBackend qualified as AB
|
||||
import Hasura.SQL.Backend
|
||||
@ -46,6 +52,7 @@ data TrackNativeQuery (b :: BackendType) = TrackNativeQuery
|
||||
tnqRootFieldName :: NativeQueryName,
|
||||
tnqCode :: Text,
|
||||
tnqArguments :: HashMap NativeQueryArgumentName (NullableScalarType b),
|
||||
tnqArrayRelationships :: InsOrd.InsOrdHashMap RelName (RelDef (RelManualConfig b)),
|
||||
tnqDescription :: Maybe Text,
|
||||
tnqReturns :: CustomReturnTypeName
|
||||
}
|
||||
@ -64,11 +71,14 @@ instance (Backend b) => HasCodec (TrackNativeQuery b) where
|
||||
AC..= tnqCode
|
||||
<*> AC.optionalFieldWithDefault "arguments" mempty argumentsDoc
|
||||
AC..= tnqArguments
|
||||
<*> AC.optionalFieldWithDefaultWith "array_relationships" nativeQueryArrayRelationshipsCodec mempty arrayRelationshipsDoc
|
||||
AC..= tnqArrayRelationships
|
||||
<*> AC.optionalField "description" descriptionDoc
|
||||
AC..= tnqDescription
|
||||
<*> AC.requiredField "returns" returnsDoc
|
||||
AC..= tnqReturns
|
||||
where
|
||||
arrayRelationshipsDoc = "Any relationships between an output value and multiple values in another data source"
|
||||
sourceDoc = "The source in which this native query should be tracked"
|
||||
rootFieldDoc = "Root field name for the native query"
|
||||
codeDoc = "Native code expression (SQL) to run"
|
||||
@ -107,6 +117,7 @@ nativeQueryTrackToMetadata env sourceConnConfig TrackNativeQuery {..} = do
|
||||
_nqmCode = code,
|
||||
_nqmReturns = tnqReturns,
|
||||
_nqmArguments = tnqArguments,
|
||||
_nqmArrayRelationships = tnqArrayRelationships,
|
||||
_nqmDescription = tnqDescription
|
||||
}
|
||||
|
||||
@ -158,7 +169,7 @@ runGetNativeQuery q = do
|
||||
let nativeQuery :: Maybe (NativeQueries b)
|
||||
nativeQuery = metadata ^? metaSources . ix (gnqSource q) . toSourceMetadata . smNativeQueries @b
|
||||
|
||||
pure (encJFromJValue (OMap.elems <$> nativeQuery))
|
||||
pure (encJFromJValue (InsOrd.elems <$> nativeQuery))
|
||||
|
||||
-- | Handler for the 'track_native_query' endpoint. The type 'TrackNativeQuery b'
|
||||
-- (appearing here in wrapped as 'BackendTrackNativeQuery b' for 'AnyBackend'
|
||||
@ -200,7 +211,7 @@ runTrackNativeQuery env trackNativeQueryRequest = do
|
||||
MOSourceObjId source $
|
||||
AB.mkAnyBackend $
|
||||
SMONativeQuery @b fieldName
|
||||
existingNativeQueries = OMap.keys (_smNativeQueries sourceMetadata)
|
||||
existingNativeQueries = InsOrd.keys (_smNativeQueries sourceMetadata)
|
||||
|
||||
when (fieldName `elem` existingNativeQueries) do
|
||||
throw400 AlreadyTracked $ "Native query '" <> toTxt fieldName <> "' is already tracked."
|
||||
@ -208,7 +219,7 @@ runTrackNativeQuery env trackNativeQueryRequest = do
|
||||
buildSchemaCacheFor metadataObj $
|
||||
MetadataModifier $
|
||||
(metaSources . ix source . toSourceMetadata @b . smNativeQueries)
|
||||
%~ OMap.insert fieldName metadata
|
||||
%~ InsOrd.insert fieldName metadata
|
||||
|
||||
pure successMsg
|
||||
where
|
||||
@ -269,7 +280,7 @@ dropNativeQueryInMetadata :: forall b. BackendMetadata b => SourceName -> Native
|
||||
dropNativeQueryInMetadata source rootFieldName = do
|
||||
MetadataModifier $
|
||||
metaSources . ix source . toSourceMetadata @b . smNativeQueries
|
||||
%~ OMap.delete rootFieldName
|
||||
%~ InsOrd.delete rootFieldName
|
||||
|
||||
-- | check feature flag is enabled before carrying out any actions
|
||||
throwIfFeatureDisabled :: (HasFeatureFlagChecker m, MonadError QErr m) => m ()
|
||||
|
@ -6,6 +6,7 @@ module Hasura.NativeQuery.Cache
|
||||
( NativeQueryInfo (..),
|
||||
NativeQueryCache,
|
||||
nqiRootFieldName,
|
||||
nqiArrayRelationships,
|
||||
nqiCode,
|
||||
nqiReturns,
|
||||
nqiArguments,
|
||||
@ -20,6 +21,8 @@ import Hasura.NativeQuery.Metadata (InterpolatedQuery, NativeQueryArgumentName,
|
||||
import Hasura.NativeQuery.Types (NullableScalarType)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend)
|
||||
import Hasura.RQL.Types.Common (RelName)
|
||||
import Hasura.RQL.Types.Relationships.Local (RelInfo)
|
||||
import Hasura.RQL.Types.Table (RolePermInfoMap)
|
||||
import Hasura.SQL.Backend (BackendType)
|
||||
|
||||
@ -32,6 +35,7 @@ data NativeQueryInfo (b :: BackendType) = NativeQueryInfo
|
||||
_nqiCode :: InterpolatedQuery NativeQueryArgumentName,
|
||||
_nqiReturns :: CustomReturnTypeInfo b,
|
||||
_nqiArguments :: HashMap NativeQueryArgumentName (NullableScalarType b),
|
||||
_nqiArrayRelationships :: InsOrdHashMap RelName (RelInfo b),
|
||||
_nqiDescription :: Maybe Text
|
||||
}
|
||||
deriving stock (Generic)
|
||||
|
@ -11,6 +11,7 @@ module Hasura.NativeQuery.Metadata
|
||||
nqmCode,
|
||||
nqmDescription,
|
||||
nqmReturns,
|
||||
nqmArrayRelationships,
|
||||
nqmRootFieldName,
|
||||
NativeQueryArgumentName (..),
|
||||
InterpolatedItem (..),
|
||||
@ -25,15 +26,23 @@ import Autodocodec qualified as AC
|
||||
import Control.Lens (makeLenses)
|
||||
import Data.Aeson (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
|
||||
import Data.Bifunctor (first)
|
||||
import Data.HashMap.Strict.InsOrd.Autodocodec (sortedElemsCodec)
|
||||
import Data.Text qualified as T
|
||||
import Hasura.CustomReturnType.Metadata (CustomReturnTypeName)
|
||||
import Data.Text.Extended qualified as T
|
||||
import Hasura.CustomReturnType.Types
|
||||
import Hasura.Metadata.DTO.Utils (codecNamePrefix)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName (..), NullableScalarType)
|
||||
import Hasura.NativeQuery.Types (NativeQueryName (..), NullableScalarType (..), nullableScalarTypeMapCodec)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend
|
||||
import Hasura.RQL.Types.Common (RelName)
|
||||
import Hasura.RQL.Types.Relationships.Local (RelDef (..), RelManualConfig (..))
|
||||
import Hasura.SQL.Backend
|
||||
import Language.Haskell.TH.Syntax (Lift)
|
||||
|
||||
-- | copy pasta'd from Hasura.RQL.Types.Metadata.Common, forgive me Padre i did
|
||||
-- not have the heart for the Real Fix.
|
||||
type Relationships = InsOrdHashMap RelName
|
||||
|
||||
newtype RawQuery = RawQuery {getRawQuery :: Text}
|
||||
deriving newtype (Eq, Ord, Show, FromJSON, ToJSON)
|
||||
|
||||
@ -123,6 +132,7 @@ data NativeQueryMetadata (b :: BackendType) = NativeQueryMetadata
|
||||
_nqmCode :: InterpolatedQuery NativeQueryArgumentName,
|
||||
_nqmReturns :: CustomReturnTypeName,
|
||||
_nqmArguments :: HashMap NativeQueryArgumentName (NullableScalarType b),
|
||||
_nqmArrayRelationships :: Relationships (RelDef (RelManualConfig b)),
|
||||
_nqmDescription :: Maybe Text
|
||||
}
|
||||
deriving (Generic)
|
||||
@ -145,6 +155,8 @@ instance (Backend b) => HasCodec (NativeQueryMetadata b) where
|
||||
AC..= _nqmReturns
|
||||
<*> optionalFieldWithDefault "arguments" mempty argumentDoc
|
||||
AC..= _nqmArguments
|
||||
<*> optSortedList "array_relationships" _rdName
|
||||
AC..= _nqmArrayRelationships
|
||||
<*> optionalField "description" descriptionDoc
|
||||
AC..= _nqmDescription
|
||||
where
|
||||
@ -154,6 +166,14 @@ instance (Backend b) => HasCodec (NativeQueryMetadata b) where
|
||||
returnsDoc = "Return type (table) of the expression"
|
||||
descriptionDoc = "A description of the native query which appears in the graphql schema"
|
||||
|
||||
optSortedList ::
|
||||
(HasCodec a, Eq a, Hashable k, Ord k, T.ToTxt k) =>
|
||||
Text ->
|
||||
(a -> k) ->
|
||||
ObjectCodec (InsOrdHashMap k a) (InsOrdHashMap k a)
|
||||
optSortedList name keyForElem =
|
||||
AC.optionalFieldWithOmittedDefaultWith' name (sortedElemsCodec keyForElem) mempty
|
||||
|
||||
deriving via
|
||||
(Autodocodec (NativeQueryMetadata b))
|
||||
instance
|
||||
|
@ -3,6 +3,7 @@ module Hasura.NativeQuery.Types
|
||||
( NativeQueryName (..),
|
||||
NullableScalarType (..),
|
||||
nullableScalarTypeMapCodec,
|
||||
nativeQueryArrayRelationshipsCodec,
|
||||
)
|
||||
where
|
||||
|
||||
@ -14,6 +15,8 @@ import Data.Text.Extended (ToTxt)
|
||||
import Hasura.Metadata.DTO.Utils (codecNamePrefix)
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Hasura.RQL.Types.Backend (Backend (..))
|
||||
import Hasura.RQL.Types.Common (RelName)
|
||||
import Hasura.RQL.Types.Relationships.Local (RelDef, RelManualConfig)
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
import Language.Haskell.TH.Syntax (Lift)
|
||||
|
||||
@ -109,3 +112,25 @@ nullableScalarTypeMapCodec =
|
||||
AC.object "NullableScalarType" $
|
||||
AC.objectCodec @(MergedObject (NameField (Column b)) (NullableScalarType b))
|
||||
)
|
||||
|
||||
nativeQueryArrayRelationshipsCodec ::
|
||||
forall b.
|
||||
(Backend b) =>
|
||||
AC.Codec
|
||||
Value
|
||||
(InsOrd.InsOrdHashMap RelName (RelDef (RelManualConfig b)))
|
||||
(InsOrd.InsOrdHashMap RelName (RelDef (RelManualConfig b)))
|
||||
nativeQueryArrayRelationshipsCodec =
|
||||
AC.dimapCodec
|
||||
( InsOrd.fromList
|
||||
. fmap
|
||||
( \(MergedObject (NameField name) nst) ->
|
||||
(name, nst)
|
||||
)
|
||||
)
|
||||
( fmap (\(fld, nst) -> MergedObject (NameField fld) nst) . InsOrd.toList
|
||||
)
|
||||
( AC.listCodec $
|
||||
AC.object "RelDefRelManualConfig" $
|
||||
AC.objectCodec @(MergedObject (NameField RelName) (RelDef (RelManualConfig b)))
|
||||
)
|
||||
|
@ -703,8 +703,13 @@ purgeMetadataObj = \case
|
||||
SMOTable qt -> dropTableInMetadata @b source qt
|
||||
SMOFunction qf -> dropFunctionInMetadata @b source qf
|
||||
SMOFunctionPermission qf rn -> dropFunctionPermissionInMetadata @b source qf rn
|
||||
SMOCustomReturnType crt -> dropCustomReturnTypeInMetadata @b source crt
|
||||
SMONativeQuery lm -> dropNativeQueryInMetadata @b source lm
|
||||
SMONativeQueryObj nativeQueryName nativeQueryMetadataObjId ->
|
||||
MetadataModifier $
|
||||
nativeQueryMetadataSetter @b source nativeQueryName
|
||||
%~ case nativeQueryMetadataObjId of
|
||||
NQMORel rn _ -> dropNativeQueryRelationshipInMetadata rn
|
||||
SMOCustomReturnType crt -> dropCustomReturnTypeInMetadata @b source crt
|
||||
SMOCustomReturnTypeObj customReturnTypeName customReturnTypeMetadataObjId ->
|
||||
MetadataModifier $
|
||||
customReturnTypeMetadataSetter @b source customReturnTypeName
|
||||
|
@ -38,7 +38,7 @@ import Data.Set qualified as S
|
||||
import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Cache (CustomReturnTypeCache, CustomReturnTypeInfo (..))
|
||||
import Hasura.CustomReturnType.Common (toFieldInfo)
|
||||
import Hasura.CustomReturnType.Common (columnsFromFields, toFieldInfo)
|
||||
import Hasura.CustomReturnType.Metadata (CustomReturnTypeMetadata (..))
|
||||
import Hasura.EncJSON
|
||||
import Hasura.Function.API
|
||||
@ -756,7 +756,7 @@ buildSchemaCacheRule logger env = proc (MetadataWithResourceVersion metadataNoDe
|
||||
unless (_cdcAreNativeQueriesEnabled dynamicConfig) $
|
||||
throw400 InvalidConfiguration "The Custom Return Type feature is disabled"
|
||||
|
||||
fieldInfoMap <- case toFieldInfo _crtmFields of
|
||||
fieldInfoMap <- case toFieldInfo (columnsFromFields _crtmFields) of
|
||||
Nothing -> pure mempty
|
||||
Just fields -> pure (mapFromL fieldInfoName fields)
|
||||
|
||||
@ -822,6 +822,7 @@ buildSchemaCacheRule logger env = proc (MetadataWithResourceVersion metadataNoDe
|
||||
_nqiCode = _nqmCode,
|
||||
_nqiReturns = customReturnType,
|
||||
_nqiArguments = _nqmArguments,
|
||||
_nqiArrayRelationships = mempty,
|
||||
_nqiDescription = _nqmDescription
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import Data.Text.Extended
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Cache (crtiPermissions, _crtiFields)
|
||||
import Hasura.Function.Cache
|
||||
import Hasura.NativeQuery.Cache (nqiArrayRelationships)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.DDL.Permission.Internal (permissionIsDefined)
|
||||
import Hasura.RQL.DDL.Schema.Cache.Common
|
||||
@ -304,6 +305,9 @@ deleteMetadataObject = \case
|
||||
SMOFunctionPermission functionName role ->
|
||||
siFunctions . ix functionName . fiPermissions %~ M.delete role
|
||||
SMONativeQuery name -> siNativeQueries %~ M.delete name
|
||||
SMONativeQueryObj nativeQueryName nativeQueryObjId ->
|
||||
siNativeQueries . ix nativeQueryName %~ case nativeQueryObjId of
|
||||
NQMORel name _ -> nqiArrayRelationships %~ InsOrd.delete name
|
||||
SMOCustomReturnType name -> siCustomReturnTypes %~ M.delete name
|
||||
SMOCustomReturnTypeObj customReturnTypeName customReturnTypeObjectId ->
|
||||
siCustomReturnTypes . ix customReturnTypeName %~ case customReturnTypeObjectId of
|
||||
|
@ -14,6 +14,7 @@ module Hasura.RQL.Types.Metadata
|
||||
dropPermissionInMetadata,
|
||||
dropCustomReturnTypePermissionInMetadata,
|
||||
dropRelationshipInMetadata,
|
||||
dropNativeQueryRelationshipInMetadata,
|
||||
dropRemoteRelationshipInMetadata,
|
||||
dropTableInMetadata,
|
||||
dropRemoteSchemaInMetadata,
|
||||
@ -60,7 +61,7 @@ import Hasura.Function.Cache
|
||||
import Hasura.Function.Metadata (FunctionMetadata (..))
|
||||
import Hasura.Incremental qualified as Inc
|
||||
import Hasura.Metadata.DTO.MetadataV3 (MetadataV3 (..))
|
||||
import Hasura.NativeQuery.Metadata (NativeQueryMetadata, NativeQueryName)
|
||||
import Hasura.NativeQuery.Metadata (NativeQueryMetadata, NativeQueryName, nqmArrayRelationships)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Allowlist
|
||||
import Hasura.RQL.Types.ApiLimit
|
||||
@ -388,6 +389,10 @@ dropRelationshipInMetadata relName =
|
||||
(tmObjectRelationships %~ OM.delete relName)
|
||||
. (tmArrayRelationships %~ OM.delete relName)
|
||||
|
||||
dropNativeQueryRelationshipInMetadata :: RelName -> NativeQueryMetadata b -> NativeQueryMetadata b
|
||||
dropNativeQueryRelationshipInMetadata relName =
|
||||
nqmArrayRelationships %~ OM.delete relName
|
||||
|
||||
dropPermissionInMetadata ::
|
||||
RoleName -> PermType -> TableMetadata b -> TableMetadata b
|
||||
dropPermissionInMetadata rn = \case
|
||||
|
@ -8,6 +8,7 @@ module Hasura.RQL.Types.Metadata.Object
|
||||
SourceMetadataObjId (..),
|
||||
TableMetadataObjId (..),
|
||||
CustomReturnTypeMetadataObjId (..),
|
||||
NativeQueryMetadataObjId (..),
|
||||
droppableInconsistentMetadata,
|
||||
getInconsistentRemoteSchemas,
|
||||
groupInconsistentMetadataById,
|
||||
@ -79,12 +80,20 @@ data CustomReturnTypeMetadataObjId
|
||||
|
||||
instance Hashable CustomReturnTypeMetadataObjId
|
||||
|
||||
-- | the logical model should probably also link to its custom return type
|
||||
data NativeQueryMetadataObjId
|
||||
= NQMORel RelName RelType
|
||||
deriving (Show, Eq, Ord, Generic)
|
||||
|
||||
instance Hashable NativeQueryMetadataObjId
|
||||
|
||||
data SourceMetadataObjId b
|
||||
= SMOTable (TableName b)
|
||||
| SMOFunction (FunctionName b)
|
||||
| SMOFunctionPermission (FunctionName b) RoleName
|
||||
| SMOTableObj (TableName b) TableMetadataObjId
|
||||
| SMONativeQuery NativeQueryName
|
||||
| SMONativeQueryObj NativeQueryName NativeQueryMetadataObjId
|
||||
| SMOCustomReturnType CustomReturnTypeName
|
||||
| SMOCustomReturnTypeObj CustomReturnTypeName CustomReturnTypeMetadataObjId
|
||||
deriving (Generic)
|
||||
@ -148,6 +157,8 @@ moiTypeName = \case
|
||||
SMOTable _ -> "table"
|
||||
SMOFunction _ -> "function"
|
||||
SMONativeQuery _ -> "native_query"
|
||||
SMONativeQueryObj _ nativeQueryObjId -> case nativeQueryObjId of
|
||||
NQMORel _ relType -> relTypeToTxt relType <> "_relation"
|
||||
SMOCustomReturnType _ -> "custom_type"
|
||||
SMOCustomReturnTypeObj _ customReturnTypeObjectId -> case customReturnTypeObjectId of
|
||||
CRTMOPerm _ permType -> permTypeToCode permType <> "_permission"
|
||||
@ -203,6 +214,9 @@ moiName objectId =
|
||||
<> " in source "
|
||||
<> toTxt source
|
||||
SMONativeQuery name -> toTxt name <> " in source " <> toTxt source
|
||||
SMONativeQueryObj nativeQueryName nativeQueryObjId ->
|
||||
case nativeQueryObjId of
|
||||
NQMORel name _ -> toTxt name <> " in " <> toTxt nativeQueryName
|
||||
SMOCustomReturnType name -> toTxt name <> " in source " <> toTxt source
|
||||
SMOCustomReturnTypeObj customReturnTypeName customReturnTypeObjectId -> do
|
||||
let objectName :: Text
|
||||
|
@ -21,7 +21,7 @@ module Hasura.RQL.Types.Relationships.Local
|
||||
)
|
||||
where
|
||||
|
||||
import Autodocodec (HasCodec (codec), dimapCodec, disjointEitherCodec, optionalField', requiredField')
|
||||
import Autodocodec (HasCodec (codec), HasObjectCodec, dimapCodec, disjointEitherCodec, optionalField', requiredField')
|
||||
import Autodocodec qualified as AC
|
||||
import Autodocodec.Extended (optionalFieldOrIncludedNull', typeableName)
|
||||
import Control.Lens (makeLenses)
|
||||
@ -44,12 +44,14 @@ data RelDef a = RelDef
|
||||
deriving (Show, Eq, Generic)
|
||||
|
||||
instance (HasCodec a, Typeable a) => HasCodec (RelDef a) where
|
||||
codec =
|
||||
AC.object ("RelDef_" <> typeableName @a) $
|
||||
RelDef
|
||||
<$> requiredField' "name" AC..= _rdName
|
||||
<*> requiredField' "using" AC..= _rdUsing
|
||||
<*> optionalField' "comment" AC..= _rdComment
|
||||
codec = AC.object ("RelDef_" <> typeableName @a) AC.objectCodec
|
||||
|
||||
instance (HasCodec a) => HasObjectCodec (RelDef a) where
|
||||
objectCodec =
|
||||
RelDef
|
||||
<$> requiredField' "name" AC..= _rdName
|
||||
<*> requiredField' "using" AC..= _rdUsing
|
||||
<*> optionalField' "comment" AC..= _rdComment
|
||||
|
||||
$(deriveFromJSON hasuraJSON {omitNothingFields = True} ''RelDef)
|
||||
$(makeLenses ''RelDef)
|
||||
|
@ -14,7 +14,6 @@ import Hasura.Backends.Postgres.SQL.Types
|
||||
import Hasura.Base.Error
|
||||
import Hasura.CustomReturnType.Metadata
|
||||
import Hasura.NativeQuery.Metadata
|
||||
import Hasura.NativeQuery.Types
|
||||
import Hasura.Prelude hiding (first)
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy)
|
||||
@ -81,6 +80,7 @@ spec = do
|
||||
_nqmCode = InterpolatedQuery mempty,
|
||||
_nqmReturns = CustomReturnTypeName (G.unsafeMkName "custom_return_type_name"),
|
||||
_nqmArguments = mempty,
|
||||
_nqmArrayRelationships = mempty,
|
||||
_nqmDescription = mempty
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user