2006-08-23 [長年日記]

[Haskell] HDBCを使ってMySQLに接続

HDBC-1.0.1.0を使ってMySQL 5.0.24に接続するテスト。HDBCにはMySQLのドライバが無いので、unixODBCを使ってODBC経由で接続します。

unixODBCは2.2.11、mysql-connector-odbcは3.51.12、HDBC-ODBCは1.0.1.0を使います。

import IO
import qualified Database.HDBC as DB
import qualified Database.HDBC.ODBC as ODBC

main :: IO ()
main = process `DB.catchSql` print
 where
     process = bracket (ODBC.connectODBC "DSN=MySQL-test;") DB.disconnect proc
     proc conn = q conn
     q conn = do res <- DB.quickQuery conn "select * from test" []
                 mapM_ (mapM_ p) res
     p (DB.SqlString s) = printWithLen s
     p x = printWithLen $ show x
     printWithLen x = putStrLn $ x ++ " (" ++ (show $ length x) ++ ")"

ただし、このバージョンの組み合わせだとうまく接続できないので、HDBC-ODBCにパッチを当てます。

diff -ur hdbc-odbc-1.0.1.0.orig/Database/HDBC/ODBC/Connection.hsc hdbc-odbc-1.0.1.0/Database/HDBC/ODBC/Connection.hsc
--- hdbc-odbc-1.0.1.0.orig/Database/HDBC/ODBC/Connection.hsc	2006-07-19 05:18:31.000000000 +0900
+++ hdbc-odbc-1.0.1.0/Database/HDBC/ODBC/Connection.hsc	2006-08-23 16:57:30.000000000 +0900
@@ -97,7 +97,7 @@
             -- Now connect.
             sqlDriverConnect dbcptr nullPtr cs (fromIntegral cslen)
                              nullPtr 0 nullPtr
-                             #{const SQL_DRIVER_COMPLETE}
+                             #{const SQL_DRIVER_NOPROMPT}
                               >>= checkError "connectODBC/sqlDriverConnect" 
                                   (DbcHandle dbcptr)
             mkConn args fdbcptr

ついでに、mysql-odbc-connectorのコードがバグっていて、DSNなどを渡す文字列が\0で終わっていないとゴミを拾ってしまいます。とりあえず、文字列の最後に「;」をぶら下げておくとごまかせます。

[]