postgresql-tx-simple 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+153/−32 lines, 5 filesdep +bytestringdep ~postgresql-txnew-uploader
Dependencies added: bytestring
Dependency ranges changed: postgresql-tx
Files
- CHANGELOG.md +8/−1
- package.yaml +4/−3
- postgresql-tx-simple.cabal +6/−5
- src/Database/PostgreSQL/Tx/Simple.hs +71/−23
- src/Database/PostgreSQL/Tx/Simple/Internal.hs +64/−0
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Change log +## 0.2.0.0++* Updated for postgresql-tx-0.2.0.0.+* Added `HasCallStack` constraints in transaction runners.+* Added more transaction runners: `withTransactionMode`, `withTransactionModeRetry`, `withTransactionSerializable`.+* Moved internals to an `Internal` module.+ ## 0.1.0.0 -Initial release+* Initial release
package.yaml view
@@ -1,6 +1,6 @@ name: postgresql-tx-simple-version: 0.1.0.0-github: "simspace/postgresql-tx/simple"+version: 0.2.0.0+github: "simspace/postgresql-tx" license: BSD3 license-file: LICENSE.md author: "Cary Robbins"@@ -20,8 +20,9 @@ dependencies: - base >= 4.7 && < 5+- bytestring >= 0.10.10.0 && < 0.11 - postgresql-simple >= 0.6.2 && < 0.7-- postgresql-tx >= 0.1.0.0 && < 0.2+- postgresql-tx >= 0.2.0.0 && < 0.3 - transformers >= 0.5.6.2 && < 0.6 library:
postgresql-tx-simple.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.31.2. -- -- see: https://github.com/sol/hpack ----- hash: c49c4584915e0a9050d6fb99053fd27a445d8a627a7797f743efae7b38b42d34+-- hash: a28e2079196694ad2a65da28273d761629b586f6af9c436a58761fccd48ba274 name: postgresql-tx-simple-version: 0.1.0.0+version: 0.2.0.0 synopsis: postgresql-tx interfacing for use with postgresql-simple. description: Please see the README on GitHub at <https://github.com/simspace/postgresql-tx#readme> category: Database@@ -27,11 +27,11 @@ source-repository head type: git location: https://github.com/simspace/postgresql-tx- subdir: simple library exposed-modules: Database.PostgreSQL.Tx.Simple+ Database.PostgreSQL.Tx.Simple.Internal other-modules: Paths_postgresql_tx_simple hs-source-dirs:@@ -39,7 +39,8 @@ ghc-options: -Wall build-depends: base >=4.7 && <5+ , bytestring >=0.10.10.0 && <0.11 , postgresql-simple >=0.6.2 && <0.7- , postgresql-tx >=0.1.0.0 && <0.2+ , postgresql-tx >=0.2.0.0 && <0.3 , transformers >=0.5.6.2 && <0.6 default-language: Haskell2010
src/Database/PostgreSQL/Tx/Simple.hs view
@@ -1,42 +1,90 @@-{-# LANGUAGE BlockArguments #-}-module Database.PostgreSQL.Tx.Simple where+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+module Database.PostgreSQL.Tx.Simple+ ( PgSimpleEnv+ , PgSimpleM+ , module Database.PostgreSQL.Tx.Simple+ ) where -import Control.Monad.Trans.Reader (ReaderT)+import Control.Exception (Exception) import Data.Int (Int64)-import Database.PostgreSQL.Tx (TxM, unsafeRunTxM, unsafeReaderIOTx)+import Database.PostgreSQL.Tx (TxM, shouldRetryTx)+import Database.PostgreSQL.Tx.Simple.Internal+import GHC.Stack (HasCallStack) import qualified Database.PostgreSQL.Simple as Simple import qualified Database.PostgreSQL.Simple.Transaction as Simple -type PgSimpleM = ReaderT Simple.Connection TxM+-- | Analogue of 'Simple.withTransaction'.+--+-- @since 0.1.0.0+withTransaction+ :: (PgSimpleEnv r, HasCallStack)+ => r -> (HasCallStack => TxM r a) -> IO a+withTransaction = unsafeRunTransaction Simple.withTransaction -withTransaction :: Simple.Connection -> TxM a -> IO a-withTransaction c x = Simple.withTransaction c (unsafeRunTxM x)+-- | Analogue of 'Simple.withTransactionLevel'.+--+-- @since 0.1.0.0+withTransactionLevel+ :: (PgSimpleEnv r, HasCallStack)+ => Simple.IsolationLevel -> r -> (HasCallStack => TxM r a) -> IO a+withTransactionLevel = unsafeRunTransaction . Simple.withTransactionLevel -withTransactionLevel :: Simple.IsolationLevel -> Simple.Connection -> TxM a -> IO a-withTransactionLevel lvl c x = Simple.withTransactionLevel lvl c (unsafeRunTxM x)+-- | Analogue of 'Simple.withTransactionMode'.+--+-- @since 0.2.0.0+withTransactionMode+ :: (PgSimpleEnv r, HasCallStack)+ => Simple.TransactionMode -> r -> (HasCallStack => TxM r a) -> IO a+withTransactionMode = unsafeRunTransaction . Simple.withTransactionMode -unsafeFromPgSimple1- :: (Simple.Connection -> a1 -> IO r)- -> a1 -> PgSimpleM r-unsafeFromPgSimple1 f a1 = unsafeReaderIOTx \c -> f c a1+-- | Analogue of 'Simple.withTransactionSerializable'.+-- Unlike @postgresql-simple@, uses 'shouldRetryTx' to also retry+-- on @deadlock_detected@, not just @serialization_failure@.+--+-- Note that any 'IO' that occurs inside the 'TxM' may be executed multiple times.+--+-- @since 0.2.0.0+withTransactionSerializable+ :: (PgSimpleEnv r, HasCallStack)+ => r -> (HasCallStack => TxM r a) -> IO a+withTransactionSerializable =+ withTransactionModeRetry mode shouldRetryTx+ where+ mode = Simple.TransactionMode Simple.Serializable Simple.ReadWrite -unsafeFromPgSimple2- :: (Simple.Connection -> a1 -> a2 -> IO r)- -> a1 -> a2 -> PgSimpleM r-unsafeFromPgSimple2 f a1 a2 = unsafeReaderIOTx \c -> f c a1 a2+-- | Analogue of 'Simple.withTransactionModeRetry'.+-- You should generally prefer 'withTransactionSerializable'.+--+-- Note that any 'IO' that occurs inside the 'TxM' may be executed multiple times.+--+-- @since 0.2.0.0+withTransactionModeRetry+ :: (Exception e, PgSimpleEnv r, HasCallStack)+ => Simple.TransactionMode -> (e -> Bool) -> r -> (HasCallStack => TxM r a) -> IO a+withTransactionModeRetry mode shouldRetry =+ unsafeRunTransaction $ Simple.withTransactionModeRetry' mode shouldRetry --- | Re-export of 'Simple.query'-query :: (Simple.ToRow q, Simple.FromRow r) => Simple.Query -> q -> PgSimpleM [r]+-- | Analogue of 'Simple.query'+--+-- @since 0.1.0.0+query :: (Simple.ToRow q, Simple.FromRow x) => Simple.Query -> q -> PgSimpleM [x] query = unsafeFromPgSimple2 Simple.query --- | Re-export of 'Simple.query_'-query_ :: (Simple.FromRow r) => Simple.Query -> PgSimpleM [r]+-- | Analogue of 'Simple.query_'.+--+-- @since 0.1.0.0+query_ :: (Simple.FromRow x) => Simple.Query -> PgSimpleM [x] query_ = unsafeFromPgSimple1 Simple.query_ --- | Re-export of 'Simple.execute'+-- | Analogue of 'Simple.execute'.+--+-- @since 0.1.0.0 execute :: (Simple.ToRow q) => Simple.Query -> q -> PgSimpleM Int64 execute = unsafeFromPgSimple2 Simple.execute --- | Re-export of 'Simple.execute_'+-- | Analogue of 'Simple.execute_'.+--+-- @since 0.1.0.0 execute_ :: Simple.Query -> PgSimpleM Int64 execute_ = unsafeFromPgSimple1 Simple.execute_
+ src/Database/PostgreSQL/Tx/Simple/Internal.hs view
@@ -0,0 +1,64 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-}+module Database.PostgreSQL.Tx.Simple.Internal+ ( -- * Disclaimer+ -- $disclaimer++ -- ** Internals+ module Database.PostgreSQL.Tx.Simple.Internal+ ) where++import Data.Kind (Constraint)+import Database.PostgreSQL.Tx (TxEnv, TxException, TxM, askTxEnv, mapExceptionTx)+import Database.PostgreSQL.Tx.Unsafe (unsafeMkTxException, unsafeMksTxM, unsafeRunIOInTxM, unsafeRunTxM)+import qualified Data.ByteString.Char8 as Char8+import qualified Database.PostgreSQL.Simple as Simple++-- | Runtime environment needed to run @postgresql-simple@ via @postgresql-tx@.+--+-- @since 0.2.0.0+type PgSimpleEnv r = (TxEnv Simple.Connection r) :: Constraint++-- | Monad type alias for running @postgresql-simple@ via @postgresql-tx@.+--+-- @since 0.2.0.0+type PgSimpleM a = forall r. (PgSimpleEnv r) => TxM r a++unsafeRunTransaction+ :: (PgSimpleEnv r)+ => (Simple.Connection -> IO a -> IO a)+ -> r -> TxM r a -> IO a+unsafeRunTransaction f r x = do+ unsafeRunTxM r do+ conn <- askTxEnv+ unsafeRunIOInTxM $ f conn (unsafeRunTxM r x)++fromSqlError :: Simple.SqlError -> TxException+fromSqlError = unsafeMkTxException (Just . Char8.unpack . Simple.sqlState)++unsafeFromPgSimple+ :: (Simple.Connection -> IO x)+ -> PgSimpleM x+unsafeFromPgSimple f =+ mapExceptionTx (Just . fromSqlError) do+ unsafeMksTxM f++unsafeFromPgSimple1+ :: (Simple.Connection -> a1 -> IO x)+ -> a1 -> PgSimpleM x+unsafeFromPgSimple1 f a1 = unsafeFromPgSimple \c -> f c a1++unsafeFromPgSimple2+ :: (Simple.Connection -> a1 -> a2 -> IO x)+ -> a1 -> a2 -> PgSimpleM x+unsafeFromPgSimple2 f a1 a2 = unsafeFromPgSimple \c -> f c a1 a2++-- $disclaimer+--+-- Changes to this module will not be reflected in the library's version+-- updates.