如何从处理程序访问全局MongoDB连接?

时间:2012-10-23 11:48:09

标签: mongodb haskell state haskell-snap-framework

我正在尝试使用Snap创建一个简单的Web应用程序。我希望有一个全局的MongoDB连接,我可以在处理程序中使用它。

我在appInit中打开此连接,该连接有效。

data App = App { _mongoDB :: Pipe -- connection
               }

appInit :: SnapletInit App App
appInit = makeSnaplet "site" "My Site" Nothing $ do
    db <- liftIO $ do
        pipe <- runIOE $ connect (host "127.0.0.1")
        return pipe
    return $ App db

但是,我不知道如何从处理程序访问此连接(_mongoDB)。我尝试了几件事,包括以下内容,但每次都会出现类型错误。

watchHandler :: Handler App App ()
watchHandler = do
    res <- liftIO $ do
        pipe <- gets _mongoDB -- type error
        results <- access pipe master "db" (find $ select [] "movies")
        return results

    writeBS "test"

它给了我以下错误:

No instance for (MonadState App IO)
  arising from a use of `gets'
Possible fix: add an instance declaration for (MonadState App IO)
In a stmt of a 'do' block: pipe <- gets _mongoDB
In the second argument of `($)', namely
  `do { pipe <- gets _mongoDB;
        results <- access pipe master "db" (find $ select [] "movies");
        return results }'
In a stmt of a 'do' block:
  res <- liftIO
         $ do { pipe <- gets _mongoDB;
                results <- access pipe master "db" (find $ select [] "movies");
                return results }

它让我感到困惑。如何从处理程序访问我的MongoDB连接?

1 个答案:

答案 0 :(得分:3)

liftIO块仅用于IO操作,访问应用程序状态需要在Handler monad本身中完成。

watchHandler :: Handler App App ()
watchHandler = do
    pipe <- gets _mongoDB
    res <- liftIO $ do
        results <- access pipe master "db" (find $ select [] "movies")
        return results

    writeBS "test"

此外,绑定值然后立即返回它是多余的。你可以写:

watchHandler :: Handler App App ()
watchHandler = do
    pipe <- gets _mongoDB
    res <- liftIO $ access pipe master "db" (find $ select [] "movies")

    writeBS "test"
相关问题