packages feed

sqlite-easy 1.0.1.0 → 1.1.0.0

raw patch · 6 files changed

+75/−4 lines, 6 files

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2022-2023, Gil Mizrahi+Copyright (c) 2022-2024, Gil Mizrahi  All rights reserved. 
changelog.md view
@@ -1,3 +1,12 @@+### 1.1.0.0++* Add `openWith` and `createSqlitePoolWith`.+* `createSqlitePool` will now set the `foreign_keys` pragma and the `busy_timeout` pragma to 30000ms.++### 1.0.1.0++* Fix compilation with direct-sqlite 2.3.29.+ ### 1.0.0.0  * Bump resource-pool bounds to >=0.4 && <5.
sqlite-easy.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4  name: sqlite-easy-version: 1.0.1.0+version: 1.1.0.0 synopsis: A primitive yet easy to use sqlite library. description: A primitive yet easy to use sqlite library built using sqlite-direct, resource-pool and migrant. author: Gil Mizrahi
src/Database/Sqlite/Easy.hs view
@@ -6,12 +6,14 @@     -- $connecting     withDb   , withDatabase+  , openWith   , ConnectionString(..)   , Database     -- ** Pooling connections     -- $pooling   , Pool   , createSqlitePool+  , createSqlitePoolWith   , withPool   , withResource   , destroyAllResources
src/Database/Sqlite/Easy/Internal.hs view
@@ -12,6 +12,7 @@ import qualified Database.SQLite3 as Direct import Data.String (IsString, fromString) import Data.Text (Text)+import qualified Data.Text as T import Data.Typeable import Data.Pool import Control.Monad.Reader@@ -29,13 +30,44 @@   deriving Show  -- | Create a pool of a sqlite3 db with a specific connection string.+--   This also sets a few default pragmas. createSqlitePool :: ConnectionString -> IO (Pool Database)-createSqlitePool (ConnectionString connStr) =+createSqlitePool connStr =   newPool $ defaultPoolConfig-    (Direct.open connStr)+    (openWith connStr defaultPragmas)     Direct.close     180     50++-- | Create a pool of a sqlite3 db with a specific connection string.+--   This will also run the supplied SQL statements after establishing+--   each connection.+createSqlitePoolWith :: ConnectionString -> [SQL] -> IO (Pool Database)+createSqlitePoolWith connStr statements =+  newPool $ defaultPoolConfig+    (openWith connStr statements)+    Direct.close+    180+    50++-- | Open a connection to a database, run the supplied statements,+--   and return the connection.+openWith :: ConnectionString -> [SQL] -> IO Database+openWith (ConnectionString connStr) sqls = do+  conn <- Direct.open connStr+  Direct.exec+    conn+    (T.unlines $ map (\(SQL sql) -> sql <> "; ") sqls)+  pure conn++-- | Default pragmas to be set when opening a connection from a pool.+defaultPragmas :: [SQL]+defaultPragmas =+  [ -- https://www.sqlite.org/pragma.html#pragma_foreign_keys+    "PRAGMA foreign_keys = on"+  , -- https://www.sqlite.org/pragma.html#pragma_busy_timeout+    "PRAGMA busy_timeout = 30000"+  ]  -- | Open a database, run some stuff, close the database. withDb :: ConnectionString -> SQLite a -> IO a
test/SqliteEasySpec.hs view
@@ -1,3 +1,4 @@+{-# language ViewPatterns #-} {-# language OverloadedStrings #-} {-# language ScopedTypeVariables #-} @@ -7,6 +8,7 @@ import Test.Hspec import Database.Sqlite.Easy import UnliftIO.Exception (try, catch, displayException, SomeException(..))+import GHC.Conc (forkIO, threadDelay)  spec :: Spec spec = do@@ -114,3 +116,29 @@         run "select * from t"       destroyAllResources pool       shouldBe result [[SQLInteger 1]]++  describe "concurrency" $ do+    it "write concurrently to default pool" $ do+      pool <- createSqlitePool "/tmp/sqlite-easy-test.db"+      let table = "test_conc"+      withPool pool $ do+        [] <- run $ "drop table if exists " <> table+        [] <- run $ "create table " <> table <> "(x int not null)"+        pure ()+      forkIO $ withPool pool $ transaction $ do+        liftIO $ threadDelay 100000+        [] <- run $ "insert into " <> table <> " values (2)"+        pure ()+      liftIO $ threadDelay 50000+      forkIO $ withPool pool $ transaction $ do+        [] <- run $ "insert into " <> table <> " values (1)"+        liftIO $ threadDelay 100000+        pure ()+      liftIO $ threadDelay 80000+      readerResult <- withPool pool $ transaction $ do+        run $ "select * from " <> table+      liftIO $ threadDelay 200000+      result <- withPool pool $ do+        run $ "select * from " <> table <> " order by rowid"+      destroyAllResources pool+      shouldBe (readerResult, result) ([], [[SQLInteger 1], [SQLInteger 2]])