Scotty参数以Sqlite3提供

时间:2014-10-10 21:55:17

标签: haskell sqlite hdbc scotty

我正在尝试创建一个网站,通过URL路由获取信息,然后将此信息传递到HDBC SQLITE3数据库。我已经弄清楚如何使用Scotty通过参数获取信息以及如何使用HDBC创建数据库。但是我将参数信息传递给数据库时遇到了麻烦。我收到了这个错误:(抱歉这个初学者问题,我只使用Haskell大约三周)

Controllers/Home.hs:51:48:
No instance for (Convertible a0 SqlValue)
  arising from a use of `toSql'
Possible fix:
  add an instance declaration for (Convertible a0 SqlValue)
In the expression: toSql
In the expression: toSql $ userId
In the third argument of `run', namely
  `[toSql $ userId, toSql $ name]'

Controllers/Home.hs:51:64:
No instance for (Convertible a1 SqlValue)
  arising from a use of `toSql'
Possible fix:
  add an instance declaration for (Convertible a1 SqlValue)
In the expression: toSql
In the expression: toSql $ name
In the third argument of `run', namely
  `[toSql $ userId, toSql $ name]'

以下是我正在尝试运行的代码:

import Control.Monad
import Web.Scotty (ScottyM, ActionM, get, html, param)
import Data.Monoid (mconcat)
import Database.HDBC
import Database.HDBC.Sqlite3
import Control.Monad.Trans ( MonadIO(liftIO) )
import Data.Convertible
createUser ::  ScottyM()
createUser = get "/create/user/:userId/:name" $ do
  name <- param "name"
  userId <- param "userId"
  liftIO $ createUserDB name userId
  html $ mconcat ["<p>/create/user/" , userId , "/" , name ,"</p>"]
createUserDB :: a1 -> a0 -> IO()
createUserDB name userId = do
  conn <- connectSqlite3 databaseFilePath
  run conn "INSERT INTO users VALUES (? , ?)" [toSql $ userId, toSql $ name]
  commit conn
  disconnect conn
databaseFilePath = "data/mydb.db"

如果有人可以提供解决方法,以及为什么他们的修复工作那会非常有用!

1 个答案:

答案 0 :(得分:1)

我认为编译器抱怨是因为代码要求createUserDB的参数满足错误消息中的约束(即它们可以转换为Sqlvalue),但是你给出的签名没有& #39; t提供该保证(a0a1可以是任何类型)。

最简单的选择是删除createUserDB的类型签名,然后让编译器推断它。或者,您可以将其限制为Text值(因为nameuserId类型为Text,而Database.HDBC.SqlValue定义了Convertible Text SqlValue的实例:

createUserDB :: Text -> Text -> IO ()

通常,您还可以使用函数签名中的上下文来限制类型:

createUserDB :: (Convertible a0 SqlValue, Convertible a1 SqlValue) => a1 -> a0 -> IO ()

但这可能不是一个好主意,其中类型显然是SQL字符串,可能映射到varchars。