2015-05-13 6 views
2

Я искал четкий ответ на этот вопрос, но еще не смог найти его - Как включить автоматическое ведение журнала SQL-запросов, выполняемых persistent? Может ли кто-нибудь дать мне небольшую примерную программу для этого?Как включить автоматическое ведение журнала SQL-запросов с помощью Persistent

Ниже приведен пример программы, которая в настоящее время не имеет протоколирования. Как включить запись в него?

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) 

ответ

3

Необходимо ввести код SQL в Monad, который реализует MonadLogger, а не только IO. (см. http://hackage.haskell.org/package/monad-logger-0.3.13.1/docs/Control-Monad-Logger.html#v:runStdoutLoggingT). Однако runSqlite уже устанавливает для вас журнал (никому ...), поэтому вам нужно использовать функцию нижнего уровня сSqliteConn. Так, например, если вы измените свой код:

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

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

(с соответствующими зависимостями на resourcet и монады-регистратора), вы можете иметь ваш SQL заявление написано в стандартный вывод.

Как пример в реальной жизни, посмотрите проект моего браузера scion-class-браузера: в 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, которая делает то, что вы хотите.

В качестве примечания, ваш код не печатает из согласующих записей, потому что вы не должны сравнивать с валь Ничего, но вместо того, чтобы использовать isNothing:

where_ (isNothing $ person ^. PersonStatus) 
+0

Я может быть что-то отсутствует. Я попытался ввести код, но он, похоже, не имеет эффекта. Правильно ли следующее? 'главная :: IO()' ' основной = runResourceT $ runStdoutLoggingT $ runSqlite ": память:" $ do' Выход остается только -' Перенастройка: CREATE TABLE "лицо" ("идентификатор" INTEGER PRIMARY KEY , "name" VARCHAR NOT NULL, "status" VARCHAR NULL) ' –

+1

Простите, моя ошибка, runSqlLite уже устанавливает регистрацию (никому), поэтому вам нужно использовать функции нижнего уровня. Я обновил свой ответ. –

+0

Это сработало! Благодаря! Да, я понял, что должен был использовать 'isNothing', это ошибка, которая потребовала времени для отслеживания без регистрации SQL и вызвала этот вопрос :) –