hpqtypes-1.13.0.0: src/Database/PostgreSQL/PQTypes/Class.hs
module Database.PostgreSQL.PQTypes.Class
( -- * Class
MonadDB (..)
-- * Misc
, BackendPid (..)
, QueryName (..)
) where
import Control.Monad.Trans
import Control.Monad.Trans.Control
import GHC.Stack
import Database.PostgreSQL.PQTypes.FromRow
import Database.PostgreSQL.PQTypes.Internal.BackendPid
import Database.PostgreSQL.PQTypes.Internal.Connection
import Database.PostgreSQL.PQTypes.Internal.Notification
import Database.PostgreSQL.PQTypes.Internal.QueryResult
import Database.PostgreSQL.PQTypes.SQL.Class
import Database.PostgreSQL.PQTypes.Transaction.Settings
class (Applicative m, Monad m) => MonadDB m where
-- | Run SQL query and return number of affected/returned rows. Note that
-- for a given connection, only one thread may be executing 'runQuery' at
-- a given time. If simultaneous call is made from another thread, it
-- will block until currently running 'runQuery' finishes.
runQuery :: (HasCallStack, IsSQL sql) => sql -> m Int
-- | Similar to 'runQuery', but it prepares and executes a statement under a
-- given name.
runPreparedQuery :: (HasCallStack, IsSQL sql) => QueryName -> sql -> m Int
-- | Get last SQL query that was executed and ID of the server process
-- attached to the session that executed it.
getLastQuery :: m (BackendPid, SomeSQL)
-- | Subsequent queries in the callback do not alter the result of
-- 'getLastQuery'.
withFrozenLastQuery :: m a -> m a
-- | Get current connection statistics.
getConnectionStats :: m ConnectionStats
-- | Get current query result.
getQueryResult :: FromRow row => m (Maybe (QueryResult row))
-- | Clear current query result.
clearQueryResult :: m ()
-- | Get current connection acquisition mode.
getConnectionAcquisitionMode :: HasCallStack => m ConnectionAcquisitionMode
-- | Acquire and hold a connection with a given isolation level and
-- permissions.
--
-- If the connection is already held, a check is performed if the isolation
-- level and permissions are the same as the ones currently in place. If so,
-- nothing happens, otherwise an error is thrown.
acquireAndHoldConnection :: HasCallStack => IsolationLevel -> Permissions -> m ()
-- | Unsafely switch to the 'AcquireOnDemand' mode.
--
-- This function is unsafe because if a connection is already held, the
-- transaction in progress is commited, so atomicity guarantee is lost.
unsafeAcquireOnDemandConnection :: HasCallStack => m ()
-- | Attempt to receive a notification from the server. This
-- function waits until a notification arrives or specified
-- number of microseconds has passed. If a negative number
-- of microseconds is passed as an argument, it will wait
-- indefinitely. In addition, there are a couple of things
-- to be aware of:
--
-- * A lock on the underlying database connection is acquired
-- for the duration of the function.
--
-- * Notifications can be received only between transactions
-- (see <http://www.postgresql.org/docs/current/static/sql-notify.html>
-- for further info), therefore calling this function within
-- a transaction block will return 'Just' only if notifications
-- were received before the transaction began.
getNotification :: HasCallStack => Int -> m (Maybe Notification)
-- | Execute supplied monadic action with new connection
-- using current connection source and transaction settings.
--
-- Particularly useful when you want to spawn a new thread, but
-- do not want the connection in child thread to be shared with
-- the parent one.
withNewConnection :: HasCallStack => m a -> m a
-- | Generic, overlappable instance.
instance
{-# OVERLAPPABLE #-}
( Applicative (t m)
, Monad (t m)
, MonadTrans t
, MonadTransControl t
, MonadDB m
)
=> MonadDB (t m)
where
runQuery = withFrozenCallStack $ lift . runQuery
runPreparedQuery name = withFrozenCallStack $ lift . runPreparedQuery name
getLastQuery = lift getLastQuery
withFrozenLastQuery m = controlT $ \run -> withFrozenLastQuery (run m)
getConnectionStats = lift getConnectionStats
getQueryResult = lift getQueryResult
clearQueryResult = lift clearQueryResult
getConnectionAcquisitionMode = lift getConnectionAcquisitionMode
acquireAndHoldConnection isoLevel = lift . acquireAndHoldConnection isoLevel
unsafeAcquireOnDemandConnection = lift unsafeAcquireOnDemandConnection
getNotification = lift . getNotification
withNewConnection m = controlT $ \run -> withNewConnection (run m)