module UpsertTest where

import Data.Function (on)

import Init
import PersistentTestModels

-- | MongoDB assumes that a @NULL@ value in the database is some "empty"
-- value. So a query that does @+ 2@ to a @NULL@ value results in @2@. SQL
-- databases instead "annihilate" with null, so @NULL + 2 = NULL@.
data BackendNullUpdateBehavior
    = AssumeNullIsZero
    | Don'tUpdateNull

-- | @UPSERT@ on SQL databses does an "update-or-insert," which preserves
-- all prior values, including keys. MongoDB does not preserve the
-- identifier, so the entity key changes on an upsert.
data BackendUpsertKeyBehavior
    = UpsertGenerateNewKey
    | UpsertPreserveOldKey

specsWith
    :: forall backend m. Runner backend m
    => RunDb backend m
    -> BackendNullUpdateBehavior
    -> BackendUpsertKeyBehavior
    -> Spec
specsWith :: RunDb backend m
-> BackendNullUpdateBehavior -> BackendUpsertKeyBehavior -> Spec
specsWith RunDb backend m
runDb BackendNullUpdateBehavior
handleNull BackendUpsertKeyBehavior
handleKey = String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"UpsertTests" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
  let
    ifKeyIsPreserved :: ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved ReaderT backend m ()
expectation =
      case BackendUpsertKeyBehavior
handleKey of
        BackendUpsertKeyBehavior
UpsertGenerateNewKey -> () -> ReaderT backend m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        BackendUpsertKeyBehavior
UpsertPreserveOldKey -> ReaderT backend m ()
expectation

  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"upsert" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"adds a new row with no updates" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        Entity Key (UpsertGeneric backend)
_ UpsertGeneric backend
u <- UpsertGeneric backend
-> [Update (UpsertGeneric backend)]
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> [Update record] -> ReaderT backend m (Entity record)
upsert (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"new" Text
"" Int
2) [EntityField (UpsertGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertGeneric backend) typ
UpsertAttr EntityField (UpsertGeneric backend) Text
-> Text -> Update (UpsertGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"update"]
        Int
c <- [Filter (UpsertGeneric backend)] -> ReaderT backend m Int
forall backend (m :: * -> *) record.
(PersistQueryRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m Int
count ([] :: [Filter (UpsertGeneric backend)])
        Int
c Int -> Int -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Int
1
        UpsertGeneric backend -> Text
forall backend. UpsertGeneric backend -> Text
upsertAttr UpsertGeneric backend
u Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"new"
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"keeps the existing row" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        Entity Key (UpsertGeneric backend)
k0 UpsertGeneric backend
initial <- UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"initial" Text
"" Int
1)
        Entity Key (UpsertGeneric backend)
k1 UpsertGeneric backend
update' <- UpsertGeneric backend
-> [Update (UpsertGeneric backend)]
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> [Update record] -> ReaderT backend m (Entity record)
upsert (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"update" Text
"" Int
2) []
        UpsertGeneric backend
update' UpsertGeneric backend
-> UpsertGeneric backend -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== UpsertGeneric backend
initial
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Key (UpsertGeneric backend)
k0 Key (UpsertGeneric backend)
-> Key (UpsertGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Key (UpsertGeneric backend)
k1
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"updates an existing row - assignment" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
-- #ifdef WITH_MONGODB
--         initial <- insertEntity (Upsert "cow" "initial" "extra" 1)
--         update' <-
--             upsert (Upsert "cow" "wow" "such unused" 2) [UpsertAttr =. "update"]
--         ((==@) `on` entityKey) initial update'
--         upsertAttr (entityVal update') @== "update"
--         upsertExtra (entityVal update') @== "extra"
-- #else
        Entity (UpsertGeneric backend)
initial <- UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"initial" Text
"extra" Int
1)
        Entity (UpsertGeneric backend)
update' <-
            UpsertGeneric backend
-> [Update (UpsertGeneric backend)]
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> [Update record] -> ReaderT backend m (Entity record)
upsert (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"wow" Text
"such unused" Int
2) [EntityField (UpsertGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertGeneric backend) typ
UpsertAttr EntityField (UpsertGeneric backend) Text
-> Text -> Update (UpsertGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"update"]
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ (Key (UpsertGeneric backend)
-> Key (UpsertGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
(==@) (Key (UpsertGeneric backend)
 -> Key (UpsertGeneric backend) -> ReaderT backend m ())
-> (Entity (UpsertGeneric backend) -> Key (UpsertGeneric backend))
-> Entity (UpsertGeneric backend)
-> Entity (UpsertGeneric backend)
-> ReaderT backend m ()
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Entity (UpsertGeneric backend) -> Key (UpsertGeneric backend)
forall record. Entity record -> Key record
entityKey) Entity (UpsertGeneric backend)
initial Entity (UpsertGeneric backend)
update'
        UpsertGeneric backend -> Text
forall backend. UpsertGeneric backend -> Text
upsertAttr (Entity (UpsertGeneric backend) -> UpsertGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertGeneric backend)
update') Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"update"
        UpsertGeneric backend -> Text
forall backend. UpsertGeneric backend -> Text
upsertExtra (Entity (UpsertGeneric backend) -> UpsertGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertGeneric backend)
update') Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"extra"
-- #endif
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"updates existing row - addition " (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
-- #ifdef WITH_MONGODB
--         initial <- insertEntity (Upsert "a1" "initial" "extra" 2)
--         update' <-
--             upsert (Upsert "a1" "wow" "such unused" 2) [UpsertAge +=. 3]
--         ((==@) `on` entityKey) initial update'
--         upsertAge (entityVal update') @== 5
--         upsertExtra (entityVal update') @== "extra"
-- #else
        Entity (UpsertGeneric backend)
initial <- UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"initial" Text
"extra" Int
2)
        Entity (UpsertGeneric backend)
update' <-
            UpsertGeneric backend
-> [Update (UpsertGeneric backend)]
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> [Update record] -> ReaderT backend m (Entity record)
upsert (Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
"a" Text
"wow" Text
"such unused" Int
2) [EntityField (UpsertGeneric backend) Int
forall backend typ.
(typ ~ Int) =>
EntityField (UpsertGeneric backend) typ
UpsertAge EntityField (UpsertGeneric backend) Int
-> Int -> Update (UpsertGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
+=. Int
3]
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ (Key (UpsertGeneric backend)
-> Key (UpsertGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
(==@) (Key (UpsertGeneric backend)
 -> Key (UpsertGeneric backend) -> ReaderT backend m ())
-> (Entity (UpsertGeneric backend) -> Key (UpsertGeneric backend))
-> Entity (UpsertGeneric backend)
-> Entity (UpsertGeneric backend)
-> ReaderT backend m ()
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Entity (UpsertGeneric backend) -> Key (UpsertGeneric backend)
forall record. Entity record -> Key record
entityKey) Entity (UpsertGeneric backend)
initial Entity (UpsertGeneric backend)
update'
        UpsertGeneric backend -> Int
forall backend. UpsertGeneric backend -> Int
upsertAge (Entity (UpsertGeneric backend) -> UpsertGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertGeneric backend)
update') Int -> Int -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Int
5
        UpsertGeneric backend -> Text
forall backend. UpsertGeneric backend -> Text
upsertExtra (Entity (UpsertGeneric backend) -> UpsertGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertGeneric backend)
update') Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"extra"
-- #endif

  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"upsertBy" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    let uniqueEmail :: Unique (UpsertByGeneric backend)
uniqueEmail = Text -> Unique (UpsertByGeneric backend)
forall backend. Text -> Unique (UpsertByGeneric backend)
UniqueUpsertBy Text
"a"
        _uniqueCity :: Unique (UpsertByGeneric backend)
_uniqueCity = Text -> Unique (UpsertByGeneric backend)
forall backend. Text -> Unique (UpsertByGeneric backend)
UniqueUpsertByCity Text
"Boston"
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"adds a new row with no updates" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        Entity Key (UpsertByGeneric backend)
_ UpsertByGeneric backend
u <-
            Unique (UpsertByGeneric backend)
-> UpsertByGeneric backend
-> [Update (UpsertByGeneric backend)]
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy
                Unique (UpsertByGeneric backend)
forall backend. Unique (UpsertByGeneric backend)
uniqueEmail
                (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"a" Text
"Boston" Text
"new")
                [EntityField (UpsertByGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertByGeneric backend) typ
UpsertByAttr EntityField (UpsertByGeneric backend) Text
-> Text -> Update (UpsertByGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"update"]
        Int
c <- [Filter (UpsertByGeneric backend)] -> ReaderT backend m Int
forall backend (m :: * -> *) record.
(PersistQueryRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m Int
count ([] :: [Filter (UpsertByGeneric backend)])
        Int
c Int -> Int -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Int
1
        UpsertByGeneric backend -> Text
forall backend. UpsertByGeneric backend -> Text
upsertByAttr UpsertByGeneric backend
u Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"new"
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"keeps the existing row" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        Entity Key (UpsertByGeneric backend)
k0 UpsertByGeneric backend
initial <- UpsertByGeneric backend
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"a" Text
"Boston" Text
"initial")
        Entity Key (UpsertByGeneric backend)
k1 UpsertByGeneric backend
update' <- Unique (UpsertByGeneric backend)
-> UpsertByGeneric backend
-> [Update (UpsertByGeneric backend)]
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy Unique (UpsertByGeneric backend)
forall backend. Unique (UpsertByGeneric backend)
uniqueEmail (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"a" Text
"Boston" Text
"update") []
        UpsertByGeneric backend
update' UpsertByGeneric backend
-> UpsertByGeneric backend -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== UpsertByGeneric backend
initial
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Key (UpsertByGeneric backend)
k0 Key (UpsertByGeneric backend)
-> Key (UpsertByGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Key (UpsertByGeneric backend)
k1
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"updates an existing row" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
-- #ifdef WITH_MONGODB
--         initial <- insertEntity (UpsertBy "ko" "Kumbakonam" "initial")
--         update' <-
--             upsertBy
--                 (UniqueUpsertBy "ko")
--                 (UpsertBy "ko" "Bangalore" "such unused")
--                 [UpsertByAttr =. "update"]
--         ((==@) `on` entityKey) initial update'
--         upsertByAttr (entityVal update') @== "update"
--         upsertByCity (entityVal update') @== "Kumbakonam"
-- #else
        Entity (UpsertByGeneric backend)
initial <- UpsertByGeneric backend
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"a" Text
"Boston" Text
"initial")
        Entity (UpsertByGeneric backend)
update' <-
            Unique (UpsertByGeneric backend)
-> UpsertByGeneric backend
-> [Update (UpsertByGeneric backend)]
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy
                Unique (UpsertByGeneric backend)
forall backend. Unique (UpsertByGeneric backend)
uniqueEmail
                (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"a" Text
"wow" Text
"such unused")
                [EntityField (UpsertByGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertByGeneric backend) typ
UpsertByAttr EntityField (UpsertByGeneric backend) Text
-> Text -> Update (UpsertByGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"update"]
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ (Key (UpsertByGeneric backend)
-> Key (UpsertByGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
(==@) (Key (UpsertByGeneric backend)
 -> Key (UpsertByGeneric backend) -> ReaderT backend m ())
-> (Entity (UpsertByGeneric backend)
    -> Key (UpsertByGeneric backend))
-> Entity (UpsertByGeneric backend)
-> Entity (UpsertByGeneric backend)
-> ReaderT backend m ()
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Entity (UpsertByGeneric backend) -> Key (UpsertByGeneric backend)
forall record. Entity record -> Key record
entityKey) Entity (UpsertByGeneric backend)
initial Entity (UpsertByGeneric backend)
update'
        UpsertByGeneric backend -> Text
forall backend. UpsertByGeneric backend -> Text
upsertByAttr (Entity (UpsertByGeneric backend) -> UpsertByGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertByGeneric backend)
update') Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"update"
        UpsertByGeneric backend -> Text
forall backend. UpsertByGeneric backend -> Text
upsertByCity (Entity (UpsertByGeneric backend) -> UpsertByGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertByGeneric backend)
update') Text -> Text -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text
"Boston"
-- #endif
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"updates by the appropriate constraint" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        Entity (UpsertByGeneric backend)
initBoston <- UpsertByGeneric backend
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"bos" Text
"Boston" Text
"bos init")
        Entity (UpsertByGeneric backend)
initKrum <- UpsertByGeneric backend
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"krum" Text
"Krum" Text
"krum init")
        Entity (UpsertByGeneric backend)
updBoston <-
            Unique (UpsertByGeneric backend)
-> UpsertByGeneric backend
-> [Update (UpsertByGeneric backend)]
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy
                (Text -> Unique (UpsertByGeneric backend)
forall backend. Text -> Unique (UpsertByGeneric backend)
UniqueUpsertBy Text
"bos")
                (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"bos" Text
"Krum" Text
"unused")
                [EntityField (UpsertByGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertByGeneric backend) typ
UpsertByAttr EntityField (UpsertByGeneric backend) Text
-> Text -> Update (UpsertByGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"bos update"]
        Entity (UpsertByGeneric backend)
updKrum <-
            Unique (UpsertByGeneric backend)
-> UpsertByGeneric backend
-> [Update (UpsertByGeneric backend)]
-> ReaderT backend m (Entity (UpsertByGeneric backend))
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy
                (Text -> Unique (UpsertByGeneric backend)
forall backend. Text -> Unique (UpsertByGeneric backend)
UniqueUpsertByCity Text
"Krum")
                (Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"bos" Text
"Krum" Text
"unused")
                [EntityField (UpsertByGeneric backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (UpsertByGeneric backend) typ
UpsertByAttr EntityField (UpsertByGeneric backend) Text
-> Text -> Update (UpsertByGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
=. Text
"krum update"]
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ (Key (UpsertByGeneric backend)
-> Key (UpsertByGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
(==@) (Key (UpsertByGeneric backend)
 -> Key (UpsertByGeneric backend) -> ReaderT backend m ())
-> (Entity (UpsertByGeneric backend)
    -> Key (UpsertByGeneric backend))
-> Entity (UpsertByGeneric backend)
-> Entity (UpsertByGeneric backend)
-> ReaderT backend m ()
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Entity (UpsertByGeneric backend) -> Key (UpsertByGeneric backend)
forall record. Entity record -> Key record
entityKey) Entity (UpsertByGeneric backend)
initBoston Entity (UpsertByGeneric backend)
updBoston
        ReaderT backend m () -> ReaderT backend m ()
ifKeyIsPreserved (ReaderT backend m () -> ReaderT backend m ())
-> ReaderT backend m () -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ (Key (UpsertByGeneric backend)
-> Key (UpsertByGeneric backend) -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
(==@) (Key (UpsertByGeneric backend)
 -> Key (UpsertByGeneric backend) -> ReaderT backend m ())
-> (Entity (UpsertByGeneric backend)
    -> Key (UpsertByGeneric backend))
-> Entity (UpsertByGeneric backend)
-> Entity (UpsertByGeneric backend)
-> ReaderT backend m ()
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` Entity (UpsertByGeneric backend) -> Key (UpsertByGeneric backend)
forall record. Entity record -> Key record
entityKey) Entity (UpsertByGeneric backend)
initKrum Entity (UpsertByGeneric backend)
updKrum
        Entity (UpsertByGeneric backend) -> UpsertByGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertByGeneric backend)
updBoston UpsertByGeneric backend
-> UpsertByGeneric backend -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"bos" Text
"Boston" Text
"bos update"
        Entity (UpsertByGeneric backend) -> UpsertByGeneric backend
forall record. Entity record -> record
entityVal Entity (UpsertByGeneric backend)
updKrum UpsertByGeneric backend
-> UpsertByGeneric backend -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== Text -> Text -> Text -> UpsertByGeneric backend
forall backend. Text -> Text -> Text -> UpsertByGeneric backend
UpsertBy Text
"krum" Text
"Krum" Text
"krum update"

  String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"maybe update" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
      let noAge :: PersonMaybeAgeGeneric backend
noAge = Text -> Maybe Int -> PersonMaybeAgeGeneric backend
forall backend. Text -> Maybe Int -> PersonMaybeAgeGeneric backend
PersonMaybeAge Text
"Michael" Maybe Int
forall a. Maybe a
Nothing
      Key (PersonMaybeAgeGeneric backend)
keyNoAge <- PersonMaybeAgeGeneric backend
-> ReaderT backend m (Key (PersonMaybeAgeGeneric backend))
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
record -> ReaderT backend m (Key record)
insert PersonMaybeAgeGeneric backend
forall backend. PersonMaybeAgeGeneric backend
noAge
      PersonMaybeAgeGeneric backend
noAge2 <- Key (PersonMaybeAgeGeneric backend)
-> [Update (PersonMaybeAgeGeneric backend)]
-> ReaderT backend m (PersonMaybeAgeGeneric backend)
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Key record -> [Update record] -> ReaderT backend m record
updateGet Key (PersonMaybeAgeGeneric backend)
keyNoAge [EntityField (PersonMaybeAgeGeneric backend) (Maybe Int)
forall backend typ.
(typ ~ Maybe Int) =>
EntityField (PersonMaybeAgeGeneric backend) typ
PersonMaybeAgeAge EntityField (PersonMaybeAgeGeneric backend) (Maybe Int)
-> Maybe Int -> Update (PersonMaybeAgeGeneric backend)
forall v typ.
PersistField typ =>
EntityField v typ -> typ -> Update v
+=. Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2]
      -- the correct answer depends on the backend. MongoDB assumes
      -- a 'Nothing' value is 0, and does @0 + 2@ for @Just 2@. In a SQL
      -- database, @NULL@ annihilates, so @NULL + 2 = NULL@.
      PersonMaybeAgeGeneric backend -> Maybe Int
forall backend. PersonMaybeAgeGeneric backend -> Maybe Int
personMaybeAgeAge PersonMaybeAgeGeneric backend
noAge2 Maybe Int -> Maybe Int -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== case BackendNullUpdateBehavior
handleNull of
          BackendNullUpdateBehavior
AssumeNullIsZero ->
              Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2
          BackendNullUpdateBehavior
Don'tUpdateNull ->
              Maybe Int
forall a. Maybe a
Nothing

  String -> Spec -> Spec
forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"putMany" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"adds new rows when entity has no unique constraints" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        let mkPerson :: Text -> Person1Generic backend
mkPerson Text
name_ = Text -> Int -> Person1Generic backend
forall backend. Text -> Int -> Person1Generic backend
Person1 Text
name_ Int
25
        let names :: [Text]
names = [Text
"putMany bob", Text
"putMany bob", Text
"putMany smith"]
        let records :: [Person1Generic backend]
records = (Text -> Person1Generic backend)
-> [Text] -> [Person1Generic backend]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Person1Generic backend
forall backend. Text -> Person1Generic backend
mkPerson [Text]
names
        ()
_ <- [Person1Generic backend] -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[record] -> ReaderT backend m ()
putMany [Person1Generic backend]
records
        [Entity (Person1Generic backend)]
entitiesDb <- [Filter (Person1Generic backend)]
-> [SelectOpt (Person1Generic backend)]
-> ReaderT backend m [Entity (Person1Generic backend)]
forall record backend (m :: * -> *).
(MonadIO m, PersistQueryRead backend,
 PersistRecordBackend record backend) =>
[Filter record]
-> [SelectOpt record] -> ReaderT backend m [Entity record]
selectList [EntityField (Person1Generic backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (Person1Generic backend) typ
Person1Name EntityField (Person1Generic backend) Text
-> [Text] -> Filter (Person1Generic backend)
forall v typ.
PersistField typ =>
EntityField v typ -> [typ] -> Filter v
<-. [Text]
names] []
        let recordsDb :: [Person1Generic backend]
recordsDb = (Entity (Person1Generic backend) -> Person1Generic backend)
-> [Entity (Person1Generic backend)] -> [Person1Generic backend]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Entity (Person1Generic backend) -> Person1Generic backend
forall record. Entity record -> record
entityVal [Entity (Person1Generic backend)]
entitiesDb
        [Person1Generic backend]
recordsDb [Person1Generic backend]
-> [Person1Generic backend] -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== [Person1Generic backend]
records
        [Filter (Person1Generic backend)] -> ReaderT backend m ()
forall backend (m :: * -> *) record.
(PersistQueryWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[Filter record] -> ReaderT backend m ()
deleteWhere [EntityField (Person1Generic backend) Text
forall backend typ.
(typ ~ Text) =>
EntityField (Person1Generic backend) typ
Person1Name EntityField (Person1Generic backend) Text
-> [Text] -> Filter (Person1Generic backend)
forall v typ.
PersistField typ =>
EntityField v typ -> [typ] -> Filter v
<-. [Text]
names]
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"adds new rows when no conflicts" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        let mkUpsert :: Text -> UpsertGeneric backend
mkUpsert Text
e = Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
e Text
"new" Text
"" Int
1
        let keys :: [Text]
keys = [Text
"putMany1",Text
"putMany2",Text
"putMany3"]
        let vals :: [UpsertGeneric backend]
vals = (Text -> UpsertGeneric backend)
-> [Text] -> [UpsertGeneric backend]
forall a b. (a -> b) -> [a] -> [b]
map Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert [Text]
keys
        ()
_ <- [UpsertGeneric backend] -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[record] -> ReaderT backend m ()
putMany [UpsertGeneric backend]
vals
        Just (Entity Key (UpsertGeneric backend)
_ UpsertGeneric backend
v1) <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany1"
        Just (Entity Key (UpsertGeneric backend)
_ UpsertGeneric backend
v2) <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany2"
        Just (Entity Key (UpsertGeneric backend)
_ UpsertGeneric backend
v3) <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany3"
        [UpsertGeneric backend
v1,UpsertGeneric backend
v2,UpsertGeneric backend
v3] [UpsertGeneric backend]
-> [UpsertGeneric backend] -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== [UpsertGeneric backend]
vals
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany1"
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany2"
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany3"
    String -> IO () -> SpecWith (Arg (IO ()))
forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"handles conflicts by replacing old keys with new records" (IO () -> SpecWith (Arg (IO ())))
-> IO () -> SpecWith (Arg (IO ()))
forall a b. (a -> b) -> a -> b
$ RunDb backend m
runDb RunDb backend m -> RunDb backend m
forall a b. (a -> b) -> a -> b
$ do
        let mkUpsert1 :: Text -> UpsertGeneric backend
mkUpsert1 Text
e = Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
e Text
"new" Text
"" Int
1
        let mkUpsert2 :: Text -> UpsertGeneric backend
mkUpsert2 Text
e = Text -> Text -> Text -> Int -> UpsertGeneric backend
forall backend.
Text -> Text -> Text -> Int -> UpsertGeneric backend
Upsert Text
e Text
"new" Text
"" Int
2
        let vals :: [UpsertGeneric backend]
vals = (Text -> UpsertGeneric backend)
-> [Text] -> [UpsertGeneric backend]
forall a b. (a -> b) -> [a] -> [b]
map Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert2 [Text
"putMany4", Text
"putMany5", Text
"putMany6", Text
"putMany7"]
        Entity Key (UpsertGeneric backend)
k1 UpsertGeneric backend
_ <- UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (UpsertGeneric backend
 -> ReaderT backend m (Entity (UpsertGeneric backend)))
-> UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall a b. (a -> b) -> a -> b
$ Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert1 Text
"putMany4"
        Entity Key (UpsertGeneric backend)
k2 UpsertGeneric backend
_ <- UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
 MonadIO m) =>
e -> ReaderT backend m (Entity e)
insertEntity (UpsertGeneric backend
 -> ReaderT backend m (Entity (UpsertGeneric backend)))
-> UpsertGeneric backend
-> ReaderT backend m (Entity (UpsertGeneric backend))
forall a b. (a -> b) -> a -> b
$ Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert1 Text
"putMany5"
        ()
_ <- [UpsertGeneric backend] -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
[record] -> ReaderT backend m ()
putMany ([UpsertGeneric backend] -> ReaderT backend m ())
-> [UpsertGeneric backend] -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert1 Text
"putMany4" UpsertGeneric backend
-> [UpsertGeneric backend] -> [UpsertGeneric backend]
forall a. a -> [a] -> [a]
: [UpsertGeneric backend]
forall backend. [UpsertGeneric backend]
vals
        Just Entity (UpsertGeneric backend)
e1 <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany4"
        Just Entity (UpsertGeneric backend)
e2 <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany5"
        Just e3 :: Entity (UpsertGeneric backend)
e3@(Entity Key (UpsertGeneric backend)
k3 UpsertGeneric backend
_) <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany6"
        Just e4 :: Entity (UpsertGeneric backend)
e4@(Entity Key (UpsertGeneric backend)
k4 UpsertGeneric backend
_) <- Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy (Unique (UpsertGeneric backend)
 -> ReaderT backend m (Maybe (Entity (UpsertGeneric backend))))
-> Unique (UpsertGeneric backend)
-> ReaderT backend m (Maybe (Entity (UpsertGeneric backend)))
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany7"

        [Entity (UpsertGeneric backend)
e1,Entity (UpsertGeneric backend)
e2,Entity (UpsertGeneric backend)
e3,Entity (UpsertGeneric backend)
e4] [Entity (UpsertGeneric backend)]
-> [Entity (UpsertGeneric backend)] -> ReaderT backend m ()
forall a (m :: * -> *).
(HasCallStack, Eq a, Show a, MonadIO m) =>
a -> a -> m ()
@== [ Key (UpsertGeneric backend)
-> UpsertGeneric backend -> Entity (UpsertGeneric backend)
forall record. Key record -> record -> Entity record
Entity Key (UpsertGeneric backend)
k1 (Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert2 Text
"putMany4")
                          , Key (UpsertGeneric backend)
-> UpsertGeneric backend -> Entity (UpsertGeneric backend)
forall record. Key record -> record -> Entity record
Entity Key (UpsertGeneric backend)
k2 (Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert2 Text
"putMany5")
                          , Key (UpsertGeneric backend)
-> UpsertGeneric backend -> Entity (UpsertGeneric backend)
forall record. Key record -> record -> Entity record
Entity Key (UpsertGeneric backend)
k3 (Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert2 Text
"putMany6")
                          , Key (UpsertGeneric backend)
-> UpsertGeneric backend -> Entity (UpsertGeneric backend)
forall record. Key record -> record -> Entity record
Entity Key (UpsertGeneric backend)
k4 (Text -> UpsertGeneric backend
forall backend. Text -> UpsertGeneric backend
mkUpsert2 Text
"putMany7")
                          ]
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany4"
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany5"
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany6"
        Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
 PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m ()
deleteBy (Unique (UpsertGeneric backend) -> ReaderT backend m ())
-> Unique (UpsertGeneric backend) -> ReaderT backend m ()
forall a b. (a -> b) -> a -> b
$ Text -> Unique (UpsertGeneric backend)
forall backend. Text -> Unique (UpsertGeneric backend)
UniqueUpsert Text
"putMany7"