handle all requests in a transaction.
This commit is contained in:
+13
-12
@@ -4,6 +4,7 @@
|
|||||||
module Dbapi where
|
module Dbapi where
|
||||||
|
|
||||||
import Types (SqlRow, getRow)
|
import Types (SqlRow, getRow)
|
||||||
|
import Middleware(reportPgErrors)
|
||||||
|
|
||||||
import Control.Monad (join)
|
import Control.Monad (join)
|
||||||
import Control.Exception.Base (bracket_)
|
import Control.Exception.Base (bracket_)
|
||||||
@@ -100,8 +101,17 @@ app anonymous conn req respond = do
|
|||||||
|
|
||||||
|
|
||||||
appWithRole :: Connection -> Application
|
appWithRole :: Connection -> Application
|
||||||
appWithRole conn req respond =
|
appWithRole conn = reportPgErrors (\req respond ->
|
||||||
respond =<< case (path, verb) of
|
let
|
||||||
|
path = pathInfo req
|
||||||
|
verb = requestMethod req
|
||||||
|
qq = queryString req
|
||||||
|
hdrs = requestHeaders req
|
||||||
|
ver = fromMaybe "1" $ requestedVersion hdrs
|
||||||
|
range = requestedRange hdrs
|
||||||
|
cRange = requestedContentRange hdrs
|
||||||
|
allOrigins = ("Access-Control-Allow-Origin", "*") :: Header
|
||||||
|
in respond =<< case (path, verb) of
|
||||||
([], _) ->
|
([], _) ->
|
||||||
responseLBS status200 [jsonContentType] <$> printTables ver conn
|
responseLBS status200 [jsonContentType] <$> printTables ver conn
|
||||||
|
|
||||||
@@ -159,16 +169,7 @@ appWithRole conn req respond =
|
|||||||
|
|
||||||
(_, _) ->
|
(_, _) ->
|
||||||
return $ responseLBS status404 [] ""
|
return $ responseLBS status404 [] ""
|
||||||
|
)
|
||||||
where
|
|
||||||
path = pathInfo req
|
|
||||||
verb = requestMethod req
|
|
||||||
qq = queryString req
|
|
||||||
hdrs = requestHeaders req
|
|
||||||
ver = fromMaybe "1" $ requestedVersion hdrs
|
|
||||||
range = requestedRange hdrs
|
|
||||||
cRange = requestedContentRange hdrs
|
|
||||||
allOrigins = ("Access-Control-Allow-Origin", "*") :: Header
|
|
||||||
|
|
||||||
defaultCorsPolicy :: CorsResourcePolicy
|
defaultCorsPolicy :: CorsResourcePolicy
|
||||||
defaultCorsPolicy = CorsResourcePolicy Nothing
|
defaultCorsPolicy = CorsResourcePolicy Nothing
|
||||||
|
|||||||
+3
-2
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
module Main where
|
module Main where
|
||||||
import Dbapi
|
import Dbapi
|
||||||
import Middleware (reportPgErrors)
|
import Middleware (inTransaction)
|
||||||
import Network.Wai.Handler.Warp hiding (Connection)
|
import Network.Wai.Handler.Warp hiding (Connection)
|
||||||
import Database.HDBC.PostgreSQL (connectPostgreSQL')
|
import Database.HDBC.PostgreSQL (connectPostgreSQL')
|
||||||
import Data.String.Conversions (cs)
|
import Data.String.Conversions (cs)
|
||||||
@@ -41,7 +41,8 @@ main = do
|
|||||||
|
|
||||||
Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String)
|
Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String)
|
||||||
conn <- connectPostgreSQL' dburi
|
conn <- connectPostgreSQL' dburi
|
||||||
runTLS tls settings $ gzip def $ cors corsPolicy $ reportPgErrors $ app (cs $ configAnonRole conf) conn
|
runTLS tls settings $ gzip def $ cors corsPolicy $
|
||||||
|
inTransaction conn (app (cs $ configAnonRole conf))
|
||||||
|
|
||||||
where
|
where
|
||||||
describe = progDesc "create a REST API to an existing Postgres database"
|
describe = progDesc "create a REST API to an existing Postgres database"
|
||||||
|
|||||||
+10
-3
@@ -5,12 +5,19 @@ module Middleware where
|
|||||||
|
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
|
|
||||||
|
import Database.HDBC (runRaw)
|
||||||
|
import Database.HDBC.PostgreSQL (Connection)
|
||||||
import Network.HTTP.Types.Header (hContentType)
|
import Network.HTTP.Types.Header (hContentType)
|
||||||
import Network.HTTP.Types.Status (status400)
|
import Network.HTTP.Types.Status (status400)
|
||||||
import Database.HDBC.Types (SqlError(..))
|
import Database.HDBC.Types (SqlError(..))
|
||||||
import Control.Exception (catchJust)
|
import Network.Wai (Application, Request, Response, ResponseReceived, responseLBS)
|
||||||
import Network.Wai
|
import Control.Exception (finally, catchJust)
|
||||||
|
|
||||||
|
type ResHandler = Response -> IO ResponseReceived
|
||||||
|
|
||||||
|
inTransaction :: Connection -> (Connection -> Application) -> Request -> ResHandler -> IO ResponseReceived
|
||||||
|
inTransaction conn app req respond =
|
||||||
|
finally (putStrLn "begin txn" >> runRaw conn "begin" >> app conn req respond) (putStrLn "commit txn" >> runRaw conn "commit")
|
||||||
|
|
||||||
instance ToJSON SqlError where
|
instance ToJSON SqlError where
|
||||||
toJSON t = object [
|
toJSON t = object [
|
||||||
@@ -21,7 +28,7 @@ instance ToJSON SqlError where
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
reportPgErrors :: Middleware
|
reportPgErrors :: Application -> Request -> ResHandler -> IO ResponseReceived
|
||||||
reportPgErrors app req respond =
|
reportPgErrors app req respond =
|
||||||
catchJust isPgException (app req respond) (
|
catchJust isPgException (app req respond) (
|
||||||
respond . responseLBS status400 [(hContentType, "application/json")]
|
respond . responseLBS status400 [(hContentType, "application/json")]
|
||||||
|
|||||||
Reference in New Issue
Block a user