{-# LANGUAGE OverloadedStrings #-}
module Hasql.Private.TransactionIO where
import Control.Applicative
import Data.ByteString (ByteString)
import ByteString.TreeBuilder
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Class
import Control.Monad.Error.Class
import Control.Monad.IO.Unlift
import Data.Acquire
import Control.Monad.Trans.Resource
import Hasql.Statement
import Hasql.Session
import qualified Hasql.Session as Session
import Hasql.Private.Session.UnliftIO
import Hasql.Private.Types
import qualified Hasql.Private.Statements as Statements
newtype TransactionIO a = TransactionIO (ReaderT Transaction Session a)
deriving (a -> TransactionIO b -> TransactionIO a
(a -> b) -> TransactionIO a -> TransactionIO b
(forall a b. (a -> b) -> TransactionIO a -> TransactionIO b)
-> (forall a b. a -> TransactionIO b -> TransactionIO a)
-> Functor TransactionIO
forall a b. a -> TransactionIO b -> TransactionIO a
forall a b. (a -> b) -> TransactionIO a -> TransactionIO b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> TransactionIO b -> TransactionIO a
$c<$ :: forall a b. a -> TransactionIO b -> TransactionIO a
fmap :: (a -> b) -> TransactionIO a -> TransactionIO b
$cfmap :: forall a b. (a -> b) -> TransactionIO a -> TransactionIO b
Functor, Functor TransactionIO
a -> TransactionIO a
Functor TransactionIO
-> (forall a. a -> TransactionIO a)
-> (forall a b.
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b)
-> (forall a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c)
-> (forall a b.
TransactionIO a -> TransactionIO b -> TransactionIO b)
-> (forall a b.
TransactionIO a -> TransactionIO b -> TransactionIO a)
-> Applicative TransactionIO
TransactionIO a -> TransactionIO b -> TransactionIO b
TransactionIO a -> TransactionIO b -> TransactionIO a
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
forall a. a -> TransactionIO a
forall a b. TransactionIO a -> TransactionIO b -> TransactionIO a
forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
forall a b.
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
forall a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: TransactionIO a -> TransactionIO b -> TransactionIO a
$c<* :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO a
*> :: TransactionIO a -> TransactionIO b -> TransactionIO b
$c*> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
liftA2 :: (a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
$cliftA2 :: forall a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
<*> :: TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
$c<*> :: forall a b.
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
pure :: a -> TransactionIO a
$cpure :: forall a. a -> TransactionIO a
$cp1Applicative :: Functor TransactionIO
Applicative, Applicative TransactionIO
a -> TransactionIO a
Applicative TransactionIO
-> (forall a b.
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b)
-> (forall a b.
TransactionIO a -> TransactionIO b -> TransactionIO b)
-> (forall a. a -> TransactionIO a)
-> Monad TransactionIO
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
TransactionIO a -> TransactionIO b -> TransactionIO b
forall a. a -> TransactionIO a
forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
forall a b.
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> TransactionIO a
$creturn :: forall a. a -> TransactionIO a
>> :: TransactionIO a -> TransactionIO b -> TransactionIO b
$c>> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
>>= :: TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
$c>>= :: forall a b.
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
$cp1Monad :: Applicative TransactionIO
Monad, Monad TransactionIO
Monad TransactionIO
-> (forall a. IO a -> TransactionIO a) -> MonadIO TransactionIO
IO a -> TransactionIO a
forall a. IO a -> TransactionIO a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: IO a -> TransactionIO a
$cliftIO :: forall a. IO a -> TransactionIO a
$cp1MonadIO :: Monad TransactionIO
MonadIO, MonadError QueryError, MonadIO TransactionIO
MonadIO TransactionIO
-> (forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b)
-> MonadUnliftIO TransactionIO
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
forall (m :: * -> *).
MonadIO m
-> (forall b. ((forall a. m a -> IO a) -> IO b) -> m b)
-> MonadUnliftIO m
withRunInIO :: ((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
$cwithRunInIO :: forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
$cp1MonadUnliftIO :: MonadIO TransactionIO
MonadUnliftIO)
data Transaction = Transaction
instance Semigroup a => Semigroup (TransactionIO a) where
<> :: TransactionIO a -> TransactionIO a -> TransactionIO a
(<>) = (a -> a -> a)
-> TransactionIO a -> TransactionIO a -> TransactionIO a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>)
instance Monoid a => Monoid (TransactionIO a) where
mempty :: TransactionIO a
mempty = a -> TransactionIO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Monoid a => a
mempty
run :: TransactionIO a -> IsolationLevel -> Mode -> Deferrable -> Bool -> Session a
run :: TransactionIO a
-> IsolationLevel -> Mode -> Deferrable -> Bool -> Session a
run (TransactionIO ReaderT Transaction Session a
txio) IsolationLevel
isolation Mode
mode Deferrable
deferrable Bool
preparable = ResourceT Session a -> Session a
forall (m :: * -> *) a. MonadUnliftIO m => ResourceT m a -> m a
runResourceT (ResourceT Session a -> Session a)
-> ResourceT Session a -> Session a
forall a b. (a -> b) -> a -> b
$ do
UnliftIO forall a. Session a -> IO a
runInIO <- Session (UnliftIO Session) -> ResourceT Session (UnliftIO Session)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift Session (UnliftIO Session)
forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO
let acq :: Acquire Transaction
acq = IO Transaction
-> (Transaction -> ReleaseType -> IO ()) -> Acquire Transaction
forall a. IO a -> (a -> ReleaseType -> IO ()) -> Acquire a
mkAcquireType (Session Transaction -> IO Transaction
forall a. Session a -> IO a
runInIO (Session Transaction -> IO Transaction)
-> Session Transaction -> IO Transaction
forall a b. (a -> b) -> a -> b
$ IsolationLevel -> Mode -> Deferrable -> Bool -> Session Transaction
startTransaction IsolationLevel
isolation Mode
mode Deferrable
deferrable Bool
preparable) ((Session () -> IO ()
forall a. Session a -> IO a
runInIO (Session () -> IO ())
-> (ReleaseType -> Session ()) -> ReleaseType -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((ReleaseType -> Session ()) -> ReleaseType -> IO ())
-> (Transaction -> ReleaseType -> Session ())
-> Transaction
-> ReleaseType
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Transaction -> ReleaseType -> Session ()
endTransaction Bool
preparable)
(ReleaseKey
_, Transaction
tx) <- Acquire Transaction -> ResourceT Session (ReleaseKey, Transaction)
forall (m :: * -> *) a.
MonadResource m =>
Acquire a -> m (ReleaseKey, a)
allocateAcquire Acquire Transaction
acq
Session a -> ResourceT Session a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Session a -> ResourceT Session a)
-> Session a -> ResourceT Session a
forall a b. (a -> b) -> a -> b
$ ReaderT Transaction Session a -> Transaction -> Session a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT ReaderT Transaction Session a
txio Transaction
tx
sql :: ByteString -> TransactionIO ()
sql :: ByteString -> TransactionIO ()
sql = ReaderT Transaction Session () -> TransactionIO ()
forall a. ReaderT Transaction Session a -> TransactionIO a
TransactionIO (ReaderT Transaction Session () -> TransactionIO ())
-> (ByteString -> ReaderT Transaction Session ())
-> ByteString
-> TransactionIO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Session () -> ReaderT Transaction Session ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Session () -> ReaderT Transaction Session ())
-> (ByteString -> Session ())
-> ByteString
-> ReaderT Transaction Session ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Session ()
Session.sql
statement :: params -> Statement params result -> TransactionIO result
statement :: params -> Statement params result -> TransactionIO result
statement params
params Statement params result
stmt = ReaderT Transaction Session result -> TransactionIO result
forall a. ReaderT Transaction Session a -> TransactionIO a
TransactionIO (ReaderT Transaction Session result -> TransactionIO result)
-> (Session result -> ReaderT Transaction Session result)
-> Session result
-> TransactionIO result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Session result -> ReaderT Transaction Session result
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Session result -> TransactionIO result)
-> Session result -> TransactionIO result
forall a b. (a -> b) -> a -> b
$ params -> Statement params result -> Session result
forall params result.
params -> Statement params result -> Session result
Session.statement params
params Statement params result
stmt
startTransaction :: IsolationLevel -> Mode -> Deferrable -> Bool -> Session Transaction
startTransaction :: IsolationLevel -> Mode -> Deferrable -> Bool -> Session Transaction
startTransaction IsolationLevel
isolation Mode
mode Deferrable
deferrable Bool
prepare = do
() -> Statement () () -> Session ()
forall params result.
params -> Statement params result -> Session result
Session.statement () (IsolationLevel -> Mode -> Deferrable -> Bool -> Statement () ()
Statements.startTransaction IsolationLevel
isolation Mode
mode Deferrable
deferrable Bool
prepare)
Transaction -> Session Transaction
forall (f :: * -> *) a. Applicative f => a -> f a
pure Transaction
Transaction
endTransaction :: Bool -> Transaction -> ReleaseType -> Session ()
endTransaction :: Bool -> Transaction -> ReleaseType -> Session ()
endTransaction Bool
prepare Transaction
tx = \case
ReleaseType
ReleaseEarly -> Bool -> Transaction -> Session ()
commitTransaction Bool
prepare Transaction
tx
ReleaseType
ReleaseNormal -> Bool -> Transaction -> Session ()
commitTransaction Bool
prepare Transaction
tx
ReleaseType
ReleaseException -> Bool -> Transaction -> Session ()
rollbackTransaction Bool
prepare Transaction
tx
commitTransaction :: Bool -> Transaction -> Session ()
commitTransaction :: Bool -> Transaction -> Session ()
commitTransaction Bool
prepare Transaction
Transaction = do
() -> Statement () () -> Session ()
forall params result.
params -> Statement params result -> Session result
Session.statement () (Bool -> Statement () ()
Statements.commitTransaction Bool
prepare)
rollbackTransaction :: Bool -> Transaction -> Session ()
rollbackTransaction :: Bool -> Transaction -> Session ()
rollbackTransaction Bool
prepare Transaction
Transaction = do
() -> Statement () () -> Session ()
forall params result.
params -> Statement params result -> Session result
Session.statement () (Bool -> Statement () ()
Statements.rollbackTransaction Bool
prepare)