beam-core-0.7.0.0: Database/Beam/Backend/SQL.hs
module Database.Beam.Backend.SQL
( module Database.Beam.Backend.SQL.SQL2003
, module Database.Beam.Backend.SQL.Types
, module Database.Beam.Backend.Types
, MonadBeam(..) ) where
import Database.Beam.Backend.SQL.SQL2003
import Database.Beam.Backend.SQL.Types
import Database.Beam.Backend.Types
import Control.Monad.IO.Class
-- * MonadBeam class
-- | A class that ties together a Sql syntax, backend, handle, and monad type.
--
-- Intuitively, this allows you to write code that performs database commands
-- without having to know the underlying API. As long as you have an
-- appropriate handle from a database library that Beam can use, you can use
-- the 'MonadBeam' methods to execute the query.
--
-- Provided here is a low-level interface. Most often, you'll only need the
-- 'withDatabase' and 'withDatabaseDebug' function. The 'run*' functions are
-- wrapped by the appropriate functions in "Database.Beam.Query".
--
-- This interface is very high-level and isn't meant to expose the full power
-- of the underlying database. Namely, it only supports simple data retrieval
-- strategies. More complicated strategies (for example, Postgres's @COPY@)
-- are supported in individual backends. See the documentation of those
-- backends for more details.
class (BeamBackend be, Monad m, MonadIO m, Sql92SanityCheck syntax) =>
MonadBeam syntax be handle m | m -> syntax be handle where
{-# MINIMAL withDatabaseDebug, runReturningMany #-}
-- | Run a database action, and log debugging information about statements
-- executed using the specified 'IO' action.
withDatabaseDebug :: (String -> IO ()) -- ^ Database statement logging function
-> handle -- ^ The database connection handle against which to execute the action
-> m a -- ^ The database action
-> IO a
withDatabase :: handle -> m a -> IO a
-- | Run a database action, but don't report any debug information
withDatabase = withDatabaseDebug (\_ -> pure ())
-- | Run a query determined by the given syntax, providing an action that will
-- be called to consume the results from the database (if any). The action
-- will get a reader action that can be used to fetch the next row. When
-- this reader action returns 'Nothing', there are no rows left to consume.
-- When the reader action returns, the database result is freed.
runReturningMany :: FromBackendRow be x
=> syntax -- ^ The query to run
-> (m (Maybe x) -> m a) -- ^ Reader action that will be called with a function to fetch the next row
-> m a
-- | Run the given command and don't consume any results. Useful for DML
-- statements like INSERT, UPDATE, and DELETE, or DDL statements.
runNoReturn :: syntax -> m ()
runNoReturn cmd =
runReturningMany cmd $ \(_ :: m (Maybe ())) -> pure ()
-- | Run the given command and fetch the unique result. The result is
-- 'Nothing' if either no results are returned or more than one result is
-- returned.
runReturningOne :: FromBackendRow be x => syntax -> m (Maybe x)
runReturningOne cmd =
runReturningMany cmd $ \next ->
do a <- next
case a of
Nothing -> pure Nothing
Just x -> do
a' <- next
case a' of
Nothing -> pure (Just x)
Just _ -> pure Nothing
-- | Run the given command, collect all the results, and return them as a
-- list. May be more convenient than 'runReturningMany', but reads the entire
-- result set into memory.
runReturningList :: FromBackendRow be x => syntax -> m [x]
runReturningList cmd =
runReturningMany cmd $ \next ->
let collectM acc = do
a <- next
case a of
Nothing -> pure (acc [])
Just x -> collectM (acc . (x:))
in collectM id