Niarn200
Niarn200

Reputation: 33

Entering relations to database using Persistent

Starting out with Haskell and Yesod, probably getting a bit too far with Yesod relative to Haskell :)

I build entities using Persistent via

share [mkPersist sqlSettings, mkMigrate "migrateAll"][persistLowerCase|
Game
  title String
  company String
  UniqueTitle title
  deriving Show
Tag
  label String
  description String Maybe
  UniqueLabel label
  deriving Show
GameTag
  gameId GameId
  tagId TagId
  UniqueGameTag gameId tagId
|]

-- Yesod related code ...

In main I have

main :: IO ()
main = do
let taggings = fromFile :: [(Game, Tag)] -- fromFile code not included
runStderrLoggingT $ withSqlitePool ":inmemory:" 10 $ λpool →  liftIO $ do
runResourceT $ flip runSqlPool pool $ do
  runMigration migrateAll
  let (g, t) = head taggings
  gid ←  insert g
  tid ←  insert t
  insert (GameTag gid tid)
warp 3000 $ App pool

Doing this I get the first relation into the database, and by selecting elements from the list I can add more 'by hand', but I can't figure out how to get all the relations into the database by somehow iterating over taggings. How do i define a function that I can map over taggings ::[(Game, Tag)] and inserts the game tags of the type GameTag constructed by Persistent?

Upvotes: 3

Views: 143

Answers (1)

jamshidh
jamshidh

Reputation: 12070

The main trick here isn't in pulling out the function, that is easy:

f (g, t) = do
  gid <- insert g
  tid <- insert t
  insert (GameTag gid tid)

The trick is knowing how to use this.... Standard map won't work alone, because the function is defined in a monad (you can use it, it will just give you a list of actions back without running them).

map f taggings -- returns just a list, type [ResourceT IO a], doesn't run anything

Here are two ways to actually run the actions from within main.

sequence (map f taggings) --sequentially runs the actions in the list

or, the more readable

forM taggings f

or, in the slightly more verbose

forM taggings $ \tagging -> do
  f tagging

You also might want to look at mapM. Also also should learn about forM_ and sequence_ to supress the (often useless) return values.

Upvotes: 2

Related Questions