Skip to content

Commit

Permalink
Add insertUnique_ to PersistUniqueWrite (#1469)
Browse files Browse the repository at this point in the history
* Add insertUnique_ to PersistUniqueWrite

- Works the same as insertUnique, but doesn't return a key
- For SQL databases this can be twice as fast since there is no SELECT
  to get the key after the original INSERT

commit 093b2347762e15a12fc4422c718d6adeb3e7fb89
Author: Luke Seale <19484084+lbseale@users.noreply.github.com>
Date:   Tue Jan 24 17:33:41 2023 -0800

    Add a test for insertUnique_

commit 75ffc4f3eb5048d1983fab6d8b0df22e1d6f4517
Author: Luke Seale <19484084+lbseale@users.noreply.github.com>
Date:   Tue Jan 24 17:33:19 2023 -0800

    Add help for insertUnique_

    - Also fix incorrect type annotation

commit bc81b359f454d0984062ab4f32980df75a6a85d8
Author: Luke Seale <19484084+lbseale@users.noreply.github.com>
Date:   Tue Jan 24 17:31:50 2023 -0800

    Add insertUnique_ to PersistUniqueWrite typeclass

    - Works the same way is insertUnique, but calls insert_ instead of
      insert
    - Return type is Maybe (), since it insert_ doesn't return a key

* Add since tag for insertUnqiue_

* Add change to ChangeLog
  • Loading branch information
lbseale committed Mar 3, 2023
1 parent 23773f2 commit 20f6914
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
11 changes: 11 additions & 0 deletions persistent-test/src/ReadWriteTest.hs
Expand Up @@ -53,3 +53,14 @@ specsWith originalRunDb = describe "ReadWriteTest" $ do
mkey1 @== Nothing
mperson <- selectFirst [PersonName ==. name_] []
fmap entityVal mperson @== Just person

let nameLuke = "Luke Seale New"
personLuke = Person nameLuke 31 Nothing
mkey2 <- insertUnique_ personLuke
mkey3 <- insertUnique_ personLuke
mkey3 @== Nothing
mpersonLuke <- selectFirst [PersonName ==. nameLuke] []
fmap entityVal mpersonLuke @== Just personLuke



6 changes: 6 additions & 0 deletions persistent/ChangeLog.md
Expand Up @@ -8,6 +8,12 @@
* [#1476](https://github.com/yesodweb/persistent/pull/1476)
* Fix `mkRecordName` to suffix `_` if the field name matches any of Haskell keywords.

## 2.14.5.0

* [#1469] https://github.com/yesodweb/persistent/pull/1469
* Change default implementation for `insertUnique_` to not perform
unecessary queries (mirrors 1449)

## 2.14.4.4

* [#1460] https://github.com/yesodweb/persistent/pull/1460
Expand Down
31 changes: 31 additions & 0 deletions persistent/Database/Persist/Class/PersistUnique.hs
Expand Up @@ -140,6 +140,37 @@ class (PersistUniqueRead backend, PersistStoreWrite backend) =>
Nothing -> Just `liftM` insert datum
Just _ -> return Nothing

-- | Same as 'insertUnique' but doesn't return a @Key@.
--
-- === __Example usage__
--
-- With <#schema-persist-unique-1 schema-1> and <#dataset-persist-unique-1 dataset-1>, we try to insert the following two records:
--
-- > linusId <- insertUnique_ $ User "Linus" 48
-- > spjId <- insertUnique_ $ User "SPJ" 90
--
-- > +-----+------+-----+
-- > |id |name |age |
-- > +-----+------+-----+
-- > |1 |SPJ |40 |
-- > +-----+------+-----+
-- > |2 |Simon |41 |
-- > +-----+------+-----+
-- > |3 |Linus |48 |
-- > +-----+------+-----+
--
-- Linus's record was inserted to <#dataset-persist-unique-1 dataset-1>, while SPJ wasn't because SPJ already exists in <#dataset-persist-unique-1 dataset-1>.
--
-- @since 2.14.5.0
insertUnique_
:: forall record m. (MonadIO m, PersistRecordBackend record backend, SafeToInsert record)
=> record -> ReaderT backend m (Maybe ())
insertUnique_ datum = do
conflict <- checkUnique datum
case conflict of
Nothing -> Just `liftM` insert_ datum
Just _ -> return Nothing

-- | Update based on a uniqueness constraint or insert:
--
-- * insert the new record if it does not exist;
Expand Down

0 comments on commit 20f6914

Please sign in to comment.