module Database.PostgreSQL.Transaction
( PGTransactionT
, PGTransaction
, runPGTransactionT
, runPGTransactionT'
, runPGTransactionIO
, query
, query_
, execute
, executeOne
, executeMany
, returning
, queryHead
, queryOnly
, formatQuery
) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif
import Control.Monad.Reader
import Control.Monad.Trans.Control
import Data.Int
import qualified Database.PostgreSQL.Simple as Postgres
import Database.PostgreSQL.Simple.FromField
import Database.PostgreSQL.Simple.FromRow
import Database.PostgreSQL.Simple.ToRow
import qualified Database.PostgreSQL.Simple.Transaction as Postgres.Transaction
import qualified Database.PostgreSQL.Simple.Types as PGTypes
newtype PGTransactionT m a =
PGTransactionT (ReaderT Postgres.Connection m a)
deriving ( Functor
, Applicative
, Monad
, MonadTrans
, MonadReader Postgres.Connection
, MonadIO
)
type PGTransaction = PGTransactionT IO
runPGTransactionT' :: MonadBaseControl IO m
=> Postgres.Transaction.IsolationLevel
-> PGTransactionT m a
-> Postgres.Connection
-> m a
runPGTransactionT' isolation (PGTransactionT pgTrans) conn =
let runTransaction run =
Postgres.Transaction.withTransactionLevel isolation conn (run pgTrans)
in control runTransaction `runReaderT` conn
runPGTransactionT :: MonadBaseControl IO m
=> PGTransactionT m a
-> Postgres.Connection
-> m a
runPGTransactionT = runPGTransactionT' Postgres.Transaction.DefaultIsolationLevel
runPGTransactionIO :: MonadIO m
=> PGTransaction a
-> Postgres.Connection
-> m a
runPGTransactionIO = (liftIO .) . runPGTransactionT
query :: (ToRow input, FromRow output, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m [output]
query params q = ask >>= (\conn -> liftIO $ Postgres.query conn q params)
query_ :: (FromRow output, MonadIO m)
=> Postgres.Query
-> PGTransactionT m [output]
query_ q = ask >>= liftIO . (`Postgres.query_` q)
execute :: (ToRow input, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m Int64
execute params q = ask >>= (\conn -> liftIO $ Postgres.execute conn q params)
executeMany :: (ToRow input, MonadIO m)
=> [input]
-> Postgres.Query
-> PGTransactionT m Int64
executeMany params q = ask >>= (\conn -> liftIO $ Postgres.executeMany conn q params)
returning :: (ToRow input, FromRow output, MonadIO m)
=> [input]
-> Postgres.Query
-> PGTransactionT m [output]
returning params q = ask >>= (\conn -> liftIO $ Postgres.returning conn q params)
queryHead :: (ToRow input, FromRow output, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m (Maybe output)
queryHead params q = do
results <- query params q
return $ case results of
(a:_) -> Just a
_ -> Nothing
executeOne :: (ToRow input, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m Bool
executeOne params q = (== 1) <$> execute params q
queryOnly :: (ToRow input, FromField f, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m (Maybe f)
queryOnly params q = fmap Postgres.fromOnly <$> queryHead params q
formatQuery :: (ToRow input, MonadIO m)
=> input
-> Postgres.Query
-> PGTransactionT m Postgres.Query
formatQuery params q = do
conn <- ask
liftIO (PGTypes.Query <$> Postgres.formatQuery conn q params)