2022-02-25 19:08:18 +03:00
|
|
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
|
|
|
|
2022-05-02 08:03:12 +03:00
|
|
|
module Hasura.Backends.DataConnector.Adapter.Execute
|
2022-02-25 19:08:18 +03:00
|
|
|
(
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
2022-04-08 09:48:37 +03:00
|
|
|
import Data.Aeson qualified as J
|
|
|
|
import Data.ByteString.Lazy qualified as BL
|
|
|
|
import Data.Text.Encoding qualified as TE
|
2022-05-02 08:03:12 +03:00
|
|
|
import Hasura.Backends.DataConnector.API qualified as API
|
|
|
|
import Hasura.Backends.DataConnector.Agent.Client
|
|
|
|
import Hasura.Backends.DataConnector.IR.Export as IR
|
|
|
|
import Hasura.Backends.DataConnector.IR.Query qualified as IR.Q
|
|
|
|
import Hasura.Backends.DataConnector.Plan qualified as DC
|
2022-04-28 04:51:58 +03:00
|
|
|
import Hasura.Base.Error (Code (..), QErr, throw400, throw500)
|
2022-04-08 09:48:37 +03:00
|
|
|
import Hasura.EncJSON (EncJSON, encJFromJValue)
|
|
|
|
import Hasura.GraphQL.Execute.Backend (BackendExecute (..), DBStepInfo (..), ExplainPlan (..))
|
|
|
|
import Hasura.GraphQL.Namespace qualified as GQL
|
2022-02-25 19:08:18 +03:00
|
|
|
import Hasura.Prelude
|
2022-04-08 09:48:37 +03:00
|
|
|
import Hasura.SQL.AnyBackend (mkAnyBackend)
|
2022-05-02 08:03:12 +03:00
|
|
|
import Hasura.SQL.Backend (BackendType (DataConnector))
|
2022-04-08 09:48:37 +03:00
|
|
|
import Hasura.Session
|
2022-02-25 19:08:18 +03:00
|
|
|
import Hasura.Tracing qualified as Tracing
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------
|
|
|
|
|
2022-05-02 08:03:12 +03:00
|
|
|
instance BackendExecute 'DataConnector where
|
|
|
|
type PreparedQuery 'DataConnector = DC.Plan
|
|
|
|
type MultiplexedQuery 'DataConnector = Void
|
|
|
|
type ExecutionMonad 'DataConnector = Tracing.TraceT (ExceptT QErr IO)
|
2022-02-25 19:08:18 +03:00
|
|
|
|
2022-04-08 09:48:37 +03:00
|
|
|
mkDBQueryPlan UserInfo {..} sourceName sourceConfig ir = do
|
2022-05-02 08:03:12 +03:00
|
|
|
plan' <- DC.mkPlan _uiSession sourceConfig ir
|
2022-04-08 09:48:37 +03:00
|
|
|
pure
|
|
|
|
DBStepInfo
|
|
|
|
{ dbsiSourceName = sourceName,
|
|
|
|
dbsiSourceConfig = sourceConfig,
|
|
|
|
dbsiPreparedQuery = Just plan',
|
2022-05-02 08:03:12 +03:00
|
|
|
dbsiAction = buildAction sourceConfig (DC.query plan')
|
2022-04-08 09:48:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
mkDBQueryExplain fieldName UserInfo {..} sourceName sourceConfig ir = do
|
2022-05-02 08:03:12 +03:00
|
|
|
plan' <- DC.mkPlan _uiSession sourceConfig ir
|
2022-04-08 09:48:37 +03:00
|
|
|
pure $
|
2022-05-02 08:03:12 +03:00
|
|
|
mkAnyBackend @'DataConnector
|
2022-04-08 09:48:37 +03:00
|
|
|
DBStepInfo
|
|
|
|
{ dbsiSourceName = sourceName,
|
|
|
|
dbsiSourceConfig = sourceConfig,
|
|
|
|
dbsiPreparedQuery = Just plan',
|
|
|
|
dbsiAction = pure . encJFromJValue . toExplainPlan fieldName $ plan'
|
|
|
|
}
|
2022-02-25 19:08:18 +03:00
|
|
|
mkDBMutationPlan _ _ _ _ _ =
|
2022-05-02 08:03:12 +03:00
|
|
|
throw400 NotSupported "mkDBMutationPlan: not implemented for the Data Connector backend."
|
2022-04-07 17:41:43 +03:00
|
|
|
mkLiveQuerySubscriptionPlan _ _ _ _ _ =
|
2022-05-02 08:03:12 +03:00
|
|
|
throw400 NotSupported "mkLiveQuerySubscriptionPlan: not implemented for the Data Connector backend."
|
2022-04-07 17:41:43 +03:00
|
|
|
mkDBStreamingSubscriptionPlan _ _ _ _ =
|
2022-05-02 08:03:12 +03:00
|
|
|
throw400 NotSupported "mkLiveQuerySubscriptionPlan: not implemented for the Data Connector backend."
|
2022-02-25 19:08:18 +03:00
|
|
|
mkDBRemoteRelationshipPlan _ _ _ _ _ _ _ =
|
2022-05-02 08:03:12 +03:00
|
|
|
throw500 "mkDBRemoteRelationshipPlan: not implemented for the Data Connector backend."
|
2022-03-21 13:39:49 +03:00
|
|
|
mkSubscriptionExplain _ =
|
2022-05-02 08:03:12 +03:00
|
|
|
throw400 NotSupported "mkSubscriptionExplain: not implemented for the Data Connector backend."
|
2022-04-08 09:48:37 +03:00
|
|
|
|
2022-05-02 08:03:12 +03:00
|
|
|
toExplainPlan :: GQL.RootFieldAlias -> DC.Plan -> ExplainPlan
|
2022-04-08 09:48:37 +03:00
|
|
|
toExplainPlan fieldName plan_ =
|
2022-05-02 08:03:12 +03:00
|
|
|
ExplainPlan fieldName (Just "") (Just [TE.decodeUtf8 $ BL.toStrict $ J.encode $ DC.query $ plan_])
|
2022-04-08 09:48:37 +03:00
|
|
|
|
2022-05-02 08:03:12 +03:00
|
|
|
buildAction :: DC.SourceConfig -> IR.Q.Query -> Tracing.TraceT (ExceptT QErr IO) EncJSON
|
|
|
|
buildAction DC.SourceConfig {..} query = do
|
2022-04-28 04:51:58 +03:00
|
|
|
-- NOTE: Should this check occur during query construction in 'mkPlan'?
|
2022-05-02 08:03:12 +03:00
|
|
|
when (DC.queryHasRelations query && not (API.dcRelationships (API.srCapabilities _scSchema))) $
|
2022-04-08 09:48:37 +03:00
|
|
|
throw400 NotSupported "Agents must provide their own dataloader."
|
2022-04-29 05:13:13 +03:00
|
|
|
API.Routes {..} <- liftIO $ client @(Tracing.TraceT (ExceptT QErr IO)) _scManager _scEndpoint
|
2022-05-02 02:01:11 +03:00
|
|
|
case fmap (_query _scConfig) $ IR.queryToAPI query of
|
2022-04-28 04:51:58 +03:00
|
|
|
Right query' -> do
|
|
|
|
queryResponse <- query'
|
|
|
|
pure $ encJFromJValue queryResponse
|
|
|
|
Left (IR.ExposedLiteral lit) ->
|
|
|
|
throw500 $ "Invalid query constructed: Exposed IR Literal '" <> lit <> "'."
|