在Haskell HDBC的单个事务中严格向SQLite提交多个SQL语句

时间:2014-08-02 19:58:04

标签: haskell sqlite transactions hdbc

我的Haskell技能非常处于婴儿期,而且monads让我感到困惑。

但是,我需要构建一个将在sqlite3数据库中安装所有fixture的函数。

module UmeQuery where

import Database.HDBC 
import Database.HDBC.Sqlite3

testdb = "testdata/ume.umedb"

runSetup dbFile = do
    conn <- connectSqlite3 dbFile
    res <- withTransaction conn ( setup conn )
    disconnect conn
    return $ res

setup conn = do 
    n1 <- setupUtterances conn
    n2 <- setupLevels conn
    return $ [n1, n2] 


setupUtterances conn = do 
    q1 <- quickQuery' conn "DROP TABLE IF EXISTS utterances;" []
    q2 <- quickQuery' conn "CREATE TABLE utterances (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, filelength REAL, updated_at TEXT, checksum_algorithm TEXT, checksum TEXT, UNIQUE(name) ON CONFLICT FAIL );" []
    return $ [q1,q2] 

setupLevels conn = do 
    q1 <- quickQuery' conn "DROP TABLE IF EXISTS levels;"
    q2 <- quickQuery' conn "CREATE TABLE levels (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE ON CONFLICT FAIL );"
    return $ [q1,q2]

当我尝试运行它时,我得到以下输出:

UmeQuery.hs:16:15:
Couldn't match expected type `IO [[[SqlValue]]]'
            with actual type `[SqlValue] -> [IO [[SqlValue]]]'
In the return type of a call of `setupLevels'
Probable cause: `setupLevels' is applied to too few arguments
In a stmt of a 'do' block: n2 <- setupLevels conn
In the expression:
  do { n1 <- setupUtterances conn;
       n2 <- setupLevels conn;
       return $ [n1, n2] }

我想得到的只是表明一切都很好的东西。请注意,我似乎需要严格,否则在创建新表之前不会总是超出“DROP TABLE”语句。

另外,如果我可以同时提出两个问题:设置最终会以类似的方式设置12个表。在这种情况下,有没有什么办法可以在包含所涉及函数的列表中将setup设置为($ conn)的fmap?当然,它会使代码更好。

1 个答案:

答案 0 :(得分:1)

对不起,是的,这个问题被认为是我在没有意识到的情况下蜷缩着。编码太迟了,我想。

import Database.HDBC 
import Database.HDBC.Sqlite3

testdb = "testdata/ume.umedb"

runSetup dbFile = do
    conn <- connectSqlite3 dbFile
    res <- withTransaction conn ( setup )
    disconnect conn
    return $ res

setup conn = do 
    n1 <- setupUtterances conn
    n2 <- setupLevels conn
    return $ n1 

setupUtterances conn = do 
    quickQuery' conn "DROP TABLE IF EXISTS utterances;" []
    quickQuery' conn "CREATE TABLE utterances (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, filelength REAL, updated_at TEXT, checksum_algorithm TEXT, checksum TEXT, UNIQUE(name) ON CONFLICT FAIL );" []
    return ()

setupLevels conn = do 
    quickQuery' conn "DROP TABLE IF EXISTS levels;" []
    quickQuery' conn "CREATE TABLE levels (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE ON CONFLICT FAIL );" []
    return ()

main = runSetup testdb

这很有效。