hasql-transaction 1.0.1.2 → 1.0.1.3
raw patch · 13 files changed
+228/−194 lines, 13 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- conflicts-test/Main.hs +11/−11
- conflicts-test/Main/Statements.hs +3/−5
- conflicts-test/Main/Transactions.hs +3/−6
- hasql-transaction.cabal +116/−40
- library/Hasql/Transaction.hs +6/−8
- library/Hasql/Transaction/Config.hs +21/−0
- library/Hasql/Transaction/Private/Model.hs +0/−25
- library/Hasql/Transaction/Private/Prelude.hs +26/−48
- library/Hasql/Transaction/Private/SQL.hs +8/−7
- library/Hasql/Transaction/Private/Sessions.hs +12/−12
- library/Hasql/Transaction/Private/Statements.hs +5/−10
- library/Hasql/Transaction/Private/Transaction.hs +8/−12
- library/Hasql/Transaction/Sessions.hs +9/−10
conflicts-test/Main.hs view
@@ -1,15 +1,15 @@ module Main where -import Prelude+import qualified Control.Concurrent.Async as F import qualified Hasql.Connection as A import qualified Hasql.Session as B import qualified Hasql.Transaction as C import qualified Hasql.Transaction.Sessions as G import qualified Main.Statements as D import qualified Main.Transactions as E-import qualified Control.Concurrent.Async as F-+import Prelude +main :: IO () main = bracket acquire release use where@@ -17,12 +17,12 @@ (,) <$> acquire <*> acquire where acquire =- join $- fmap (either (fail . show) return) $- A.acquire connectionSettings+ join+ $ fmap (either (fail . show) return)+ $ A.acquire connectionSettings where connectionSettings =- A.settings "localhost" 5432 "postgres" "" "postgres"+ A.settings "localhost" 5432 "postgres" "postgres" "postgres" release (connection1, connection2) = do transaction connection1 E.dropSchema@@ -42,14 +42,14 @@ tests = [readAndWriteTransactionsTest, transactionsTest, transactionAndQueryTest] -+session :: A.Connection -> B.Session a -> IO a session connection session =- B.run session connection >>=- either (fail . show) return+ B.run session connection+ >>= either (fail . show) return +transaction :: A.Connection -> C.Transaction a -> IO a transaction connection transaction = session connection (G.transaction G.RepeatableRead G.Write transaction)- type Test = A.Connection -> A.Connection -> IO Bool
conflicts-test/Main/Statements.hs view
@@ -1,11 +1,10 @@ module Main.Statements where -import Prelude import Contravariant.Extras-import Hasql.Statement-import qualified Hasql.Encoders as E import qualified Hasql.Decoders as D-+import qualified Hasql.Encoders as E+import Hasql.Statement+import Prelude createAccountTable :: Statement () () createAccountTable =@@ -45,4 +44,3 @@ ((E.param . E.nonNullable) E.int8) (D.rowMaybe ((D.column . D.nonNullable) D.numeric)) True-
conflicts-test/Main/Transactions.hs view
@@ -1,9 +1,8 @@ module Main.Transactions where -import Prelude import Hasql.Transaction import qualified Main.Statements as A-+import Prelude createSchema :: Transaction () createSchema =@@ -20,10 +19,8 @@ do success <- statement (id1, amount) A.modifyBalance if success- then- statement (id2, negate amount) A.modifyBalance- else- return False+ then statement (id2, negate amount) A.modifyBalance+ else return False transferTimes :: Int -> Int64 -> Int64 -> Scientific -> Transaction () transferTimes times id1 id2 amount =
hasql-transaction.cabal view
@@ -1,61 +1,137 @@-name: hasql-transaction-version: 1.0.1.2-category: Hasql, Database, PostgreSQL-synopsis: Composable abstraction over retryable transactions for Hasql-homepage: https://github.com/nikita-volkov/hasql-transaction-bug-reports: https://github.com/nikita-volkov/hasql-transaction/issues-author: Nikita Volkov <nikita.y.volkov@mail.ru>-maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>-copyright: (c) 2015, Nikita Volkov-license: MIT-license-file: LICENSE-build-type: Simple+name: hasql-transaction+version: 1.0.1.3+category: Hasql, Database, PostgreSQL+synopsis:+ Composable abstraction over retryable transactions for Hasql++homepage: https://github.com/nikita-volkov/hasql-transaction+bug-reports: https://github.com/nikita-volkov/hasql-transaction/issues+author: Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer: Nikita Volkov <nikita.y.volkov@mail.ru>+copyright: (c) 2015, Nikita Volkov+license: MIT+license-file: LICENSE+build-type: Simple cabal-version: >=1.10 source-repository head- type: git+ type: git location: git://github.com/nikita-volkov/hasql-transaction.git library- hs-source-dirs: library- default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010+ hs-source-dirs: library+ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction+ Arrows+ BangPatterns+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveTraversable+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TemplateHaskell+ TupleSections+ TypeFamilies+ TypeOperators+ UnboxedTuples++ default-language: Haskell2010 exposed-modules: Hasql.Transaction Hasql.Transaction.Sessions+ other-modules:+ Hasql.Transaction.Config Hasql.Transaction.Private.Prelude- Hasql.Transaction.Private.Model+ Hasql.Transaction.Private.Sessions Hasql.Transaction.Private.SQL Hasql.Transaction.Private.Statements- Hasql.Transaction.Private.Sessions Hasql.Transaction.Private.Transaction+ build-depends:- base >=4.12 && <5,- bytestring >=0.10 && <0.12,- bytestring-tree-builder >=0.2.7.8 && <0.3,- contravariant >=1.3 && <2,- contravariant-extras >=0.3 && <0.4,- hasql >=1.6 && <1.7,- mtl >=2.2 && <3,- transformers >=0.5 && <0.7+ base >=4.12 && <5+ , bytestring >=0.10 && <0.12+ , bytestring-tree-builder >=0.2.7.8 && <0.3+ , contravariant >=1.3 && <2+ , contravariant-extras >=0.3 && <0.4+ , hasql >=1.6 && <1.7+ , mtl >=2.2 && <3+ , transformers >=0.5 && <0.7 test-suite conflicts-test- type: exitcode-stdio-1.0- hs-source-dirs: conflicts-test- default-extensions: Arrows, BangPatterns, ConstraintKinds, DataKinds, DefaultSignatures, DeriveDataTypeable, DeriveFoldable, DeriveFunctor, DeriveGeneric, DeriveTraversable, EmptyDataDecls, FlexibleContexts, FlexibleInstances, FunctionalDependencies, GADTs, GeneralizedNewtypeDeriving, LambdaCase, LiberalTypeSynonyms, MagicHash, MultiParamTypeClasses, MultiWayIf, NoImplicitPrelude, NoMonomorphismRestriction, OverloadedStrings, PatternGuards, ParallelListComp, QuasiQuotes, RankNTypes, RecordWildCards, ScopedTypeVariables, StandaloneDeriving, TemplateHaskell, TupleSections, TypeFamilies, TypeOperators, UnboxedTuples- default-language: Haskell2010- main-is: Main.hs+ type: exitcode-stdio-1.0+ hs-source-dirs: conflicts-test+ default-extensions:+ NoImplicitPrelude+ NoMonomorphismRestriction+ Arrows+ BangPatterns+ ConstraintKinds+ DataKinds+ DefaultSignatures+ DeriveDataTypeable+ DeriveFoldable+ DeriveFunctor+ DeriveGeneric+ DeriveTraversable+ EmptyDataDecls+ FlexibleContexts+ FlexibleInstances+ FunctionalDependencies+ GADTs+ GeneralizedNewtypeDeriving+ LambdaCase+ LiberalTypeSynonyms+ MagicHash+ MultiParamTypeClasses+ MultiWayIf+ OverloadedStrings+ ParallelListComp+ PatternGuards+ QuasiQuotes+ RankNTypes+ RecordWildCards+ ScopedTypeVariables+ StandaloneDeriving+ TemplateHaskell+ TupleSections+ TypeFamilies+ TypeOperators+ UnboxedTuples++ default-language: Haskell2010+ main-is: Main.hs other-modules: Main.Statements Main.Transactions- ghc-options:- -O2- -threaded- "-with-rtsopts=-N"++ ghc-options: -O2 -threaded -with-rtsopts=-N build-depends:- contravariant-extras >=0.3 && <0.4,- hasql-transaction,- hasql,- async >=2.1 && <3,- rerebase >=1.11 && <2+ async >=2.1 && <3+ , contravariant-extras >=0.3 && <0.4+ , hasql+ , hasql-transaction+ , rerebase >=1.11 && <2
library/Hasql/Transaction.hs view
@@ -1,14 +1,12 @@ -- | -- An API for declaration of transactions. module Hasql.Transaction-(- -- * Transaction monad- Transaction,- condemn,- sql,- statement,-)+ ( -- * Transaction monad+ Transaction,+ condemn,+ sql,+ statement,+ ) where import Hasql.Transaction.Private.Transaction-import Hasql.Transaction.Private.Model
+ library/Hasql/Transaction/Config.hs view
@@ -0,0 +1,21 @@+module Hasql.Transaction.Config where++import Hasql.Transaction.Private.Prelude++data Mode+ = -- |+ -- Read-only. No writes possible.+ Read+ | -- |+ -- Write and commit.+ Write+ deriving (Show, Eq, Ord, Enum, Bounded)++-- |+-- For reference see+-- <http://www.postgresql.org/docs/current/static/transaction-iso.html the Postgres' documentation>.+data IsolationLevel+ = ReadCommitted+ | RepeatableRead+ | Serializable+ deriving (Show, Eq, Ord, Enum, Bounded)
− library/Hasql/Transaction/Private/Model.hs
@@ -1,25 +0,0 @@-module Hasql.Transaction.Private.Model-where--import Hasql.Transaction.Private.Prelude---- |----data Mode =- -- |- -- Read-only. No writes possible.- Read |- -- |- -- Write and commit.- Write- deriving (Show, Eq, Ord, Enum, Bounded)---- |--- For reference see--- <http://www.postgresql.org/docs/current/static/transaction-iso.html the Postgres' documentation>.----data IsolationLevel =- ReadCommitted |- RepeatableRead |- Serializable- deriving (Show, Eq, Ord, Enum, Bounded)
library/Hasql/Transaction/Private/Prelude.hs view
@@ -1,25 +1,28 @@ module Hasql.Transaction.Private.Prelude-( - module Exports,- tryError,-)+ ( module Exports,+ tryError,+ ) where ---- base--------------------------+import Contravariant.Extras as Exports import Control.Applicative as Exports import Control.Arrow as Exports import Control.Category as Exports import Control.Concurrent as Exports import Control.Exception as Exports-import Control.Monad as Exports hiding (join, fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)-import Control.Monad.IO.Class as Exports+import Control.Monad as Exports hiding (fail, forM, forM_, join, mapM, mapM_, msum, sequence, sequence_)+import Control.Monad.Error.Class as Exports (MonadError (..)) import Control.Monad.Fail as Exports import Control.Monad.Fix as Exports hiding (fix)+import Control.Monad.IO.Class as Exports import Control.Monad.ST as Exports+import Control.Monad.Trans.Class as Exports+import Control.Monad.Trans.Maybe as Exports hiding (liftListen, liftPass)+import Control.Monad.Trans.Reader as Exports hiding (liftCallCC, liftCatch)+import Control.Monad.Trans.State.Strict as Exports hiding (liftCallCC, liftCatch, liftListen, liftPass) import Data.Bits as Exports import Data.Bool as Exports+import Data.ByteString as Exports (ByteString) import Data.Char as Exports import Data.Coerce as Exports import Data.Complex as Exports@@ -29,19 +32,21 @@ import Data.Fixed as Exports import Data.Foldable as Exports hiding (toList) import Data.Function as Exports hiding (id, (.))-import Data.Functor as Exports+import Data.Functor as Exports hiding (unzip)+import Data.Functor.Contravariant as Exports+import Data.Functor.Contravariant.Divisible as Exports import Data.Functor.Identity as Exports-import Data.Int as Exports import Data.IORef as Exports+import Data.Int as Exports import Data.Ix as Exports-import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')+import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, isSubsequenceOf, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sortOn, sum, uncons) import Data.Maybe as Exports-import Data.Monoid as Exports hiding (Last(..), First(..), (<>), Alt)+import Data.Monoid as Exports hiding (Alt, First (..), Last (..), (<>)) import Data.Ord as Exports import Data.Proxy as Exports import Data.Ratio as Exports-import Data.Semigroup as Exports import Data.STRef as Exports+import Data.Semigroup as Exports import Data.String as Exports import Data.Traversable as Exports import Data.Tuple as Exports@@ -52,13 +57,12 @@ import Foreign.ForeignPtr as Exports import Foreign.Ptr as Exports import Foreign.StablePtr as Exports-import Foreign.Storable as Exports hiding (sizeOf, alignment)-import GHC.Conc as Exports hiding (withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)-import GHC.Exts as Exports (lazy, inline, sortWith, groupWith, IsList(..))+import Foreign.Storable as Exports hiding (alignment, sizeOf)+import GHC.Conc as Exports hiding (threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar)+import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith) import GHC.Generics as Exports (Generic, Generic1) import GHC.IO.Exception as Exports import Numeric as Exports-import Prelude as Exports hiding (fail, concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.)) import System.Environment as Exports import System.Exit as Exports import System.IO as Exports@@ -67,37 +71,11 @@ import System.Mem as Exports import System.Mem.StableName as Exports import System.Timeout as Exports-import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)-import Text.Printf as Exports (printf, hPrintf)-import Text.Read as Exports (Read(..), readMaybe, readEither)+import Text.Printf as Exports (hPrintf, printf)+import Text.Read as Exports (Read (..), readEither, readMaybe) import Unsafe.Coerce as Exports---- transformers---------------------------import Control.Monad.IO.Class as Exports-import Control.Monad.Trans.Class as Exports-import Control.Monad.Trans.Maybe as Exports hiding (liftListen, liftPass)-import Control.Monad.Trans.Reader as Exports hiding (liftCallCC, liftCatch)-import Control.Monad.Trans.State.Strict as Exports hiding (liftCallCC, liftCatch, liftListen, liftPass)---- mtl---------------------------import Control.Monad.Error.Class as Exports (MonadError (..))---- contravariant---------------------------import Data.Functor.Contravariant as Exports-import Data.Functor.Contravariant.Divisible as Exports---- contravariant-extras---------------------------import Contravariant.Extras as Exports---- bytestring---------------------------import Data.ByteString as Exports (ByteString)+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, (.)) -tryError :: MonadError e m => m a -> m (Either e a)+tryError :: (MonadError e m) => m a -> m (Either e a) tryError m = catchError (liftM Right m) (return . Left)
library/Hasql/Transaction/Private/SQL.hs view
@@ -1,10 +1,8 @@-module Hasql.Transaction.Private.SQL-where+module Hasql.Transaction.Private.SQL where -import Hasql.Transaction.Private.Prelude-import Hasql.Transaction.Private.Model import qualified ByteString.TreeBuilder as D-+import Hasql.Transaction.Config+import Hasql.Transaction.Private.Prelude beginTransaction :: IsolationLevel -> Mode -> ByteString beginTransaction isolation mode =@@ -25,5 +23,8 @@ declareCursor :: ByteString -> ByteString -> ByteString declareCursor name sql =- D.toByteString $- "DECLARE " <> D.byteString name <> " NO SCROLL CURSOR FOR " <> D.byteString sql+ D.toByteString+ $ "DECLARE "+ <> D.byteString name+ <> " NO SCROLL CURSOR FOR "+ <> D.byteString sql
library/Hasql/Transaction/Private/Sessions.hs view
@@ -1,12 +1,10 @@-module Hasql.Transaction.Private.Sessions-where+module Hasql.Transaction.Private.Sessions where -import Hasql.Transaction.Private.Prelude-import Hasql.Transaction.Private.Model import Hasql.Session+import Hasql.Transaction.Config+import Hasql.Transaction.Private.Prelude import qualified Hasql.Transaction.Private.Statements as Statements - {- We may want to do one transaction retry in case of the 23505 error, and fail if an identical@@ -14,7 +12,7 @@ -} inRetryingTransaction :: IsolationLevel -> Mode -> Session (a, Bool) -> Bool -> Session a inRetryingTransaction level mode session preparable =- fix $ \ retry -> do+ fix $ \retry -> do attemptRes <- tryTransaction level mode session preparable case attemptRes of Just a -> return a@@ -22,22 +20,24 @@ tryTransaction :: IsolationLevel -> Mode -> Session (a, Bool) -> Bool -> Session (Maybe a) tryTransaction level mode body preparable = do- statement () (Statements.beginTransaction level mode preparable) - bodyRes <- catchError (fmap Just body) $ \ error -> do+ bodyRes <- catchError (fmap Just body) $ \error -> do statement () (Statements.abortTransaction preparable) handleTransactionError error $ return Nothing case bodyRes of- Just (res, commit) -> catchError (commitOrAbort commit preparable $> Just res) $ \ error -> do+ Just (res, commit) -> catchError (commitOrAbort commit preparable $> Just res) $ \error -> do handleTransactionError error $ return Nothing Nothing -> return Nothing -commitOrAbort commit preparable = if commit- then statement () (Statements.commitTransaction preparable)- else statement () (Statements.abortTransaction preparable)+commitOrAbort :: Bool -> Bool -> Session ()+commitOrAbort commit preparable =+ if commit+ then statement () (Statements.commitTransaction preparable)+ else statement () (Statements.abortTransaction preparable) +handleTransactionError :: QueryError -> Session a -> Session a handleTransactionError error onTransactionError = case error of QueryError _ _ (ResultError (ServerError "40001" _ _ _ _)) -> onTransactionError error -> throwError error
library/Hasql/Transaction/Private/Statements.hs view
@@ -1,16 +1,13 @@-module Hasql.Transaction.Private.Statements-where+module Hasql.Transaction.Private.Statements where -import Hasql.Transaction.Private.Prelude-import Hasql.Transaction.Private.Model-import qualified Hasql.Statement as A-import qualified Hasql.Encoders as B import qualified Hasql.Decoders as C+import qualified Hasql.Encoders as B+import qualified Hasql.Statement as A+import Hasql.Transaction.Config+import Hasql.Transaction.Private.Prelude import qualified Hasql.Transaction.Private.SQL as D - -- * Transactions-------------------------- beginTransaction :: IsolationLevel -> Mode -> Bool -> A.Statement () () beginTransaction isolation mode preparable =@@ -24,9 +21,7 @@ abortTransaction preparable = A.Statement "ABORT" B.noParams C.noResult preparable - -- * Streaming-------------------------- declareCursor :: ByteString -> ByteString -> B.Params a -> A.Statement a () declareCursor name sql encoder =
library/Hasql/Transaction/Private/Transaction.hs view
@@ -1,30 +1,26 @@-module Hasql.Transaction.Private.Transaction-where+module Hasql.Transaction.Private.Transaction where -import Hasql.Transaction.Private.Prelude-import Hasql.Transaction.Private.Model-import qualified Hasql.Statement as A import qualified Hasql.Session as B-import qualified Hasql.Transaction.Private.Statements as C+import qualified Hasql.Statement as A+import Hasql.Transaction.Config+import Hasql.Transaction.Private.Prelude import qualified Hasql.Transaction.Private.Sessions as D - -- | -- A composable abstraction over the retryable transactions. -- -- Executes multiple queries under the specified mode and isolation level, -- while automatically retrying the transaction in case of conflicts. -- Thus this abstraction closely reproduces the behaviour of 'STM'.-newtype Transaction a =- Transaction (StateT Bool B.Session a)+newtype Transaction a+ = Transaction (StateT Bool B.Session a) deriving (Functor, Applicative, Monad) -instance Semigroup a => Semigroup (Transaction a) where+instance (Semigroup a) => Semigroup (Transaction a) where (<>) = liftA2 (<>) -instance Monoid a => Monoid (Transaction a) where+instance (Monoid a) => Monoid (Transaction a) where mempty = pure mempty- mappend = liftA2 mappend -- | -- Execute the transaction using the provided isolation level and mode.
library/Hasql/Transaction/Sessions.hs view
@@ -1,18 +1,17 @@ module Hasql.Transaction.Sessions-(- transaction,- unpreparedTransaction,- -- * Transaction settings- C.Mode(..),- C.IsolationLevel(..),-)+ ( transaction,+ unpreparedTransaction,++ -- * Transaction settings+ C.Mode (..),+ C.IsolationLevel (..),+ ) where import Data.Bool-import qualified Hasql.Transaction.Private.Transaction as A import qualified Hasql.Session as B-import qualified Hasql.Transaction.Private.Model as C-+import qualified Hasql.Transaction.Config as C+import qualified Hasql.Transaction.Private.Transaction as A -- | -- Execute the transaction using the provided isolation level and mode.