2022-04-29 05:13:13 +03:00
|
|
|
{-# LANGUAGE UndecidableInstances #-}
|
|
|
|
|
|
|
|
module Hasura.SQL.BackendMap
|
|
|
|
( BackendMap,
|
Move, document, and prune action types and custom types types.
### Description
This PR is a first step in a series of cleanups of action relationships. This first step does not contain any behavioral change, and it simply reorganizes / prunes / rearranges / documents the code. Mainly:
- it divides some files in RQL.Types between metadata types, schema cache types, execution types;
- it renames some types for consistency;
- it minimizes exports and prunes unnecessary types;
- it moves some types in places where they make more sense;
- it replaces uses of `DMap BackendTag` with `BackendMap`.
Most of the "movement" within files re-organizes declarations in a "top-down" fashion, by moving all TH splices to the end of the file, which avoids order or declarations mattering.
### Optional list types
One main type change this PR makes is a replacement of variant list types in `CustomTypes.hs`; we had `Maybe [a]`, or sometimes `Maybe (NonEmpty a)`. This PR harmonizes all of them to `[a]`, as most of the code would use them as such, by doing `fromMaybe []` or `maybe [] toList`.
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4613
GitOrigin-RevId: bc624e10df587eba862ff27a5e8021b32d0d78a2
2022-06-07 18:43:34 +03:00
|
|
|
singleton,
|
2022-04-29 05:13:13 +03:00
|
|
|
lookup,
|
|
|
|
elems,
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Data.Aeson (FromJSON, ToJSON, Value, object, withObject)
|
|
|
|
import Data.Aeson qualified as J
|
2022-06-08 18:31:28 +03:00
|
|
|
import Data.Aeson.Key qualified as K
|
|
|
|
import Data.Aeson.KeyMap qualified as KM
|
2022-04-29 05:13:13 +03:00
|
|
|
import Data.Kind (Type)
|
|
|
|
import Data.Map.Strict (Map)
|
|
|
|
import Data.Map.Strict qualified as Map
|
|
|
|
import Data.Text.Extended (toTxt)
|
Move, document, and prune action types and custom types types.
### Description
This PR is a first step in a series of cleanups of action relationships. This first step does not contain any behavioral change, and it simply reorganizes / prunes / rearranges / documents the code. Mainly:
- it divides some files in RQL.Types between metadata types, schema cache types, execution types;
- it renames some types for consistency;
- it minimizes exports and prunes unnecessary types;
- it moves some types in places where they make more sense;
- it replaces uses of `DMap BackendTag` with `BackendMap`.
Most of the "movement" within files re-organizes declarations in a "top-down" fashion, by moving all TH splices to the end of the file, which avoids order or declarations mattering.
### Optional list types
One main type change this PR makes is a replacement of variant list types in `CustomTypes.hs`; we had `Maybe [a]`, or sometimes `Maybe (NonEmpty a)`. This PR harmonizes all of them to `[a]`, as most of the code would use them as such, by doing `fromMaybe []` or `maybe [] toList`.
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4613
GitOrigin-RevId: bc624e10df587eba862ff27a5e8021b32d0d78a2
2022-06-07 18:43:34 +03:00
|
|
|
import Hasura.Prelude hiding (empty, lookup)
|
|
|
|
import Hasura.SQL.AnyBackend (AnyBackend, SatisfiesForAllBackends, dispatchAnyBackend'', mkAnyBackend, parseAnyBackendFromJSON, unpackAnyBackend)
|
2022-04-29 05:13:13 +03:00
|
|
|
import Hasura.SQL.Backend (BackendType, parseBackendTypeFromText)
|
|
|
|
import Hasura.SQL.Tag (HasTag, backendTag, reify)
|
|
|
|
|
|
|
|
-- | A BackendMap is a data structure that can contain at most one value of an 'i' per 'BackendType'
|
|
|
|
-- The 'i' type must be one that is parameterized by a BackendType-kinded type parameter
|
|
|
|
newtype BackendMap (i :: BackendType -> Type) = BackendMap (Map BackendType (AnyBackend i))
|
|
|
|
deriving stock (Generic)
|
|
|
|
deriving newtype (Semigroup, Monoid)
|
|
|
|
|
|
|
|
deriving newtype instance i `SatisfiesForAllBackends` Show => Show (BackendMap i)
|
|
|
|
|
|
|
|
deriving newtype instance i `SatisfiesForAllBackends` Eq => Eq (BackendMap i)
|
|
|
|
|
Move, document, and prune action types and custom types types.
### Description
This PR is a first step in a series of cleanups of action relationships. This first step does not contain any behavioral change, and it simply reorganizes / prunes / rearranges / documents the code. Mainly:
- it divides some files in RQL.Types between metadata types, schema cache types, execution types;
- it renames some types for consistency;
- it minimizes exports and prunes unnecessary types;
- it moves some types in places where they make more sense;
- it replaces uses of `DMap BackendTag` with `BackendMap`.
Most of the "movement" within files re-organizes declarations in a "top-down" fashion, by moving all TH splices to the end of the file, which avoids order or declarations mattering.
### Optional list types
One main type change this PR makes is a replacement of variant list types in `CustomTypes.hs`; we had `Maybe [a]`, or sometimes `Maybe (NonEmpty a)`. This PR harmonizes all of them to `[a]`, as most of the code would use them as such, by doing `fromMaybe []` or `maybe [] toList`.
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4613
GitOrigin-RevId: bc624e10df587eba862ff27a5e8021b32d0d78a2
2022-06-07 18:43:34 +03:00
|
|
|
singleton :: forall b i. HasTag b => i b -> BackendMap i
|
|
|
|
singleton value = BackendMap $ Map.singleton (reify $ backendTag @b) (mkAnyBackend value)
|
|
|
|
|
2022-04-29 05:13:13 +03:00
|
|
|
-- | Get a value from the map for the particular 'BackendType' 'b'. This function
|
|
|
|
-- is usually used with a type application.
|
|
|
|
-- @
|
|
|
|
-- lookup @('Postgres 'Vanilla) backendMap
|
|
|
|
-- @
|
|
|
|
lookup :: forall (b :: BackendType) i. HasTag b => BackendMap i -> Maybe (i b)
|
|
|
|
lookup (BackendMap backendMap) =
|
|
|
|
Map.lookup (reify $ backendTag @b) backendMap >>= unpackAnyBackend @b
|
|
|
|
|
|
|
|
-- | Get all values in the map
|
|
|
|
elems :: forall i. BackendMap i -> [AnyBackend i]
|
|
|
|
elems (BackendMap backendMap) = Map.elems backendMap
|
|
|
|
|
|
|
|
instance i `SatisfiesForAllBackends` FromJSON => FromJSON (BackendMap i) where
|
|
|
|
parseJSON =
|
|
|
|
withObject "BackendMap" $ \obj -> do
|
|
|
|
BackendMap . Map.fromList
|
|
|
|
<$> traverse
|
|
|
|
( \(backendTypeStr, val) -> do
|
2022-06-08 18:31:28 +03:00
|
|
|
backendType <- parseBackendTypeFromText $ K.toText backendTypeStr
|
2022-04-29 05:13:13 +03:00
|
|
|
(backendType,) <$> parseAnyBackendFromJSON backendType val
|
|
|
|
)
|
2022-06-08 18:31:28 +03:00
|
|
|
(KM.toList obj)
|
2022-04-29 05:13:13 +03:00
|
|
|
|
|
|
|
instance i `SatisfiesForAllBackends` ToJSON => ToJSON (BackendMap i) where
|
|
|
|
toJSON (BackendMap backendMap) =
|
|
|
|
object $ valueToPair <$> Map.elems backendMap
|
|
|
|
where
|
2022-06-08 18:31:28 +03:00
|
|
|
valueToPair :: AnyBackend i -> (K.Key, Value)
|
2022-04-29 05:13:13 +03:00
|
|
|
valueToPair value = dispatchAnyBackend'' @ToJSON @HasTag value $ \(v :: i b) ->
|
2022-06-08 18:31:28 +03:00
|
|
|
let backendTypeText = K.fromText . toTxt . reify $ backendTag @b
|
2022-04-29 05:13:13 +03:00
|
|
|
in (backendTypeText, J.toJSON v)
|