persistent-mtl 0.2.0.0 → 0.2.1.0
raw patch · 3 files changed
+20/−7 lines, 3 filesdep +unliftio-pooldep −resourcet-poolPVP ok
version bump matches the API change (PVP)
Dependencies added: unliftio-pool
Dependencies removed: resourcet-pool
API changes (from Hackage documentation)
+ Database.Persist.Monad: rerunnableLift :: MonadUnliftIO m => m a -> SqlTransaction m a
Files
- CHANGELOG.md +7/−0
- persistent-mtl.cabal +3/−3
- src/Database/Persist/Monad.hs +10/−4
CHANGELOG.md view
@@ -1,3 +1,10 @@+# Unreleased++# 0.2.1.0++* Add `rerunnableLift` for `SqlTransaction`+* Use `unliftio-pool` instead of `resourcet-pool`, which has better async exeception safety+ # 0.2.0.0 * Use a separate monad within `withTransaction` to prevent unsafe/arbitrary IO actions ([#7](https://github.com/brandonchinn178/persistent-mtl/issues/7), [#28](https://github.com/brandonchinn178/persistent-mtl/issues/28))
persistent-mtl.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 9c53e0610dea4ca814133d0596978b961b85fd54cb6df7a82eccb6d260824dde+-- hash: 1c982d6beda7cf991f9c302b1cbcb030441f7956de96f1d4080e3776fb192b33 name: persistent-mtl-version: 0.2.0.0+version: 0.2.1.0 synopsis: Monad transformer for the persistent API description: A monad transformer and mtl-style type class for using the persistent API directly in your monad transformer stack.@@ -51,11 +51,11 @@ , persistent >=2.8.2 && <3 , resource-pool >=0.2.3.2 && <0.3 , resourcet >=1.2.1 && <2- , resourcet-pool >=0.1.0.0 && <0.2 , text >=1.2.3.0 && <2 , transformers >=0.5.2.0 && <0.6 , unliftio >=0.2.7.0 && <0.3 , unliftio-core >=0.1.2.0 && <0.3+ , unliftio-pool >=0.2.0.0 && <0.3 default-language: Haskell2010 test-suite persistent-mtl-test
src/Database/Persist/Monad.hs view
@@ -62,6 +62,7 @@ -- * Transactions , SqlTransaction+ , rerunnableLift , TransactionError(..) -- * Lifted functions@@ -73,15 +74,14 @@ import Control.Monad.Reader (ReaderT, ask, runReaderT) import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad.Trans.Resource (MonadResource)-import Data.Acquire (withAcquire) import Data.Pool (Pool)-import Data.Pool.Acquire (poolToAcquire) import Database.Persist.Sql (SqlBackend, SqlPersistT, runSqlConn) import qualified GHC.TypeLits as GHC import UnliftIO.Concurrent (threadDelay) import UnliftIO.Exception (Exception, SomeException, catchJust, throwIO)+import UnliftIO.Pool (withResource) -import Control.Monad.IO.Rerunnable (MonadRerunnableIO)+import Control.Monad.IO.Rerunnable (MonadRerunnableIO, rerunnableIO) import Database.Persist.Monad.Class import Database.Persist.Monad.Shim import Database.Persist.Monad.SqlQueryRep@@ -123,6 +123,12 @@ runSqlTransaction :: MonadUnliftIO m => SqlBackend -> SqlTransaction m a -> m a runSqlTransaction conn = (`runSqlConn` conn) . unSqlTransaction +-- | 'SqlTransaction' does not have an instance for 'MonadTrans' to prevent+-- accidental lifting of unsafe monadic actions. Use this function to explicitly+-- mark a monadic action as rerunnable.+rerunnableLift :: MonadUnliftIO m => m a -> SqlTransaction m a+rerunnableLift m = SqlTransaction $ lift $ withRunInIO $ \runInIO -> rerunnableIO $ runInIO m+ -- | Errors that can occur within a SQL transaction. data TransactionError = RetryLimitExceeded@@ -192,7 +198,7 @@ -- Start a new transaction and run the given 'SqlTransaction' withTransaction m = do SqlQueryEnv{..} <- SqlQueryT ask- withAcquire (poolToAcquire backendPool) $ \conn ->+ withResource backendPool $ \conn -> let filterRetry e = if retryIf e then Just e else Nothing loop i = catchJust filterRetry (runSqlTransaction conn m) $ \_ -> if i < retryLimit