App has database pools!

This commit is contained in:
Adam C. Baker
2014-10-17 17:16:41 -07:00
parent 49f0bf7c3f
commit 0798cb81a6
4 changed files with 8 additions and 19 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ cabal-version: >=1.10
executable dbapi executable dbapi
main-is: Main.hs main-is: Main.hs
ghc-options: -Wall -W -threaded ghc-options: -Wall -W -Werror
default-language: Haskell2010 default-language: Haskell2010
build-depends: base >=4.6 && <5 build-depends: base >=4.6 && <5
, HDBC, HDBC-postgresql , HDBC, HDBC-postgresql
+4 -14
View File
@@ -16,12 +16,6 @@ import Network.Wai.Middleware.Static (staticPolicy, only)
import Database.HDBC (disconnect) import Database.HDBC (disconnect)
import Database.HDBC.PostgreSQL(connectPostgreSQL') import Database.HDBC.PostgreSQL(connectPostgreSQL')
import Data.Pool(createPool) import Data.Pool(createPool)
import System.Process
import Control.Concurrent(threadDelay)
import Network.HTTP.Types.Status
import Network.Wai
argParser :: Parser AppConfig argParser :: Parser AppConfig
argParser = AppConfig argParser = AppConfig
@@ -37,21 +31,17 @@ argParser = AppConfig
main :: IO () main :: IO ()
main = do main = do
conf <- execParser (info (helper <*> argParser) describe) conf <- execParser (info (helper <*> argParser) describe)
let dburi = configDbUri conf pool <- createPool (connectPostgreSQL' (configDbUri conf)) disconnect 1 600 10
pool <- createPool (putStrLn "creating connection" >> connectPostgreSQL' (configDbUri conf)) (\c-> putStrLn "destroying connection" >> disconnect c) 1 600 10
let port = configPort conf let port = configPort conf
unless (configSecure conf) $ unless (configSecure conf) $
putStrLn "WARNING, running in insecure mode, auth will be in plaintext" putStrLn "WARNING, running in insecure mode, auth will be in plaintext"
Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String) Prelude.putStrLn $ "Listening on port " ++ (show $ configPort conf :: String)
conn <- connectPostgreSQL' dburi
run port $ (if configSecure conf then redirectInsecure else id) run port $ (if configSecure conf then redirectInsecure else id)
. gzip def . gzip def . cors corsPolicy . clientErrors
. cors corsPolicy
. clientErrors
. staticPolicy (only [("favicon.ico", "static/favicon.ico")]) . staticPolicy (only [("favicon.ico", "static/favicon.ico")])
$ (inTransaction . authenticated (cs $ configAnonRole conf) . withSavepoint) . withDBConnection pool . inTransaction
app conn . authenticated (cs $ configAnonRole conf) . withSavepoint $ app
where where
describe = progDesc "create a REST API to an existing Postgres database" describe = progDesc "create a REST API to an existing Postgres database"
+2 -3
View File
@@ -16,7 +16,6 @@ import Data.String.Conversions(cs)
import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Char8 as BS
import Control.Exception (finally, throw, catchJust, catch, SomeException, import Control.Exception (finally, throw, catchJust, catch, SomeException,
bracket_) bracket_)
import Control.Concurrent(threadDelay)
import Network.HTTP.Types.Header (RequestHeaders, hContentType, hAuthorization, import Network.HTTP.Types.Header (RequestHeaders, hContentType, hAuthorization,
hLocation) hLocation)
@@ -53,9 +52,9 @@ authenticated anon app conn req respond = do
LoginFailed -> LoginFailed ->
respond $ responseLBS status401 [] "Invalid username or password" respond $ responseLBS status401 [] "Invalid username or password"
LoginSuccess role -> LoginSuccess role ->
bracket_ (setRole conn role >> threadDelay 10000000) (resetRole conn) $ app conn req respond bracket_ (setRole conn role) (resetRole conn) $ app conn req respond
NoCredentials -> NoCredentials ->
bracket_ (setRole conn anon >> threadDelay 10000000) (resetRole conn) $ app conn req respond bracket_ (setRole conn anon) (resetRole conn) $ app conn req respond
where where
httpRequesterRole :: RequestHeaders -> IO LoginAttempt httpRequesterRole :: RequestHeaders -> IO LoginAttempt
+1 -1
View File
@@ -72,7 +72,7 @@ spec = around appWithFixture $ do
it "fails with 400 and error" $ it "fails with 400 and error" $
post "/simple_pk" "}{ x = 2" post "/simple_pk" "}{ x = 2"
`shouldRespondWith` ResponseMatcher { `shouldRespondWith` ResponseMatcher {
matchBody = Just [json| {"error":"Failed to parse JSON payload. Failed reading: satisfy"} |] matchBody = Just [json| {"error":"Failed to parse JSON payload. Failed reading: satisfyElem"} |]
, matchStatus = 400 , matchStatus = 400
, matchHeaders = [] , matchHeaders = []
} }