Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- class (Backend b, ToTxt (MultiplexedQuery b), Show (ResolvedConnectionTemplate b), Eq (ResolvedConnectionTemplate b), Hashable (ResolvedConnectionTemplate b)) => BackendExecute (b :: BackendType) where
- type PreparedQuery b :: Type
- type MultiplexedQuery b :: Type
- type ExecutionMonad b :: (Type -> Type) -> Type -> Type
- mkDBQueryPlan :: forall m. (MonadError QErr m, MonadQueryTags m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> QueryDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> m (DBStepInfo b)
- mkDBMutationPlan :: forall m. (MonadError QErr m, MonadIO m, MonadQueryTags m, MonadReader QueryTagsComment m, MonadTrace m) => Environment -> Manager -> Logger Hasura -> UserInfo -> StringifyNumbers -> SourceName -> SourceConfig b -> MutationDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> Maybe (HashMap Name (Value Variable)) -> m (DBStepInfo b)
- mkLiveQuerySubscriptionPlan :: forall m. (MonadError QErr m, MonadIO m, MonadBaseControl IO m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> Maybe Name -> RootFieldMap (QueryDB b Void (UnpreparedValue b)) -> [Header] -> Maybe Name -> m (SubscriptionQueryPlan b (MultiplexedQuery b))
- mkDBStreamingSubscriptionPlan :: forall m. (MonadError QErr m, MonadIO m, MonadBaseControl IO m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> (RootFieldAlias, QueryDB b Void (UnpreparedValue b)) -> [Header] -> Maybe Name -> m (SubscriptionQueryPlan b (MultiplexedQuery b))
- mkDBQueryExplain :: forall m. MonadError QErr m => RootFieldAlias -> UserInfo -> SourceName -> SourceConfig b -> QueryDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> m (AnyBackend DBStepInfo)
- mkSubscriptionExplain :: (MonadError QErr m, MonadIO m, MonadBaseControl IO m) => SubscriptionQueryPlan b (MultiplexedQuery b) -> m SubscriptionQueryPlanExplanation
- mkDBRemoteRelationshipPlan :: forall m. (MonadError QErr m, MonadQueryTags m) => UserInfo -> SourceName -> SourceConfig b -> NonEmpty Object -> HashMap FieldName (Column b, ScalarType b) -> FieldName -> (FieldName, SourceRelationshipSelection b Void UnpreparedValue) -> [Header] -> Maybe Name -> StringifyNumbers -> m (DBStepInfo b)
- convertRemoteSourceRelationship :: forall b. Backend b => HashMap (Column b) (Column b) -> SelectFromG b (UnpreparedValue b) -> Column b -> ColumnType b -> (FieldName, SourceRelationshipSelection b Void UnpreparedValue) -> StringifyNumbers -> QueryDB b Void (UnpreparedValue b)
- data DBStepInfo b = DBStepInfo {}
- data ActionResult b = ActionResult {
- arStatistics :: Maybe (ExecutionStatistics b)
- arResult :: EncJSON
- withNoStatistics :: EncJSON -> ActionResult b
- newtype OnBaseMonad t a = OnBaseMonad {
- runOnBaseMonad :: forall m. (Functor (t m), MonadIO m, MonadBaseControl IO m, MonadTrace m, MonadError QErr m) => t m a
- data ExplainPlan = ExplainPlan {}
- data ExecutionStep where
- ExecStepDB :: ResponseHeaders -> AnyBackend DBStepInfo -> Maybe RemoteJoins -> ExecutionStep
- ExecStepAction :: ActionExecutionPlan -> ActionsInfo -> Maybe RemoteJoins -> ExecutionStep
- ExecStepRemote :: !RemoteSchemaInfo -> !ResultCustomizer -> !GQLReqOutgoing -> Maybe RemoteJoins -> ExecutionStep
- ExecStepRaw :: Value -> ExecutionStep
- ExecStepMulti :: [ExecutionStep] -> ExecutionStep
- type ExecutionPlan = RootFieldMap ExecutionStep
Documentation
class (Backend b, ToTxt (MultiplexedQuery b), Show (ResolvedConnectionTemplate b), Eq (ResolvedConnectionTemplate b), Hashable (ResolvedConnectionTemplate b)) => BackendExecute (b :: BackendType) where Source #
This typeclass enacapsulates how a given backend translates a root field into an execution plan. For now, each root field maps to one execution step, but in the future, when we have a client-side dataloader, each root field might translate into a multi-step plan.
type PreparedQuery b :: Type Source #
type MultiplexedQuery b :: Type Source #
type ExecutionMonad b :: (Type -> Type) -> Type -> Type Source #
mkDBQueryPlan :: forall m. (MonadError QErr m, MonadQueryTags m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> QueryDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> m (DBStepInfo b) Source #
mkDBMutationPlan :: forall m. (MonadError QErr m, MonadIO m, MonadQueryTags m, MonadReader QueryTagsComment m, MonadTrace m) => Environment -> Manager -> Logger Hasura -> UserInfo -> StringifyNumbers -> SourceName -> SourceConfig b -> MutationDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> Maybe (HashMap Name (Value Variable)) -> m (DBStepInfo b) Source #
mkLiveQuerySubscriptionPlan :: forall m. (MonadError QErr m, MonadIO m, MonadBaseControl IO m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> Maybe Name -> RootFieldMap (QueryDB b Void (UnpreparedValue b)) -> [Header] -> Maybe Name -> m (SubscriptionQueryPlan b (MultiplexedQuery b)) Source #
mkDBStreamingSubscriptionPlan :: forall m. (MonadError QErr m, MonadIO m, MonadBaseControl IO m, MonadReader QueryTagsComment m) => UserInfo -> SourceName -> SourceConfig b -> (RootFieldAlias, QueryDB b Void (UnpreparedValue b)) -> [Header] -> Maybe Name -> m (SubscriptionQueryPlan b (MultiplexedQuery b)) Source #
mkDBQueryExplain :: forall m. MonadError QErr m => RootFieldAlias -> UserInfo -> SourceName -> SourceConfig b -> QueryDB b Void (UnpreparedValue b) -> [Header] -> Maybe Name -> m (AnyBackend DBStepInfo) Source #
mkSubscriptionExplain :: (MonadError QErr m, MonadIO m, MonadBaseControl IO m) => SubscriptionQueryPlan b (MultiplexedQuery b) -> m SubscriptionQueryPlanExplanation Source #
mkDBRemoteRelationshipPlan Source #
:: forall m. (MonadError QErr m, MonadQueryTags m) | |
=> UserInfo | |
-> SourceName | |
-> SourceConfig b | |
-> NonEmpty Object | List of json objects, each of which becomes a row of the table. |
-> HashMap FieldName (Column b, ScalarType b) | The above objects have this schema. |
-> FieldName | This is a field name from the lhs that *has* to be selected in the
response along with the relationship. It is populated in
|
-> (FieldName, SourceRelationshipSelection b Void UnpreparedValue) | |
-> [Header] | |
-> Maybe Name | |
-> StringifyNumbers | |
-> m (DBStepInfo b) |
Instances
convertRemoteSourceRelationship Source #
:: forall b. Backend b | |
=> HashMap (Column b) (Column b) | Join columns for the relationship |
-> SelectFromG b (UnpreparedValue b) | The LHS of the join, this is the expression which selects from json objects |
-> Column b | This is the argument id column, that needs to be added to the response This is used by by the remote joins processing logic to convert the response from upstream to join indices |
-> ColumnType b | This is the type of the argument id column |
-> (FieldName, SourceRelationshipSelection b Void UnpreparedValue) | The relationship column and its name (how it should be selected in the response) |
-> StringifyNumbers | |
-> QueryDB b Void (UnpreparedValue b) |
This is a helper function to convert a remote source's relationship to a normal relationship to a temporary table. This function can be used to implement executeRemoteRelationship function in databases which support constructing a temporary table for a list of json objects.
data DBStepInfo b Source #
data ActionResult b Source #
withNoStatistics :: EncJSON -> ActionResult b Source #
Lift a result from the database into an ActionResult
.
newtype OnBaseMonad t a Source #
Provides an abstraction over the base monad in which a computation runs.
Given a transformer t
and a type a
, OnBaseMonad t a
represents a
computation of type t m a
, for any base monad m
. This allows DBStepInfo
to store a backend-specific computation, using a backend-specific monad
transformer, on top of the base app monad, without DBStepInfo
needing to
know about the base monad m
.
However, this kind of type erasure forces us to bundle all of the constraints
on the base monad m
here. The constraints here are the union of the
constraints required across all backends. If it were possible to express
constraint functions of the form (Type -> Type) -> Constraint
at the type
level, we could make the list of constraints a type family in
BackendExecute
, allowing each backend to specify its own specific
constraints; and we could then provide the list of constraints as an
additional argument to OnBaseMonad
, pushing the requirement to implement
the union of all constraints to the base execution functions.
All backends require MonadError QErr
to report errors, and MonadIO
to be
able to communicate over the network. Most of them require MonadTrace
to
be able to create new spans as part of the execution, and several use
MonadBaseControl IO
to use try
in their error handling.
OnBaseMonad | |
|
Instances
Functor (OnBaseMonad t) Source # | |
Defined in Hasura.GraphQL.Execute.Backend fmap :: (a -> b) -> OnBaseMonad t a -> OnBaseMonad t b # (<$) :: a -> OnBaseMonad t b -> OnBaseMonad t a # |
data ExplainPlan Source #
The result of an explain query: for a given root field (denoted by its name): the generated SQL query, and the detailed explanation obtained from the database (if any). We mostly use this type as an intermediary step, and immediately tranform any value we obtain into an equivalent JSON representation.
Instances
data ExecutionStep where Source #
One execution step to processing a GraphQL query (e.g. one root field).
ExecStepDB :: ResponseHeaders -> AnyBackend DBStepInfo -> Maybe RemoteJoins -> ExecutionStep | A query to execute against the database |
ExecStepAction :: ActionExecutionPlan -> ActionsInfo -> Maybe RemoteJoins -> ExecutionStep | Execute an action |
ExecStepRemote :: !RemoteSchemaInfo -> !ResultCustomizer -> !GQLReqOutgoing -> Maybe RemoteJoins -> ExecutionStep | A graphql query to execute against a remote schema |
ExecStepRaw :: Value -> ExecutionStep | Output a plain JSON object |
ExecStepMulti :: [ExecutionStep] -> ExecutionStep |
type ExecutionPlan = RootFieldMap ExecutionStep Source #
The series of steps that need to be executed for a given query. For now, those steps are all independent. In the future, when we implement a client-side dataloader and generalized joins, this will need to be changed into an annotated tree.