Pergunta

I'm attempting to fork a non-web service in my Yesod application, and it needs to do some interaction with database. From this post I decided to put the service in makeApplication. I would like my service to return some value when certain things happen and store it into database. Thus, I'm wondering whats the best way to do this?

How do I run runDB $ insert $ Stuff (T.pack "stuff") inside the makeApplication function?

EDIT: As suggested by Michael I made the following helper function inside Application.hs

runDBIO conf foundation f = do
    dbconf <- withYamlEnvironment "config/postgresql.yml" (appEnv conf)
        Database.Persist.loadConfig >>=
        Database.Persist.applyEnv
    p <- Database.Persist.createPoolConfig (dbconf :: Settings.PersistConf)
    logger <- mkLogger True stdout

    runLoggingT
        (Database.Persist.runPool dbconf f p)
        (messageLoggerSource foundation logger)

And in the makeApplication I used it like so:

runDBIO conf foundation $ do
    dbid <- insert $ Stuff (T.pack "some random stuff")
    string <- get dbid
    liftIO $ print string

However, I'm getting this compile error:

No instance for (resourcet-0.4.5:Control.Monad.Trans.Resource.MonadResource IO)
arising from a use of 'insert'

Am I inputting the wrong type for runPool? Or I need to make an instance for insert? I don't see why runMigration migrateAll works but insert does not.

Foi útil?

Solução

You can see a demonstration of how to run a database action in the IO monad in the scaffolding itself. Essentially you need to provide two pieces of information: how to log queries, and the database connection pool. You could factor that code out into a helper function (e.g., runDBIO), and then run runDBIO $ insert $ Stuff $ T.pack "stuff".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top