persistent-mtl-0.4.0.0: Monad transformer for the persistent API
Safe HaskellNone
LanguageHaskell2010

Database.Persist.Monad

Description

Defines the SqlQueryT monad transformer, which has a MonadSqlQuery instance to execute persistent database operations. Also provides easy transaction management with withTransaction, which supports retrying with exponential backoff and restricts IO actions to only allow IO actions explicitly marked as rerunnable.

Usage:

myFunction :: (MonadSqlQuery m, MonadIO m) => m ()
myFunction = do
  insert_ $ Person { name = "Alice", age = Just 25 }
  insert_ $ Person { name = "Bob", age = Nothing }

  -- some other business logic

  personList <- selectList [] []
  liftIO $ print (personList :: [Person])

  -- everything in here will run in a transaction
  withTransaction $ do
    selectFirst [PersonAge >. 30] [] >>= \case
      Nothing -> insert_ $ Person { name = "Claire", age = Just 50 }
      Just (Entity key person) -> replace key person{ age = Just (age person - 10) }

    -- liftIO doesn't work in here, since transactions can be retried.
    -- Use rerunnableIO to run IO actions, after verifying that the IO action
    -- can be rerun if the transaction needs to be retried.
    rerunnableIO $ putStrLn "Transaction is finished!"

  -- some more business logic

  return ()
Synopsis

Type class for executing database queries

class (Monad m, MonadSqlQuery (TransactionM m)) => MonadSqlQuery m Source #

The type-class for monads that can run persistent database queries.

Minimal complete definition

runQueryRep, withTransaction

Instances

Instances details
MonadSqlQuery m => MonadSqlQuery (MaybeT m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (MaybeT m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> MaybeT m a Source #

withTransaction :: TransactionM (MaybeT m) a -> MaybeT m a Source #

MonadUnliftIO m => MonadSqlQuery (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Associated Types

type TransactionM (SqlQueryT m) :: Type -> Type Source #

(MonadSqlQuery m, MonadUnliftIO m) => MonadSqlQuery (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Associated Types

type TransactionM (SqlTransaction m) :: Type -> Type Source #

MonadIO m => MonadSqlQuery (MockSqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad.TestUtils

Associated Types

type TransactionM (MockSqlQueryT m) :: Type -> Type Source #

MonadSqlQuery m => MonadSqlQuery (IdentityT m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (IdentityT m) :: Type -> Type Source #

(Monoid w, MonadSqlQuery m) => MonadSqlQuery (WriterT w m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (WriterT w m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> WriterT w m a Source #

withTransaction :: TransactionM (WriterT w m) a -> WriterT w m a Source #

(Monoid w, MonadSqlQuery m) => MonadSqlQuery (WriterT w m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (WriterT w m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> WriterT w m a Source #

withTransaction :: TransactionM (WriterT w m) a -> WriterT w m a Source #

MonadSqlQuery m => MonadSqlQuery (StateT s m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (StateT s m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> StateT s m a Source #

withTransaction :: TransactionM (StateT s m) a -> StateT s m a Source #

MonadSqlQuery m => MonadSqlQuery (StateT s m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (StateT s m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> StateT s m a Source #

withTransaction :: TransactionM (StateT s m) a -> StateT s m a Source #

MonadSqlQuery m => MonadSqlQuery (ReaderT r m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (ReaderT r m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> ReaderT r m a Source #

withTransaction :: TransactionM (ReaderT r m) a -> ReaderT r m a Source #

MonadSqlQuery m => MonadSqlQuery (ExceptT e m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (ExceptT e m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> ExceptT e m a Source #

withTransaction :: TransactionM (ExceptT e m) a -> ExceptT e m a Source #

(Monoid w, MonadSqlQuery m) => MonadSqlQuery (RWST r w s m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (RWST r w s m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> RWST r w s m a Source #

withTransaction :: TransactionM (RWST r w s m) a -> RWST r w s m a Source #

(Monoid w, MonadSqlQuery m) => MonadSqlQuery (RWST r w s m) Source # 
Instance details

Defined in Database.Persist.Monad.Class

Associated Types

type TransactionM (RWST r w s m) :: Type -> Type Source #

Methods

runQueryRep :: Typeable record => SqlQueryRep record a -> RWST r w s m a Source #

withTransaction :: TransactionM (RWST r w s m) a -> RWST r w s m a Source #

withTransaction :: MonadSqlQuery m => TransactionM m a -> m a Source #

Run all queries in the given action using the same database connection.

SqlQueryT monad transformer

data SqlQueryT m a Source #

The monad transformer that implements MonadSqlQuery.

Instances

Instances details
MonadTrans SqlQueryT Source # 
Instance details

Defined in Database.Persist.Monad

Methods

lift :: Monad m => m a -> SqlQueryT m a #

MonadReader r m => MonadReader r (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

ask :: SqlQueryT m r #

local :: (r -> r) -> SqlQueryT m a -> SqlQueryT m a #

reader :: (r -> a) -> SqlQueryT m a #

Monad m => Monad (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

(>>=) :: SqlQueryT m a -> (a -> SqlQueryT m b) -> SqlQueryT m b #

(>>) :: SqlQueryT m a -> SqlQueryT m b -> SqlQueryT m b #

return :: a -> SqlQueryT m a #

Functor m => Functor (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

fmap :: (a -> b) -> SqlQueryT m a -> SqlQueryT m b #

(<$) :: a -> SqlQueryT m b -> SqlQueryT m a #

Applicative m => Applicative (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

pure :: a -> SqlQueryT m a #

(<*>) :: SqlQueryT m (a -> b) -> SqlQueryT m a -> SqlQueryT m b #

liftA2 :: (a -> b -> c) -> SqlQueryT m a -> SqlQueryT m b -> SqlQueryT m c #

(*>) :: SqlQueryT m a -> SqlQueryT m b -> SqlQueryT m b #

(<*) :: SqlQueryT m a -> SqlQueryT m b -> SqlQueryT m a #

MonadIO m => MonadIO (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

liftIO :: IO a -> SqlQueryT m a #

MonadUnliftIO m => MonadUnliftIO (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

withRunInIO :: ((forall a. SqlQueryT m a -> IO a) -> IO b) -> SqlQueryT m b #

MonadResource m => MonadResource (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

liftResourceT :: ResourceT IO a -> SqlQueryT m a #

MonadThrow m => MonadThrow (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

throwM :: Exception e => e -> SqlQueryT m a #

MonadCatch m => MonadCatch (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

catch :: Exception e => SqlQueryT m a -> (e -> SqlQueryT m a) -> SqlQueryT m a #

MonadMask m => MonadMask (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

mask :: ((forall a. SqlQueryT m a -> SqlQueryT m a) -> SqlQueryT m b) -> SqlQueryT m b #

uninterruptibleMask :: ((forall a. SqlQueryT m a -> SqlQueryT m a) -> SqlQueryT m b) -> SqlQueryT m b #

generalBracket :: SqlQueryT m a -> (a -> ExitCase b -> SqlQueryT m c) -> (a -> SqlQueryT m b) -> SqlQueryT m (b, c) #

MonadLogger m => MonadLogger (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

monadLoggerLog :: ToLogStr msg => Loc -> LogSource -> LogLevel -> msg -> SqlQueryT m () #

MonadRerunnableIO m => MonadRerunnableIO (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

rerunnableIO :: IO a -> SqlQueryT m a Source #

MonadUnliftIO m => MonadSqlQuery (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

Associated Types

type TransactionM (SqlQueryT m) :: Type -> Type Source #

type TransactionM (SqlQueryT m) Source # 
Instance details

Defined in Database.Persist.Monad

mapSqlQueryT :: (m a -> n b) -> SqlQueryT m a -> SqlQueryT n b Source #

runSqlQueryT :: Pool SqlBackend -> SqlQueryT m a -> m a Source #

Run the SqlQueryT monad transformer with the given backend.

runSqlQueryTWith :: SqlQueryEnv -> SqlQueryT m a -> m a Source #

Run the SqlQueryT monad transformer with the explicitly provided environment.

data SqlQueryEnv Source #

Environment to configure running SqlQueryT.

For simple usage, you can just use runSqlQueryT, but for more advanced usage, including the ability to retry transactions, use mkSqlQueryEnv with runSqlQueryTWith.

Constructors

SqlQueryEnv 

Fields

  • backendPool :: Pool SqlBackend

    The pool for your persistent backend. Get this from withSqlitePool or the equivalent for your backend.

  • retryIf :: SomeException -> Bool

    Retry a transaction when an exception matches this predicate. Will retry with an exponential backoff.

    Defaults to always returning False (i.e. never retry)

  • retryLimit :: Int

    The number of times to retry, if retryIf is satisfied.

    Defaults to 10.

mkSqlQueryEnv :: Pool SqlBackend -> (SqlQueryEnv -> SqlQueryEnv) -> SqlQueryEnv Source #

Build a SqlQueryEnv from the default.

Usage:

let env = mkSqlQueryEnv pool $ \env -> env { retryIf = 10 }
in runSqlQueryTWith env m

Transactions

data SqlTransaction m a Source #

The monad that tracks transaction state.

Conceptually equivalent to SqlPersistT, but restricts IO operations, for two reasons: 1. Forking a thread that uses the same SqlBackend as the current thread causes Bad Things to happen. 2. Transactions may need to be retried, in which case IO operations in a transaction are required to be rerunnable.

You shouldn't need to explicitly use this type; your functions should only declare the MonadSqlQuery constraint.

Instances

Instances details
Monad m => Monad (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

(>>=) :: SqlTransaction m a -> (a -> SqlTransaction m b) -> SqlTransaction m b #

(>>) :: SqlTransaction m a -> SqlTransaction m b -> SqlTransaction m b #

return :: a -> SqlTransaction m a #

Functor m => Functor (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

fmap :: (a -> b) -> SqlTransaction m a -> SqlTransaction m b #

(<$) :: a -> SqlTransaction m b -> SqlTransaction m a #

Applicative m => Applicative (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

pure :: a -> SqlTransaction m a #

(<*>) :: SqlTransaction m (a -> b) -> SqlTransaction m a -> SqlTransaction m b #

liftA2 :: (a -> b -> c) -> SqlTransaction m a -> SqlTransaction m b -> SqlTransaction m c #

(*>) :: SqlTransaction m a -> SqlTransaction m b -> SqlTransaction m b #

(<*) :: SqlTransaction m a -> SqlTransaction m b -> SqlTransaction m a #

(TypeError ('Text "Cannot run arbitrary IO actions within a transaction. If the IO action is rerunnable, use rerunnableIO") :: Constraint, Monad m) => MonadIO (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Methods

liftIO :: IO a -> SqlTransaction m a #

MonadRerunnableIO m => MonadRerunnableIO (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

(MonadSqlQuery m, MonadUnliftIO m) => MonadSqlQuery (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

Associated Types

type TransactionM (SqlTransaction m) :: Type -> Type Source #

type TransactionM (SqlTransaction m) Source # 
Instance details

Defined in Database.Persist.Monad

rerunnableLift :: MonadUnliftIO m => m a -> SqlTransaction m a Source #

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.

data TransactionError Source #

Errors that can occur within a SQL transaction.

Constructors

RetryLimitExceeded

The retry limit was reached when retrying a transaction.

Lifted functions