{-# OPTIONS_GHC -fno-warn-orphans #-}

module Hasura.Backends.BigQuery.Instances.Transport () where

import Control.Monad.Trans.Control
import Data.Aeson qualified as J
import Hasura.Backends.BigQuery.Instances.Execute ()
import Hasura.Backends.DataConnector.Agent.Client (AgentLicenseKey)
import Hasura.Base.Error
import Hasura.CredentialCache
import Hasura.EncJSON
import Hasura.GraphQL.Execute.Backend
import Hasura.GraphQL.Logging
  ( ExecutionLog (..),
    ExecutionStats (..),
    GeneratedQuery (..),
    MonadExecutionLog (..),
    MonadQueryLog (..),
    QueryLog (..),
    QueryLogKind (QueryLogKindDatabase),
  )
import Hasura.GraphQL.Namespace (RootFieldAlias)
import Hasura.GraphQL.Transport.Backend
import Hasura.GraphQL.Transport.HTTP.Protocol
import Hasura.Logging qualified as L
import Hasura.Prelude
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.BackendType
import Hasura.SQL.AnyBackend (AnyBackend)
import Hasura.Server.Types (RequestId)
import Hasura.Session
import Hasura.Tracing

instance BackendTransport 'BigQuery where
  runDBQuery :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadQueryLog m, MonadExecutionLog m, MonadTrace m) =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad
     (ExecutionMonad 'BigQuery)
     (Maybe (AnyBackend ExecutionStats), EncJSON)
-> Maybe (PreparedQuery 'BigQuery)
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runDBQuery = RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad
     IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad
     (ExecutionMonad 'BigQuery)
     (Maybe (AnyBackend ExecutionStats), EncJSON)
-> Maybe (PreparedQuery 'BigQuery)
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadQueryLog m,
 MonadExecutionLog m, MonadTrace m, MonadError QErr m) =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad
     IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runQuery
  runDBQueryExplain :: forall (m :: * -> *).
(MonadIO m, MonadError QErr m, MonadBaseControl IO m,
 MonadTrace m) =>
Maybe (CredentialCache AgentLicenseKey)
-> DBStepInfo 'BigQuery -> m EncJSON
runDBQueryExplain = Maybe (CredentialCache AgentLicenseKey)
-> DBStepInfo 'BigQuery -> m EncJSON
forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadTrace m) =>
Maybe (CredentialCache AgentLicenseKey)
-> DBStepInfo 'BigQuery -> m EncJSON
runQueryExplain
  runDBMutation :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadQueryLog m, MonadTrace m) =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad (ExecutionMonad 'BigQuery) EncJSON
-> Maybe (PreparedQuery 'BigQuery)
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runDBMutation = RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad IdentityT EncJSON
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad (ExecutionMonad 'BigQuery) EncJSON
-> Maybe (PreparedQuery 'BigQuery)
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
forall (m :: * -> *).
MonadError QErr m =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad IdentityT EncJSON
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runMutation
  runDBSubscription :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m) =>
SourceConfig 'BigQuery
-> MultiplexedQuery 'BigQuery
-> [(CohortId, CohortVariables)]
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, Either QErr [(CohortId, ByteString)])
runDBSubscription = [Char]
-> BigQuerySourceConfig
-> Void
-> [(CohortId, CohortVariables)]
-> ()
-> m (DiffTime, Either QErr [(CohortId, ByteString)])
forall a. HasCallStack => [Char] -> a
error [Char]
"Not supported."
  runDBStreamingSubscription :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m) =>
SourceConfig 'BigQuery
-> MultiplexedQuery 'BigQuery
-> [(CohortId, CohortVariables)]
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime,
      Either QErr [(CohortId, ByteString, CursorVariableValues)])
runDBStreamingSubscription = [Char]
-> BigQuerySourceConfig
-> Void
-> [(CohortId, CohortVariables)]
-> ()
-> m (DiffTime,
      Either QErr [(CohortId, ByteString, CursorVariableValues)])
forall a. HasCallStack => [Char] -> a
error [Char]
"Not supported"

runQuery ::
  ( MonadIO m,
    MonadBaseControl IO m,
    MonadQueryLog m,
    MonadExecutionLog m,
    MonadTrace m,
    MonadError QErr m
  ) =>
  RequestId ->
  GQLReqUnparsed ->
  RootFieldAlias ->
  UserInfo ->
  L.Logger L.Hasura ->
  Maybe (CredentialCache AgentLicenseKey) ->
  SourceConfig 'BigQuery ->
  OnBaseMonad IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON) ->
  Maybe Text ->
  ResolvedConnectionTemplate 'BigQuery ->
  -- | Also return the time spent in the PG query; for telemetry.
  m (DiffTime, EncJSON)
runQuery :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadQueryLog m,
 MonadExecutionLog m, MonadTrace m, MonadError QErr m) =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad
     IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runQuery RequestId
reqId GQLReqUnparsed
query RootFieldAlias
fieldName UserInfo
_userInfo Logger Hasura
logger Maybe (CredentialCache AgentLicenseKey)
_ SourceConfig 'BigQuery
_sourceConfig OnBaseMonad IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
tx Maybe Text
genSql ResolvedConnectionTemplate 'BigQuery
_ = do
  -- log the generated SQL and the graphql query
  -- FIXME: fix logging by making logQueryLog expect something backend agnostic!
  Logger Hasura -> QueryLog -> m ()
forall (m :: * -> *).
MonadQueryLog m =>
Logger Hasura -> QueryLog -> m ()
logQueryLog Logger Hasura
logger (QueryLog -> m ()) -> QueryLog -> m ()
forall a b. (a -> b) -> a -> b
$ QueryLogKind
-> GQLReqUnparsed
-> RootFieldAlias
-> Maybe Text
-> RequestId
-> QueryLog
mkQueryLog (Maybe BackendResolvedConnectionTemplate -> QueryLogKind
QueryLogKindDatabase Maybe BackendResolvedConnectionTemplate
forall a. Maybe a
Nothing) GQLReqUnparsed
query RootFieldAlias
fieldName Maybe Text
genSql RequestId
reqId
  (DiffTime
diffTime, (Maybe (AnyBackend ExecutionStats)
stats, EncJSON
result)) <- m (Maybe (AnyBackend ExecutionStats), EncJSON)
-> m (DiffTime, (Maybe (AnyBackend ExecutionStats), EncJSON))
forall (m :: * -> *) a. MonadIO m => m a -> m (DiffTime, a)
withElapsedTime (m (Maybe (AnyBackend ExecutionStats), EncJSON)
 -> m (DiffTime, (Maybe (AnyBackend ExecutionStats), EncJSON)))
-> m (Maybe (AnyBackend ExecutionStats), EncJSON)
-> m (DiffTime, (Maybe (AnyBackend ExecutionStats), EncJSON))
forall a b. (a -> b) -> a -> b
$ OnBaseMonad IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
-> m (Maybe (AnyBackend ExecutionStats), EncJSON)
forall (m :: * -> *) a.
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadTrace m) =>
OnBaseMonad IdentityT a -> m a
run OnBaseMonad IdentityT (Maybe (AnyBackend ExecutionStats), EncJSON)
tx

  Logger Hasura -> ExecutionLog -> m ()
forall (m :: * -> *).
MonadExecutionLog m =>
Logger Hasura -> ExecutionLog -> m ()
logExecutionLog Logger Hasura
logger (ExecutionLog -> m ()) -> ExecutionLog -> m ()
forall a b. (a -> b) -> a -> b
$ RequestId -> Maybe (AnyBackend ExecutionStats) -> ExecutionLog
mkExecutionLog RequestId
reqId Maybe (AnyBackend ExecutionStats)
stats

  (DiffTime, EncJSON) -> m (DiffTime, EncJSON)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DiffTime
diffTime, EncJSON
result)

runQueryExplain ::
  ( MonadIO m,
    MonadBaseControl IO m,
    MonadError QErr m,
    MonadTrace m
  ) =>
  Maybe (CredentialCache AgentLicenseKey) ->
  DBStepInfo 'BigQuery ->
  m EncJSON
runQueryExplain :: forall (m :: * -> *).
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadTrace m) =>
Maybe (CredentialCache AgentLicenseKey)
-> DBStepInfo 'BigQuery -> m EncJSON
runQueryExplain Maybe (CredentialCache AgentLicenseKey)
_ (DBStepInfo SourceName
_ SourceConfig 'BigQuery
_ Maybe (PreparedQuery 'BigQuery)
_ OnBaseMonad (ExecutionMonad 'BigQuery) (ActionResult 'BigQuery)
action ResolvedConnectionTemplate 'BigQuery
_) = (ActionResult 'BigQuery -> EncJSON)
-> m (ActionResult 'BigQuery) -> m EncJSON
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ActionResult 'BigQuery -> EncJSON
forall (b :: BackendType). ActionResult b -> EncJSON
arResult (OnBaseMonad IdentityT (ActionResult 'BigQuery)
-> m (ActionResult 'BigQuery)
forall (m :: * -> *) a.
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadTrace m) =>
OnBaseMonad IdentityT a -> m a
run OnBaseMonad IdentityT (ActionResult 'BigQuery)
OnBaseMonad (ExecutionMonad 'BigQuery) (ActionResult 'BigQuery)
action)

runMutation ::
  ( MonadError QErr m
  ) =>
  RequestId ->
  GQLReqUnparsed ->
  RootFieldAlias ->
  UserInfo ->
  L.Logger L.Hasura ->
  Maybe (CredentialCache AgentLicenseKey) ->
  SourceConfig 'BigQuery ->
  OnBaseMonad IdentityT EncJSON ->
  Maybe Text ->
  ResolvedConnectionTemplate 'BigQuery ->
  -- | Also return 'Mutation' when the operation was a mutation, and the time
  -- spent in the PG query; for telemetry.
  m (DiffTime, EncJSON)
runMutation :: forall (m :: * -> *).
MonadError QErr m =>
RequestId
-> GQLReqUnparsed
-> RootFieldAlias
-> UserInfo
-> Logger Hasura
-> Maybe (CredentialCache AgentLicenseKey)
-> SourceConfig 'BigQuery
-> OnBaseMonad IdentityT EncJSON
-> Maybe Text
-> ResolvedConnectionTemplate 'BigQuery
-> m (DiffTime, EncJSON)
runMutation RequestId
_reqId GQLReqUnparsed
_query RootFieldAlias
_fieldName UserInfo
_userInfo Logger Hasura
_logger Maybe (CredentialCache AgentLicenseKey)
_ SourceConfig 'BigQuery
_sourceConfig OnBaseMonad IdentityT EncJSON
_tx Maybe Text
_genSql ResolvedConnectionTemplate 'BigQuery
_ =
  -- do
  Text -> m (DiffTime, EncJSON)
forall (m :: * -> *) a. QErrM m => Text -> m a
throw500 Text
"BigQuery does not support mutations!"

run ::
  ( MonadIO m,
    MonadBaseControl IO m,
    MonadError QErr m,
    MonadTrace m
  ) =>
  OnBaseMonad IdentityT a ->
  m a
run :: forall (m :: * -> *) a.
(MonadIO m, MonadBaseControl IO m, MonadError QErr m,
 MonadTrace m) =>
OnBaseMonad IdentityT a -> m a
run = IdentityT m a -> m a
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT (IdentityT m a -> m a)
-> (OnBaseMonad IdentityT a -> IdentityT m a)
-> OnBaseMonad IdentityT a
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnBaseMonad IdentityT a -> IdentityT m a
OnBaseMonad IdentityT a
-> forall (m :: * -> *).
   (Functor (IdentityT m), MonadIO m, MonadBaseControl IO m,
    MonadTrace m, MonadError QErr m) =>
   IdentityT m a
forall (t :: (* -> *) -> * -> *) a.
OnBaseMonad t a
-> forall (m :: * -> *).
   (Functor (t m), MonadIO m, MonadBaseControl IO m, MonadTrace m,
    MonadError QErr m) =>
   t m a
runOnBaseMonad

-- @QueryLogKindDatabase Nothing@ means that the backend doesn't support connection templates
mkQueryLog ::
  QueryLogKind ->
  GQLReqUnparsed ->
  RootFieldAlias ->
  Maybe Text ->
  RequestId ->
  QueryLog
mkQueryLog :: QueryLogKind
-> GQLReqUnparsed
-> RootFieldAlias
-> Maybe Text
-> RequestId
-> QueryLog
mkQueryLog QueryLogKind
_qlKind GQLReqUnparsed
_qlQuery RootFieldAlias
fieldName Maybe Text
preparedSql RequestId
_qlRequestId = QueryLog {Maybe (RootFieldAlias, GeneratedQuery)
RequestId
GQLReqUnparsed
QueryLogKind
_qlKind :: QueryLogKind
_qlQuery :: GQLReqUnparsed
_qlRequestId :: RequestId
_qlGeneratedSql :: Maybe (RootFieldAlias, GeneratedQuery)
_qlQuery :: GQLReqUnparsed
_qlGeneratedSql :: Maybe (RootFieldAlias, GeneratedQuery)
_qlRequestId :: RequestId
_qlKind :: QueryLogKind
..}
  where
    _qlGeneratedSql :: Maybe (RootFieldAlias, GeneratedQuery)
_qlGeneratedSql = Maybe Text
preparedSql Maybe Text
-> (Text -> (RootFieldAlias, GeneratedQuery))
-> Maybe (RootFieldAlias, GeneratedQuery)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \Text
query -> (RootFieldAlias
fieldName, Text -> Value -> GeneratedQuery
GeneratedQuery Text
query Value
J.Null)

mkExecutionLog ::
  RequestId ->
  Maybe (AnyBackend ExecutionStats) ->
  ExecutionLog
mkExecutionLog :: RequestId -> Maybe (AnyBackend ExecutionStats) -> ExecutionLog
mkExecutionLog RequestId
_elRequestId Maybe (AnyBackend ExecutionStats)
_elStatistics = ExecutionLog {Maybe (AnyBackend ExecutionStats)
RequestId
_elRequestId :: RequestId
_elStatistics :: Maybe (AnyBackend ExecutionStats)
_elRequestId :: RequestId
_elStatistics :: Maybe (AnyBackend ExecutionStats)
..}