如何使用Persistent启用SQL语句的自动日志记录

时间:2015-05-13 12:32:32

标签: haskell logging persistent esqueleto

我已经搜索了这个问题的明确答案,但还没有找到一个答案 - 如何启用持久执行的SQL语句的自动记录?有人可以给我一个小例子程序吗?

以下是目前没有记录的示例程序。如何启用日志记录?

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
    Person
    name Text
    status Text Maybe
    deriving Show
|]

main :: IO ()
main = runSqlite ":memory:" $ do
    runMigration migrateAll
    insert (Person "Oliver Charles" Nothing)
    insert (Person "Jon Snow" Nothing)
    insert (Person "Marky Mark" (Just "helloo helloo"))
    noStatusPeople >>= mapM_ (liftIO . print)
    where
        noStatusPeople =
            select $ from $ \person -> do
                where_ (person ^. PersonStatus ==. val Nothing)
                return (person ^. PersonName)

1 个答案:

答案 0 :(得分:3)

您需要在实现MonadLogger而不仅仅是IO的Monad中调用您的SQL代码。 (见http://hackage.haskell.org/package/monad-logger-0.3.13.1/docs/Control-Monad-Logger.html#v:runStdoutLoggingT)。但是,runSqlite已经为您设置了日志记录(无...),因此您需要使用较低级别的函数withSqliteConn。 例如,如果您将代码更改为:

import Control.Monad.Logger
import Control.Monad.Trans.Resource

runResourceT $ runStdoutLoggingT $ withSqliteConn ":memory:" . runSqlConn  $ do...

(对resourcet和monad-logger有适当的依赖关系),你可以将你的SQL语句写入标准输出。

作为一个真实的例子,看看我的scion-class-browser项目: 在https://github.com/JPMoresmau/scion-class-browser/blob/5ab9c7576f8faf93299826e72defe70dd5b6dd6f/src/Server/PersistentCommands.hs#L93中,您看到对runSqlite的调用。 runLogging是一个辅助函数,用于在https://github.com/JPMoresmau/scion-class-browser/blob/f7f2ab0de4f4edb01b307411abf0aa951a3c7c48/src/Scion/PersistentBrowser/DbTypes.hs#L16中定义的日志记录或无日志记录之间切换(当前构建版本不记录,由注释掉的代码替换)。

当然,你可以代替使用简单转储到stdout或stderr,编写你自己的MonadLogger实现,做你想做的事。

作为旁注,您的代码不会打印出匹配的记录,因为您不应该与val Nothing比较,而是使用isNothing:

where_ (isNothing $ person ^. PersonStatus)