2

我已经搜索了这个问题的明确答案,但还没有找到 - 如何启用持久执行的 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)
4

1 回答 1

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...

(通过对资源和 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(当前构建版本不记录,替换为注释掉的代码)。

当然,您可以编写自己的 MonadLogger 实现来满足您的需求,而不是使用简单的转储到 stdout 或 stderr。

附带说明一下,您的代码不会打印出匹配的记录,因为您不应该与 val Nothing 进行比较,而是使用 isNothing:

where_ (isNothing $ person ^. PersonStatus)
于 2015-05-13T15:38:41.943 回答