如何在一个处理程序中使用Auth和PostgresqlSimple?

时间:2014-01-08 17:49:30

标签: haskell haskell-snap-framework

好吧,所以实际上有一些问题,我会尝试将它们中的每一个单独描述,但从某种意义上说它们都是相关的。

我想插入一个用户ID,我希望从AuthManager插入。好的,我们可以使用currentUser然后做一些maybe voodoo来获取实际的unUid。但问题何时才开始。好的,我们希望使用execute来验证查询:

execute "INSERT INTO events(title,recurring) VALUES(?,?);" (eventname,recurring)

动臂即可。好的,然后在执行cabal install时,它没有说明我没有声明HasPostgres的实例。因为我的处理程序的类型是...-> ...-> Handler App (AuthManager App),所以很有道理。 这是第一个问题:我不知道如何正确地创建实例以使类型正确正如我所尝试的那样,只是复制Application.hs中的初始实例根本无法帮助我们。

这给我们带来了在尝试寻找替代解决方案时出现的其他问题。所以我尝试的解决方案就是用execute调用替换with pg $ execute调用。这有以下结果:

Couldn't match type `App' with `AuthManager App'
Expected type: Handler App (AuthManager App) GHC.Int.Int64
  Actual type: Handler App App GHC.Int.Int64

再次,无济于事。接下来我尝试删除(AuthManager App)类型,只需用App替换它,这样我就可以用AuthManager替换with auth $ call次调用。然后我意识到这也不是解决方案,因为一旦你从那里得到AuthManager,你需要从调用它的每个函数中删除它。

我需要一些帮助来解决这个问题。我可以以某种方式提升类型来解决这个问题吗?或者什么是这个问题的好方法?


修改

好的,所以我试图从我的类型中删除AuthManager App,所以我毕竟可以使用postgres。现在,这并不像人们期望的那样顺利。下一部分来自Snap init生成的常规应用程序:

handleLoginSubmit :: Handler App App ()
handleLoginSubmit =
with auth $ loginUser "login" "password" Nothing
          (\_ ->handleLogin err) (handleFoo)
where
  err = Just "Unknown user or password"

好的,handleLoginhandleFoo现在都有Handler App App ()类型,但是Haskell抱怨它需要类型Handler App (AuthManager App) ()

Couldn't match type `App' with `AuthManager App'
Expected type: Handler App (AuthManager App) ()
  Actual type: Handler App App ()


--Definition of App:
data App = App
{ _heist :: Snaplet (Heist App)
, _sess :: Snaplet SessionManager
, _auth :: Snaplet (AuthManager App)
, _pg   :: Snaplet Postgres
}

2 个答案:

答案 0 :(得分:4)

您想使用此类型签名。

yourHandler :: Handler App App ()
    with pg $ execute ...
    with auth $ loginUser ...

with函数允许您将Handler b v函数(只能访问v snaplet的数据)引导到Handler b b,该函数可以访问所有内容。而它唯一需要做的就是镜头从b到v。

答案 1 :(得分:2)

我写了一个基于Postgres Snaplet的snaplet,所以这对你有用。

instance HasPostgres (Handler App (AuthManager App)) where
     getPostgresState = withTop pg get

然后是带有签名的路线:

myRoute :: Handler App (AuthManager App) ()