hasql-cursor-query 0.4.5.3 → 0.4.5.4
raw patch · 16 files changed
+225/−146 lines, 16 filesdep +hspecdep +pqidep +pqi-ffidep −rebasedep −tastydep −tasty-hunitdep ~hasqldep ~hasql-transactionPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec, pqi, pqi-ffi, pqi-native, rerebase, testcontainers-postgresql, text
Dependencies removed: rebase, tasty, tasty-hunit
Dependency ranges changed: hasql, hasql-transaction
API changes (from Hackage documentation)
Files
- CHANGELOG.md +3/−0
- hasql-cursor-query.cabal +28/−11
- library/Hasql/CursorQuery/Private/CursorTransactions.hs +2/−1
- library/Hasql/CursorQuery/Private/Prelude.hs +1/−1
- src/integration-tests/Helpers/Adapters.hs +30/−0
- src/integration-tests/Helpers/CursorQueries.hs +35/−0
- src/integration-tests/Helpers/Hooks.hs +19/−0
- src/integration-tests/Helpers/Scripts.hs +37/−0
- src/integration-tests/Helpers/Statements.hs +31/−0
- src/integration-tests/Main.hs +1/−0
- src/integration-tests/Specs/CursorQuerySpec.hs +23/−0
- src/integration-tests/Specs/SpecHook.hs +15/−0
- tasty/Main.hs +0/−27
- tasty/Main/CursorQueries.hs +0/−39
- tasty/Main/IO.hs +0/−36
- tasty/Main/Statements.hs +0/−31
+ CHANGELOG.md view
@@ -0,0 +1,3 @@+# v0.4.5.4++- Widen the hasql bounds to support `hasql-2`
hasql-cursor-query.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hasql-cursor-query-version: 0.4.5.3+version: 0.4.5.4 category: Hasql, Database, PostgreSQL, Streaming synopsis: A declarative abstraction over PostgreSQL Cursor homepage: https://github.com/nikita-volkov/hasql-cursor-query@@ -10,6 +10,8 @@ copyright: (c) 2016, Nikita Volkov license: MIT license-file: LICENSE+extra-doc-files:+ CHANGELOG.md source-repository head type: git@@ -64,6 +66,10 @@ common test import: base+ default-extensions:+ BlockArguments+ ImportQualifiedPost+ ghc-options: -threaded "-with-rtsopts=-N -I0 -qg"@@ -90,25 +96,36 @@ bytestring >=0.10 && <0.14, contravariant >=1.3 && <2, foldl >1 && <2,- hasql >=1.9 && <1.10,+ hasql >=1.10 && <1.11 || >=2.0 && <2.1, hasql-cursor-transaction >=0.6 && <0.7,- hasql-transaction >=1.1 && <1.2,+ hasql-transaction >=1.1 && <1.3, profunctors >=5 && <6,+ text >=1 && <3, -test-suite tasty+test-suite test import: test type: exitcode-stdio-1.0- hs-source-dirs: tasty+ hs-source-dirs: src/integration-tests main-is: Main.hs other-modules:- Main.CursorQueries- Main.IO- Main.Statements+ Helpers.Adapters+ Helpers.CursorQueries+ Helpers.Hooks+ Helpers.Scripts+ Helpers.Statements+ Specs.CursorQuerySpec+ Specs.SpecHook + build-tool-depends:+ hspec-discover:hspec-discover ^>=2.11.12+ build-depends: foldl >=1.2 && <2, hasql, hasql-cursor-query,- rebase <2,- tasty >=0.12 && <2,- tasty-hunit >=0.9 && <0.11,+ hspec >=2.6 && <3,+ pqi ^>=1.0,+ pqi-ffi ^>=1.0,+ pqi-native ^>=1.0,+ rerebase >=1.15 && <2,+ testcontainers-postgresql >=0.2 && <0.3,
library/Hasql/CursorQuery/Private/CursorTransactions.hs view
@@ -1,6 +1,7 @@ module Hasql.CursorQuery.Private.CursorTransactions where import qualified Control.Foldl as D+import qualified Data.Text.Encoding as Text import qualified Hasql.CursorQuery.Private.CursorQuery as B import qualified Hasql.CursorQuery.Private.Decoders as I import Hasql.CursorQuery.Private.Prelude@@ -36,5 +37,5 @@ cursorQuery :: params -> B.CursorQuery params result -> G.CursorTransaction s result cursorQuery params (B.CursorQuery template encoder (B.ReducingDecoder rowDecoder rowsFold) batchSize) = do- cursor <- G.declareCursor template (G.encodedParams encoder params)+ cursor <- G.declareCursor (Text.decodeUtf8 template) (G.encodedParams encoder params) fetchAndFoldCursor cursor batchSize rowDecoder rowsFold
library/Hasql/CursorQuery/Private/Prelude.hs view
@@ -57,6 +57,7 @@ import GHC.Generics as Exports (Generic, Generic1) import GHC.IO.Exception as Exports import Numeric as Exports+import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.)) import System.Environment as Exports import System.Exit as Exports import System.IO as Exports@@ -68,4 +69,3 @@ import Text.Printf as Exports (hPrintf, printf) import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports-import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.))
+ src/integration-tests/Helpers/Adapters.hs view
@@ -0,0 +1,30 @@+module Helpers.Adapters+ ( adapters,+ byAdapter,+ hook,+ )+where++import Pqi qualified+import Pqi.Ffi qualified+import Pqi.Native qualified+import Prelude+import Test.Hspec++adapters :: [Pqi.Adapter]+adapters =+ [ Pqi.Ffi.adapter,+ Pqi.Native.adapter+ ]++-- | Run the given spec-building function once per available Pqi adapter,+-- nesting each run under a @describe@ named after the adapter.+byAdapter :: (Pqi.Adapter -> Spec) -> Spec+byAdapter f =+ for_ adapters \adapter ->+ describe (toList (Pqi.name adapter)) (f adapter)++hook :: SpecWith Pqi.Adapter -> Spec+hook hookedSpec =+ byAdapter \adapter ->+ mapSubject (const adapter) hookedSpec
+ src/integration-tests/Helpers/CursorQueries.hs view
@@ -0,0 +1,35 @@+module Helpers.CursorQueries where++import Control.Foldl qualified as Foldl+import Hasql.CursorQuery+import Hasql.Decoders qualified as D+import Hasql.Encoders qualified as E+import Prelude++countPGType :: CursorQuery () Int+countPGType =+ cursorQuery sql encoder decoder batchSize_10+ where+ sql =+ "select oid::int8, typname::text from pg_type"+ encoder =+ E.noParams+ decoder =+ reducingDecoder rowDecoder Foldl.length+ where+ rowDecoder =+ (,) <$> (D.column . D.nonNullable) D.int8 <*> (D.column . D.nonNullable) D.text++selectOidAndTypeName :: CursorQuery () [(Int64, Text)]+selectOidAndTypeName =+ cursorQuery sql encoder decoder batchSize_10+ where+ sql =+ "select oid::int8, typname::text from pg_type"+ encoder =+ E.noParams+ decoder =+ reducingDecoder rowDecoder Foldl.list+ where+ rowDecoder =+ (,) <$> (D.column . D.nonNullable) D.int8 <*> (D.column . D.nonNullable) D.text
+ src/integration-tests/Helpers/Hooks.hs view
@@ -0,0 +1,19 @@+-- | Hooks for Hspec.+module Helpers.Hooks where++import Data.Bool+import Prelude hiding (Handler)+import TestcontainersPostgresql qualified++-- | Testing action in the scope of the host name and port of a running fresh isolated postgres server.+type Handler = (Text, Word16) -> IO ()++postgres17 :: Handler -> IO ()+postgres17 handler =+ TestcontainersPostgresql.run+ TestcontainersPostgresql.Config+ { forwardLogs = False,+ tagName = "postgres:17",+ auth = TestcontainersPostgresql.TrustAuth+ }+ (\(host, portInt) -> handler (host, fromIntegral portInt))
+ src/integration-tests/Helpers/Scripts.hs view
@@ -0,0 +1,37 @@+module Helpers.Scripts+ ( ScopeParams,+ onConnection,+ session,+ )+where++import Hasql.Connection qualified as Connection+import Hasql.Connection.Settings qualified as Settings+import Hasql.Session qualified as Session+import Pqi qualified+import Prelude++-- |+-- Adapter, host and port of a running isolated postgres server.+type ScopeParams = (Pqi.Adapter, Text, Word16)++-- |+-- Acquire a connection against the running isolated postgres server,+-- releasing it once the action completes.+onConnection :: ScopeParams -> (Connection.Connection -> IO ()) -> IO ()+onConnection (adapter, host, port) action =+ bracket acquire Connection.release action+ where+ acquire =+ Connection.acquire adapter connectionSettings+ >>= either (fail . show) return+ connectionSettings =+ Settings.hostAndPort host port+ <> Settings.user "postgres"+ <> Settings.password "postgres"+ <> Settings.dbname "postgres"++session :: Connection.Connection -> Session.Session a -> IO a+session connection theSession =+ Connection.use connection theSession+ >>= either (fail . show) return
+ src/integration-tests/Helpers/Statements.hs view
@@ -0,0 +1,31 @@+module Helpers.Statements where++import Hasql.Decoders qualified as D+import Hasql.Encoders qualified as E+import Hasql.Statement+import Prelude++countPGType :: Statement () Int+countPGType =+ preparable sql encoder decoder+ where+ sql =+ "select count(*) from pg_type"+ encoder =+ E.noParams+ decoder =+ (D.singleRow . D.column . D.nonNullable . fmap fromIntegral) D.int8++selectOidAndTypeName :: Statement () [(Int64, Text)]+selectOidAndTypeName =+ preparable sql encoder decoder+ where+ sql =+ "select oid::int8, typname::text from pg_type"+ encoder =+ E.noParams+ decoder =+ D.rowList rowDecoder+ where+ rowDecoder =+ (,) <$> (D.column . D.nonNullable) D.int8 <*> (D.column . D.nonNullable) D.text
+ src/integration-tests/Main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ src/integration-tests/Specs/CursorQuerySpec.hs view
@@ -0,0 +1,23 @@+module Specs.CursorQuerySpec where++import Hasql.CursorQuery.Sessions qualified as CursorQuery+import Hasql.Session qualified as Session+import Helpers.CursorQueries qualified as CursorQueries+import Helpers.Scripts qualified as Scripts+import Helpers.Statements qualified as Statements+import Prelude+import Test.Hspec++spec :: SpecWith Scripts.ScopeParams+spec = do+ it "Counts the same amount of rows as a plain aggregate query" \scopeParams ->+ Scripts.onConnection scopeParams \connection -> do+ count1 <- Scripts.session connection (Session.statement () Statements.countPGType)+ count2 <- Scripts.session connection (CursorQuery.cursorQuery () CursorQueries.countPGType)+ count2 `shouldBe` count1++ it "Selects the same rows as a plain select query" \scopeParams ->+ Scripts.onConnection scopeParams \connection -> do+ result1 <- Scripts.session connection (Session.statement () Statements.selectOidAndTypeName)+ result2 <- Scripts.session connection (CursorQuery.cursorQuery () CursorQueries.selectOidAndTypeName)+ result2 `shouldBe` result1
+ src/integration-tests/Specs/SpecHook.hs view
@@ -0,0 +1,15 @@+-- Docs: https://hspec.github.io/hspec-discover.html+module Specs.SpecHook where++import Helpers.Adapters qualified as Adapters+import Helpers.Hooks qualified as Hooks+import Helpers.Scripts qualified as Scripts+import Test.Hspec++hook :: SpecWith Scripts.ScopeParams -> Spec+hook hookedSpec =+ Adapters.hook+ ( aroundAllWith+ (\action adapter -> Hooks.postgres17 \(host, port) -> action (adapter, host, port))+ hookedSpec+ )
− tasty/Main.hs
@@ -1,27 +0,0 @@-module Main where--import qualified Hasql.CursorQuery.Sessions as C-import qualified Hasql.Session as A-import qualified Main.CursorQueries as D-import qualified Main.IO as F-import qualified Main.Statements as E-import Rebase.Prelude-import Test.Tasty-import Test.Tasty.HUnit-import Test.Tasty.Runners--main :: IO ()-main =- defaultMain $- localOption (NumThreads 1) $- testGroup- "All tests"- [ testCase "Amount" $- do- (count1, count2) <- F.session ((,) <$> A.statement () E.countPGType <*> C.cursorQuery () D.countPGType)- assertEqual (show (count1, count2)) count1 count2,- testCase "Equality" $- do- (result1, result2) <- F.session ((,) <$> A.statement () E.slectOIDAndTypeName <*> C.cursorQuery () D.slectOIDAndTypeName)- assertEqual (show (result1, result2)) result1 result2- ]
− tasty/Main/CursorQueries.hs
@@ -1,39 +0,0 @@-module Main.CursorQueries where--import qualified Control.Foldl as C-import Hasql.CursorQuery-import qualified Hasql.Decoders as B-import qualified Hasql.Encoders as A-import Rebase.Prelude--countPGType :: CursorQuery () Int-countPGType =- cursorQuery sql encoder decoder batchSize_10- where- sql =- "select oid, typname from pg_type"- encoder =- A.noParams- decoder =- reducingDecoder rowDecoder fold- where- rowDecoder =- (,) <$> (B.column . B.nonNullable) B.int8 <*> (B.column . B.nonNullable) B.text- fold =- C.length--slectOIDAndTypeName :: CursorQuery () [(Int64, Text)]-slectOIDAndTypeName =- cursorQuery sql encoder decoder batchSize_10- where- sql =- "select oid, typname from pg_type"- encoder =- A.noParams- decoder =- reducingDecoder rowDecoder fold- where- rowDecoder =- (,) <$> (B.column . B.nonNullable) B.int8 <*> (B.column . B.nonNullable) B.text- fold =- C.list
− tasty/Main/IO.hs
@@ -1,36 +0,0 @@-module Main.IO where--import qualified Hasql.Connection as B-import qualified Hasql.Connection.Setting as Setting-import qualified Hasql.Connection.Setting.Connection as Connection-import qualified Hasql.Connection.Setting.Connection.Param as Param-import qualified Hasql.Session as A-import Rebase.Prelude--session :: A.Session a -> IO a-session session =- withConnection (A.run session)- >>= either (fail . show) (either (fail . show) return)- where- withConnection :: (B.Connection -> IO a) -> IO (Either B.ConnectionError a)- withConnection handler =- runExceptT $ acquire >>= \connection -> use connection <* release connection- where- acquire =- ExceptT $ B.acquire settings- where- settings =- [ Setting.connection- ( Connection.params- [ Param.host "localhost",- Param.port 5432,- Param.user "postgres",- Param.password "postgres",- Param.dbname "postgres"- ]- )- ]- use connection =- lift $ handler connection- release connection =- lift $ B.release connection
− tasty/Main/Statements.hs
@@ -1,31 +0,0 @@-module Main.Statements where--import qualified Hasql.Decoders as B-import qualified Hasql.Encoders as A-import Hasql.Statement-import Rebase.Prelude--countPGType :: Statement () Int-countPGType =- Statement sql encoder decoder True- where- sql =- "select count(*) from pg_type"- encoder =- A.noParams- decoder =- (B.singleRow . B.column . B.nonNullable . fmap fromIntegral) B.int8--slectOIDAndTypeName :: Statement () [(Int64, Text)]-slectOIDAndTypeName =- Statement sql encoder decoder True- where- sql =- "select oid, typname from pg_type"- encoder =- A.noParams- decoder =- B.rowList rowDecoder- where- rowDecoder =- (,) <$> (B.column . B.nonNullable) B.int8 <*> (B.column . B.nonNullable) B.text