{-# LANGUAGE CPP #-}

-- | Wrappers that apply 'liftSql' to Persistent utilities of the same name.
module Database.Persist.Sql.Lifted.Persistent
  ( checkUnique
  , checkUniqueUpdateable
  , count
  , delete
  , deleteBy
  , deleteWhere
  , exists
  , get
  , getBy
  , getByValue
  , getEntity
  , getJust
  , getJustEntity
  , getMany
  , insert
  , insert_
  , insertBy
  , insertEntity
  , insertEntityMany
  , insertKey
  , insertMany
  , insertMany_
  , insertRecord
  , insertUnique
  , insertUniqueEntity
  , onlyUnique
  , putMany
  , replace
  , replaceUnique
  , repsert
  , repsertMany
  , selectFirst
  , selectKeys
  , selectKeysList
  , selectList
  , update
  , updateGet
  , updateWhere
  , upsert
  , upsertBy
  ) where

import Conduit (ConduitT, MonadResource, transPipe)
import Data.Bool (Bool)
import Data.Either (Either)
import Data.Eq (Eq)
import Data.Function (($))
import Data.Int (Int)
import Data.Map.Strict (Map)
import Data.Maybe (Maybe)
#if MIN_VERSION_base(4,17,0)
import Data.Type.Equality (type (~))
#endif
import Database.Persist
  ( AtLeastOneUniqueKey
  , Entity
  , Filter
  , OnlyOneUniqueKey
  , PersistEntity (..)
  , SelectOpt
  , Update
  )
import Database.Persist.Class qualified as P
import Database.Persist.Class.PersistEntity (SafeToInsert)
import Database.Persist.Sql.Lifted.Core (MonadSqlBackend, SqlBackend, liftSql)
import GHC.Stack (HasCallStack)

-- | Check whether there are any conflicts for unique keys with this entity
--   and existing entities in the database
checkUnique
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Maybe (Unique a))
  -- ^ 'Nothing' if the entity would be unique, and could thus safely
  --   be inserted. On a conflict, 'Just' the conflicting key.
checkUnique :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
a -> m (Maybe (Unique a))
checkUnique a
a = ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a)))
-> ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Maybe (Unique a))
forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
 PersistUniqueRead backend) =>
record -> ReaderT backend m (Maybe (Unique record))
P.checkUnique a
a

-- | Check whether there are any conflicts for unique keys with this entity and existing entities in the database
--
-- This is useful for updating because it ignores conflicts when the particular entity already exists.
checkUniqueUpdateable
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Entity a
  -> m (Maybe (Unique a))
  -- ^ 'Nothing' if the entity would stay unique, and could thus safely be updated.
  --   On a conflict, 'Just' the conflicting key.
checkUniqueUpdateable :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Entity a -> m (Maybe (Unique a))
checkUniqueUpdateable Entity a
e = ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a)))
-> ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall a b. (a -> b) -> a -> b
$ Entity a -> ReaderT SqlBackend m (Maybe (Unique a))
forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
 PersistUniqueRead backend) =>
Entity record -> ReaderT backend m (Maybe (Unique record))
P.checkUniqueUpdateable Entity a
e

-- | The total number of records fulfilling the given criteria
count
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> m Int
count :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> m Int
count [Filter a]
fs = ReaderT SqlBackend m Int -> m Int
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m Int -> m Int)
-> ReaderT SqlBackend m Int -> m Int
forall a b. (a -> b) -> a -> b
$ [Filter a] -> ReaderT SqlBackend m Int
forall backend (m :: * -> *) record.
(PersistQueryRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m Int
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record] -> ReaderT SqlBackend m Int
P.count [Filter a]
fs

-- | Delete a specific record by identifier
--
-- Does nothing if record does not exist.
delete
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> m ()
delete :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> m ()
delete Key a
k = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Key a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> ReaderT SqlBackend m ()
P.delete Key a
k

-- | Delete a specific record by unique key
--
-- Does nothing if no record matches.
deleteBy
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Unique a
  -> m ()
deleteBy :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Unique a -> m ()
deleteBy Unique a
u = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Unique a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Unique record -> ReaderT SqlBackend m ()
P.deleteBy Unique a
u

-- | Delete all records matching the given criteria
deleteWhere
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> m ()
deleteWhere :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> m ()
deleteWhere [Filter a]
fs = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Filter a] -> ReaderT SqlBackend m ()
forall backend (m :: * -> *) record.
(PersistQueryWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m ()
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record] -> ReaderT SqlBackend m ()
P.deleteWhere [Filter a]
fs

-- | Check if there is at least one record fulfilling the given criteria
exists
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> m Bool
exists :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> m Bool
exists [Filter a]
fs = ReaderT SqlBackend m Bool -> m Bool
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m Bool -> m Bool)
-> ReaderT SqlBackend m Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ [Filter a] -> ReaderT SqlBackend m Bool
forall backend (m :: * -> *) record.
(PersistQueryRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m Bool
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record] -> ReaderT SqlBackend m Bool
P.exists [Filter a]
fs

-- | Get a record by identifier, if available
get
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> m (Maybe a)
get :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> m (Maybe a)
get Key a
k = ReaderT SqlBackend m (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe a) -> m (Maybe a))
-> ReaderT SqlBackend m (Maybe a) -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Key a -> ReaderT SqlBackend m (Maybe a)
forall backend record (m :: * -> *).
(PersistStoreRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> ReaderT backend m (Maybe record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> ReaderT SqlBackend m (Maybe record)
P.get Key a
k

-- | Get a record by unique key, if available, returning both the identifier and the record
getBy
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Unique a
  -> m (Maybe (Entity a))
getBy :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Unique a -> m (Maybe (Entity a))
getBy Unique a
u = ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a)))
-> ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ Unique a -> ReaderT SqlBackend m (Maybe (Entity a))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Unique record -> ReaderT SqlBackend m (Maybe (Entity record))
P.getBy Unique a
u

-- Get a record by unique key, if available, returning both the identifier and the record
--
-- This function makes the most sense on entities with a single 'Unique' constructor.
getByValue
  :: forall a m
   . ( PersistEntityBackend a ~ SqlBackend
     , AtLeastOneUniqueKey a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Maybe (Entity a))
  -- ^ A record matching one of the unique keys.
getByValue :: forall a (m :: * -> *).
(PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a,
 MonadSqlBackend m, HasCallStack) =>
a -> m (Maybe (Entity a))
getByValue a
a = ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a)))
-> ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Maybe (Entity a))
forall record (m :: * -> *) backend.
(MonadIO m, PersistUniqueRead backend,
 PersistRecordBackend record backend, AtLeastOneUniqueKey record) =>
record -> ReaderT backend m (Maybe (Entity record))
P.getByValue a
a

-- | Get a record by identifier, if available
getEntity
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> m (Maybe (Entity a))
getEntity :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> m (Maybe (Entity a))
getEntity Key a
k = ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a)))
-> ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ Key a -> ReaderT SqlBackend m (Maybe (Entity a))
forall e backend (m :: * -> *).
(PersistStoreRead backend, PersistRecordBackend e backend,
 MonadIO m) =>
Key e -> ReaderT backend m (Maybe (Entity e))
P.getEntity Key a
k

-- | Get a record by identifier, if available, for a non-null (not 'Maybe') foreign key
--
-- Unsafe unless your database is enforcing that the foreign key is valid.
getJust
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> m a
getJust :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> m a
getJust Key a
k = ReaderT SqlBackend m a -> m a
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m a -> m a) -> ReaderT SqlBackend m a -> m a
forall a b. (a -> b) -> a -> b
$ Key a -> ReaderT SqlBackend m a
forall record backend (m :: * -> *).
(PersistStoreRead backend, PersistRecordBackend record backend,
 MonadIO m) =>
Key record -> ReaderT backend m record
P.getJust Key a
k

-- | Get a record by identifier, if available, for a non-null (not 'Maybe') foreign key
--
-- Unsafe unless your database is enforcing that the foreign key is valid.
getJustEntity
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> m (Entity a)
getJustEntity :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> m (Entity a)
getJustEntity Key a
k = ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Entity a) -> m (Entity a))
-> ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall a b. (a -> b) -> a -> b
$ Key a -> ReaderT SqlBackend m (Entity a)
forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend, MonadIO m,
 PersistEntity record, PersistStoreRead backend) =>
Key record -> ReaderT backend m (Entity record)
P.getJustEntity Key a
k

-- | Get many records by their respective identifiers, if available
getMany
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Key a]
  -> m (Map (Key a) a)
getMany :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Key a] -> m (Map (Key a) a)
getMany [Key a]
ks = ReaderT SqlBackend m (Map (Key a) a) -> m (Map (Key a) a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Map (Key a) a) -> m (Map (Key a) a))
-> ReaderT SqlBackend m (Map (Key a) a) -> m (Map (Key a) a)
forall a b. (a -> b) -> a -> b
$ [Key a] -> ReaderT SqlBackend m (Map (Key a) a)
forall backend record (m :: * -> *).
(PersistStoreRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Key record] -> ReaderT backend m (Map (Key record) record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Key record] -> ReaderT SqlBackend m (Map (Key record) record)
P.getMany [Key a]
ks

-- | Create a new record in the database
insert
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Key a)
  -- ^ The auto-increment ID that was generated
insert :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m (Key a)
insert a
a = ReaderT SqlBackend m (Key a) -> m (Key a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Key a) -> m (Key a))
-> ReaderT SqlBackend m (Key a) -> m (Key a)
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Key a)
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Key record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
record -> ReaderT SqlBackend m (Key record)
P.insert a
a

-- | Create a new record in the database
insert_
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m ()
insert_ :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m ()
insert_ a
a = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
record -> ReaderT SqlBackend m ()
P.insert_ a
a

-- | Insert a value, checking for conflicts with any unique constraints
insertBy
  :: forall a m
   . ( PersistEntityBackend a ~ SqlBackend
     , AtLeastOneUniqueKey a
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Either (Entity a) (Key a))
  -- ^ If a duplicate exists in the database, it is returned as 'Left'.
  --   Otherwise, the new 'Key' is returned as 'Right'.
insertBy :: forall a (m :: * -> *).
(PersistEntityBackend a ~ SqlBackend, AtLeastOneUniqueKey a,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m (Either (Entity a) (Key a))
insertBy a
a = ReaderT SqlBackend m (Either (Entity a) (Key a))
-> m (Either (Entity a) (Key a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Either (Entity a) (Key a))
 -> m (Either (Entity a) (Key a)))
-> ReaderT SqlBackend m (Either (Entity a) (Key a))
-> m (Either (Entity a) (Key a))
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Either (Entity a) (Key a))
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueWrite backend,
 PersistRecordBackend record backend, AtLeastOneUniqueKey record,
 SafeToInsert record) =>
record -> ReaderT backend m (Either (Entity record) (Key record))
P.insertBy a
a

-- | Create a new record in the database, returning an auto-increment ID and the inserted record
insertEntity
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Entity a)
insertEntity :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m (Entity a)
insertEntity a
a = ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Entity a) -> m (Entity a))
-> ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Entity a)
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 SafeToInsert e, MonadIO m, HasCallStack) =>
e -> ReaderT backend m (Entity e)
P.insertEntity a
a

-- | Create multiple records in the database, with specified keys
insertEntityMany
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Entity a]
  -> m ()
insertEntityMany :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Entity a] -> m ()
insertEntityMany [Entity a]
es = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Entity a] -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Entity record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Entity record] -> ReaderT SqlBackend m ()
P.insertEntityMany [Entity a]
es

-- | Create a new record in the database using the given key
insertKey
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> a
  -> m ()
insertKey :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> a -> m ()
insertKey Key a
k a
a = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Key a -> a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> record -> ReaderT SqlBackend m ()
P.insertKey Key a
k a
a

-- | Create multiple records in the database and return their 'Key's
insertMany
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => [a]
  -> m [Key a]
insertMany :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
[a] -> m [Key a]
insertMany [a]
as = ReaderT SqlBackend m [Key a] -> m [Key a]
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m [Key a] -> m [Key a])
-> ReaderT SqlBackend m [Key a] -> m [Key a]
forall a b. (a -> b) -> a -> b
$ [a] -> ReaderT SqlBackend m [Key a]
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m [Key record]
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
[record] -> ReaderT SqlBackend m [Key record]
P.insertMany [a]
as

-- | Create multiple records in the database
insertMany_
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => [a]
  -> m ()
insertMany_ :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
[a] -> m ()
insertMany_ [a]
as = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [a] -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
[record] -> ReaderT SqlBackend m ()
P.insertMany_ [a]
as

-- | Create a new record in the database
insertRecord
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m a
  -- ^ The record that was inserted
insertRecord :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m a
insertRecord a
a = ReaderT SqlBackend m a -> m a
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m a -> m a) -> ReaderT SqlBackend m a -> m a
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m a
forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend,
 PersistEntity record, MonadIO m, PersistStoreWrite backend,
 SafeToInsert record, HasCallStack) =>
record -> ReaderT backend m record
P.insertRecord a
a

-- | Create a new record in the database
insertUnique
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Maybe (Key a))
  -- ^ An auto-increment ID, or 'Nothing' when the record couldn't be
  --   inserted because of a uniqueness constraint
insertUnique :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m (Maybe (Key a))
insertUnique a
a = ReaderT SqlBackend m (Maybe (Key a)) -> m (Maybe (Key a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Key a)) -> m (Maybe (Key a)))
-> ReaderT SqlBackend m (Maybe (Key a)) -> m (Maybe (Key a))
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Maybe (Key a))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Maybe (Key record))
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
record -> ReaderT SqlBackend m (Maybe (Key record))
P.insertUnique a
a

-- | Create a new record in the database
insertUniqueEntity
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Maybe (Entity a))
  -- ^ An auto-increment ID and the inserted record, or 'Nothing' when the record
  --   couldn't be inserted because of a uniqueness constraint.
insertUniqueEntity :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
a -> m (Maybe (Entity a))
insertUniqueEntity a
a = ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a)))
-> ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Maybe (Entity a))
forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
 PersistUniqueWrite backend, SafeToInsert record) =>
record -> ReaderT backend m (Maybe (Entity record))
P.insertUniqueEntity a
a

-- | Return the single unique key for a record
onlyUnique
  :: forall a m
   . ( PersistEntityBackend a ~ SqlBackend
     , OnlyOneUniqueKey a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -> m (Unique a)
onlyUnique :: forall a (m :: * -> *).
(PersistEntityBackend a ~ SqlBackend, OnlyOneUniqueKey a,
 MonadSqlBackend m, HasCallStack) =>
a -> m (Unique a)
onlyUnique a
a = ReaderT SqlBackend m (Unique a) -> m (Unique a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Unique a) -> m (Unique a))
-> ReaderT SqlBackend m (Unique a) -> m (Unique a)
forall a b. (a -> b) -> a -> b
$ a -> ReaderT SqlBackend m (Unique a)
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueWrite backend,
 PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> ReaderT backend m (Unique record)
P.onlyUnique a
a

-- | Put many records into the database
--
-- * Insert new records that do not exist (or violate any unique constraints);
-- * Replace existing records (matching any unique constraint).
putMany
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => [a]
  -- ^ A list of the records you want to insert or replace.
  -> m ()
putMany :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
[a] -> m ()
putMany [a]
as = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [a] -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
[record] -> ReaderT SqlBackend m ()
P.putMany [a]
as

-- | Replace the record in the database with the given key
--
-- The result is undefined if such record does not exist.
replace
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> a
  -> m ()
replace :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> a -> m ()
replace Key a
k a
a = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Key a -> a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> record -> ReaderT SqlBackend m ()
P.replace Key a
k a
a

-- | Attempt to replace the record of the given key with the given new record
--
-- First query the unique fields to make sure the replacement maintains uniqueness constraints.
replaceUnique
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , Eq (Unique a)
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> a
  -> m (Maybe (Unique a))
  -- ^ 'Nothing' if the replacement was made. If uniqueness is violated,
  --   'Just' the 'Unique' violation.
replaceUnique :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 Eq (Unique a), MonadSqlBackend m, HasCallStack) =>
Key a -> a -> m (Maybe (Unique a))
replaceUnique Key a
k a
a = ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a)))
-> ReaderT SqlBackend m (Maybe (Unique a)) -> m (Maybe (Unique a))
forall a b. (a -> b) -> a -> b
$ Key a -> a -> ReaderT SqlBackend m (Maybe (Unique a))
forall record backend (m :: * -> *).
(MonadIO m, Eq (Unique record),
 PersistRecordBackend record backend, PersistUniqueWrite backend) =>
Key record -> record -> ReaderT backend m (Maybe (Unique record))
P.replaceUnique Key a
k a
a

-- | Put the record in the database with the given key
--
-- If a record with the given key does not exist then a new record will be inserted.
repsert
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> a
  -> m ()
repsert :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> a -> m ()
repsert Key a
k a
a = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Key a -> a -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> record -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> record -> ReaderT SqlBackend m ()
P.repsert Key a
k a
a

-- | Put many entities into the database
--
-- For each item, if a record with the given key does not exist then a new record will be inserted.
repsertMany
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [(Key a, a)]
  -> m ()
repsertMany :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[(Key a, a)] -> m ()
repsertMany [(Key a, a)]
kas = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [(Key a, a)] -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[(Key record, record)] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[(Key record, record)] -> ReaderT SqlBackend m ()
P.repsertMany [(Key a, a)]
kas

-- | Get just the first record for the criteria
selectFirst
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> [SelectOpt a]
  -> m (Maybe (Entity a))
selectFirst :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> [SelectOpt a] -> m (Maybe (Entity a))
selectFirst [Filter a]
fs [SelectOpt a]
os = ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a)))
-> ReaderT SqlBackend m (Maybe (Entity a)) -> m (Maybe (Entity a))
forall a b. (a -> b) -> a -> b
$ [Filter a]
-> [SelectOpt a] -> ReaderT SqlBackend m (Maybe (Entity a))
forall backend (m :: * -> *) record.
(PersistQueryRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m (Maybe (Entity record))
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record]
-> [SelectOpt record]
-> ReaderT SqlBackend m (Maybe (Entity record))
P.selectFirst [Filter a]
fs [SelectOpt a]
os

-- | Get the 'Key's of all records matching the given criteria
selectKeys
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , MonadResource m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> [SelectOpt a]
  -> ConduitT () (Key a) m ()
  -- ^ Keys corresponding to the filters and options provided
selectKeys :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, MonadResource m, HasCallStack) =>
[Filter a] -> [SelectOpt a] -> ConduitT () (Key a) m ()
selectKeys [Filter a]
fs [SelectOpt a]
os = (forall a. ReaderT SqlBackend m a -> m a)
-> ConduitT () (Key a) (ReaderT SqlBackend m) ()
-> ConduitT () (Key a) m ()
forall (m :: * -> *) (n :: * -> *) i o r.
Monad m =>
(forall a. m a -> n a) -> ConduitT i o m r -> ConduitT i o n r
transPipe ReaderT SqlBackend m a -> m a
forall a. ReaderT SqlBackend m a -> m a
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ConduitT () (Key a) (ReaderT SqlBackend m) ()
 -> ConduitT () (Key a) m ())
-> ConduitT () (Key a) (ReaderT SqlBackend m) ()
-> ConduitT () (Key a) m ()
forall a b. (a -> b) -> a -> b
$ [Filter a]
-> [SelectOpt a] -> ConduitT () (Key a) (ReaderT SqlBackend m) ()
forall record backend (m :: * -> *).
(PersistQueryRead backend, MonadResource m,
 PersistRecordBackend record backend, MonadReader backend m) =>
[Filter record]
-> [SelectOpt record] -> ConduitM () (Key record) m ()
P.selectKeys [Filter a]
fs [SelectOpt a]
os

-- | Get the 'Key's of all records matching the given criteria
selectKeysList
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> [SelectOpt a]
  -> m [Key a]
selectKeysList :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> [SelectOpt a] -> m [Key a]
selectKeysList [Filter a]
fs [SelectOpt a]
os = ReaderT SqlBackend m [Key a] -> m [Key a]
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m [Key a] -> m [Key a])
-> ReaderT SqlBackend m [Key a] -> m [Key a]
forall a b. (a -> b) -> a -> b
$ [Filter a] -> [SelectOpt a] -> ReaderT SqlBackend m [Key a]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Key record]
P.selectKeysList [Filter a]
fs [SelectOpt a]
os

selectList
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> [SelectOpt a]
  -> m [Entity a]
  -- ^ Entities corresponding to the filters and options provided
selectList :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> [SelectOpt a] -> m [Entity a]
selectList [Filter a]
fs [SelectOpt a]
os = ReaderT SqlBackend m [Entity a] -> m [Entity a]
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m [Entity a] -> m [Entity a])
-> ReaderT SqlBackend m [Entity a] -> m [Entity a]
forall a b. (a -> b) -> a -> b
$ [Filter a] -> [SelectOpt a] -> ReaderT SqlBackend m [Entity a]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
P.selectList [Filter a]
fs [SelectOpt a]
os

-- | Update individual fields on a specific record
update
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> [Update a]
  -> m ()
update :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> [Update a] -> m ()
update Key a
k [Update a]
us = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ Key a -> [Update a] -> ReaderT SqlBackend m ()
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> [Update record] -> ReaderT backend m ()
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> [Update record] -> ReaderT SqlBackend m ()
P.update Key a
k [Update a]
us

-- | Update individual fields on a specific record, and retrieve the updated value from the database
--
-- This function will throw an exception if the given key is not found in the database.
updateGet
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => Key a
  -> [Update a]
  -> m a
updateGet :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
Key a -> [Update a] -> m a
updateGet Key a
k [Update a]
us = ReaderT SqlBackend m a -> m a
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m a -> m a) -> ReaderT SqlBackend m a -> m a
forall a b. (a -> b) -> a -> b
$ Key a -> [Update a] -> ReaderT SqlBackend m a
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> [Update record] -> ReaderT backend m record
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend) =>
Key record -> [Update record] -> ReaderT SqlBackend m record
P.updateGet Key a
k [Update a]
us

-- | Update individual fields on any record matching the given criteria
updateWhere
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , MonadSqlBackend m
     , HasCallStack
     )
  => [Filter a]
  -- ^ If you provide multiple values in the list, the conditions are ANDed together.
  -> [Update a]
  -> m ()
updateWhere :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 MonadSqlBackend m, HasCallStack) =>
[Filter a] -> [Update a] -> m ()
updateWhere [Filter a]
fs [Update a]
us = ReaderT SqlBackend m () -> m ()
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m () -> m ())
-> ReaderT SqlBackend m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Filter a] -> [Update a] -> ReaderT SqlBackend m ()
forall backend (m :: * -> *) record.
(PersistQueryWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> [Update record] -> ReaderT backend m ()
forall (m :: * -> *) record.
(MonadIO m, PersistRecordBackend record SqlBackend) =>
[Filter record] -> [Update record] -> ReaderT SqlBackend m ()
P.updateWhere [Filter a]
fs [Update a]
us

-- | Update based on a uniqueness constraint or insert:
--
-- * Unsert the new record if it does not exist;
-- * If the record exists (matched via it's uniqueness constraint), then update the
--   existing record with the parameters which is passed on as list to the function.
upsert
  :: forall a m
   . ( PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , OnlyOneUniqueKey a
     , MonadSqlBackend m
     , HasCallStack
     )
  => a
  -- ^ New record to insert
  -> [Update a]
  -- ^ Updates to perform if the record already exists
  -> m (Entity a)
  -- ^ The record in the database after the operation
upsert :: forall a (m :: * -> *).
(PersistEntityBackend a ~ SqlBackend, SafeToInsert a,
 OnlyOneUniqueKey a, MonadSqlBackend m, HasCallStack) =>
a -> [Update a] -> m (Entity a)
upsert a
a [Update a]
us = ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Entity a) -> m (Entity a))
-> ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall a b. (a -> b) -> a -> b
$ a -> [Update a] -> ReaderT SqlBackend m (Entity a)
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, OnlyOneUniqueKey record,
 SafeToInsert record) =>
record -> [Update record] -> ReaderT backend m (Entity record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 OnlyOneUniqueKey record, SafeToInsert record) =>
record -> [Update record] -> ReaderT SqlBackend m (Entity record)
P.upsert a
a [Update a]
us

-- | Update based on a given uniqueness constraint or insert:
--
-- * Insert the new record if it does not exist;
-- * Update the existing record that matches the given uniqueness constraint.
upsertBy
  :: forall a m
   . ( PersistEntity a
     , PersistEntityBackend a ~ SqlBackend
     , SafeToInsert a
     , MonadSqlBackend m
     , HasCallStack
     )
  => Unique a
  -- ^ Uniqueness constraint to find by
  -> a
  -- ^ New record to insert
  -> [Update a]
  -- ^ Updates to perform if the record already exists
  -> m (Entity a)
  -- ^ The record in the database after the operation
upsertBy :: forall a (m :: * -> *).
(PersistEntity a, PersistEntityBackend a ~ SqlBackend,
 SafeToInsert a, MonadSqlBackend m, HasCallStack) =>
Unique a -> a -> [Update a] -> m (Entity a)
upsertBy Unique a
u a
a [Update a]
us = ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall (m :: * -> *) a.
(MonadSqlBackend m, HasCallStack) =>
ReaderT SqlBackend m a -> m a
liftSql (ReaderT SqlBackend m (Entity a) -> m (Entity a))
-> ReaderT SqlBackend m (Entity a) -> m (Entity a)
forall a b. (a -> b) -> a -> b
$ Unique a -> a -> [Update a] -> ReaderT SqlBackend m (Entity a)
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, SafeToInsert record) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
forall record (m :: * -> *).
(MonadIO m, PersistRecordBackend record SqlBackend,
 SafeToInsert record) =>
Unique record
-> record
-> [Update record]
-> ReaderT SqlBackend m (Entity record)
P.upsertBy Unique a
u a
a [Update a]
us