graphql-engine/server/src-lib/Hasura/StoredProcedure/Schema.hs
Daniel Harvey 9de3db4729 chore(server): respect logical model array nullability
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9303
GitOrigin-RevId: 4d38a125a6889e2b0be34905e21a78036a77881e
2023-05-31 00:15:47 +00:00

123 lines
4.2 KiB
Haskell

-- | Schema parsers for stored procedures.
module Hasura.StoredProcedure.Schema (defaultBuildStoredProcedureRootFields) where
import Data.Has (Has (getter))
import Data.HashMap.Strict qualified as HashMap
import Hasura.GraphQL.Schema.Backend
( BackendLogicalModelSelectSchema (..),
MonadBuildSchema,
)
import Hasura.GraphQL.Schema.Common
( SchemaT,
retrieve,
)
import Hasura.GraphQL.Schema.Parser qualified as P
import Hasura.LogicalModel.Schema
import Hasura.LogicalModelResolver.Schema (argumentsSchema)
import Hasura.Prelude
import Hasura.RQL.IR.Root (RemoteRelationshipField)
import Hasura.RQL.IR.Select (QueryDB (QDBMultipleRows))
import Hasura.RQL.IR.Select qualified as IR
import Hasura.RQL.IR.Value (Provenance (FromInternal), UnpreparedValue (UVParameter))
import Hasura.RQL.Types.Column qualified as Column
import Hasura.RQL.Types.Metadata.Object qualified as MO
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
import Hasura.RQL.Types.Schema.Options qualified as Options
import Hasura.RQL.Types.Source
( SourceInfo (_siCustomization, _siName),
)
import Hasura.RQL.Types.SourceCustomization
( ResolvedSourceCustomization (_rscNamingConvention),
)
import Hasura.SQL.AnyBackend (mkAnyBackend)
import Hasura.StoredProcedure.Cache (StoredProcedureInfo (..))
import Hasura.StoredProcedure.IR (StoredProcedure (..))
import Hasura.StoredProcedure.Metadata (ArgumentName (..))
import Hasura.StoredProcedure.Types (NullableScalarType (..))
import Language.GraphQL.Draft.Syntax qualified as G
defaultBuildStoredProcedureRootFields ::
forall b r m n.
( MonadBuildSchema b r m n,
BackendLogicalModelSelectSchema b
) =>
StoredProcedureInfo b ->
SchemaT
r
m
(Maybe (P.FieldParser n (QueryDB b (RemoteRelationshipField UnpreparedValue) (UnpreparedValue b))))
defaultBuildStoredProcedureRootFields StoredProcedureInfo {..} = runMaybeT $ do
let fieldName = _spiGraphqlName
storedProcedureArgsParser <-
storedProcedureArgumentsSchema @b @r @m @n fieldName _spiArguments
sourceInfo :: SourceInfo b <- asks getter
let sourceName = _siName sourceInfo
tCase = _rscNamingConvention $ _siCustomization sourceInfo
description = G.Description <$> _spiDescription
stringifyNumbers <- retrieve Options.soStringifyNumbers
logicalModelPermissions <-
MaybeT
. fmap Just
$ buildLogicalModelPermissions @b @r @m @n _spiReturns
(selectionSetParser, logicalModelsArgsParser) <-
MaybeT $ buildLogicalModelFields mempty NotNullable _spiReturns
let arguments spArgs =
HashMap.mapWithKey
( \(ArgumentName name) val ->
case Column.cvType val of
Column.ColumnScalar st ->
(st, UVParameter (FromInternal name) val)
Column.ColumnEnumReference {} ->
-- should not happen
error "Enums are unsupported in stored procedures."
)
spArgs
let sourceObj =
MO.MOSourceObjId
sourceName
(mkAnyBackend $ MO.SMOStoredProcedure @b _spiStoredProcedure)
pure
$ P.setFieldParserOrigin sourceObj
$ P.subselection
fieldName
description
( (,)
<$> logicalModelsArgsParser
<*> storedProcedureArgsParser
)
selectionSetParser
<&> \((lmArgs, spArgs), fields) ->
QDBMultipleRows
$ IR.AnnSelectG
{ IR._asnFields = fields,
IR._asnFrom =
IR.FromStoredProcedure
StoredProcedure
{ spStoredProcedure = _spiStoredProcedure,
spGraphqlName = _spiGraphqlName,
spArgs = arguments spArgs,
spLogicalModel = buildLogicalModelIR _spiReturns
},
IR._asnPerm = logicalModelPermissions,
IR._asnArgs = lmArgs,
IR._asnStrfyNum = stringifyNumbers,
IR._asnNamingConvention = Just tCase
}
storedProcedureArgumentsSchema ::
forall b r m n.
(MonadBuildSchema b r m n) =>
G.Name ->
HashMap ArgumentName (NullableScalarType b) ->
MaybeT (SchemaT r m) (P.InputFieldsParser n (HashMap ArgumentName (Column.ColumnValue b)))
storedProcedureArgumentsSchema = argumentsSchema "Stored Procedure"