module Hasql.Transaction.Sessions
where
import Hasql.Transaction.Prelude
import Hasql.Transaction.Types
import Hasql.Session
import qualified Hasql.Transaction.Statements as Statements
inAlternatingTransaction :: Mode -> Level -> [Session (a, Condemnation)] -> Session a
inAlternatingTransaction mode level =
let
loop = \ case
session : sessionsTail -> tryTransaction mode level session >>= \ case
Just a -> return a
Nothing -> loop sessionsTail
_ -> error "Attempt to run no alternatives"
in loop
tryTransaction :: Mode -> Level -> Session (a, Condemnation) -> Session (Maybe a)
tryTransaction mode level session = do
statement () (Statements.beginTransaction mode level)
catchError
(do
(result, condemnation) <- session
case condemnation of
Uncondemned -> statement () Statements.commitTransaction
Condemned -> statement () Statements.abortTransaction
return (Just result))
(\ error -> do
statement () Statements.abortTransaction
case error of
QueryError _ _ (ResultError (ServerError "40001" _ _ _)) -> return Nothing
error -> throwError error)