Use subsnaplet during snaplet initialization?

五迷三道 提交于 2019-12-06 11:52:38

The DB access functions provided by snaplet-postgresql-simple run in any monad that is an instance of the HasPostgres type class. Typically, this will be the Handler monad for your application.

You can't use Handler functions inside an Initializer. The whole point of the Initializer monad is to set up the initial state data type that is needed to run the web server and the Handler monad. So it's truly impossible to run handlers inside an initializer--unless of course you're running one web server from inside another web server...ick.

So you have two possible options. You could create a HasPostgres instance for your Initializer. But that doesn't make much sense unless you're connecting to a static server. This might be acceptable if you're doing debugging. Sometimes I'll do that for IO to make it trivial to test my database functions:

instance HasPostgres IO where
    getPostgresState = do
        pool <- createPool (connect $ ConnectInfo "127.0.0.1" ...) ...
        return $ Postgres pool

But in general it won't make sense to make an instance like this for use in production code. This means that if you want to access the database in an Initializer you have to use the postgresql-simple functions directly rather than the wrappers provided by snaplet-postgresql-simple. That's why I exported the pgPool accessor function. It will look something like this:

initDB :: SnapletInit b (DB b)
initDB = makeSnaplet "db" "cached database" Nothing $ do
    pgs <- nestSnaplet "pgsql" pgsql pgsInit
    let pool = pgPool $ extract pgs
    results <- liftIO $ withResource pool (\conn -> query_ conn myQuery)

You can see a real live example of this in snaplet-postgresql-simple's auth backend.

Update:

I just uploaded a new version of snaplet-postgresql-simple to hackage that provides a HasPostgres instance for ReaderT. This allows you to accomplish this more simply with runReaderT. There's a small code snippet of this in the documentation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!