2

我正在尝试使用 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 连接?

4

1 回答 1

3

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

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"
于 2012-10-23T13:21:29.987 回答