Run queries in a transaction again

This commit is contained in:
Joe Nelson
2016-01-24 18:09:19 -08:00
parent ac73e8d77b
commit 51f71eb53d
3 changed files with 26 additions and 2 deletions
+3 -1
View File
@@ -11,6 +11,7 @@ import PostgREST.Config (AppConfig (..),
import PostgREST.DbStructure
import PostgREST.Error (errResponse, pgErrResponse)
import PostgREST.Middleware
import PostgREST.QueryBuilder (inTransaction, Isolation(..))
import Control.Monad (unless, void)
import Data.Monoid ((<>))
@@ -94,7 +95,8 @@ main = do
runSettings appSettings $ middle $ \ req respond -> do
time <- getPOSIXTime
body <- strictRequestBody req
let handleReq = H.run (runWithClaims conf time (app dbStructure conf body) req)
let handleReq = H.run $ inTransaction ReadCommitted
(runWithClaims conf time (app dbStructure conf body) req)
withResource pool $ \case
Left err -> respond $ errResponse HT.status500 (cs . show $ err)
Right c -> do
+20
View File
@@ -18,6 +18,7 @@ module PostgREST.QueryBuilder (
, callProc
, createReadStatement
, createWriteStatement
, inTransaction
, operators
, pgFmtIdent
, pgFmtLit
@@ -26,9 +27,11 @@ module PostgREST.QueryBuilder (
, sourceCTEName
, unquoted
, ResultsWithCount
, Isolation(..)
) where
import qualified Hasql.Query as H
import qualified Hasql.Session as H
import qualified Hasql.Encoders as HE
import qualified Hasql.Decoders as HD
@@ -501,3 +504,20 @@ pgFmtAsJsonPath (Just xx) = " AS " <> last xx
trimNullChars :: Text -> Text
trimNullChars = T.takeWhile (/= '\x0')
data Isolation = ReadCommitted | RepeatableRead | Serializable
{- |
Wrap a session in a transaction of desired isolation level
-}
inTransaction :: Isolation -> H.Session a -> H.Session a
inTransaction lvl f = do
H.sql $ "begin " <> isolate <> ";"
r <- f
H.sql "end;"
return r
where
isolate = case lvl of
ReadCommitted -> "ISOLATION LEVEL READ COMMITTED"
RepeatableRead -> "ISOLATION LEVEL REPEATABLE READ"
Serializable -> "ISOLATION LEVEL SERIALIZABLE"
+3 -1
View File
@@ -25,6 +25,7 @@ import PostgREST.Config (AppConfig(..))
import PostgREST.Middleware
import PostgREST.Error(pgErrResponse)
import PostgREST.Types
import PostgREST.QueryBuilder (inTransaction, Isolation(..))
dbString :: String
dbString = "postgres://postgrest_test_authenticator@localhost:5432/postgrest_test"
@@ -44,7 +45,8 @@ withApp config dbStructure c perform = do
perform $ defaultMiddle $ \req resp -> do
time <- getPOSIXTime
body <- strictRequestBody req
let handleReq = H.run (runWithClaims config time (app dbStructure config body) req)
let handleReq = H.run $ inTransaction ReadCommitted
(runWithClaims config time (app dbStructure config body) req)
resOrError <- handleReq c
either (resp . pgErrResponse) resp resOrError