@@ -69,8 +69,8 @@ module Database.PostgreSQL.Simple
71 -- * Queries that stream results
71 -- * Queries that stream results
73 , FoldOptions(..)
72 , FoldOptions(..)
74 , defaultFoldOptions
74 , defaultFoldOptions
76 , foldWithOptions
76 , foldWithOptions
@@ -85,11 +85,13 @@ module Database.PostgreSQL.Simple
85-- , Base.insertID
85-- , Base.insertID
86 -- * Transaction handling
86 -- * Transaction handling
87 , withTransaction
87 , withTransaction
88− , withTransactionLevel
88+ , TransactionMode(..)
89 , IsolationLevel(..)
89 , IsolationLevel(..)
91+ , withTransactionMode
90-- , Base.autocommit
92-- , Base.autocommit
92− , beginLevel
94+ , beginMode
94 , rollback
96 , rollback
95 -- * Helper functions
97 -- * Helper functions
@@ -332,12 +334,14 @@ data FetchQuantity
333data FoldOptions
335data FoldOptions
334 = FoldOptions {
336 = FoldOptions {
335− fetchQuantity :: !FetchQuantity,
337+ fetchQuantity :: !FetchQuantity,
336− isolationLevel :: !IsolationLevel
338+ transactionMode :: !TransactionMode
339−defaultFoldOptions = FoldOptions { fetchQuantity = Automatic
341+defaultFoldOptions = FoldOptions {
340− , isolationLevel = ReadCommitted }
342+ fetchQuantity = Automatic,
343+ transactionMode = TransactionMode ReadCommitted ReadOnly
342foldWithOptions :: ( QueryResults row, QueryParams params )
346foldWithOptions :: ( QueryResults row, QueryParams params )
343 => FoldOptions
347 => FoldOptions
@@ -382,7 +386,7 @@ doFold :: ( QueryResults row )
382doFold FoldOptions{..} conn _template q a f = do
386doFold FoldOptions{..} conn _template q a f = do
383 stat <- withConnection conn PQ.transactionStatus
387 stat <- withConnection conn PQ.transactionStatus
384 case stat of
388 case stat of
385− PQ.TransIdle -> withTransactionLevel isolationLevel conn go
389+ PQ.TransIdle -> withTransactionMode transactionMode conn go
386 PQ.TransInTrans -> go
390 PQ.TransInTrans -> go
387 PQ.TransActive -> fail "foldWithOpts FIXME: PQ.TransActive"
391 PQ.TransActive -> fail "foldWithOpts FIXME: PQ.TransActive"
388 -- This _shouldn't_ occur in the current incarnation of
392 -- This _shouldn't_ occur in the current incarnation of
@@ -484,6 +488,19 @@ data IsolationLevel
484 | Serializable
488 | Serializable
485 deriving (Show, Eq, Ord, Enum, Bounded)
489 deriving (Show, Eq, Ord, Enum, Bounded)
494+ deriving (Show, Eq, Ord, Enum, Bounded)
496+data TransactionMode = TransactionMode {
497+ isolationLevel :: !IsolationLevel,
498+ readWriteMode :: !ReadWriteMode
499+ } deriving (Show, Eq, Ord)
501+defaultTransactionMode :: TransactionMode
502+defaultTransactionMode = TransactionMode ReadCommitted ReadWrite
487-- | Execute an action inside a SQL transaction.
504-- | Execute an action inside a SQL transaction.
489-- This function initiates a transaction with a \"@begin
506-- This function initiates a transaction with a \"@begin
@@ -495,18 +512,17 @@ data IsolationLevel
495-- PostgreSQL-related exception), the transaction will be rolled back using
512-- PostgreSQL-related exception), the transaction will be rolled back using
496-- 'rollback', then the exception will be rethrown.
513-- 'rollback', then the exception will be rethrown.
497withTransaction :: Connection -> IO a -> IO a
514withTransaction :: Connection -> IO a -> IO a
498−withTransaction = withTransactionLevel ReadCommitted
515+withTransaction = withTransactionMode defaultTransactionMode
500-- | Execute an action inside a SQL transaction with a given isolation level.
517-- | Execute an action inside a SQL transaction with a given isolation level.
501−withTransactionLevel :: IsolationLevel -> Connection -> IO a -> IO a
518+withTransactionMode :: TransactionMode -> Connection -> IO a -> IO a
502−withTransactionLevel isolationLevel conn act = do
519+withTransactionMode mode conn act = do
503− beginLevel isolationLevel conn
520+ beginMode mode conn
504 r <- act `onException` rollback conn
521 r <- act `onException` rollback conn
505 commit conn
522 commit conn
508-- | Rollback a transaction.
525-- | Rollback a transaction.
509−-- rollback :: (MonadCatchIO m,MonadIO m) => Connection -> m ()
510rollback :: Connection -> IO ()
526rollback :: Connection -> IO ()
511rollback conn = execute_ conn "ABORT" >> return ()
527rollback conn = execute_ conn "ABORT" >> return ()
@@ -516,15 +532,24 @@ commit conn = execute_ conn "COMMIT" >> return ()
517-- | Begin a transaction.
533-- | Begin a transaction.
518begin :: Connection -> IO ()
534begin :: Connection -> IO ()
519−begin = beginLevel ReadCommitted
535+begin = beginMode defaultTransactionMode
521-- | Begin a transaction with a given isolation level
537-- | Begin a transaction with a given isolation level
522−beginLevel :: IsolationLevel -> Connection -> IO ()
538+beginMode :: TransactionMode -> Connection -> IO ()
523−beginLevel isolationLevel conn = do
539+beginMode mode conn = do
524− execute_ conn $! case isolationLevel of
540+ execute_ conn $! case mode of
541+ TransactionMode ReadCommitted ReadWrite ->
525− ReadCommitted -> "BEGIN"
543+ TransactionMode ReadCommitted ReadOnly ->
545+ TransactionMode RepeatableRead ReadWrite ->
546+ "BEGIN ISOLATION LEVEL REPEATABLE READ"
547+ TransactionMode RepeatableRead ReadOnly ->
526− RepeatableRead -> "BEGIN ISOLATION LEVEL REPEATABLE READ"
548+ "BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY"
549+ TransactionMode Serializable ReadWrite ->
550+ "BEGIN ISOLATION LEVEL SERIALIZABLE"
551+ TransactionMode Serializable ReadOnly ->
527− Serializable -> "BEGIN ISOLATION LEVEL SERIALIZABLE"
552+ "BEGIN ISOLATION LEVEL SERIALIZABLE READ ONLY"
528 return ()
553 return ()
530fmtError :: String -> Query -> [Action] -> a
555fmtError :: String -> Query -> [Action] -> a