HDBC-odbc 2.3.1.0 → 2.3.1.1
raw patch · 9 files changed
+183/−90 lines, 9 filesnew-uploader
Files
- Database/HDBC/ODBC/Connection.hsc +11/−11
- Database/HDBC/ODBC/Statement.hsc +51/−20
- Database/HDBC/ODBC/Utils.hsc +2/−2
- HDBC-odbc.cabal +9/−5
- README.md +103/−0
- README.txt +0/−46
- TODO +0/−2
- testsrc/TestSbasics.hs +6/−0
- testsrc/Tests.hs +1/−4
Database/HDBC/ODBC/Connection.hsc view
@@ -184,45 +184,45 @@ -- FIXME: will this checkError segfault? checkError "disconnect" (DbcHandle $ llconn) res -foreign import #{CALLCONV} unsafe "sql.h SQLAllocHandle"+foreign import #{CALLCONV} safe "sql.h SQLAllocHandle" sqlAllocHandle :: #{type SQLSMALLINT} -> Ptr () -> Ptr () -> IO (#{type SQLRETURN}) -foreign import ccall unsafe "hdbc-odbc-helper.h wrapobjodbc_extra"+foreign import ccall safe "hdbc-odbc-helper.h wrapobjodbc_extra" wrapconn :: Ptr CConn -> Ptr CEnv -> Ptr WrappedCConn -> IO (Ptr WrappedCConn) -foreign import ccall unsafe "hdbc-odbc-helper.h &sqlFreeHandleDbc_finalizer"+foreign import ccall safe "hdbc-odbc-helper.h &sqlFreeHandleDbc_finalizer" sqlFreeHandleDbc_ptr :: FunPtr (Ptr WrappedCConn -> IO ()) -foreign import ccall unsafe "hdbc-odbc-helper.h sqlFreeHandleDbc_app"+foreign import ccall safe "hdbc-odbc-helper.h sqlFreeHandleDbc_app" sqlFreeHandleDbc_app :: Ptr WrappedCConn -> IO (#{type SQLRETURN}) -foreign import #{CALLCONV} unsafe "sql.h SQLSetEnvAttr"+foreign import #{CALLCONV} safe "sql.h SQLSetEnvAttr" sqlSetEnvAttr :: Ptr CEnv -> #{type SQLINTEGER} -> Ptr () -> #{type SQLINTEGER} -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLDriverConnect"+foreign import #{CALLCONV} safe "sql.h SQLDriverConnect" sqlDriverConnect :: Ptr CConn -> Ptr () -> CString -> #{type SQLSMALLINT} -> CString -> #{type SQLSMALLINT} -> Ptr #{type SQLSMALLINT} -> #{type SQLUSMALLINT} -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h getSqlOvOdbc3"+foreign import ccall safe "hdbc-odbc-helper.h getSqlOvOdbc3" getSqlOvOdbc3 :: Ptr () -foreign import ccall unsafe "hdbc-odbc-helper.h SQLSetConnectAttr"+foreign import ccall safe "hdbc-odbc-helper.h SQLSetConnectAttr" sqlSetConnectAttr :: Ptr CConn -> #{type SQLINTEGER} -> Ptr #{type SQLUINTEGER} -> #{type SQLINTEGER} -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLEndTran"+foreign import #{CALLCONV} safe "sql.h SQLEndTran" sqlEndTran :: #{type SQLSMALLINT} -> Ptr CConn -> #{type SQLSMALLINT} -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h disableAutoCommit"+foreign import ccall safe "hdbc-odbc-helper.h disableAutoCommit" disableAutoCommit :: Ptr CConn -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLGetInfo"+foreign import #{CALLCONV} safe "sql.h SQLGetInfo" sqlGetInfo :: Ptr CConn -> #{type SQLUSMALLINT} -> Ptr () -> #{type SQLSMALLINT} -> Ptr #{type SQLSMALLINT} -> IO #{type SQLRETURN}
Database/HDBC/ODBC/Statement.hsc view
@@ -342,6 +342,37 @@ Just bindCols -> do return (mBindCols, bindCols) +-- This is only for String data. For binary fix should be very easy. Just check the column type and use buflen instead of buflen - 1+getLongColData cstmt bindCol = do+ let (BindColString buf bufLen col) = bindCol+ l $ "buflen: " ++ show bufLen+ bs <- B.packCStringLen (buf, fromIntegral (bufLen - 1))+ l $ "sql_no_total col " ++ show (BUTF8.toString bs)+ bs2 <- getRestLongColData cstmt #{const SQL_CHAR} col bs+ return $ SqlByteString bs2+++getRestLongColData cstmt cBinding icol acc = do+ l "getLongColData"+ alloca $ \plen ->+ allocaBytes colBufSizeMaximum $ \buf ->+ do res <- sqlGetData cstmt (fromIntegral icol) cBinding+ buf (fromIntegral colBufSizeMaximum) plen+ if res == #{const SQL_SUCCESS} || res == #{const SQL_SUCCESS_WITH_INFO}+ then do+ len <- peek plen+ if len == #{const SQL_NO_DATA}+ then return acc+ else do+ let bufmax = fromIntegral $ colBufSizeMaximum - 1+ bs <- B.packCStringLen (buf, fromIntegral (if len == #{const SQL_NO_TOTAL} || len > bufmax then bufmax else len))+ l $ "sql_no_total col is: " ++ show (BUTF8.toString bs)+ let newacc = B.append acc bs+ if len /= #{const SQL_NO_TOTAL} && len <= bufmax+ then return newacc+ else getRestLongColData cstmt cBinding icol newacc+ else raiseError "sqlGetData" res (StmtHandle cstmt)+ -- TODO: This code does not deal well with data that is extremely large, -- where multiple fetches are required. getColData cstmt cBinding icol = do@@ -683,7 +714,7 @@ l "mkBindCol: BindColBinary" let colSize = min colBufSizeMaximum $ fromMaybe colBufSizeDefault mColSize let bufLen = sizeOf (undefined :: CUChar) * (colSize + 1)- buf <- malloc+ buf <- mallocBytes bufLen pStrLen <- malloc sqlBindCol cstmt col (#{const SQL_C_BINARY}) (castPtr buf) (fromIntegral bufLen) pStrLen return (BindColBinary buf (fromIntegral bufLen) col, pStrLen)@@ -743,7 +774,7 @@ strLen <- peek pStrLen case strLen of #{const SQL_NULL_DATA} -> return SqlNull- #{const SQL_NO_TOTAL} -> fail $ "Unexpected SQL_NO_TOTAL"+ #{const SQL_NO_TOTAL} -> getLongColData pcstmt bindCol _ -> bindColToSqlValue' pcstmt bindCol strLen -- | This is a worker function for `bindcolToSqlValue`. Note that the case@@ -858,10 +889,10 @@ ffinish stmt = withRawStmt stmt $ sqlFreeHandleSth_app -foreign import ccall unsafe "hdbc-odbc-helper.h wrapobjodbc"+foreign import ccall safe "hdbc-odbc-helper.h wrapobjodbc" wrapstmt :: Ptr CStmt -> Ptr WrappedCConn -> IO (Ptr WrappedCStmt) -foreign import #{CALLCONV} unsafe "sql.h SQLDescribeCol"+foreign import #{CALLCONV} safe "sql.h SQLDescribeCol" sqlDescribeCol :: Ptr CStmt -> #{type SQLSMALLINT} -- ^ Column number -> CString -- ^ Column name@@ -873,7 +904,7 @@ -> Ptr (#{type SQLSMALLINT}) -- ^ nullable ptr -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLGetData"+foreign import #{CALLCONV} safe "sql.h SQLGetData" sqlGetData :: Ptr CStmt -- ^ statement handle -> #{type SQLUSMALLINT} -- ^ Column number -> #{type SQLSMALLINT} -- ^ target type@@ -882,7 +913,7 @@ -> Ptr (#{type SQLLEN}) -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLBindCol"+foreign import #{CALLCONV} safe "sql.h SQLBindCol" sqlBindCol :: Ptr CStmt -- ^ statement handle -> #{type SQLUSMALLINT} -- ^ Column number -> #{type SQLSMALLINT} -- ^ target type@@ -891,31 +922,31 @@ -> Ptr (#{type SQLLEN}) -- ^ strlen_or_indptr -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h sqlFreeHandleSth_app"+foreign import ccall safe "hdbc-odbc-helper.h sqlFreeHandleSth_app" sqlFreeHandleSth_app :: Ptr WrappedCStmt -> IO () -foreign import ccall unsafe "hdbc-odbc-helper.h &sqlFreeHandleSth_finalizer"+foreign import ccall safe "hdbc-odbc-helper.h &sqlFreeHandleSth_finalizer" sqlFreeHandleSth_ptr :: FunPtr (Ptr WrappedCStmt -> IO ()) -foreign import #{CALLCONV} unsafe "sql.h SQLPrepare"+foreign import #{CALLCONV} safe "sql.h SQLPrepare" sqlPrepare :: Ptr CStmt -> CString -> #{type SQLINTEGER} -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLExecute"+foreign import #{CALLCONV} safe "sql.h SQLExecute" sqlExecute :: Ptr CStmt -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLAllocHandle"+foreign import #{CALLCONV} safe "sql.h SQLAllocHandle" sqlAllocStmtHandle :: #{type SQLSMALLINT} -> Ptr CConn -> Ptr (Ptr CStmt) -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLNumResultCols"+foreign import #{CALLCONV} safe "sql.h SQLNumResultCols" sqlNumResultCols :: Ptr CStmt -> Ptr #{type SQLSMALLINT} -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLRowCount"+foreign import #{CALLCONV} safe "sql.h SQLRowCount" sqlRowCount :: Ptr CStmt -> Ptr #{type SQLINTEGER} -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLBindParameter"+foreign import #{CALLCONV} safe "sql.h SQLBindParameter" sqlBindParameter :: Ptr CStmt -- ^ Statement handle -> #{type SQLUSMALLINT} -- ^ Parameter Number -> #{type SQLSMALLINT} -- ^ Input or output@@ -928,10 +959,10 @@ -> Ptr #{type SQLLEN} -- ^ strlen_or_indptr -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h &nullDataHDBC"+foreign import ccall safe "hdbc-odbc-helper.h &nullDataHDBC" nullDataHDBC :: Ptr #{type SQLLEN} -foreign import #{CALLCONV} unsafe "sql.h SQLDescribeParam"+foreign import #{CALLCONV} safe "sql.h SQLDescribeParam" sqlDescribeParam :: Ptr CStmt -> #{type SQLUSMALLINT} -- ^ parameter number -> Ptr #{type SQLSMALLINT} -- ^ data type ptr@@ -940,13 +971,13 @@ -> Ptr #{type SQLSMALLINT} -- ^ nullable ptr -> IO #{type SQLRETURN} -foreign import #{CALLCONV} unsafe "sql.h SQLFetch"+foreign import #{CALLCONV} safe "sql.h SQLFetch" sqlFetch :: Ptr CStmt -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h simpleSqlTables"+foreign import ccall safe "hdbc-odbc-helper.h simpleSqlTables" simpleSqlTables :: Ptr CStmt -> IO #{type SQLRETURN} -foreign import ccall unsafe "hdbc-odbc-helper.h simpleSqlColumns"+foreign import ccall safe "hdbc-odbc-helper.h simpleSqlColumns" simpleSqlColumns :: Ptr CStmt -> Ptr CChar -> #{type SQLSMALLINT} -> IO #{type SQLRETURN} @@ -976,6 +1007,6 @@ (StmtHandle sthptr) peek pcount -foreign import #{CALLCONV} unsafe "sql.h SQLNumParams"+foreign import #{CALLCONV} safe "sql.h SQLNumParams" sqlNumParams :: Ptr CStmt -> Ptr #{type SQLSMALLINT} -> IO #{type SQLRETURN}
Database/HDBC/ODBC/Utils.hsc view
@@ -117,10 +117,10 @@ isOK :: #{type SQLRETURN} -> Bool isOK r = sqlSucceeded r /= 0 -foreign import ccall unsafe "sqlSucceeded"+foreign import ccall safe "sqlSucceeded" sqlSucceeded :: #{type SQLRETURN} -> CInt -foreign import #{CALLCONV} unsafe "sql.h SQLGetDiagRec"+foreign import #{CALLCONV} safe "sql.h SQLGetDiagRec" sqlGetDiagRec :: #{type SQLSMALLINT} -> Ptr () -> #{type SQLSMALLINT} -> CString -> Ptr (#{type SQLINTEGER}) -> CString -> #{type SQLSMALLINT}
HDBC-odbc.cabal view
@@ -1,18 +1,17 @@ Name: HDBC-odbc-Version: 2.3.1.0+Version: 2.3.1.1 Cabal-Version: >=1.2.3 Build-type: Simple License: BSD3-Maintainer: Nicolas Wu <nick@well-typed.com>+Maintainer: Nicolas Wu <nicolas.wu@gmail.com> Author: John Goerzen Copyright: Copyright (c) 2005-2011 John Goerzen license-file: LICENSE extra-source-files: LICENSE, hdbc-odbc-helper.h, Makefile,- README.txt,- TODO,+ README.md, testsrc/TestTime.hs-homepage: http://software.complete.org/hdbc-odbc+homepage: https://github.com/hdbc/hdbc-odbc Category: Database synopsis: ODBC driver for HDBC Description: This package provides an ODBC database backend for HDBC.@@ -20,10 +19,15 @@ and Microsoft ODBC on Windows. It is also the preferred way to access MySQL databases from Haskell. Stability: Beta+Cabal-Version: >=1.6 Flag buildtests description: Build the executable to run unit tests default: False++source-repository head+ type: git+ location: https://github.com/hdbc/hdbc-odbc.git Library Exposed-Modules: Database.HDBC.ODBC
+ README.md view
@@ -0,0 +1,103 @@+HDBC-ODBC+=========++Welcome to HDBC, Haskell Database Connectivity.++This package provides a database backend driver for ODBC. You should+be able to use any ODBC front-end with it.++Please see HDBC itself for documentation on use.++This package provides one function in module Database.HDBC.ODBC:++ -- | Connect to an ODBC server.+ -- For information on the meaning of the passed string, please see:+ -- <http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqldrivers.asp>+ connectODBC :: String -> IO Connection++For example, you might use `connectODBC` as follows:++ connectODBC "DSN=hdbctest1"++For more information about HDBC-ODBC,+please visit the [wiki](https://github.com/hdbc/hdbc-odbc/wiki).++Differences from HDBC standard+------------------------------++None known at this time.++MySQL note+----------++Important note for MySQL users:++Unless you are going to use InnoDB tables, you are strongly encouraged to set++ Option = 262144++in your odbc.ini (for Unix users), or to disable transaction support in your+DSN setup for Windows users.++If you fail to do this, the MySQL ODBC driver will incorrectly state that it+supports transactions. dbTransactionSupport will incorrectly return True.+commit and rollback will then silently fail. This is certainly *NOT* what you+want. It is a bug (or misfeature) in the MySQL driver, not in HDBC.++You should ignore this advice if you are using InnoDB tables.++For the error "2013: Mysql server has gone away" error message, you'll have to+use withRTSSignalsBlocked from the HDBC-mysql package.++query conn stmStr binds = withRTSSignalsBlocked $ quickQuery conn stmStr binds++Getting Started+---------------++Here are some instructions to set up ODBC with a sqlite3 backend, and how+to communicate with that database with HDBC-ODBC.+These instructions are written to work with Ubuntu 11.10.++First, we'll need to install the appropriate libraries:++ sudo apt-get install unixodbc unixodbc-dev unixodbc-bin+ sudo apt-get install libsqliteodbc++Verify that the sqlite ODBC drivers have been set up correctly:++ odbcinst -q -d+This should return:++ [SQLite]+ [SQLite3]++Next, fire up the `ODBCConfig` too to set up a new DSN:++ ODBCConfig++If you want to run the HDBC test suite, then set your DSN to `hdbctest`,+and set up to connect to a database of your choice, such as an empty file+in the `hdbc-odbc/testsrc` directory:++ touch hdbc-odbc/testsrc/hdbctest.db++You can check that everything is working appropriately in ghci:++ ghci> :m + Database.HDBC Database.HDBC.ODBC+ ghci> conn <- connectODBC "DSN=hdbctest"+ ghci> hdbcDriverName conn+ "odbc"+ ghci> hdbcClientVer conn+ "03.52"++You can then run some tests on your database:++ cd testsrc+ runhaskell runtests.hs++Contributing+------------++Contributions are welcome! If you would like to contribute, please fork the the+[github repository](https://github.com/hdbc/hdbc-odbc), and submit a pull+request.
− README.txt
@@ -1,46 +0,0 @@-Welcome to HDBC, Haskell Database Connectivity.--This package provides a database backend driver for ODBC. You should-be able to use any ODBC front-end with it.--Please see HDBC itself for documentation on use.--This package provides one function in module Database.HDBC.ODBC:--{- | Connect to an ODBC server.--For information on the meaning of the passed string, please see:--<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/odbcsqldrivers.asp>--An example string is:-->"DSN=hdbctest1"---}-connectODBC :: String -> IO Connection--DIFFERENCES FROM HDBC STANDARD---------------------------------None known at this time.--MYSQL NOTE-------------Important note for MySQL users:--Unless you are going to use InnoDB tables, you are strongly encouraged to set--Option = 262144--in your odbc.ini (for Unix users), or to disable transaction support in your-DSN setup for Windows users.--If you fail to do this, the MySQL ODBC driver will incorrectly state that it-supports transactions. dbTransactionSupport will incorrectly return True.-commit and rollback will then silently fail. This is certainly /NOT/ what you-want. It is a bug (or misfeature) in the MySQL driver, not in HDBC.--You should ignore this advice if you are using InnoDB tables.-
− TODO
@@ -1,2 +0,0 @@-optimize multiple executions and executeMany-
testsrc/TestSbasics.hs view
@@ -9,6 +9,11 @@ do dbh <- connectDB disconnect dbh +singleFinish = dbTestCase $ \dbh ->+ do sth <- prepare dbh "SELECT 1 + 1"+ sExecute sth []+ finish sth+ multiFinish = dbTestCase (\dbh -> do sth <- prepare dbh "SELECT 1 + 1" sExecute sth []@@ -137,6 +142,7 @@ tests = TestList [ TestLabel "openClosedb" openClosedb,+ TestLabel "singleFinish" singleFinish, TestLabel "multiFinish" multiFinish, TestLabel "basicQueries" basicQueries, TestLabel "createTable" createTable,
testsrc/Tests.hs view
@@ -9,10 +9,7 @@ import qualified TestMisc import qualified TestTime -test1 = TestCase ("x" @=? "x")--tests = TestList [TestLabel "test1" test1,- TestLabel "String basics" TestSbasics.tests,+tests = TestList [TestLabel "String basics" TestSbasics.tests, TestLabel "SqlValue basics" Testbasics.tests, TestLabel "SpecificDB" SpecificDBTests.tests, TestLabel "Misc tests" TestMisc.tests,