2013-05-13 58 views
4

我试图在我的Yesod应用程序中分支非web服务,并且它需要与数据库进行一些交互。从this发布后,我决定将该服务放在makeApplication中。我希望我的服务在发生某些事情时返回一些价值并将其存储到数据库中。因此,我想知道最好的办法是什么?如何查询makeApplication函数中的数据库

如何在makeApplication函数中运行runDB $ insert $ Stuff (T.pack "stuff")

编辑: 正如迈克尔建议我做内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) 

而在makeApplication我用它像这样下面的辅助函数:

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

不过,我得到这个编译错误:

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

我输入错误的typ e for runPool?或者我需要为insert做一个实例? 我不明白为什么runMigration migrateAll有效,但insert没有。

回答

2

您可以在the scaffolding itself中看到如何在IO monad中运行数据库操作的演示。实质上,您需要提供两条信息:如何记录查询以及数据库连接池。您可以将该代码分解为辅助函数(例如,runDBIO),然后运行runDBIO $ insert $ Stuff $ T.pack "stuff"

+0

这听起来很酷,我会试试看!问题,你对辅助功能的看法是什么?我一直认为这是一种反模式。 – HHC 2013-05-14 01:51:05

+0

也许我们对帮助函数的定义是不同的。我的意思是一个函数将一些常见的代码分解出来,我绝对不会考虑一种反模式。 – 2013-05-14 05:46:08

+0

是的,如果它是通用代码,创建一个函数是非常有意义的。也许我的意思是关于助手函数就像在Java中一样,人们制作实用程序类,将许多不相关的函数放入同一个类中。 – HHC 2013-05-14 06:04:14