mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
NaQI - validate against the database - infra and check syntax
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7778 GitOrigin-RevId: c8366ad7261d9c120dc0612bedb96fa5ae59eda3
This commit is contained in:
parent
4c37b6838c
commit
f90373b1ca
@ -602,6 +602,7 @@ library
|
||||
, Hasura.Backends.Postgres.Instances.API
|
||||
, Hasura.Backends.Postgres.Instances.Execute
|
||||
, Hasura.Backends.Postgres.Instances.Metadata
|
||||
, Hasura.Backends.Postgres.Instances.NativeQueries
|
||||
, Hasura.Backends.Postgres.Instances.PingSource
|
||||
, Hasura.Backends.Postgres.Instances.Schema
|
||||
, Hasura.Backends.Postgres.Instances.SchemaCache
|
||||
@ -807,6 +808,7 @@ library
|
||||
, Hasura.RQL.Types.SchemaCache.Instances
|
||||
, Hasura.RQL.Types.SchemaCacheTypes
|
||||
, Hasura.RQL.Types.Source
|
||||
, Hasura.RQL.Types.SourceConfiguration
|
||||
, Hasura.RQL.Types.SourceCustomization
|
||||
, Hasura.RQL.Types.Subscription
|
||||
, Hasura.RQL.Types.Table
|
||||
|
@ -47,6 +47,12 @@ schema =
|
||||
{ tableColumns =
|
||||
[ Schema.column "divided" Schema.TInt
|
||||
]
|
||||
},
|
||||
(table "stuff")
|
||||
{ tableColumns =
|
||||
[ Schema.column "thing" Schema.TInt,
|
||||
Schema.column "date" Schema.TUTCTime
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@ -314,3 +320,86 @@ tests opts = do
|
||||
[yaml|
|
||||
[]
|
||||
|]
|
||||
|
||||
describe "Validation fails on track a native query when query" do
|
||||
it "has a syntax error" $
|
||||
\testEnv -> do
|
||||
let schemaName = Schema.getSchemaName testEnv
|
||||
let spicyQuery :: Text
|
||||
spicyQuery = "query bad"
|
||||
shouldReturnYaml
|
||||
opts
|
||||
( GraphqlEngine.postMetadataWithStatus
|
||||
400
|
||||
testEnv
|
||||
[yaml|
|
||||
type: pg_track_native_query
|
||||
args:
|
||||
type: query
|
||||
source: postgres
|
||||
root_field_name: divided_stuff
|
||||
code: *spicyQuery
|
||||
arguments:
|
||||
denominator: int
|
||||
target_date: date
|
||||
returns:
|
||||
name: already_tracked_return_type
|
||||
schema: *schemaName
|
||||
|]
|
||||
)
|
||||
[yaml|
|
||||
code: validation-failed
|
||||
error: Failed to validate query
|
||||
internal:
|
||||
arguments: []
|
||||
error:
|
||||
description: null
|
||||
exec_status: "FatalError"
|
||||
hint: null
|
||||
message: "syntax error at or near \"query\""
|
||||
status_code: "42601"
|
||||
prepared: false
|
||||
statement: "PREPARE _naqi_vali_divided_stuff AS query bad"
|
||||
path: "$.args"
|
||||
|]
|
||||
|
||||
it "refers to non existing table" $
|
||||
\testEnv -> do
|
||||
let schemaName = Schema.getSchemaName testEnv
|
||||
let spicyQuery :: Text
|
||||
spicyQuery = "SELECT thing / {{denominator}} AS divided FROM does_not_exist WHERE date = {{target_date}}"
|
||||
shouldReturnYaml
|
||||
opts
|
||||
( GraphqlEngine.postMetadataWithStatus
|
||||
400
|
||||
testEnv
|
||||
[yaml|
|
||||
type: pg_track_native_query
|
||||
args:
|
||||
type: query
|
||||
source: postgres
|
||||
root_field_name: divided_stuff
|
||||
code: *spicyQuery
|
||||
arguments:
|
||||
denominator: int
|
||||
target_date: date
|
||||
returns:
|
||||
name: already_tracked_return_type
|
||||
schema: *schemaName
|
||||
|]
|
||||
)
|
||||
[yaml|
|
||||
code: validation-failed
|
||||
error: Failed to validate query
|
||||
internal:
|
||||
arguments: []
|
||||
error:
|
||||
description: null
|
||||
exec_status: "FatalError"
|
||||
hint: null
|
||||
message: "relation \"does_not_exist\" does not exist"
|
||||
status_code: "42P01"
|
||||
prepared: false
|
||||
statement: "PREPARE _naqi_vali_divided_stuff AS SELECT thing / $1 AS divided FROM does_not_exist WHERE date = $2"
|
||||
path: "$.args"
|
||||
|]
|
||||
|
@ -183,6 +183,59 @@ tests opts = do
|
||||
|
||||
actual `shouldBe` expected
|
||||
|
||||
it "Runs a simple query that takes no parameters but ends with a comment" $ \testEnvironment -> do
|
||||
let spicyQuery :: Text
|
||||
spicyQuery = "SELECT * FROM (VALUES ('hello', 'world'), ('welcome', 'friend')) as t(\"one\", \"two\") -- my query"
|
||||
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
schemaName = Schema.getSchemaName testEnvironment
|
||||
|
||||
shouldReturnYaml
|
||||
opts
|
||||
( GraphqlEngine.postMetadata
|
||||
testEnvironment
|
||||
[yaml|
|
||||
type: pg_track_native_query
|
||||
args:
|
||||
type: query
|
||||
source: *source
|
||||
root_field_name: hello_comment_function
|
||||
code: *spicyQuery
|
||||
returns:
|
||||
name: hello_world_table
|
||||
schema: *schemaName
|
||||
|]
|
||||
)
|
||||
[yaml|
|
||||
message: success
|
||||
|]
|
||||
|
||||
let expected =
|
||||
[yaml|
|
||||
data:
|
||||
hello_comment_function:
|
||||
- one: "hello"
|
||||
two: "world"
|
||||
- one: "welcome"
|
||||
two: "friend"
|
||||
|]
|
||||
|
||||
actual :: IO Value
|
||||
actual =
|
||||
GraphqlEngine.postGraphql
|
||||
testEnvironment
|
||||
[graphql|
|
||||
query {
|
||||
hello_comment_function {
|
||||
one
|
||||
two
|
||||
}
|
||||
}
|
||||
|]
|
||||
|
||||
actual `shouldBe` expected
|
||||
|
||||
it "Runs a simple query that takes one parameter and uses it multiple times" $ \testEnvironment -> do
|
||||
let backendTypeMetadata = fromMaybe (error "Unknown backend") $ getBackendTypeConfig testEnvironment
|
||||
source = BackendType.backendSourceName backendTypeMetadata
|
||||
@ -387,7 +440,7 @@ tests opts = do
|
||||
expected =
|
||||
[yaml|
|
||||
data:
|
||||
first:
|
||||
first:
|
||||
- excerpt: "I like to eat dog food I am a dogs..."
|
||||
second:
|
||||
- excerpt: "I like to eat..."
|
||||
|
@ -20,8 +20,6 @@ import Language.GraphQL.Draft.Syntax qualified as G
|
||||
instance Backend 'BigQuery where
|
||||
type BackendConfig 'BigQuery = ()
|
||||
type BackendInfo 'BigQuery = ()
|
||||
type SourceConfig 'BigQuery = BigQuery.BigQuerySourceConfig
|
||||
type SourceConnConfiguration 'BigQuery = BigQuery.BigQueryConnSourceConfig
|
||||
type TableName 'BigQuery = BigQuery.TableName
|
||||
type FunctionName 'BigQuery = BigQuery.FunctionName
|
||||
type RawFunctionInfo 'BigQuery = BigQuery.RestRoutine
|
||||
@ -117,4 +115,8 @@ instance Backend 'BigQuery where
|
||||
|
||||
defaultTriggerOnReplication = Nothing
|
||||
|
||||
instance HasSourceConfiguration 'BigQuery where
|
||||
type SourceConfig 'BigQuery = BigQuery.BigQuerySourceConfig
|
||||
type SourceConnConfiguration 'BigQuery = BigQuery.BigQueryConnSourceConfig
|
||||
|
||||
instance NativeQueryMetadata 'BigQuery
|
||||
|
@ -24,7 +24,7 @@ import Hasura.Base.Error (Code (ValidationFailed), QErr, runAesonParser, throw40
|
||||
import Hasura.NativeQuery.Types (NativeQueryMetadata)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.IR.BoolExp
|
||||
import Hasura.RQL.Types.Backend (Backend (..), ComputedFieldReturnType, SupportedNamingCase (..), XDisable, XEnable)
|
||||
import Hasura.RQL.Types.Backend (Backend (..), ComputedFieldReturnType, HasSourceConfiguration (..), SupportedNamingCase (..), XDisable, XEnable)
|
||||
import Hasura.RQL.Types.Column (ColumnType (..))
|
||||
import Hasura.RQL.Types.ResizePool (ServerReplicas)
|
||||
import Hasura.SQL.Backend (BackendType (DataConnector))
|
||||
@ -43,8 +43,6 @@ type Unimplemented = ()
|
||||
instance Backend 'DataConnector where
|
||||
type BackendConfig 'DataConnector = InsOrdHashMap DC.DataConnectorName DC.DataConnectorOptions
|
||||
type BackendInfo 'DataConnector = HashMap DC.DataConnectorName DC.DataConnectorInfo
|
||||
type SourceConfig 'DataConnector = DC.SourceConfig
|
||||
type SourceConnConfiguration 'DataConnector = DC.ConnSourceConfig
|
||||
|
||||
type TableName 'DataConnector = DC.TableName
|
||||
type FunctionName 'DataConnector = DC.FunctionName
|
||||
@ -159,6 +157,10 @@ instance Backend 'DataConnector where
|
||||
|
||||
defaultTriggerOnReplication = Nothing
|
||||
|
||||
instance HasSourceConfiguration 'DataConnector where
|
||||
type SourceConfig 'DataConnector = DC.SourceConfig
|
||||
type SourceConnConfiguration 'DataConnector = DC.ConnSourceConfig
|
||||
|
||||
instance NativeQueryMetadata 'DataConnector
|
||||
|
||||
data CustomBooleanOperator a = CustomBooleanOperator
|
||||
|
@ -29,8 +29,6 @@ import Language.GraphQL.Draft.Syntax qualified as G
|
||||
instance Backend 'MSSQL where
|
||||
type BackendConfig 'MSSQL = ()
|
||||
type BackendInfo 'MSSQL = ()
|
||||
type SourceConfig 'MSSQL = MSSQL.MSSQLSourceConfig
|
||||
type SourceConnConfiguration 'MSSQL = MSSQL.MSSQLConnConfiguration
|
||||
type TableName 'MSSQL = MSSQL.TableName
|
||||
type RawFunctionInfo 'MSSQL = Void
|
||||
|
||||
@ -125,4 +123,8 @@ instance Backend 'MSSQL where
|
||||
|
||||
defaultTriggerOnReplication = Just ((), TOREnableTrigger)
|
||||
|
||||
instance HasSourceConfiguration 'MSSQL where
|
||||
type SourceConfig 'MSSQL = MSSQL.MSSQLSourceConfig
|
||||
type SourceConnConfiguration 'MSSQL = MSSQL.MSSQLConnConfiguration
|
||||
|
||||
instance NativeQueryMetadata 'MSSQL
|
||||
|
@ -19,8 +19,6 @@ import Language.GraphQL.Draft.Syntax qualified as G
|
||||
instance Backend 'MySQL where
|
||||
type BackendConfig 'MySQL = ()
|
||||
type BackendInfo 'MySQL = ()
|
||||
type SourceConfig 'MySQL = MySQL.SourceConfig
|
||||
type SourceConnConfiguration 'MySQL = MySQL.ConnSourceConfig
|
||||
type TableName 'MySQL = MySQL.TableName
|
||||
type FunctionName 'MySQL = MySQL.FunctionName
|
||||
type RawFunctionInfo 'MySQL = Void -- MySQL.FunctionName
|
||||
@ -149,4 +147,8 @@ instance Backend 'MySQL where
|
||||
|
||||
defaultTriggerOnReplication = Nothing
|
||||
|
||||
instance HasSourceConfiguration 'MySQL where
|
||||
type SourceConfig 'MySQL = MySQL.SourceConfig
|
||||
type SourceConnConfiguration 'MySQL = MySQL.ConnSourceConfig
|
||||
|
||||
instance NativeQueryMetadata 'MySQL
|
||||
|
@ -0,0 +1,46 @@
|
||||
-- | Validate native queries against postgres-like flavors.
|
||||
module Hasura.Backends.Postgres.Instances.NativeQueries
|
||||
( validateNativeQuery,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Aeson (toJSON)
|
||||
import Database.PG.Query qualified as PG
|
||||
import Hasura.Backends.Postgres.Connection qualified as PG
|
||||
import Hasura.Backends.Postgres.Connection.Connect (withPostgresDB)
|
||||
import Hasura.Base.Error
|
||||
import Hasura.NativeQuery.Metadata
|
||||
import Hasura.Prelude
|
||||
import Hasura.SQL.Backend
|
||||
|
||||
-- | Prepare a native query against a postgres-like database to validate it.
|
||||
validateNativeQuery :: (MonadIO m, MonadError NativeQueryError m) => PG.PostgresConnConfiguration -> NativeQueryInfoImpl ('Postgres pgKind) -> m ()
|
||||
validateNativeQuery connConf nativeQuery = do
|
||||
let name = getNativeQueryNameImpl $ nqiiRootFieldName nativeQuery
|
||||
let code :: Text
|
||||
code = fold $ flip evalState (1 :: Int) do
|
||||
for (getInterpolatedQuery $ nqiiCode nativeQuery) \case
|
||||
IIText t -> pure t
|
||||
IIVariable _v -> do
|
||||
i <- get
|
||||
modify (+ 1)
|
||||
pure $ "$" <> tshow i
|
||||
result <-
|
||||
liftIO $
|
||||
withPostgresDB connConf $
|
||||
PG.rawQE
|
||||
( \e ->
|
||||
(err400 ValidationFailed "Failed to validate query")
|
||||
{ qeInternal = Just $ ExtraInternal $ toJSON e
|
||||
}
|
||||
)
|
||||
(PG.fromText $ "PREPARE _naqi_vali_" <> name <> " AS " <> code)
|
||||
[]
|
||||
False
|
||||
case result of
|
||||
-- running the query failed
|
||||
Left err ->
|
||||
throwError $ NativeQueryValidationError err
|
||||
-- running the query succeeded
|
||||
Right () ->
|
||||
pure ()
|
@ -17,6 +17,7 @@ import Data.Typeable
|
||||
import Hasura.Backends.Postgres.Connection qualified as Postgres
|
||||
import Hasura.Backends.Postgres.Connection.VersionCheck (runCockroachVersionCheck)
|
||||
import Hasura.Backends.Postgres.Execute.ConnectionTemplate qualified as Postgres
|
||||
import Hasura.Backends.Postgres.Instances.NativeQueries (validateNativeQuery)
|
||||
import Hasura.Backends.Postgres.Instances.PingSource (runCockroachDBPing)
|
||||
import Hasura.Backends.Postgres.SQL.DML qualified as Postgres
|
||||
import Hasura.Backends.Postgres.SQL.Types qualified as Postgres
|
||||
@ -89,8 +90,6 @@ instance
|
||||
where
|
||||
type BackendConfig ('Postgres pgKind) = ()
|
||||
type BackendInfo ('Postgres pgKind) = ()
|
||||
type SourceConfig ('Postgres pgKind) = Postgres.PGSourceConfig
|
||||
type SourceConnConfiguration ('Postgres pgKind) = Postgres.PostgresConnConfiguration
|
||||
type TableName ('Postgres pgKind) = Postgres.QualifiedTable
|
||||
type FunctionName ('Postgres pgKind) = Postgres.QualifiedFunction
|
||||
type FunctionArgument ('Postgres pgKind) = Postgres.FunctionArg
|
||||
@ -166,6 +165,14 @@ instance
|
||||
|
||||
resolveConnectionTemplate = Postgres.pgResolveConnectionTemplate
|
||||
|
||||
instance
|
||||
( HasTag ('Postgres pgKind)
|
||||
) =>
|
||||
HasSourceConfiguration ('Postgres pgKind)
|
||||
where
|
||||
type SourceConfig ('Postgres pgKind) = Postgres.PGSourceConfig
|
||||
type SourceConnConfiguration ('Postgres pgKind) = Postgres.PostgresConnConfiguration
|
||||
|
||||
instance
|
||||
( HasTag ('Postgres pgKind),
|
||||
Typeable ('Postgres pgKind),
|
||||
@ -181,3 +188,4 @@ instance
|
||||
trackNativeQuerySource = tnqSource
|
||||
nativeQueryInfoName = nqiiRootFieldName
|
||||
nativeQueryTrackToInfo = defaultNativeQueryTrackToInfo
|
||||
validateNativeQueryAgainstSource = validateNativeQuery
|
||||
|
@ -1186,6 +1186,8 @@ instance ToSQL TopLevelCTE where
|
||||
IIVariable v -> toSQL v
|
||||
)
|
||||
parts
|
||||
-- if the user has a comment on the last line, this will make sure it doesn't interrupt the rest of the query
|
||||
<> "\n"
|
||||
|
||||
-- | A @SELECT@ statement with Common Table Expressions.
|
||||
-- <https://www.postgresql.org/docs/current/queries-with.html>
|
||||
|
@ -19,14 +19,14 @@ module Hasura.NativeQuery.API
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Lens ((^?))
|
||||
import Control.Lens (preview, (^?))
|
||||
import Data.Aeson
|
||||
import Hasura.Base.Error
|
||||
import Hasura.EncJSON
|
||||
import Hasura.NativeQuery.Types
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Backend (Backend)
|
||||
import Hasura.RQL.Types.Common (SourceName, successMsg)
|
||||
import Hasura.RQL.Types.Common (SourceName, sourceNameToText, successMsg)
|
||||
import Hasura.RQL.Types.Metadata
|
||||
import Hasura.RQL.Types.Metadata.Backend
|
||||
import Hasura.RQL.Types.Metadata.Object
|
||||
@ -94,10 +94,17 @@ runTrackNativeQuery ::
|
||||
runTrackNativeQuery (BackendTrackNativeQuery trackNativeQueryRequest) = do
|
||||
throwIfFeatureDisabled
|
||||
|
||||
(metadata :: NativeQueryInfo b) <-
|
||||
case nativeQueryTrackToInfo @b trackNativeQueryRequest of
|
||||
sourceConnConfig <-
|
||||
maybe (throw400 NotFound $ "Source " <> sourceNameToText source <> " not found.") pure
|
||||
. preview (metaSources . ix source . toSourceMetadata @b . smConfiguration)
|
||||
=<< getMetadata
|
||||
|
||||
(metadata :: NativeQueryInfo b) <- do
|
||||
r <- liftIO $ runExceptT $ nativeQueryTrackToInfo @b sourceConnConfig trackNativeQueryRequest
|
||||
case r of
|
||||
Right nq -> pure nq
|
||||
Left (NativeQueryParseError e) -> throw400 ParseFailed e
|
||||
Left (NativeQueryValidationError e) -> throwError e
|
||||
|
||||
let fieldName = nativeQueryInfoName @b metadata
|
||||
metadataObj =
|
||||
|
@ -182,16 +182,27 @@ data TrackNativeQueryImpl (b :: BackendType) = TrackNativeQueryImpl
|
||||
}
|
||||
|
||||
-- | Default implementation of the method 'nativeQueryTrackToInfo'.
|
||||
defaultNativeQueryTrackToInfo :: TrackNativeQueryImpl b -> Either NativeQueryParseError (NativeQueryInfoImpl b)
|
||||
defaultNativeQueryTrackToInfo TrackNativeQueryImpl {..} = do
|
||||
nqiiCode <- mapLeft NativeQueryParseError (parseInterpolatedQuery tnqCode)
|
||||
defaultNativeQueryTrackToInfo ::
|
||||
forall b m.
|
||||
( MonadIO m,
|
||||
MonadError NativeQueryError m,
|
||||
NativeQueryMetadata b,
|
||||
NativeQueryInfo b ~ NativeQueryInfoImpl b
|
||||
) =>
|
||||
SourceConnConfiguration b ->
|
||||
TrackNativeQueryImpl b ->
|
||||
m (NativeQueryInfoImpl b)
|
||||
defaultNativeQueryTrackToInfo sourceConnConfig TrackNativeQueryImpl {..} = do
|
||||
nqiiCode <- liftEither $ mapLeft NativeQueryParseError (parseInterpolatedQuery tnqCode)
|
||||
let nqiiRootFieldName = tnqRootFieldName
|
||||
nqiiReturns = tnqReturns
|
||||
nqiiArguments = tnqArguments
|
||||
nqiiDescription = tnqDescription
|
||||
nqInfoImpl = NativeQueryInfoImpl {..}
|
||||
|
||||
pure $ NativeQueryInfoImpl {..}
|
||||
where
|
||||
nqiiRootFieldName = tnqRootFieldName
|
||||
nqiiReturns = tnqReturns
|
||||
nqiiArguments = tnqArguments
|
||||
nqiiDescription = tnqDescription
|
||||
validateNativeQueryAgainstSource @b sourceConnConfig nqInfoImpl
|
||||
|
||||
pure nqInfoImpl
|
||||
|
||||
instance (Backend b, HasCodec (ScalarType b)) => HasCodec (TrackNativeQueryImpl b) where
|
||||
codec =
|
||||
|
@ -6,7 +6,7 @@
|
||||
-- are free to provide their own as needed.
|
||||
module Hasura.NativeQuery.Types
|
||||
( NativeQueryMetadata (..),
|
||||
NativeQueryParseError (..),
|
||||
NativeQueryError (..),
|
||||
BackendTrackNativeQuery (..),
|
||||
)
|
||||
where
|
||||
@ -15,12 +15,12 @@ import Autodocodec
|
||||
import Data.Aeson
|
||||
import Data.Kind
|
||||
import Data.Text.Extended (ToTxt)
|
||||
import Hasura.Base.Error
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.SourceConfiguration
|
||||
import Hasura.SQL.Backend
|
||||
|
||||
type Representable a = (Show a, Eq a, Hashable a, NFData a)
|
||||
|
||||
type APIType a = (ToJSON a, FromJSON a)
|
||||
|
||||
-- | This type class models the types and functions necessary to talk about
|
||||
@ -65,9 +65,14 @@ class
|
||||
nativeQueryInfoName = absurd
|
||||
|
||||
-- | Projection function, producing a 'NativeQueryInfo b' from a 'TrackNativeQuery b'.
|
||||
nativeQueryTrackToInfo :: TrackNativeQuery b -> Either NativeQueryParseError (NativeQueryInfo b)
|
||||
default nativeQueryTrackToInfo :: (TrackNativeQuery b ~ Void) => TrackNativeQuery b -> Either NativeQueryParseError (NativeQueryInfo b)
|
||||
nativeQueryTrackToInfo = absurd
|
||||
nativeQueryTrackToInfo :: SourceConnConfiguration b -> TrackNativeQuery b -> ExceptT NativeQueryError IO (NativeQueryInfo b)
|
||||
default nativeQueryTrackToInfo :: (TrackNativeQuery b ~ Void) => SourceConnConfiguration b -> TrackNativeQuery b -> ExceptT NativeQueryError IO (NativeQueryInfo b)
|
||||
nativeQueryTrackToInfo _ = absurd
|
||||
|
||||
-- | Validate the native query against the database.
|
||||
validateNativeQueryAgainstSource :: (MonadIO m, MonadError NativeQueryError m) => SourceConnConfiguration b -> NativeQueryInfo b -> m ()
|
||||
default validateNativeQueryAgainstSource :: (NativeQueryInfo b ~ Void) => SourceConnConfiguration b -> NativeQueryInfo b -> m ()
|
||||
validateNativeQueryAgainstSource _ = absurd
|
||||
|
||||
-- | Our API endpoint solution wraps all request payload types in 'AnyBackend'
|
||||
-- for its multi-backend support, but type families must be fully applied to
|
||||
@ -81,4 +86,6 @@ deriving newtype instance NativeQueryMetadata b => FromJSON (BackendTrackNativeQ
|
||||
|
||||
-- Things that might go wrong when converting a Native Query metadata request
|
||||
-- into a valid metadata item (such as failure to interpolate the query)
|
||||
newtype NativeQueryParseError = NativeQueryParseError Text
|
||||
data NativeQueryError
|
||||
= NativeQueryParseError Text
|
||||
| NativeQueryValidationError QErr
|
||||
|
@ -2,13 +2,14 @@
|
||||
|
||||
module Hasura.RQL.Types.Backend
|
||||
( Backend (..),
|
||||
Representable,
|
||||
SessionVarType,
|
||||
XDisable,
|
||||
XEnable,
|
||||
ComputedFieldReturnType (..),
|
||||
_ReturnsTable,
|
||||
SupportedNamingCase (..),
|
||||
HasSourceConfiguration (..),
|
||||
Representable,
|
||||
)
|
||||
where
|
||||
|
||||
@ -27,13 +28,12 @@ import Hasura.Prelude
|
||||
import Hasura.RQL.Types.Common
|
||||
import Hasura.RQL.Types.HealthCheckImplementation (HealthCheckImplementation)
|
||||
import Hasura.RQL.Types.ResizePool (ServerReplicas)
|
||||
import Hasura.RQL.Types.SourceConfiguration
|
||||
import Hasura.SQL.Backend
|
||||
import Hasura.SQL.Tag
|
||||
import Hasura.SQL.Types
|
||||
import Language.GraphQL.Draft.Syntax qualified as G
|
||||
|
||||
type Representable a = (Show a, Hashable a, NFData a)
|
||||
|
||||
type SessionVarType b = CollectableType (ScalarType b)
|
||||
|
||||
data ComputedFieldReturnType (b :: BackendType)
|
||||
@ -71,7 +71,8 @@ data SupportedNamingCase = OnlyHasuraCase | AllConventions
|
||||
-- type application or a 'Proxy' parameter to disambiguate between
|
||||
-- different backends at the call site.
|
||||
class
|
||||
( Representable (BasicOrderType b),
|
||||
( HasSourceConfiguration b,
|
||||
Representable (BasicOrderType b),
|
||||
Representable (Column b),
|
||||
Representable (ComputedFieldDefinition b),
|
||||
Representable (ComputedFieldImplicitArguments b),
|
||||
@ -85,7 +86,6 @@ class
|
||||
Representable (SQLExpression b),
|
||||
Representable (ScalarSelectionArguments b),
|
||||
Representable (ScalarType b),
|
||||
Representable (SourceConnConfiguration b),
|
||||
Representable (XComputedField b),
|
||||
Representable (TableName b),
|
||||
Eq (RawFunctionInfo b),
|
||||
@ -105,13 +105,11 @@ class
|
||||
FromJSON (HealthCheckTest b),
|
||||
FromJSON (RawFunctionInfo b),
|
||||
FromJSON (ScalarType b),
|
||||
FromJSON (SourceConnConfiguration b),
|
||||
FromJSON (TableName b),
|
||||
FromJSONKey (Column b),
|
||||
HasCodec (BackendSourceKind b),
|
||||
HasCodec (Column b),
|
||||
HasCodec (FunctionName b),
|
||||
HasCodec (SourceConnConfiguration b),
|
||||
HasCodec (TableName b),
|
||||
ToJSON (BackendConfig b),
|
||||
ToJSON (Column b),
|
||||
@ -119,9 +117,7 @@ class
|
||||
ToJSON (FunctionArgument b),
|
||||
ToJSON (FunctionName b),
|
||||
ToJSON (ScalarType b),
|
||||
ToJSON (SourceConfig b),
|
||||
ToJSON (TableName b),
|
||||
ToJSON (SourceConnConfiguration b),
|
||||
ToJSON (ExtraTableMetadata b),
|
||||
ToJSON (SQLExpression b),
|
||||
ToJSON (ComputedFieldDefinition b),
|
||||
@ -153,7 +149,6 @@ class
|
||||
Show (CountType b),
|
||||
Eq (ScalarValue b),
|
||||
Show (ScalarValue b),
|
||||
Eq (SourceConfig b),
|
||||
-- Extension constraints.
|
||||
Eq (XNodesAgg b),
|
||||
Show (XNodesAgg b),
|
||||
@ -179,13 +174,6 @@ class
|
||||
-- | Runtime backend info derived from (possibly enriched) BackendConfig and stored in SchemaCache
|
||||
type BackendInfo b :: Type
|
||||
|
||||
-- | User facing connection configuration for a database.
|
||||
type SourceConnConfiguration b :: Type
|
||||
|
||||
-- | Internal connection configuration for a database - connection string,
|
||||
-- connection pool etc
|
||||
type SourceConfig b :: Type
|
||||
|
||||
-- Fully qualified name of a table
|
||||
type TableName b :: Type
|
||||
|
||||
@ -298,7 +286,7 @@ class
|
||||
|
||||
type BackendInsert b = Const Void
|
||||
|
||||
-- | Intermediate representation of Native Queries
|
||||
-- | Intermediate representation of Native Queries.
|
||||
-- The default implementation makes native queries uninstantiable.
|
||||
--
|
||||
-- It is parameterised over the type of fields, which changes during the IR
|
||||
|
36
server/src-lib/Hasura/RQL/Types/SourceConfiguration.hs
Normal file
36
server/src-lib/Hasura/RQL/Types/SourceConfiguration.hs
Normal file
@ -0,0 +1,36 @@
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
module Hasura.RQL.Types.SourceConfiguration
|
||||
( HasSourceConfiguration (..),
|
||||
Representable,
|
||||
)
|
||||
where
|
||||
|
||||
import Autodocodec (HasCodec)
|
||||
import Data.Aeson.Extended
|
||||
import Data.Kind (Type)
|
||||
import Hasura.Prelude
|
||||
import Hasura.SQL.Backend
|
||||
import Hasura.SQL.Tag
|
||||
|
||||
type Representable a = (Show a, Eq a, Hashable a, NFData a)
|
||||
|
||||
class
|
||||
( Representable (SourceConnConfiguration b),
|
||||
HasCodec (SourceConnConfiguration b),
|
||||
FromJSON (SourceConnConfiguration b),
|
||||
ToJSON (SourceConfig b),
|
||||
ToJSON (SourceConnConfiguration b),
|
||||
Eq (SourceConfig b),
|
||||
HasTag b
|
||||
) =>
|
||||
HasSourceConfiguration (b :: BackendType)
|
||||
where
|
||||
-- types
|
||||
|
||||
-- | User facing connection configuration for a database.
|
||||
type SourceConnConfiguration b :: Type
|
||||
|
||||
-- | Internal connection configuration for a database - connection string,
|
||||
-- connection pool etc
|
||||
type SourceConfig b :: Type
|
Loading…
Reference in New Issue
Block a user