packages feed

sqlite-simple 0.4.6.1 → 0.4.7.0

raw patch · 6 files changed

+66/−6 lines, 6 files

Files

Database/SQLite/Simple.hs view
@@ -75,6 +75,8 @@   , execute_   , executeNamed   , field+    -- * Transactions+  , withTransaction     -- * Low-level statement API for stream access and prepared statements   , openStatement   , closeStatement@@ -329,6 +331,12 @@  -- | A version of 'query' where the query parameters (placeholders) -- are named.+--+-- Example:+--+-- @+-- r \<- 'queryNamed' c \"SELECT * FROM posts WHERE id=:id AND date>=:date\" [\":id\" ':=' postId, \":date\" ':=' afterDate]+-- @ queryNamed :: (FromRow r) => Connection -> Query -> [NamedParam] -> IO [r] queryNamed conn templ params =   withStatementNamedParams conn templ params $ \stmt -> doFoldToList stmt@@ -452,6 +460,22 @@ lastInsertRowId :: Connection -> IO Int64 lastInsertRowId (Connection c) = BaseD.lastInsertRowId c +-- | Run an IO action inside a SQL transaction started with @BEGIN+-- TRANSACTION@.  If the action throws any kind of an exception, the+-- transaction will be rolled back with @ROLLBACK TRANSACTION@.+-- Otherwise the results are committed with @COMMIT TRANSACTION@.+withTransaction :: Connection -> IO a -> IO a+withTransaction conn action =+  mask $ \restore -> do+    begin+    r <- restore action `onException` rollback+    commit+    return r+  where+    begin    = execute_ conn "BEGIN TRANSACTION"+    commit   = execute_ conn "COMMIT TRANSACTION"+    rollback = execute_ conn "ROLLBACK TRANSACTION"+ fmtError :: Show v => String -> Query -> [v] -> a fmtError msg q xs =   throw FormatError {@@ -587,14 +611,14 @@ -- Example: -- -- @--- r \<- 'queryNamed' c \"SELECT id,text FROM posts WHERE id = :id AND date >= :date\" [\":id\" ':=' postId, \":date\" := afterDate]+-- r \<- 'queryNamed' c \"SELECT id,text FROM posts WHERE id = :id AND date >= :date\" [\":id\" ':=' postId, \":date\" ':=' afterDate] -- @ -- -- Note that you can mix different value types in the same list. -- E.g., the following is perfectly legal: -- -- @--- [\":id\" := (3 :: Int), \":str\" := (\"foo\" :: String)]+-- [\":id\" ':=' (3 :: Int), \":str\" ':=' (\"foo\" :: String)] -- @ -- -- The parameter name (or key) in the 'NamedParam' must match exactly
Database/SQLite/Simple/ToRow.hs view
@@ -26,11 +26,11 @@  import Database.SQLite3 (SQLData(..)) --- | A collection type that can be turned into a list of SQLData+-- | A collection type that can be turned into a list of 'SQLData' -- elements. class ToRow a where     toRow :: a -> [SQLData]-    -- ^ ToField a collection of values.+    -- ^ 'ToField' a collection of values.  instance ToRow () where     toRow _ = []
changelog view
@@ -1,3 +1,6 @@+0.4.7.0+	* Add `withTransaction' for running IO actions inside SQL+	  transactions with automated rollback if any exceptions are thrown. 0.4.6.1 	* Fix unit test build break with older bytestring versions 
sqlite-simple.cabal view
@@ -1,10 +1,10 @@ Name:                sqlite-simple-Version:             0.4.6.1+Version:             0.4.7.0 Synopsis:            Mid-Level SQLite client library Description:     Mid-level SQLite client library, based on postgresql-simple.     .-    Main documentation (with examples): <docs/Database-SQLite-Simple.html Database.SQLite.Simple>+    Main documentation (with examples): <sqlite-simple/docs/Database-SQLite-Simple.html Database.SQLite.Simple>     .     You can view the project page at <http://github.com/nurpax/sqlite-simple>     for more information.
test/Errors.hs view
@@ -6,6 +6,7 @@   , testErrorsInvalidNamedParams   , testErrorsWithStatement   , testErrorsColumnName+  , testErrorsTransaction   ) where  import Prelude hiding (catch)@@ -99,3 +100,34 @@   assertOOBCaught $     withStatement conn "SELECT id FROM invcolumn" $ \stmt ->       columnName stmt (ColumnIndex (-1)) >> assertFailure "Error not detected"++testErrorsTransaction :: TestEnv -> Test+testErrorsTransaction TestEnv{..} = TestCase $ do+  execute_ conn "CREATE TABLE trans (id INTEGER PRIMARY KEY, t TEXT)"+  withTransaction conn $ do+    executeNamed conn "INSERT INTO trans (t) VALUES (:txt)" [":txt" := ("foo" :: String)]+  e <- rowExists+  True @=? e+  execute_ conn "DELETE FROM trans"+  e <- rowExists+  False @=? e+  assertFormatErrorCaught+    (withTransaction conn $ do+        -- this execute should be automatically rolled back on error+        executeNamed conn+          "INSERT INTO trans (t) VALUES (:txt)" [":txt" := ("foo" :: String)]+        -- intentional mistake here to hit an error & cause rollback of txn+        executeNamed conn+          "INSERT INTO trans (t) VALUES (:txt)" [":missing" := ("foo" :: String)])+  e <- rowExists+  False @=? e+  where+    rowExists = do+      rows <- query_ conn "SELECT t FROM trans" :: IO [Only String]+      case rows of+        [Only txt] -> do+          "foo" @=? txt+          return True+        [] ->+          return False+        _ -> error "should have only one row"
test/Main.hs view
@@ -46,6 +46,7 @@     , TestLabel "Errors"    . testErrorsInvalidNamedParams     , TestLabel "Errors"    . testErrorsWithStatement     , TestLabel "Errors"    . testErrorsColumnName+    , TestLabel "Errors"    . testErrorsTransaction     , TestLabel "Utf8"      . testUtf8Simplest     , TestLabel "Utf8"      . testBlobs     , TestLabel "Instances" . testUserFromField