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.DbStructure
import PostgREST.Error (errResponse, pgErrResponse) import PostgREST.Error (errResponse, pgErrResponse)
import PostgREST.Middleware import PostgREST.Middleware
import PostgREST.QueryBuilder (inTransaction, Isolation(..))
import Control.Monad (unless, void) import Control.Monad (unless, void)
import Data.Monoid ((<>)) import Data.Monoid ((<>))
@@ -94,7 +95,8 @@ main = do
runSettings appSettings $ middle $ \ req respond -> do runSettings appSettings $ middle $ \ req respond -> do
time <- getPOSIXTime time <- getPOSIXTime
body <- strictRequestBody req 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 withResource pool $ \case
Left err -> respond $ errResponse HT.status500 (cs . show $ err) Left err -> respond $ errResponse HT.status500 (cs . show $ err)
Right c -> do Right c -> do
+20
View File
@@ -18,6 +18,7 @@ module PostgREST.QueryBuilder (
, callProc , callProc
, createReadStatement , createReadStatement
, createWriteStatement , createWriteStatement
, inTransaction
, operators , operators
, pgFmtIdent , pgFmtIdent
, pgFmtLit , pgFmtLit
@@ -26,9 +27,11 @@ module PostgREST.QueryBuilder (
, sourceCTEName , sourceCTEName
, unquoted , unquoted
, ResultsWithCount , ResultsWithCount
, Isolation(..)
) where ) where
import qualified Hasql.Query as H import qualified Hasql.Query as H
import qualified Hasql.Session as H
import qualified Hasql.Encoders as HE import qualified Hasql.Encoders as HE
import qualified Hasql.Decoders as HD import qualified Hasql.Decoders as HD
@@ -501,3 +504,20 @@ pgFmtAsJsonPath (Just xx) = " AS " <> last xx
trimNullChars :: Text -> Text trimNullChars :: Text -> Text
trimNullChars = T.takeWhile (/= '\x0') 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.Middleware
import PostgREST.Error(pgErrResponse) import PostgREST.Error(pgErrResponse)
import PostgREST.Types import PostgREST.Types
import PostgREST.QueryBuilder (inTransaction, Isolation(..))
dbString :: String dbString :: String
dbString = "postgres://postgrest_test_authenticator@localhost:5432/postgrest_test" dbString = "postgres://postgrest_test_authenticator@localhost:5432/postgrest_test"
@@ -44,7 +45,8 @@ withApp config dbStructure c perform = do
perform $ defaultMiddle $ \req resp -> do perform $ defaultMiddle $ \req resp -> do
time <- getPOSIXTime time <- getPOSIXTime
body <- strictRequestBody req 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 resOrError <- handleReq c
either (resp . pgErrResponse) resp resOrError either (resp . pgErrResponse) resp resOrError