module TestMisc(tests, setup) where import Test.HUnit import Database.HDBC import TestUtils import System.IO import Control.Exception import Data.Char import Control.Monad import qualified Data.Map as Map rowdata = [[SqlInt32 0, toSql "Testing", SqlNull], [SqlInt32 1, toSql "Foo", SqlInt32 5], [SqlInt32 2, toSql "Bar", SqlInt32 9]] colnames = ["testid", "teststring", "testint"] alrows :: [[(String, SqlValue)]] alrows = map (zip colnames) rowdata setup f = dbTestCase $ \dbh -> do run dbh "CREATE TABLE hdbctest2 (testid INTEGER PRIMARY KEY NOT NULL, teststring TEXT, testint INTEGER)" [] sth <- prepare dbh "INSERT INTO hdbctest2 VALUES (?, ?, ?)" executeMany sth rowdata commit dbh finally (f dbh) (do run dbh "DROP TABLE hdbctest2" [] commit dbh ) cloneTest dbh a = do dbh2 <- clone dbh finally (handleSqlError (a dbh2)) (handleSqlError (disconnect dbh2)) testgetColumnNames = setup $ \dbh -> do sth <- prepare dbh "SELECT * from hdbctest2" execute sth [] cols <- getColumnNames sth finish sth ["testid", "teststring", "testint"] @=? map (map toLower) cols testdescribeResult = setup $ \dbh -> when (not ((hdbcDriverName dbh) `elem` ["sqlite3"])) $ do sth <- prepare dbh "SELECT * from hdbctest2" execute sth [] cols <- describeResult sth ["testid", "teststring", "testint"] @=? map (map toLower . fst) cols let coldata = map snd cols assertBool "r0 type" (colType (coldata !! 0) `elem` [SqlBigIntT, SqlIntegerT]) assertBool "r1 type" (colType (coldata !! 1) `elem` [SqlVarCharT, SqlLongVarCharT]) assertBool "r2 type" (colType (coldata !! 2) `elem` [SqlBigIntT, SqlIntegerT]) finish sth testdescribeTable = setup $ \dbh -> when (not ((hdbcDriverName dbh) `elem` ["sqlite3"])) $ do cols <- describeTable dbh "hdbctest2" ["testid", "teststring", "testint"] @=? map (map toLower . fst) cols let coldata = map snd cols assertBool "r0 type" (colType (coldata !! 0) `elem` [SqlBigIntT, SqlIntegerT]) assertEqual "r0 nullable" (Just False) (colNullable (coldata !! 0)) assertBool "r1 type" (colType (coldata !! 1) `elem` [SqlVarCharT, SqlLongVarCharT]) assertEqual "r1 nullable" (Just True) (colNullable (coldata !! 1)) assertBool "r2 type" (colType (coldata !! 2) `elem` [SqlBigIntT, SqlIntegerT]) assertEqual "r2 nullable" (Just True) (colNullable (coldata !! 2)) testquickQuery = setup $ \dbh -> do results <- quickQuery dbh "SELECT * from hdbctest2 ORDER BY testid" [] rowdata @=? results testfetchRowAL = setup $ \dbh -> do sth <- prepare dbh "SELECT * from hdbctest2 ORDER BY testid" execute sth [] fetchRowAL sth >>= (Just (head alrows) @=?) fetchRowAL sth >>= (Just (alrows !! 1) @=?) fetchRowAL sth >>= (Just (alrows !! 2) @=?) fetchRowAL sth >>= (Nothing @=?) finish sth testfetchRowMap = setup $ \dbh -> do sth <- prepare dbh "SELECT * from hdbctest2 ORDER BY testid" execute sth [] fetchRowMap sth >>= (Just (Map.fromList $ head alrows) @=?) fetchRowMap sth >>= (Just (Map.fromList $ alrows !! 1) @=?) fetchRowMap sth >>= (Just (Map.fromList $ alrows !! 2) @=?) fetchRowMap sth >>= (Nothing @=?) finish sth testfetchAllRowsAL = setup $ \dbh -> do sth <- prepare dbh "SELECT * from hdbctest2 ORDER BY testid" execute sth [] fetchAllRowsAL sth >>= (alrows @=?) testfetchAllRowsMap = setup $ \dbh -> do sth <- prepare dbh "SELECT * from hdbctest2 ORDER BY testid" execute sth [] fetchAllRowsMap sth >>= (map (Map.fromList) alrows @=?) testexception = setup $ \dbh -> catchSql (do sth <- prepare dbh "SELECT invalidcol FROM hdbctest2" execute sth [] assertFailure "No exception was raised" ) (\e -> commit dbh) testrowcount = setup $ \dbh -> do r <- run dbh "UPDATE hdbctest2 SET testint = 25 WHERE testid = 20" [] assertEqual "UPDATE with no change" 0 r r <- run dbh "UPDATE hdbctest2 SET testint = 26 WHERE testid = 0" [] assertEqual "UPDATE with 1 change" 1 r r <- run dbh "UPDATE hdbctest2 SET testint = 27 WHERE testid <> 0" [] assertEqual "UPDATE with 2 changes" 2 r commit dbh res <- quickQuery dbh "SELECT * from hdbctest2 ORDER BY testid" [] assertEqual "final results" [[SqlInt32 0, toSql "Testing", SqlInt32 26], [SqlInt32 1, toSql "Foo", SqlInt32 27], [SqlInt32 2, toSql "Bar", SqlInt32 27]] res {- Since we might be running against a live DB, we can't look at a specific list here (though a SpecificDB test case may be able to). We can ensure that our test table is, or is not, present, as appropriate. -} testgetTables1 = setup $ \dbh -> do r <- getTables dbh True @=? "hdbctest2" `elem` r testgetTables2 = dbTestCase $ \dbh -> do r <- getTables dbh False @=? "hdbctest2" `elem` r testclone = setup $ \dbho -> cloneTest dbho $ \dbh -> do results <- quickQuery dbh "SELECT * from hdbctest2 ORDER BY testid" [] rowdata @=? results testnulls = setup $ \dbh -> do let dn = hdbcDriverName dbh when (not (dn `elem` ["postgresql", "odbc"])) ( do sth <- prepare dbh "INSERT INTO hdbctest2 VALUES (?, ?, ?)" executeMany sth rows finish sth res <- quickQuery dbh "SELECT * from hdbctest2 WHERE testid > 99 ORDER BY testid" [] seq (length res) rows @=? res ) where rows = [[SqlInt32 100, SqlString "foo\NULbar", SqlNull], [SqlInt32 101, SqlString "bar\NUL", SqlNull], [SqlInt32 102, SqlString "\NUL", SqlNull], [SqlInt32 103, SqlString "\xFF", SqlNull], [SqlInt32 104, SqlString "regular", SqlNull]] testunicode = setup $ \dbh -> do sth <- prepare dbh "INSERT INTO hdbctest2 VALUES (?, ?, ?)" executeMany sth rows finish sth res <- quickQuery dbh "SELECT * from hdbctest2 WHERE testid > 99 ORDER BY testid" [] seq (length res) rows @=? res where rows = [[SqlInt32 100, SqlString "foo\x263a", SqlNull], [SqlInt32 101, SqlString "bar\x00A3", SqlNull], [SqlInt32 102, SqlString (take 263 (repeat 'a')), SqlNull]] tests = TestList [ TestLabel "getColumnNames" testgetColumnNames, TestLabel "describeResult" testdescribeResult, TestLabel "describeTable" testdescribeTable, TestLabel "quickQuery" testquickQuery, TestLabel "fetchRowAL" testfetchRowAL, TestLabel "fetchRowMap" testfetchRowMap, TestLabel "fetchAllRowsAL" testfetchAllRowsAL, TestLabel "fetchAllRowsMap" testfetchAllRowsMap, TestLabel "sql exception" testexception, TestLabel "clone" testclone, TestLabel "update rowcount" testrowcount, TestLabel "get tables1" testgetTables1, TestLabel "get tables2" testgetTables2, TestLabel "nulls" testnulls, TestLabel "unicode" testunicode]