{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Database.Bolt.Extras.DSL.Typed.Parameters
where
import Control.Monad.IO.Class (MonadIO)
import Data.Kind (Type)
import qualified Data.Map.Strict as Map
import Data.Text (Text, pack)
import Database.Bolt (BoltActionT, IsValue (..), Record,
Value, queryP)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeLits (Symbol)
import Database.Bolt.Extras.DSL.Internal.Executer (formQuery)
import Database.Bolt.Extras.DSL.Internal.Language (CypherDSL)
import Database.Bolt.Extras.DSL.Typed.Types (SymbolS (..))
newtype CypherDSLParams (params :: [(Symbol, Type)]) (a :: Type)
= CypherDSLParams (CypherDSL a)
class QueryWithParams (params :: [(Symbol, Type)]) (m :: Type -> Type) fun | params m -> fun where
collectParams :: HasCallStack => CypherDSL () -> [(Text, Value)] -> fun
instance MonadIO m => QueryWithParams '[] m (BoltActionT m [Record]) where
collectParams :: CypherDSL () -> [(Text, Value)] -> BoltActionT m [Record]
collectParams CypherDSL ()
dsl [(Text, Value)]
params = Text -> Record -> BoltActionT m [Record]
forall (m :: * -> *).
MonadIO m =>
Text -> Record -> BoltActionT m [Record]
queryP (CypherDSL () -> Text
formQuery CypherDSL ()
dsl) (Record -> BoltActionT m [Record])
-> Record -> BoltActionT m [Record]
forall a b. (a -> b) -> a -> b
$ [(Text, Value)] -> Record
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(Text, Value)]
params
instance (IsValue typ, QueryWithParams rest m fun)
=> QueryWithParams ('(field, typ) ': rest) m ((SymbolS field, typ) -> fun)
where
collectParams :: CypherDSL () -> [(Text, Value)] -> (SymbolS field, typ) -> fun
collectParams CypherDSL ()
dsl [(Text, Value)]
params (SymbolS String
s, typ
a) = CypherDSL () -> [(Text, Value)] -> fun
forall (params :: [(Symbol, *)]) (m :: * -> *) fun.
(QueryWithParams params m fun, HasCallStack) =>
CypherDSL () -> [(Text, Value)] -> fun
collectParams @rest @m CypherDSL ()
dsl ((String -> Text
pack String
s, typ -> Value
forall a. IsValue a => a -> Value
toValue typ
a) (Text, Value) -> [(Text, Value)] -> [(Text, Value)]
forall a. a -> [a] -> [a]
: [(Text, Value)]
params)
queryWithParams
:: forall params m fun
. MonadIO m
=> QueryWithParams params m fun
=> HasCallStack
=> CypherDSLParams params ()
-> fun
queryWithParams :: CypherDSLParams params () -> fun
queryWithParams (CypherDSLParams CypherDSL ()
dsl) = CypherDSL () -> [(Text, Value)] -> fun
forall (params :: [(Symbol, *)]) (m :: * -> *) fun.
(QueryWithParams params m fun, HasCallStack) =>
CypherDSL () -> [(Text, Value)] -> fun
collectParams @params @m CypherDSL ()
dsl []