SQLの実行。読めば自明な感じ。取り出した値をそれっぽい型にするにはfromSql
が使える。
module Main (main) where
import Control.Monad
import Database.HDBC
import Database.HDBC.Sqlite3
printRows :: [[SqlValue]] -> IO ()
printRows rows = forM_ rows $ \row -> do
let row' = (fromSql :: SqlValue -> Integer) `fmap` row
print row'
main :: IO ()
main = do
con <- connectSqlite3 "test.db"
_ <- run con "create table test (x int)" []
forM_ [1 .. 10] $ \i -> do
_ <- run con "insert into test values (?)" [SqlInt32 i]
return ()
st <- prepare con "select x from test"
_ <- execute st []
fetchAllRows st >>= printRows
disconnect con
return ()
結果。
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
fetchAllRows
の実装にはunsafeInterleaveIO
が使われているので、以下のようにリストを舐める途中でfetchRow
を使うと[3]
が抜けてしまったりする。
(row : row' : rows') <- fetchAllRows st
printRows [row, row']
_ <- fetchRow st
printRows rows'
ドキュメントにもその辺触れられてて、例えばfinish
呼んじゃうと嫌なことになるよって辺りが書いてある。