haskellhaskell-persistent

In Persistent (Haskell), how can I insert a record only if it doesn't already exist?


I'm a Haskell beginner, so apologies in advance!

I've been following the Persistent tutorial here.

I have a data model with a uniqueness constraint:

Book
    gutId Int
    UniqueGutId gutId
    ...
    author [AuthorId]
    ... 
Author
    gutId Int
    UniqueAuthorGutId gutId
    ...

And when I go to insert a record using this:

  runSqlite "test.db" $ do
    runMigration migrateAll

    -- FIXME: This won't work if there's an author that's already in the database.
    authorIds <- mapM insert authors

It won't work if the record is already in the database. (It'll just return an exception.) I can do this instead:

authorIds <- mapM insertUnique authors

But the problem is, I need to use authorIds to update Book records later. So I'm just wondering if anyone knows of an easy way to insert a record if it doesn't exist, and return the new key, or get the record key if it already exists, so that I have an array of keys either way. The full code at this point is up here.


Solution

  • You just need to perform both actions you mentioned yourself:

    authorIds <- forM authors $ \a -> do
        res <- insertUnique a
        case res of
            Just key -> return key
            _ -> fromJust <$> getBy (authorGutId a)