{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
module Database.Persist.Class.PersistUnique
( PersistUniqueRead(..)
, PersistUniqueWrite(..)
, OnlyOneUniqueKey(..)
, onlyOneUniqueDef
, AtLeastOneUniqueKey(..)
, atLeastOneUniqueDef
, NoUniqueKeysError
, MultipleUniqueKeysError
, getByValue
, getByValueUniques
, insertBy
, insertUniqueEntity
, replaceUnique
, checkUnique
, checkUniqueUpdateable
, onlyUnique
, defaultUpsertBy
, defaultPutMany
, persistUniqueKeyValues
)
where
import Control.Monad (liftM)
import Control.Monad.IO.Class (MonadIO)
import Control.Monad.Trans.Reader (ReaderT)
import Data.Function (on)
import Data.List (deleteFirstsBy, (\\))
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NEL
import qualified Data.Map as Map
import Data.Maybe (catMaybes, isJust)
import GHC.TypeLits (ErrorMessage(..))
import Database.Persist.Class.PersistEntity
import Database.Persist.Class.PersistStore
import Database.Persist.Types
class PersistStoreRead backend => PersistUniqueRead backend where
getBy
:: forall record m. (MonadIO m, PersistRecordBackend record backend)
=> Unique record -> ReaderT backend m (Maybe (Entity record))
existsBy
:: forall record m. (MonadIO m, PersistRecordBackend record backend)
=> Unique record -> ReaderT backend m Bool
existsBy Unique record
uniq = forall a. Maybe a -> Bool
isJust forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy Unique record
uniq
class (PersistUniqueRead backend, PersistStoreWrite backend) =>
PersistUniqueWrite backend where
deleteBy
:: forall record m. (MonadIO m, PersistRecordBackend record backend)
=> Unique record -> ReaderT backend m ()
insertUnique
:: forall record m. (MonadIO m, PersistRecordBackend record backend, SafeToInsert record)
=> record -> ReaderT backend m (Maybe (Key record))
insertUnique record
datum = do
Maybe (Unique record)
conflict <- forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
PersistUniqueRead backend) =>
record -> ReaderT backend m (Maybe (Unique record))
checkUnique record
datum
case Maybe (Unique record)
conflict of
Maybe (Unique record)
Nothing -> forall a. a -> Maybe a
Just forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Key record)
insert record
datum
Just Unique record
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
insertUnique_
:: forall record m. (MonadIO m, PersistRecordBackend record backend, SafeToInsert record)
=> record -> ReaderT backend m (Maybe ())
insertUnique_ record
datum = do
Maybe (Unique record)
conflict <- forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
PersistUniqueRead backend) =>
record -> ReaderT backend m (Maybe (Unique record))
checkUnique record
datum
case Maybe (Unique record)
conflict of
Maybe (Unique record)
Nothing -> forall a. a -> Maybe a
Just forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m ()
insert_ record
datum
Just Unique record
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
upsert
:: forall record m. (MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record, SafeToInsert record)
=> record
-> [Update record]
-> ReaderT backend m (Entity record)
upsert record
record [Update record]
updates = do
Unique record
uniqueKey <- forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueWrite backend,
PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> ReaderT backend m (Unique record)
onlyUnique record
record
forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
upsertBy Unique record
uniqueKey record
record [Update record]
updates
upsertBy
:: forall record m. (MonadIO m, PersistRecordBackend record backend, SafeToInsert record)
=> Unique record
-> record
-> [Update record]
-> ReaderT backend m (Entity record)
upsertBy = forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend,
PersistEntity record, MonadIO m, PersistStoreWrite backend,
PersistUniqueRead backend, SafeToInsert record) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
defaultUpsertBy
putMany
:: forall record m.
( MonadIO m
, PersistRecordBackend record backend
, SafeToInsert record
)
=> [record]
-> ReaderT backend m ()
putMany = forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend,
PersistEntity record, MonadIO m, PersistStoreWrite backend,
PersistUniqueRead backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
defaultPutMany
class PersistEntity record => OnlyOneUniqueKey record where
onlyUniqueP :: record -> Unique record
onlyOneUniqueDef
:: (OnlyOneUniqueKey record, Monad proxy)
=> proxy record
-> UniqueDef
onlyOneUniqueDef :: forall record (proxy :: * -> *).
(OnlyOneUniqueKey record, Monad proxy) =>
proxy record -> UniqueDef
onlyOneUniqueDef proxy record
prxy =
case EntityDef -> [UniqueDef]
getEntityUniques (forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef proxy record
prxy) of
[UniqueDef
uniq] -> UniqueDef
uniq
[UniqueDef]
_ -> forall a. HasCallStack => [Char] -> a
error [Char]
"impossible due to OnlyOneUniqueKey constraint"
type NoUniqueKeysError ty =
'Text "The entity "
':<>: 'ShowType ty
':<>: 'Text " does not have any unique keys."
':$$: 'Text "The function you are trying to call requires a unique key "
':<>: 'Text "to be defined on the entity."
type MultipleUniqueKeysError ty =
'Text "The entity "
':<>: 'ShowType ty
':<>: 'Text " has multiple unique keys."
':$$: 'Text "The function you are trying to call requires only a single "
':<>: 'Text "unique key."
':$$: 'Text "There is probably a variant of the function with 'By' "
':<>: 'Text "appended that will allow you to select a unique key "
':<>: 'Text "for the operation."
class PersistEntity record => AtLeastOneUniqueKey record where
requireUniquesP :: record -> NonEmpty (Unique record)
atLeastOneUniqueDef
:: (AtLeastOneUniqueKey record, Monad proxy)
=> proxy record
-> NonEmpty UniqueDef
atLeastOneUniqueDef :: forall record (proxy :: * -> *).
(AtLeastOneUniqueKey record, Monad proxy) =>
proxy record -> NonEmpty UniqueDef
atLeastOneUniqueDef proxy record
prxy =
case EntityDef -> [UniqueDef]
getEntityUniques (forall record (proxy :: * -> *).
PersistEntity record =>
proxy record -> EntityDef
entityDef proxy record
prxy) of
(UniqueDef
x:[UniqueDef]
xs) -> UniqueDef
x forall a. a -> [a] -> NonEmpty a
:| [UniqueDef]
xs
[UniqueDef]
_ ->
forall a. HasCallStack => [Char] -> a
error [Char]
"impossible due to AtLeastOneUniqueKey record constraint"
insertBy
:: forall record backend m.
( MonadIO m
, PersistUniqueWrite backend
, PersistRecordBackend record backend
, AtLeastOneUniqueKey record
, SafeToInsert record
)
=> record -> ReaderT backend m (Either (Entity record) (Key record))
insertBy :: forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueWrite backend,
PersistRecordBackend record backend, AtLeastOneUniqueKey record,
SafeToInsert record) =>
record -> ReaderT backend m (Either (Entity record) (Key record))
insertBy record
val = do
Maybe (Entity record)
res <- forall record (m :: * -> *) backend.
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend, AtLeastOneUniqueKey record) =>
record -> ReaderT backend m (Maybe (Entity record))
getByValue record
val
case Maybe (Entity record)
res of
Maybe (Entity record)
Nothing -> forall a b. b -> Either a b
Right forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Key record)
insert record
val
Just Entity record
z -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left Entity record
z
insertUniqueEntity
:: forall record backend m
. ( MonadIO m
, PersistRecordBackend record backend
, PersistUniqueWrite backend
, SafeToInsert record
)
=> record
-> ReaderT backend m (Maybe (Entity record))
insertUniqueEntity :: forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
PersistUniqueWrite backend, SafeToInsert record) =>
record -> ReaderT backend m (Maybe (Entity record))
insertUniqueEntity record
datum =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Key record
key -> forall record. Key record -> record -> Entity record
Entity Key record
key record
datum) forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` forall backend record (m :: * -> *).
(PersistUniqueWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
record -> ReaderT backend m (Maybe (Key record))
insertUnique record
datum
onlyUnique
:: forall record backend m.
( MonadIO m
, PersistUniqueWrite backend
, PersistRecordBackend record backend
, OnlyOneUniqueKey record
)
=> record -> ReaderT backend m (Unique record)
onlyUnique :: forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueWrite backend,
PersistRecordBackend record backend, OnlyOneUniqueKey record) =>
record -> ReaderT backend m (Unique record)
onlyUnique = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall record. OnlyOneUniqueKey record => record -> Unique record
onlyUniqueP
getByValue
:: forall record m backend.
( MonadIO m
, PersistUniqueRead backend
, PersistRecordBackend record backend
, AtLeastOneUniqueKey record
)
=> record -> ReaderT backend m (Maybe (Entity record))
getByValue :: forall record (m :: * -> *) backend.
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend, AtLeastOneUniqueKey record) =>
record -> ReaderT backend m (Maybe (Entity record))
getByValue record
record = do
let uniqs :: NonEmpty (Unique record)
uniqs = forall record.
AtLeastOneUniqueKey record =>
record -> NonEmpty (Unique record)
requireUniquesP record
record
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Entity record))
getByValueUniques (forall a. NonEmpty a -> [a]
NEL.toList NonEmpty (Unique record)
uniqs)
getByValueUniques
:: forall record backend m.
( MonadIO m
, PersistUniqueRead backend
, PersistRecordBackend record backend
)
=> [Unique record]
-> ReaderT backend m (Maybe (Entity record))
getByValueUniques :: forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Entity record))
getByValueUniques [Unique record]
uniqs =
forall {record} {backend} {m :: * -> *}.
(PersistEntityBackend record ~ BaseBackend backend, MonadIO m,
PersistUniqueRead backend, PersistEntity record) =>
[Unique record] -> ReaderT backend m (Maybe (Entity record))
checkUniques [Unique record]
uniqs
where
checkUniques :: [Unique record] -> ReaderT backend m (Maybe (Entity record))
checkUniques [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
checkUniques (Unique record
x:[Unique record]
xs) = do
Maybe (Entity record)
y <- forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy Unique record
x
case Maybe (Entity record)
y of
Maybe (Entity record)
Nothing -> [Unique record] -> ReaderT backend m (Maybe (Entity record))
checkUniques [Unique record]
xs
Just Entity record
z -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Entity record
z
replaceUnique
:: forall record backend m. ( MonadIO m
, Eq (Unique record)
, PersistRecordBackend record backend
, PersistUniqueWrite backend )
=> Key record -> record -> ReaderT backend m (Maybe (Unique record))
replaceUnique :: forall record backend (m :: * -> *).
(MonadIO m, Eq (Unique record),
PersistRecordBackend record backend, PersistUniqueWrite backend) =>
Key record -> record -> ReaderT backend m (Maybe (Unique record))
replaceUnique Key record
key record
datumNew = forall record backend (m :: * -> *).
(PersistStoreRead backend, PersistRecordBackend record backend,
MonadIO m) =>
Key record -> ReaderT backend m record
getJust Key record
key forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= record -> ReaderT backend m (Maybe (Unique record))
replaceOriginal
where
uniqueKeysNew :: [Unique record]
uniqueKeysNew = forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys record
datumNew
replaceOriginal :: record -> ReaderT backend m (Maybe (Unique record))
replaceOriginal record
original = do
Maybe (Unique record)
conflict <- forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeys [Unique record]
changedKeys
case Maybe (Unique record)
conflict of
Maybe (Unique record)
Nothing -> forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend) =>
Key record -> record -> ReaderT backend m ()
replace Key record
key record
datumNew forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
(Just Unique record
conflictingKey) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Unique record
conflictingKey
where
changedKeys :: [Unique record]
changedKeys = [Unique record]
uniqueKeysNew forall a. Eq a => [a] -> [a] -> [a]
\\ [Unique record]
uniqueKeysOriginal
uniqueKeysOriginal :: [Unique record]
uniqueKeysOriginal = forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys record
original
checkUnique
:: forall record backend m. ( MonadIO m
, PersistRecordBackend record backend
, PersistUniqueRead backend)
=> record -> ReaderT backend m (Maybe (Unique record))
checkUnique :: forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
PersistUniqueRead backend) =>
record -> ReaderT backend m (Maybe (Unique record))
checkUnique = forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeys forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys
checkUniqueKeys
:: forall record backend m. ( MonadIO m
, PersistUniqueRead backend
, PersistRecordBackend record backend)
=> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeys :: forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeys [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
checkUniqueKeys (Unique record
x:[Unique record]
xs) = do
Maybe (Entity record)
y <- forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy Unique record
x
case Maybe (Entity record)
y of
Maybe (Entity record)
Nothing -> forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeys [Unique record]
xs
Just Entity record
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Unique record
x)
checkUniqueUpdateable
:: forall record backend m. ( MonadIO m
, PersistRecordBackend record backend
, PersistUniqueRead backend)
=> Entity record -> ReaderT backend m (Maybe (Unique record))
checkUniqueUpdateable :: forall record backend (m :: * -> *).
(MonadIO m, PersistRecordBackend record backend,
PersistUniqueRead backend) =>
Entity record -> ReaderT backend m (Maybe (Unique record))
checkUniqueUpdateable (Entity Key record
key record
record) =
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
Key record
-> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeysUpdateable Key record
key (forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys record
record)
checkUniqueKeysUpdateable
:: forall record backend m. ( MonadIO m
, PersistUniqueRead backend
, PersistRecordBackend record backend)
=> Key record -> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeysUpdateable :: forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
Key record
-> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeysUpdateable Key record
_ [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
checkUniqueKeysUpdateable Key record
key (Unique record
x:[Unique record]
xs) = do
Maybe (Entity record)
y <- forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy Unique record
x
case Maybe (Entity record)
y of
Maybe (Entity record)
Nothing ->
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
Key record
-> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeysUpdateable Key record
key [Unique record]
xs
Just (Entity Key record
k record
_)
| Key record
key forall a. Eq a => a -> a -> Bool
== Key record
k ->
forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
Key record
-> [Unique record] -> ReaderT backend m (Maybe (Unique record))
checkUniqueKeysUpdateable Key record
key [Unique record]
xs
Just Entity record
_ ->
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Unique record
x)
defaultUpsertBy
:: ( PersistEntityBackend record ~ BaseBackend backend
, PersistEntity record
, MonadIO m
, PersistStoreWrite backend
, PersistUniqueRead backend
, SafeToInsert record
)
=> Unique record
-> record
-> [Update record]
-> ReaderT backend m (Entity record)
defaultUpsertBy :: forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend,
PersistEntity record, MonadIO m, PersistStoreWrite backend,
PersistUniqueRead backend, SafeToInsert record) =>
Unique record
-> record -> [Update record] -> ReaderT backend m (Entity record)
defaultUpsertBy Unique record
uniqueKey record
record [Update record]
updates = do
Maybe (Entity record)
mrecord <- forall backend record (m :: * -> *).
(PersistUniqueRead backend, MonadIO m,
PersistRecordBackend record backend) =>
Unique record -> ReaderT backend m (Maybe (Entity record))
getBy Unique record
uniqueKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall e backend (m :: * -> *).
(PersistStoreWrite backend, PersistRecordBackend e backend,
SafeToInsert e, MonadIO m, HasCallStack) =>
e -> ReaderT backend m (Entity e)
insertEntity record
record) (forall {a1} {backend} {m :: * -> *}.
(PersistEntityBackend a1 ~ BaseBackend backend, MonadIO m,
PersistStoreWrite backend, PersistEntity a1) =>
Entity a1 -> [Update a1] -> ReaderT backend m (Entity a1)
`updateGetEntity` [Update record]
updates) Maybe (Entity record)
mrecord
where
updateGetEntity :: Entity a1 -> [Update a1] -> ReaderT backend m (Entity a1)
updateGetEntity (Entity Key a1
k a1
_) [Update a1]
upds =
(forall record. Key record -> record -> Entity record
Entity Key a1
k) forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` (forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend) =>
Key record -> [Update record] -> ReaderT backend m record
updateGet Key a1
k [Update a1]
upds)
defaultPutMany
:: forall record backend m. ( PersistEntityBackend record ~ BaseBackend backend
, PersistEntity record
, MonadIO m
, PersistStoreWrite backend
, PersistUniqueRead backend
, SafeToInsert record
)
=> [record]
-> ReaderT backend m ()
defaultPutMany :: forall record backend (m :: * -> *).
(PersistEntityBackend record ~ BaseBackend backend,
PersistEntity record, MonadIO m, PersistStoreWrite backend,
PersistUniqueRead backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
defaultPutMany [] = forall (m :: * -> *) a. Monad m => a -> m a
return ()
defaultPutMany rsD :: [record]
rsD@(record
e:[record]
_) = do
case forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys record
e of
[] -> forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
insertMany_ [record]
rsD
[Unique record]
_ -> ReaderT backend m ()
go
where
go :: ReaderT backend m ()
go = do
let rs :: [record]
rs = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (\record
r -> (forall record. PersistEntity record => record -> [PersistValue]
persistUniqueKeyValues record
r, record
r))
forall a b. (a -> b) -> a -> b
$ [record]
rsD
[Maybe (Entity record)]
mEsOld <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall record backend (m :: * -> *).
(MonadIO m, PersistUniqueRead backend,
PersistRecordBackend record backend) =>
[Unique record] -> ReaderT backend m (Maybe (Entity record))
getByValueUniques forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys) [record]
rs
let merge :: Maybe a -> b -> Maybe (a, b)
merge (Just a
x) b
y = forall a. a -> Maybe a
Just (a
x, b
y)
merge Maybe a
_ b
_ = forall a. Maybe a
Nothing
let mEsOldAndRs :: [Maybe (Entity record, record)]
mEsOldAndRs = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {a} {b}. Maybe a -> b -> Maybe (a, b)
merge [Maybe (Entity record)]
mEsOld [record]
rs
let esOldAndRs :: [(Entity record, record)]
esOldAndRs = forall a. [Maybe a] -> [a]
catMaybes [Maybe (Entity record, record)]
mEsOldAndRs
let esOld :: [Entity record]
esOld = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst [(Entity record, record)]
esOldAndRs
let rsOld :: [record]
rsOld = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall record. Entity record -> record
entityVal [Entity record]
esOld
let rsNew :: [record]
rsNew = forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
deleteFirstsBy (forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall record. PersistEntity record => record -> [PersistValue]
persistUniqueKeyValues) [record]
rs [record]
rsOld
let rsUpd :: [record]
rsUpd = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> b
snd [(Entity record, record)]
esOldAndRs
let ksOld :: [Key record]
ksOld = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall record. Entity record -> Key record
entityKey [Entity record]
esOld
let krs :: [(Key record, record)]
krs = forall a b. [a] -> [b] -> [(a, b)]
zip [Key record]
ksOld [record]
rsUpd
forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend, SafeToInsert record) =>
[record] -> ReaderT backend m ()
insertMany_ [record]
rsNew
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall backend record (m :: * -> *).
(PersistStoreWrite backend, MonadIO m,
PersistRecordBackend record backend) =>
Key record -> record -> ReaderT backend m ()
replace) [(Key record, record)]
krs
persistUniqueKeyValues :: PersistEntity record => record -> [PersistValue]
persistUniqueKeyValues :: forall record. PersistEntity record => record -> [PersistValue]
persistUniqueKeyValues = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap forall record.
PersistEntity record =>
Unique record -> [PersistValue]
persistUniqueToValues forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall record. PersistEntity record => record -> [Unique record]
persistUniqueKeys