{-# LANGUAGE OverloadedStrings #-}
module Hasql.Private.TransactionIO where
import Control.Applicative
import Data.ByteString (ByteString)
import ByteString.TreeBuilder
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Control.Monad.Error.Class
import Control.Monad.IO.Unlift
import Control.Exception.Safe
import Control.Monad.Trans.Resource
import Data.Acquire
import Hasql.Session
import qualified Hasql.Session as Session
import Hasql.Statement
import Hasql.Private.Session.MonadThrow
import Hasql.Private.Session.UnliftIO
import qualified Hasql.Private.Statements as Statements
import Hasql.Private.Types
newtype TransactionIO a = TransactionIO (ReaderT Transaction Session a)
deriving ((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
$cfmap :: forall a b. (a -> b) -> TransactionIO a -> TransactionIO b
fmap :: forall a b. (a -> b) -> TransactionIO a -> TransactionIO b
$c<$ :: forall a b. a -> TransactionIO b -> TransactionIO a
<$ :: forall a b. a -> TransactionIO b -> TransactionIO a
Functor, Functor TransactionIO
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
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
$cpure :: forall a. a -> TransactionIO a
pure :: forall a. a -> TransactionIO a
$c<*> :: forall a b.
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
<*> :: forall a b.
TransactionIO (a -> b) -> TransactionIO a -> TransactionIO b
$cliftA2 :: forall a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
liftA2 :: forall a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
$c*> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
*> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
$c<* :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO a
<* :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO a
Applicative, Applicative TransactionIO
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
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
$c>>= :: forall a b.
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
>>= :: forall a b.
TransactionIO a -> (a -> TransactionIO b) -> TransactionIO b
$c>> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
>> :: forall a b. TransactionIO a -> TransactionIO b -> TransactionIO b
$creturn :: forall a. a -> TransactionIO a
return :: forall a. a -> TransactionIO a
Monad, Monad TransactionIO
Monad TransactionIO =>
(forall a. IO a -> TransactionIO a) -> MonadIO TransactionIO
forall a. IO a -> TransactionIO a
forall (m :: * -> *).
Monad m =>
(forall a. IO a -> m a) -> MonadIO m
$cliftIO :: forall a. IO a -> TransactionIO a
liftIO :: forall a. IO a -> TransactionIO a
MonadIO, MonadError SessionError, MonadIO TransactionIO
MonadIO TransactionIO =>
(forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b)
-> MonadUnliftIO TransactionIO
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
$cwithRunInIO :: forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
withRunInIO :: forall b.
((forall a. TransactionIO a -> IO a) -> IO b) -> TransactionIO b
MonadUnliftIO, Monad TransactionIO
Monad TransactionIO =>
(forall e a. (HasCallStack, Exception e) => e -> TransactionIO a)
-> MonadThrow TransactionIO
forall e a. (HasCallStack, Exception e) => e -> TransactionIO a
forall (m :: * -> *).
Monad m =>
(forall e a. (HasCallStack, Exception e) => e -> m a)
-> MonadThrow m
$cthrowM :: forall e a. (HasCallStack, Exception e) => e -> TransactionIO a
throwM :: forall e a. (HasCallStack, Exception e) => e -> TransactionIO a
MonadThrow)
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 a b c.
(a -> b -> c)
-> TransactionIO a -> TransactionIO b -> TransactionIO c
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 a. 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 :: forall a.
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 (m :: * -> *) a. Monad m => m a -> ResourceT m a
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 (m :: * -> *) a. Monad m => m a -> ResourceT m 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 (m :: * -> *) a. Monad m => m a -> ReaderT Transaction m a
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 :: forall params result.
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 (m :: * -> *) a. Monad m => m a -> ReaderT Transaction m a
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 a. a -> Session a
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)
data CondemnTransactionException = CondemnTransactionException
deriving (Int -> CondemnTransactionException -> ShowS
[CondemnTransactionException] -> ShowS
CondemnTransactionException -> String
(Int -> CondemnTransactionException -> ShowS)
-> (CondemnTransactionException -> String)
-> ([CondemnTransactionException] -> ShowS)
-> Show CondemnTransactionException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CondemnTransactionException -> ShowS
showsPrec :: Int -> CondemnTransactionException -> ShowS
$cshow :: CondemnTransactionException -> String
show :: CondemnTransactionException -> String
$cshowList :: [CondemnTransactionException] -> ShowS
showList :: [CondemnTransactionException] -> ShowS
Show)
instance Exception CondemnTransactionException
condemn :: TransactionIO a
condemn :: forall a. TransactionIO a
condemn = CondemnTransactionException -> TransactionIO a
forall (m :: * -> *) e a.
(HasCallStack, MonadThrow m, Exception e) =>
e -> m a
throwIO CondemnTransactionException
CondemnTransactionException