Skip to content

Commit

Permalink
Add flag for using system sqlite3
Browse files Browse the repository at this point in the history
Tests pass with SQLite 3.6.22, except for the MultiRowInsert feature test.
Support for multiple row insertion via VALUES clause was added in
SQLite 3.7.11 (released 2012-03-20).

One minor discrepancy, though: when you try to 'step' a statement after a
schema change dropped the table the query reads from,
you get ErrorError with SQLite 3.7.13, and ErrorSchema with 3.6.22 .
  • Loading branch information
joeyadams committed Aug 25, 2012
1 parent 1e4942b commit 6306f82
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
12 changes: 11 additions & 1 deletion direct-sqlite.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,23 @@ Source-Repository head
type: git
location: git://github.com/IreneKnapp/direct-sqlite.git

flag systemlib
description: Use the system-wide sqlite library
default: False

Library
exposed-modules:
Database.SQLite3
Database.SQLite3.Direct
Database.SQLite3.Bindings
Database.SQLite3.Bindings.Types
c-sources: sqlite3.c

if flag(systemlib) {
extra-libraries: sqlite3
} else {
c-sources: sqlite3.c
}

include-dirs: .
build-depends: base >= 4.1 && < 5,
bytestring >= 0.9.2.1 && < 1,
Expand Down
66 changes: 54 additions & 12 deletions test/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ data TestEnv =
-- ^ Like 'withConn', but every invocation shares the same database.
}

tests :: [TestEnv -> Test]
tests =
regressionTests :: [TestEnv -> Test]
regressionTests =
[ TestLabel "Exec" . testExec
, TestLabel "Simple" . testSimplest
, TestLabel "Prepare" . testPrepare
Expand All @@ -47,6 +47,11 @@ tests =
, TestLabel "Integrity" . testIntegrity
]

featureTests :: [TestEnv -> Test]
featureTests =
[ TestLabel "MultiRowInsert" . testMultiRowInsert
]

assertFail :: IO a -> Assertion
assertFail action =
shouldFail action >>= assertBool "assertFail"
Expand Down Expand Up @@ -231,7 +236,8 @@ testColumns TestEnv{..} = TestCase $ do
Done <- step stmt
2 <- columnCount stmt
return ()
withStmt conn "INSERT INTO foo VALUES (3, 4), (5, 6)" command
withStmt conn "INSERT INTO foo VALUES (3, 4)" command
withStmt conn "INSERT INTO foo VALUES (5, 6)" command
withStmt conn "SELECT * FROM foo" $ \stmt -> do
2 <- columnCount stmt
exec conn "ALTER TABLE foo ADD COLUMN c INT"
Expand Down Expand Up @@ -326,14 +332,12 @@ testErrors TestEnv{..} = TestCase $ do
-- "BEGIN; ROLLBACK" causes running statements in the same connection to
-- throw SQLITE_ABORT.
withConnShared $ \conn -> do
exec conn "CREATE TABLE foo (a INT, b INT); \
\INSERT INTO foo VALUES (1, 2), (3, 4), (5, 6)"
foo123456 conn
withStmt conn "SELECT * FROM foo" $ \stmt -> do
-- "DROP TABLE foo" should succeed, since the statement
-- isn't running yet.
exec conn "DROP TABLE foo"
exec conn "CREATE TABLE foo (a INT, b INT); \
\INSERT INTO foo VALUES (1, 2), (3, 4), (5, 6)"
foo123456 conn

Row <- step stmt
2 <- columnCount stmt
Expand Down Expand Up @@ -372,12 +376,21 @@ testErrors TestEnv{..} = TestCase $ do
Right () <- Direct.reset stmt

-- But trying to 'step' again should fail.
expectError ErrorError $ step stmt
Left SQLError{sqlError = err} <- try $ step stmt
assertBool "Step after table vanishes should fail with SQLITE_ERROR or SQLITE_SCHEMA"
(err == ErrorError || -- SQLite 3.7.13
err == ErrorSchema) -- SQLite 3.6.22

where
expectError err io = do
Left SQLError{sqlError = err'} <- try io
assertEqual ("testErrors: expectError") err err'
assertEqual "testErrors: expectError" err err'

foo123456 conn =
exec conn "CREATE TABLE foo (a INT, b INT); \
\INSERT INTO foo VALUES (1, 2); \
\INSERT INTO foo VALUES (3, 4); \
\INSERT INTO foo VALUES (5, 6)"

-- Make sure data stored in a table comes back as-is.
testIntegrity :: TestEnv -> Test
Expand Down Expand Up @@ -412,6 +425,26 @@ testIntegrity TestEnv{..} = TestCase $ do

return ()

testMultiRowInsert :: TestEnv -> Test
testMultiRowInsert TestEnv{..} = TestCase $ do
withConn $ \conn -> do
exec conn "CREATE TABLE foo (a INT, b INT)"
result <- try $ exec conn "INSERT INTO foo VALUES (1,2), (3,4)"
case result of
Left SQLError{sqlError = ErrorError} ->
assertFailure "Installed SQLite3 does not support multi-row INSERT via the VALUES clause"
Left e ->
assertFailure $ show e
Right () -> do
-- Make sure multi-row insert actually worked
withStmt conn "SELECT * FROM foo" $ \stmt -> do
Row <- step stmt
[SQLInteger 1, SQLInteger 2] <- columns stmt
Row <- step stmt
[SQLInteger 3, SQLInteger 4] <- columns stmt
Done <- step stmt
return ()


sharedDBPath :: Text
sharedDBPath = "dist/test/direct-sqlite-test-database.db"
Expand All @@ -428,6 +461,12 @@ withTestEnv cb =
withConn = withConnPath ":memory:"
withConnPath path = bracket (open path) close

runTestGroup :: [TestEnv -> Test] -> IO Bool
runTestGroup tests = do
Counts{cases, tried, errors, failures} <-
withTestEnv $ \env -> runTestTT $ TestList $ map ($ env) tests
return (cases == tried && errors == 0 && failures == 0)

main :: IO ()
main = do
mapM_ (`hSetBuffering` LineBuffering) [stdout, stderr]
Expand All @@ -440,7 +479,10 @@ main = do
(removeFile $ T.unpack sharedDBPath)
open sharedDBPath >>= close

Counts{cases, tried, errors, failures} <-
withTestEnv $ \env -> runTestTT $ TestList $ map ($ env) tests
when (cases /= tried || errors /= 0 || failures /= 0) $ exitFailure
ok <- runTestGroup regressionTests
when (not ok) exitFailure

-- Signal failure if feature tests fail. I'd rather print a noisy warning
-- instead, but cabal redirects test output to log files by default.
ok <- runTestGroup featureTests
when (not ok) exitFailure

0 comments on commit 6306f82

Please sign in to comment.