{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE UndecidableInstances #-}
-- | Some functionality is useful enough to be provided across backends, but is
-- not standardized. For example, many RDBMS systems provide ways of fetching
-- auto-incrementing or defaulting fields on INSERT or UPDATE.
--
-- Beam provides type classes that some backends instantiate that provide this
-- support. This uses direct means on sufficiently advanced backends and is
-- emulated on others.
module Database.Beam.Backend.SQL.BeamExtensions
  ( MonadBeamInsertReturning(..)
  , runInsertReturningList
  , MonadBeamUpdateReturning(..)
  , runUpdateReturningList
  , MonadBeamDeleteReturning(..)
  , runDeleteReturningList
  , BeamHasInsertOnConflict(..)

  , SqlSerial(..)
  , onConflictUpdateInstead
  , onConflictUpdateAll
  ) where

import           Database.Beam.Backend
import           Database.Beam.Query
import           Database.Beam.Query.Internal
import           Database.Beam.Schema
import           Database.Beam.Schema.Tables

import           Control.Monad.Cont
import           Control.Monad.Except
import           Control.Monad.Identity
import qualified Control.Monad.RWS.Lazy as Lazy
import qualified Control.Monad.RWS.Strict as Strict
import           Control.Monad.Reader
import qualified Control.Monad.State.Lazy as Lazy
import qualified Control.Monad.State.Strict as Strict
import qualified Control.Monad.Writer.Lazy as Lazy
import qualified Control.Monad.Writer.Strict as Strict
import           Data.Functor.Const
import           Data.Kind (Type)
import           Data.Proxy
import           Data.Semigroup

--import GHC.Generics

-- | 'MonadBeam's that support returning data from the newly created rows of an
--   @INSERT@ statement. Useful for discovering the real value of a defaulted
--   field (such as a serial primary key).
class MonadBeam be m =>
  MonadBeamInsertReturning be m | m -> be where
  -- | Execute an @INSERT@ statement and return a list of values projected from
  --   the inserted rows. The projection function selects which columns are
  --   returned: pass 'id' to return the full row, or supply a custom
  --   projection to return a subset.
  runInsertReturningListWith
    :: ( Beamable table
       , Projectible be a
       , FromBackendRow be (QExprToIdentity a) )
    => SqlInsert be table
    -> (table (QExpr be ()) -> a)
    -> m [QExprToIdentity a]

-- | Execute an @INSERT@ statement and return the inserted rows in full.
--   A convenience around 'runInsertReturningListWith' that uses 'id' as the
--   projection.
runInsertReturningList
  :: ( MonadBeamInsertReturning be m
     , Beamable table
     , Projectible be (table (QExpr be ()))
     , FromBackendRow be (table Identity) )
  => SqlInsert be table
  -> m [table Identity]
runInsertReturningList :: forall be (m :: * -> *) (table :: (* -> *) -> *).
(MonadBeamInsertReturning be m, Beamable table,
 Projectible be (table (QExpr be ())),
 FromBackendRow be (table Identity)) =>
SqlInsert be table -> m [table Identity]
runInsertReturningList SqlInsert be table
sql = SqlInsert be table
-> (table (QExpr be ()) -> table (QExpr be ()))
-> m [QExprToIdentity (table (QExpr be ()))]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> table (QExpr be ())
forall a. a -> a
id

instance MonadBeamInsertReturning be m => MonadBeamInsertReturning be (ExceptT e m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> ExceptT e m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamInsertReturning be m => MonadBeamInsertReturning be (ContT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> ContT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ContT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamInsertReturning be m => MonadBeamInsertReturning be (ReaderT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> ReaderT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamInsertReturning be m => MonadBeamInsertReturning be (Lazy.StateT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamInsertReturning be m => MonadBeamInsertReturning be (Strict.StateT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamInsertReturning be m, Monoid r)
    => MonadBeamInsertReturning be (Lazy.WriterT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamInsertReturning be m, Monoid r)
    => MonadBeamInsertReturning be (Strict.WriterT r m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamInsertReturning be m, Monoid w)
    => MonadBeamInsertReturning be (Lazy.RWST r w s m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamInsertReturning be m, Monoid w)
    => MonadBeamInsertReturning be (Strict.RWST r w s m) where
    runInsertReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamInsertReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlInsert be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runInsertReturningListWith SqlInsert be table
sql table (QExpr be ()) -> a
proj

-- | 'MonadBeam's that support returning data from the updated rows of an
--   @UPDATE@ statement. Useful for observing the post-update values of the
--   affected rows.
class MonadBeam be m =>
  MonadBeamUpdateReturning be m | m -> be where
  -- | Execute an @UPDATE@ statement and return a list of values projected from
  --   the updated rows. The projection function selects which columns are
  --   returned: pass 'id' to return the full row, or supply a custom
  --   projection to return a subset.
  runUpdateReturningListWith
    :: ( Beamable table
       , Projectible be a
       , FromBackendRow be (QExprToIdentity a) )
    => SqlUpdate be table
    -> (table (QExpr be ()) -> a)
    -> m [QExprToIdentity a]

-- | Execute an @UPDATE@ statement and return the updated rows in full.
--   A convenience around 'runUpdateReturningListWith' that uses 'id' as the
--   projection.
runUpdateReturningList
  :: ( MonadBeamUpdateReturning be m
     , Beamable table
     , Projectible be (table (QExpr be ()))
     , FromBackendRow be (table Identity) )
  => SqlUpdate be table
  -> m [table Identity]
runUpdateReturningList :: forall be (m :: * -> *) (table :: (* -> *) -> *).
(MonadBeamUpdateReturning be m, Beamable table,
 Projectible be (table (QExpr be ())),
 FromBackendRow be (table Identity)) =>
SqlUpdate be table -> m [table Identity]
runUpdateReturningList SqlUpdate be table
sql = SqlUpdate be table
-> (table (QExpr be ()) -> table (QExpr be ()))
-> m [QExprToIdentity (table (QExpr be ()))]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> table (QExpr be ())
forall a. a -> a
id

instance MonadBeamUpdateReturning be m => MonadBeamUpdateReturning be (ExceptT e m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> ExceptT e m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamUpdateReturning be m => MonadBeamUpdateReturning be (ContT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> ContT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ContT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamUpdateReturning be m => MonadBeamUpdateReturning be (ReaderT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> ReaderT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamUpdateReturning be m => MonadBeamUpdateReturning be (Lazy.StateT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamUpdateReturning be m => MonadBeamUpdateReturning be (Strict.StateT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamUpdateReturning be m, Monoid r)
    => MonadBeamUpdateReturning be (Lazy.WriterT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamUpdateReturning be m, Monoid r)
    => MonadBeamUpdateReturning be (Strict.WriterT r m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamUpdateReturning be m, Monoid w)
    => MonadBeamUpdateReturning be (Lazy.RWST r w s m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamUpdateReturning be m, Monoid w)
    => MonadBeamUpdateReturning be (Strict.RWST r w s m) where
    runUpdateReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamUpdateReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlUpdate be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runUpdateReturningListWith SqlUpdate be table
sql table (QExpr be ()) -> a
proj

-- | 'MonadBeam's that support returning data from rows that will be deleted by
--   the given @DELETE@ statement. Useful for deallocating resources based on
--   the value of deleted rows.
class MonadBeam be m =>
  MonadBeamDeleteReturning be m | m -> be where
  -- | Execute a @DELETE@ statement and return a list of values projected from
  --   the deleted rows. The projection function selects which columns are
  --   returned: pass 'id' to return the full row, or supply a custom
  --   projection to return a subset.
  runDeleteReturningListWith
    :: ( Beamable table
       , Projectible be a
       , FromBackendRow be (QExprToIdentity a) )
    => SqlDelete be table
    -> (table (QExpr be ()) -> a)
    -> m [QExprToIdentity a]

-- | Execute a @DELETE@ statement and return the deleted rows in full.
--   A convenience around 'runDeleteReturningListWith' that uses 'id' as the
--   projection.
runDeleteReturningList
  :: ( MonadBeamDeleteReturning be m
     , Beamable table
     , Projectible be (table (QExpr be ()))
     , FromBackendRow be (table Identity) )
  => SqlDelete be table
  -> m [table Identity]
runDeleteReturningList :: forall be (m :: * -> *) (table :: (* -> *) -> *).
(MonadBeamDeleteReturning be m, Beamable table,
 Projectible be (table (QExpr be ())),
 FromBackendRow be (table Identity)) =>
SqlDelete be table -> m [table Identity]
runDeleteReturningList SqlDelete be table
sql = SqlDelete be table
-> (table (QExpr be ()) -> table (QExpr be ()))
-> m [QExprToIdentity (table (QExpr be ()))]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> table (QExpr be ())
forall a. a -> a
id

instance MonadBeamDeleteReturning be m => MonadBeamDeleteReturning be (ExceptT e m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> ExceptT e m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ExceptT e m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamDeleteReturning be m => MonadBeamDeleteReturning be (ContT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> ContT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ContT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ContT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamDeleteReturning be m => MonadBeamDeleteReturning be (ReaderT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> ReaderT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> ReaderT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamDeleteReturning be m => MonadBeamDeleteReturning be (Lazy.StateT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance MonadBeamDeleteReturning be m => MonadBeamDeleteReturning be (Strict.StateT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> StateT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> StateT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> StateT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> StateT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamDeleteReturning be m, Monoid r)
    => MonadBeamDeleteReturning be (Lazy.WriterT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamDeleteReturning be m, Monoid r)
    => MonadBeamDeleteReturning be (Strict.WriterT r m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> WriterT r m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> WriterT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a])
-> m [QExprToIdentity a] -> WriterT r m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamDeleteReturning be m, Monoid w)
    => MonadBeamDeleteReturning be (Lazy.RWST r w s m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj
instance (MonadBeamDeleteReturning be m, Monoid w)
    => MonadBeamDeleteReturning be (Strict.RWST r w s m) where
    runDeleteReturningListWith :: forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> RWST r w s m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj = m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall (m :: * -> *) a. Monad m => m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a])
-> m [QExprToIdentity a] -> RWST r w s m [QExprToIdentity a]
forall a b. (a -> b) -> a -> b
$ SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall be (m :: * -> *) (table :: (* -> *) -> *) a.
(MonadBeamDeleteReturning be m, Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
forall (table :: (* -> *) -> *) a.
(Beamable table, Projectible be a,
 FromBackendRow be (QExprToIdentity a)) =>
SqlDelete be table
-> (table (QExpr be ()) -> a) -> m [QExprToIdentity a]
runDeleteReturningListWith SqlDelete be table
sql table (QExpr be ()) -> a
proj

class BeamSqlBackend be => BeamHasInsertOnConflict be where
  -- | Specifies the kind of constraint that must be violated for the action to occur
  data SqlConflictTarget be (table :: (Type -> Type) -> Type) :: Type
  -- | What to do when an @INSERT@ statement inserts a row into the table @tbl@
  -- that violates a constraint.
  data SqlConflictAction be (table :: (Type -> Type) -> Type) :: Type

  insertOnConflict
    :: Beamable table
    => DatabaseEntity be db (TableEntity table)
    -> SqlInsertValues be (table (QExpr be s))
    -> SqlConflictTarget be table
    -> SqlConflictAction be table
    -> SqlInsert be table

  anyConflict :: SqlConflictTarget be table
  conflictingFields
    :: Projectible be proj
    => (table (QExpr be QInternal) -> proj)
    -> SqlConflictTarget be table
  conflictingFieldsWhere
    :: Projectible be proj
    => (table (QExpr be QInternal) -> proj)
    -> (forall s. table (QExpr be s) -> QExpr be s Bool)
    -> SqlConflictTarget be table

  onConflictDoNothing :: SqlConflictAction be table
  onConflictUpdateSet
    :: Beamable table
    => (forall s. table (QField s) -> table (QExpr be s) -> QAssignment be s)
    -> SqlConflictAction be table
  onConflictUpdateSetWhere
    :: Beamable table
    => (forall s. table (QField s) -> table (QExpr be s) -> QAssignment be s)
    -> (forall s. table (QField s) -> table (QExpr be s) -> QExpr be s Bool)
    -> SqlConflictAction be table

newtype InaccessibleQAssignment be = InaccessibleQAssignment
  { forall be.
InaccessibleQAssignment be
-> [(BeamSqlBackendFieldNameSyntax be,
     BeamSqlBackendExpressionSyntax be)]
unInaccessibleQAssignment :: [(BeamSqlBackendFieldNameSyntax be, BeamSqlBackendExpressionSyntax be)]
  } deriving (NonEmpty (InaccessibleQAssignment be) -> InaccessibleQAssignment be
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
(InaccessibleQAssignment be
 -> InaccessibleQAssignment be -> InaccessibleQAssignment be)
-> (NonEmpty (InaccessibleQAssignment be)
    -> InaccessibleQAssignment be)
-> (forall b.
    Integral b =>
    b -> InaccessibleQAssignment be -> InaccessibleQAssignment be)
-> Semigroup (InaccessibleQAssignment be)
forall b.
Integral b =>
b -> InaccessibleQAssignment be -> InaccessibleQAssignment be
forall be.
NonEmpty (InaccessibleQAssignment be) -> InaccessibleQAssignment be
forall be.
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall be b.
Integral b =>
b -> InaccessibleQAssignment be -> InaccessibleQAssignment be
$c<> :: forall be.
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
<> :: InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
$csconcat :: forall be.
NonEmpty (InaccessibleQAssignment be) -> InaccessibleQAssignment be
sconcat :: NonEmpty (InaccessibleQAssignment be) -> InaccessibleQAssignment be
$cstimes :: forall be b.
Integral b =>
b -> InaccessibleQAssignment be -> InaccessibleQAssignment be
stimes :: forall b.
Integral b =>
b -> InaccessibleQAssignment be -> InaccessibleQAssignment be
Data.Semigroup.Semigroup, Semigroup (InaccessibleQAssignment be)
InaccessibleQAssignment be
Semigroup (InaccessibleQAssignment be) =>
InaccessibleQAssignment be
-> (InaccessibleQAssignment be
    -> InaccessibleQAssignment be -> InaccessibleQAssignment be)
-> ([InaccessibleQAssignment be] -> InaccessibleQAssignment be)
-> Monoid (InaccessibleQAssignment be)
[InaccessibleQAssignment be] -> InaccessibleQAssignment be
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
forall be. Semigroup (InaccessibleQAssignment be)
forall be. InaccessibleQAssignment be
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall be.
[InaccessibleQAssignment be] -> InaccessibleQAssignment be
forall be.
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
$cmempty :: forall be. InaccessibleQAssignment be
mempty :: InaccessibleQAssignment be
$cmappend :: forall be.
InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
mappend :: InaccessibleQAssignment be
-> InaccessibleQAssignment be -> InaccessibleQAssignment be
$cmconcat :: forall be.
[InaccessibleQAssignment be] -> InaccessibleQAssignment be
mconcat :: [InaccessibleQAssignment be] -> InaccessibleQAssignment be
Monoid)

onConflictUpdateInstead
  :: forall be table proj
  .  ( BeamHasInsertOnConflict be
     , Beamable table
     , ProjectibleWithPredicate AnyType () (InaccessibleQAssignment be) proj
     )
  => (table (Const (InaccessibleQAssignment be)) -> proj)
  -> SqlConflictAction be table
onConflictUpdateInstead :: forall be (table :: (* -> *) -> *) proj.
(BeamHasInsertOnConflict be, Beamable table,
 ProjectibleWithPredicate
   AnyType () (InaccessibleQAssignment be) proj) =>
(table (Const (InaccessibleQAssignment be)) -> proj)
-> SqlConflictAction be table
onConflictUpdateInstead table (Const (InaccessibleQAssignment be)) -> proj
mkProj = (forall s.
 table (QField s) -> table (QExpr be s) -> QAssignment be s)
-> SqlConflictAction be table
forall be (table :: (* -> *) -> *).
(BeamHasInsertOnConflict be, Beamable table) =>
(forall s.
 table (QField s) -> table (QExpr be s) -> QAssignment be s)
-> SqlConflictAction be table
forall (table :: (* -> *) -> *).
Beamable table =>
(forall s.
 table (QField s) -> table (QExpr be s) -> QAssignment be s)
-> SqlConflictAction be table
onConflictUpdateSet table (QField s) -> table (QExpr be s) -> QAssignment be s
forall s.
table (QField s) -> table (QExpr be s) -> QAssignment be s
mkAssignments
  where
    mkAssignments
      :: forall s
      .  table (QField s)
      -> table (QExpr be s)
      -> QAssignment be s
    mkAssignments :: forall s.
table (QField s) -> table (QExpr be s) -> QAssignment be s
mkAssignments table (QField s)
table table (QExpr be s)
excluded = [(BeamSqlBackendFieldNameSyntax be,
  Sql92SelectTableExpressionSyntax
    (Sql92SelectSelectTableSyntax
       (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
-> QAssignment be s
forall be s.
[(BeamSqlBackendFieldNameSyntax be,
  BeamSqlBackendExpressionSyntax be)]
-> QAssignment be s
QAssignment ([(BeamSqlBackendFieldNameSyntax be,
   Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
 -> QAssignment be s)
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
-> QAssignment be s
forall a b. (a -> b) -> a -> b
$ InaccessibleQAssignment be
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
forall be.
InaccessibleQAssignment be
-> [(BeamSqlBackendFieldNameSyntax be,
     BeamSqlBackendExpressionSyntax be)]
unInaccessibleQAssignment (InaccessibleQAssignment be
 -> [(BeamSqlBackendFieldNameSyntax be,
      Sql92SelectTableExpressionSyntax
        (Sql92SelectSelectTableSyntax
           (Sql92SelectSyntax (BeamSqlBackendSyntax be))))])
-> InaccessibleQAssignment be
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
forall a b. (a -> b) -> a -> b
$
      Writer (InaccessibleQAssignment be) proj
-> InaccessibleQAssignment be
forall w a. Writer w a -> w
Strict.execWriter (Writer (InaccessibleQAssignment be) proj
 -> InaccessibleQAssignment be)
-> Writer (InaccessibleQAssignment be) proj
-> InaccessibleQAssignment be
forall a b. (a -> b) -> a -> b
$ Proxy AnyType
-> Proxy ((), InaccessibleQAssignment be)
-> (forall context.
    AnyType context =>
    Proxy context
    -> Proxy ()
    -> InaccessibleQAssignment be
    -> WriterT
         (InaccessibleQAssignment be) Identity (InaccessibleQAssignment be))
-> proj
-> Writer (InaccessibleQAssignment be) proj
forall (m :: * -> *).
Monad m =>
Proxy AnyType
-> Proxy ((), InaccessibleQAssignment be)
-> (forall context.
    AnyType context =>
    Proxy context
    -> Proxy ()
    -> InaccessibleQAssignment be
    -> m (InaccessibleQAssignment be))
-> proj
-> m proj
forall (contextPredicate :: * -> Constraint) be res a
       (m :: * -> *).
(ProjectibleWithPredicate contextPredicate be res a, Monad m) =>
Proxy contextPredicate
-> Proxy (be, res)
-> (forall context.
    contextPredicate context =>
    Proxy context -> Proxy be -> res -> m res)
-> a
-> m a
project'
        (forall {k} (t :: k). Proxy t
forall (t :: * -> Constraint). Proxy t
Proxy @AnyType)
        (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @((), InaccessibleQAssignment be))
        (\Proxy context
_ Proxy ()
_ InaccessibleQAssignment be
a -> InaccessibleQAssignment be
-> WriterT (InaccessibleQAssignment be) Identity ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
Strict.tell InaccessibleQAssignment be
a WriterT (InaccessibleQAssignment be) Identity ()
-> WriterT
     (InaccessibleQAssignment be) Identity (InaccessibleQAssignment be)
-> WriterT
     (InaccessibleQAssignment be) Identity (InaccessibleQAssignment be)
forall a b.
WriterT (InaccessibleQAssignment be) Identity a
-> WriterT (InaccessibleQAssignment be) Identity b
-> WriterT (InaccessibleQAssignment be) Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> InaccessibleQAssignment be
-> WriterT
     (InaccessibleQAssignment be) Identity (InaccessibleQAssignment be)
forall a. a -> WriterT (InaccessibleQAssignment be) Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return InaccessibleQAssignment be
a)
        (table (Const (InaccessibleQAssignment be)) -> proj
mkProj (table (Const (InaccessibleQAssignment be)) -> proj)
-> table (Const (InaccessibleQAssignment be)) -> proj
forall a b. (a -> b) -> a -> b
$ Identity (table (Const (InaccessibleQAssignment be)))
-> table (Const (InaccessibleQAssignment be))
forall a. Identity a -> a
runIdentity (Identity (table (Const (InaccessibleQAssignment be)))
 -> table (Const (InaccessibleQAssignment be)))
-> Identity (table (Const (InaccessibleQAssignment be)))
-> table (Const (InaccessibleQAssignment be))
forall a b. (a -> b) -> a -> b
$ (forall a.
 Columnar' (QField s) a
 -> Columnar' (QExpr be s) a
 -> Identity (Columnar' (Const (InaccessibleQAssignment be)) a))
-> table (QField s)
-> table (QExpr be s)
-> Identity (table (Const (InaccessibleQAssignment be)))
forall (m :: * -> *) (f :: * -> *) (g :: * -> *) (h :: * -> *).
Applicative m =>
(forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a))
-> table f -> table g -> m (table h)
forall (table :: (* -> *) -> *) (m :: * -> *) (f :: * -> *)
       (g :: * -> *) (h :: * -> *).
(Beamable table, Applicative m) =>
(forall a. Columnar' f a -> Columnar' g a -> m (Columnar' h a))
-> table f -> table g -> m (table h)
zipBeamFieldsM Columnar' (QField s) a
-> Columnar' (QExpr be s) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
forall a.
Columnar' (QField s) a
-> Columnar' (QExpr be s) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
forall s a.
Columnar' (QField s) a
-> Columnar' (QExpr be s) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
mkAssignment table (QField s)
table table (QExpr be s)
excluded)
    mkAssignment
      :: forall s a
      .  Columnar' (QField s) a
      -> Columnar' (QExpr be s) a
      -> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
    mkAssignment :: forall s a.
Columnar' (QField s) a
-> Columnar' (QExpr be s) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
mkAssignment (Columnar' Columnar (QField s) a
field) (Columnar' Columnar (QExpr be s) a
value) =
      Columnar' (Const (InaccessibleQAssignment be)) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
forall a. a -> Identity a
Identity (Columnar' (Const (InaccessibleQAssignment be)) a
 -> Identity (Columnar' (Const (InaccessibleQAssignment be)) a))
-> Columnar' (Const (InaccessibleQAssignment be)) a
-> Identity (Columnar' (Const (InaccessibleQAssignment be)) a)
forall a b. (a -> b) -> a -> b
$ Columnar (Const (InaccessibleQAssignment be)) a
-> Columnar' (Const (InaccessibleQAssignment be)) a
forall (f :: * -> *) a. Columnar f a -> Columnar' f a
Columnar' (Columnar (Const (InaccessibleQAssignment be)) a
 -> Columnar' (Const (InaccessibleQAssignment be)) a)
-> Columnar (Const (InaccessibleQAssignment be)) a
-> Columnar' (Const (InaccessibleQAssignment be)) a
forall a b. (a -> b) -> a -> b
$ InaccessibleQAssignment be -> Const (InaccessibleQAssignment be) a
forall {k} a (b :: k). a -> Const a b
Const (InaccessibleQAssignment be
 -> Const (InaccessibleQAssignment be) a)
-> InaccessibleQAssignment be
-> Const (InaccessibleQAssignment be) a
forall a b. (a -> b) -> a -> b
$
        [(BeamSqlBackendFieldNameSyntax be,
  Sql92SelectTableExpressionSyntax
    (Sql92SelectSelectTableSyntax
       (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
-> InaccessibleQAssignment be
forall be.
[(BeamSqlBackendFieldNameSyntax be,
  BeamSqlBackendExpressionSyntax be)]
-> InaccessibleQAssignment be
InaccessibleQAssignment ([(BeamSqlBackendFieldNameSyntax be,
   Sql92SelectTableExpressionSyntax
     (Sql92SelectSelectTableSyntax
        (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
 -> InaccessibleQAssignment be)
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
-> InaccessibleQAssignment be
forall a b. (a -> b) -> a -> b
$ QAssignment be s
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
forall be s.
QAssignment be s
-> [(BeamSqlBackendFieldNameSyntax be,
     BeamSqlBackendExpressionSyntax be)]
unQAssignment (QAssignment be s
 -> [(BeamSqlBackendFieldNameSyntax be,
      Sql92SelectTableExpressionSyntax
        (Sql92SelectSelectTableSyntax
           (Sql92SelectSyntax (BeamSqlBackendSyntax be))))])
-> QAssignment be s
-> [(BeamSqlBackendFieldNameSyntax be,
     Sql92SelectTableExpressionSyntax
       (Sql92SelectSelectTableSyntax
          (Sql92SelectSyntax (BeamSqlBackendSyntax be))))]
forall a b. (a -> b) -> a -> b
$ Columnar (QField s) a
QField s a
field QField s a -> QGenExpr QValueContext be s a -> QAssignment be s
forall be s lhs rhs.
SqlUpdatable be s lhs rhs =>
lhs -> rhs -> QAssignment be s
<-. Columnar (QExpr be s) a
QGenExpr QValueContext be s a
value

onConflictUpdateAll
  :: forall be table
  .  ( BeamHasInsertOnConflict be
     , Beamable table
     )
  => SqlConflictAction be table
onConflictUpdateAll :: forall be (table :: (* -> *) -> *).
(BeamHasInsertOnConflict be, Beamable table) =>
SqlConflictAction be table
onConflictUpdateAll = (table (Const (InaccessibleQAssignment be))
 -> table (Const (InaccessibleQAssignment be)))
-> SqlConflictAction be table
forall be (table :: (* -> *) -> *) proj.
(BeamHasInsertOnConflict be, Beamable table,
 ProjectibleWithPredicate
   AnyType () (InaccessibleQAssignment be) proj) =>
(table (Const (InaccessibleQAssignment be)) -> proj)
-> SqlConflictAction be table
onConflictUpdateInstead table (Const (InaccessibleQAssignment be))
-> table (Const (InaccessibleQAssignment be))
forall a. a -> a
id