hasql/library/Hasql/Private/Query.hs

62 lines
1.9 KiB
Haskell
Raw Normal View History

2015-12-21 16:11:14 +03:00
module Hasql.Private.Query
where
import Hasql.Prelude
import qualified Database.PostgreSQL.LibPQ as LibPQ
import qualified Hasql.Private.IO as IO
2015-12-21 16:45:10 +03:00
import qualified Hasql.Private.Connection as Connection
2015-12-21 16:11:14 +03:00
import qualified Hasql.Decoders.Results as Decoders.Results
import qualified Hasql.Encoders.Params as Encoders.Params
-- |
-- An abstraction over parametric queries.
--
-- It is composable using
-- the standard interfaces of the category theory,
-- which it has instances of.
-- E.g., here's how you can compose queries
-- using the Arrow notation:
--
-- @
-- -- |
-- -- Given an Update query,
-- -- which uses the \@fmap (> 0) 'Decoders.Results.rowsAffected'\@ decoder
-- -- to detect, whether it had any effect,
-- -- and an Insert query,
-- -- produces a query which performs Upsert.
-- composeUpsert :: Query a Bool -> Query a () -> Query a ()
-- composeUpsert update insert =
-- proc params -> do
-- updated <- update -< params
-- if updated
-- then 'returnA' -< ()
-- else insert -< params
-- @
newtype Query a b =
2015-12-21 16:45:10 +03:00
Query (Kleisli (ReaderT Connection.Connection (EitherT Decoders.Results.Error IO)) a b)
2015-12-21 16:11:14 +03:00
deriving (Category, Arrow, ArrowChoice, ArrowLoop, ArrowApply)
instance Functor (Query a) where
{-# INLINE fmap #-}
fmap =
(^<<)
instance Profunctor Query where
{-# INLINE lmap #-}
lmap =
(^>>)
{-# INLINE rmap #-}
rmap =
(^<<)
statement :: ByteString -> Encoders.Params.Params a -> Decoders.Results.Results b -> Bool -> Query a b
statement template encoder decoder preparable =
2016-01-06 09:39:14 +03:00
Query $ Kleisli $ \params ->
ReaderT $ \(Connection.Connection pqConnectionRef integerDatetimes registry) ->
2016-01-24 19:52:53 +03:00
EitherT $ withMVar pqConnectionRef $ \pqConnection -> do
r1 <- IO.sendParametricQuery pqConnection integerDatetimes registry template encoder preparable params
r2 <- IO.getResults pqConnection integerDatetimes decoder
return $ r1 *> r2
2015-12-21 16:11:14 +03:00