graphql-engine/server/src-lib/Hasura/RQL/IR/Root.hs
Antoine Leblanc d91029ad51 [gardening] remove all traverse functions from RQL.IR
### Description

This PR removes all `fmapX` and `traverseX` functions from RQL.IR, favouring instead `Functor` and `Traversable` instances throughout the code. This was a relatively straightforward change, except for two small pain points: `AnnSelectG` and `AnnInsert`. Both were parametric over two types `a` and `v`, making it impossible to make them traversable functors... But it turns out that in every single use case, `a ~ f v`. By changing those types to take such an `f :: Type -> Type` as an argument instead of `a :: Type` makes it possible to make them functors.

The only small difference is for `AnnIns`, I had to introduce one `Identity` transformation for one of the `f` parameters. This is relatively straightforward.

### Notes

This PR fixes the most verbose BigQuery hint (`let` instead of `<- pure`).

https://github.com/hasura/graphql-engine-mono/pull/1668

GitOrigin-RevId: e632263a8c559aa04aeae10dcaec915b4a81ad1a
2021-07-08 15:42:53 +00:00

79 lines
3.2 KiB
Haskell

module Hasura.RQL.IR.Root
( SourceConfigWith(..)
, RootField(..)
, MutationDB(..)
, ActionQuery(..)
, ActionMutation(..)
, QueryRootField
, MutationRootField
, SubscriptionRootField
, QueryDBRoot(..)
, MutationDBRoot(..)
) where
import Hasura.Prelude
import qualified Data.Aeson.Ordered as JO
import Data.Kind (Type)
import qualified Hasura.RQL.Types.Action as RQL
import qualified Hasura.RQL.Types.Backend as RQL
import qualified Hasura.RQL.Types.Common as RQL
import qualified Hasura.RQL.Types.RemoteSchema as RQL
import qualified Hasura.SQL.AnyBackend as AB
import Hasura.RQL.IR.Delete
import Hasura.RQL.IR.Insert
import Hasura.RQL.IR.Select
import Hasura.RQL.IR.Update
import Hasura.SQL.Backend
data SourceConfigWith (db :: BackendType -> Type) (b :: BackendType) =
SourceConfigWith (RQL.SourceConfig b) (db b)
data RootField (db :: BackendType -> Type) remote action raw where
RFDB
:: RQL.SourceName
-> AB.AnyBackend (SourceConfigWith db)
-> RootField db remote action raw
RFRemote :: remote -> RootField db remote action raw
RFAction :: action -> RootField db remote action raw
RFRaw :: raw -> RootField db remote action raw
data MutationDB (b :: BackendType) (r :: BackendType -> Type) v
= MDBInsert (AnnInsert b r v)
| MDBUpdate (AnnUpdG b r v)
| MDBDelete (AnnDelG b r v)
| MDBFunction RQL.JsonAggSelect (AnnSimpleSelectG b r v)
-- ^ This represents a VOLATILE function, and is AnnSimpleSelG for easy
-- re-use of non-VOLATILE function tracking code.
deriving stock (Generic, Functor, Foldable, Traversable)
data ActionQuery (b :: BackendType) (r :: BackendType -> Type) v
= AQQuery !(RQL.AnnActionExecution b r v)
| AQAsync !(RQL.AnnActionAsyncQuery b r v)
deriving (Functor, Foldable, Traversable)
data ActionMutation (b :: BackendType) (r :: BackendType -> Type) v
= AMSync !(RQL.AnnActionExecution b r v)
| AMAsync !RQL.AnnActionMutationAsync
deriving (Functor, Foldable, Traversable)
-- The `db` type argument of @RootField@ expects only one type argument, the backend `b`, as not all
-- types stored in a RootField will have a second parameter like @QueryDB@ does: they all only have
-- in common the fact that they're parametric over the backend. To define @QueryRootField@ in terms
-- of @QueryDB@ (and likewise for mutations), we need a type-level function `b -> QueryDB b (v
-- b)`. Sadly, neither type synonyms nor type families may be partially applied. Hence the need for
-- @QueryDBRoot@ and @MutationDBRoot@.
newtype QueryDBRoot r v b = QDBR (QueryDB b r (v b))
newtype MutationDBRoot r v b = MDBR (MutationDB b r (v b))
type QueryRootField r v = RootField (QueryDBRoot r v) RQL.RemoteField (ActionQuery ('Postgres 'Vanilla) r (v ('Postgres 'Vanilla))) JO.Value
type MutationRootField r v = RootField (MutationDBRoot r v) RQL.RemoteField (ActionMutation ('Postgres 'Vanilla) r (v ('Postgres 'Vanilla))) JO.Value
type SubscriptionRootField r v = RootField (QueryDBRoot r v) Void Void Void