git.iko.soy/typeable/postgresql-simple
on master help sign in
Add support for read-only transactions
commit476112c3f336d9940f33ccc1812562f61fe3b400 authorLeon P Smith <leon@melding-monads.com> dateFri 27 Jan 2012, 01:56 (15 years ago) parent77c4a4b
1 file changed+45−20
src/Database/PostgreSQL/Simple.hs+45−20
src/Database/PostgreSQL/Simple.hs+45−20
@@ -69,8 +69,8 @@ module Database.PostgreSQL.Simple
6969 , query
7070 , query_
7171 -- * Queries that stream results
72− , FetchQuantity(..)
7372 , FoldOptions(..)
73+ , FetchQuantity(..)
7474 , defaultFoldOptions
7575 , fold
7676 , foldWithOptions
@@ -85,11 +85,13 @@ module Database.PostgreSQL.Simple
8585-- , Base.insertID
8686 -- * Transaction handling
8787 , withTransaction
88− , withTransactionLevel
88+ , TransactionMode(..)
8989 , IsolationLevel(..)
90+ , ReadWriteMode(..)
91+ , withTransactionMode
9092-- , Base.autocommit
9193 , begin
92− , beginLevel
94+ , beginMode
9395 , commit
9496 , rollback
9597 -- * Helper functions
@@ -332,12 +334,14 @@ data FetchQuantity
332334
333335data FoldOptions
334336 = FoldOptions {
335− fetchQuantity :: !FetchQuantity,
336− isolationLevel :: !IsolationLevel
337+ fetchQuantity :: !FetchQuantity,
338+ transactionMode :: !TransactionMode
337339 }
338340
339−defaultFoldOptions = FoldOptions { fetchQuantity = Automatic
340− , isolationLevel = ReadCommitted }
341+defaultFoldOptions = FoldOptions {
342+ fetchQuantity = Automatic,
343+ transactionMode = TransactionMode ReadCommitted ReadOnly
344+ }
341345
342346foldWithOptions :: ( QueryResults row, QueryParams params )
343347 => FoldOptions
@@ -382,7 +386,7 @@ doFold :: ( QueryResults row )
382386doFold FoldOptions{..} conn _template q a f = do
383387 stat <- withConnection conn PQ.transactionStatus
384388 case stat of
385− PQ.TransIdle -> withTransactionLevel isolationLevel conn go
389+ PQ.TransIdle -> withTransactionMode transactionMode conn go
386390 PQ.TransInTrans -> go
387391 PQ.TransActive -> fail "foldWithOpts FIXME: PQ.TransActive"
388392 -- This _shouldn't_ occur in the current incarnation of
@@ -484,6 +488,19 @@ data IsolationLevel
484488 | Serializable
485489 deriving (Show, Eq, Ord, Enum, Bounded)
486490
491+data ReadWriteMode
492+ = ReadWrite
493+ | ReadOnly
494+ deriving (Show, Eq, Ord, Enum, Bounded)
495+
496+data TransactionMode = TransactionMode {
497+ isolationLevel :: !IsolationLevel,
498+ readWriteMode :: !ReadWriteMode
499+ } deriving (Show, Eq, Ord)
500+
501+defaultTransactionMode :: TransactionMode
502+defaultTransactionMode = TransactionMode ReadCommitted ReadWrite
503+
487504-- | Execute an action inside a SQL transaction.
488505--
489506-- This function initiates a transaction with a \"@begin
@@ -495,18 +512,17 @@ data IsolationLevel
495512-- PostgreSQL-related exception), the transaction will be rolled back using
496513-- 'rollback', then the exception will be rethrown.
497514withTransaction :: Connection -> IO a -> IO a
498−withTransaction = withTransactionLevel ReadCommitted
515+withTransaction = withTransactionMode defaultTransactionMode
499516
500517-- | Execute an action inside a SQL transaction with a given isolation level.
501−withTransactionLevel :: IsolationLevel -> Connection -> IO a -> IO a
502−withTransactionLevel isolationLevel conn act = do
503− beginLevel isolationLevel conn
518+withTransactionMode :: TransactionMode -> Connection -> IO a -> IO a
519+withTransactionMode mode conn act = do
520+ beginMode mode conn
504521 r <- act `onException` rollback conn
505522 commit conn
506523 return r
507524
508525-- | Rollback a transaction.
509−-- rollback :: (MonadCatchIO m,MonadIO m) => Connection -> m ()
510526rollback :: Connection -> IO ()
511527rollback conn = execute_ conn "ABORT" >> return ()
512528
@@ -516,15 +532,24 @@ commit conn = execute_ conn "COMMIT" >> return ()
516532
517533-- | Begin a transaction.
518534begin :: Connection -> IO ()
519−begin = beginLevel ReadCommitted
535+begin = beginMode defaultTransactionMode
520536
521537-- | Begin a transaction with a given isolation level
522−beginLevel :: IsolationLevel -> Connection -> IO ()
523−beginLevel isolationLevel conn = do
524− execute_ conn $! case isolationLevel of
525− ReadCommitted -> "BEGIN"
526− RepeatableRead -> "BEGIN ISOLATION LEVEL REPEATABLE READ"
527− Serializable -> "BEGIN ISOLATION LEVEL SERIALIZABLE"
538+beginMode :: TransactionMode -> Connection -> IO ()
539+beginMode mode conn = do
540+ execute_ conn $! case mode of
541+ TransactionMode ReadCommitted ReadWrite ->
542+ "BEGIN"
543+ TransactionMode ReadCommitted ReadOnly ->
544+ "BEGIN READ ONLY"
545+ TransactionMode RepeatableRead ReadWrite ->
546+ "BEGIN ISOLATION LEVEL REPEATABLE READ"
547+ TransactionMode RepeatableRead ReadOnly ->
548+ "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"
549+ TransactionMode Serializable ReadWrite ->
550+ "BEGIN ISOLATION LEVEL SERIALIZABLE"
551+ TransactionMode Serializable ReadOnly ->
552+ "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"
528553 return ()
529554
530555fmtError :: String -> Query -> [Action] -> a