@@ -55,8 +55,8 @@ import Data.Time.Clock (UTCTime, getCurrentTime)
5555
5656import PostgREST.Auth.JwtCache (JwtCacheState , update )
5757import PostgREST.Config (AppConfig (.. ),
58- addFallbackAppName ,
59- readAppConfig )
58+ readAppConfig ,
59+ toConnectionSettings )
6060import PostgREST.Config.Database (queryDbSettings ,
6161 queryPgVersion ,
6262 queryRoleSettings )
@@ -143,34 +143,47 @@ destroy :: AppState -> IO ()
143143destroy = destroyPool
144144
145145initPool :: AppConfig -> ObservationHandler -> IO SQL. Pool
146- initPool AppConfig {.. } observer = do
146+ initPool cfg @ AppConfig {.. } observer = do
147147 SQL. acquire $ SQL. settings
148148 [ SQL. size configDbPoolSize
149149 , SQL. acquisitionTimeout $ fromIntegral configDbPoolAcquisitionTimeout
150150 , SQL. agingTimeout $ fromIntegral configDbPoolMaxLifetime
151151 , SQL. idlenessTimeout $ fromIntegral configDbPoolMaxIdletime
152- , SQL. staticConnectionSettings (toUtf8 $ addFallbackAppName prettyVersion configDbUri)
152+ , SQL. staticConnectionSettings $ toConnectionSettings identity cfg
153153 , SQL. observationHandler $ observer . HasqlPoolObs
154154 ]
155155
156156-- | Run an action with a database connection.
157157usePool :: AppState -> SQL. Session a -> IO (Either SQL. UsageError a )
158158usePool AppState {stateObserver= observer, stateMainThreadId= mainThreadId, .. } sess = do
159- observer PoolRequest
159+ observer PoolRequest
160160
161- res <- SQL. use statePool sess
161+ res <- SQL. use statePool sess
162162
163- observer PoolRequestFullfilled
163+ observer PoolRequestFullfilled
164164
165- whenLeft res (\ case
166- SQL. AcquisitionTimeoutUsageError ->
167- observer PoolAcqTimeoutObs
168- err@ (SQL. ConnectionUsageError e) ->
169- let failureMessage = BS. unpack $ fromMaybe mempty e in
170- when ((" FATAL: password authentication failed" `isInfixOf` failureMessage) || (" no password supplied" `isInfixOf` failureMessage)) $ do
171- observer $ ExitDBFatalError ServerAuthError err
172- killThread mainThreadId
173- err@ (SQL. SessionUsageError (SQL. QueryError tpl _ (SQL. ResultError resultErr))) -> do
165+ whenLeft res (\ case
166+ SQL. AcquisitionTimeoutUsageError ->
167+ observer PoolAcqTimeoutObs
168+ err@ (SQL. ConnectionUsageError e) ->
169+ let failureMessage = BS. unpack $ fromMaybe mempty e in
170+ when ((" FATAL: password authentication failed" `isInfixOf` failureMessage) || (" no password supplied" `isInfixOf` failureMessage)) $ do
171+ observer $ ExitDBFatalError ServerAuthError err
172+ killThread mainThreadId
173+ err@ (SQL. SessionUsageError (SQL. QueryError tpl _ (SQL. ResultError resultErr))) ->
174+ handleResultError err tpl resultErr
175+ err@ (SQL. SessionUsageError (SQL. PipelineError (SQL. ResultError resultErr))) ->
176+ -- Passing the empty template will not work for schema cache queries, see TODO further below.
177+ handleResultError err mempty resultErr
178+ err@ (SQL. SessionUsageError (SQL. QueryError _ _ (SQL. ClientError _))) ->
179+ -- An error on the client-side, usually indicates problems with connection
180+ observer $ QueryErrorCodeHighObs err
181+ SQL. SessionUsageError (SQL. PipelineError (SQL. ClientError _)) -> pure ()
182+ )
183+
184+ return res
185+ where
186+ handleResultError err tpl resultErr = do
174187 case resultErr of
175188 SQL. UnexpectedResult {} -> do
176189 observer $ ExitDBFatalError ServerPgrstBug err
@@ -203,12 +216,6 @@ usePool AppState{stateObserver=observer, stateMainThreadId=mainThreadId, ..} ses
203216 SQL. ServerError {} ->
204217 when (Error. status (Error. PgError False err) >= HTTP. status500) $
205218 observer $ QueryErrorCodeHighObs err
206- err@ (SQL. SessionUsageError (SQL. QueryError _ _ (SQL. ClientError _))) ->
207- -- An error on the client-side, usually indicates problems with connection
208- observer $ QueryErrorCodeHighObs err
209- )
210-
211- return res
212219
213220-- | Flush the connection pool so that any future use of the pool will
214221-- use connections freshly established after this call.
@@ -308,7 +315,7 @@ retryingSchemaCacheLoad appState@AppState{stateObserver=observer, stateMainThrea
308315 qPgVersion :: IO (Maybe PgVersion )
309316 qPgVersion = do
310317 AppConfig {.. } <- getConfig appState
311- pgVersion <- usePool appState ( queryPgVersion False ) -- No need to prepare the query here, as the connection might not be established
318+ pgVersion <- usePool appState queryPgVersion
312319 case pgVersion of
313320 Left e -> do
314321 observer $ QueryPgVersionError e
@@ -336,8 +343,7 @@ retryingSchemaCacheLoad appState@AppState{stateObserver=observer, stateMainThrea
336343 qSchemaCache = do
337344 conf@ AppConfig {.. } <- getConfig appState
338345 (resultTime, result) <-
339- let transaction = if configDbPreparedStatements then SQL. transaction else SQL. unpreparedTransaction in
340- timeItT $ usePool appState (transaction SQL. ReadCommitted SQL. Read $ querySchemaCache conf)
346+ timeItT $ usePool appState (SQL. transaction SQL. ReadCommitted SQL. Read $ querySchemaCache conf)
341347 case result of
342348 Left e -> do
343349 markSchemaCachePending appState
@@ -393,7 +399,7 @@ readInDbConfig startingUp appState@AppState{stateObserver=observer} = do
393399 pgVer <- getPgVersion appState
394400 dbSettings <-
395401 if configDbConfig conf then do
396- qDbSettings <- usePool appState (queryDbSettings (quoteQi <$> configDbPreConfig conf) (configDbPreparedStatements conf) )
402+ qDbSettings <- usePool appState (queryDbSettings (quoteQi <$> configDbPreConfig conf))
397403 case qDbSettings of
398404 Left e -> do
399405 observer $ ConfigReadErrorObs e
@@ -403,7 +409,7 @@ readInDbConfig startingUp appState@AppState{stateObserver=observer} = do
403409 pure mempty
404410 (roleSettings, roleIsolationLvl) <-
405411 if configDbConfig conf then do
406- rSettings <- usePool appState (queryRoleSettings pgVer (configDbPreparedStatements conf) )
412+ rSettings <- usePool appState (queryRoleSettings pgVer)
407413 case rSettings of
408414 Left e -> do
409415 observer $ QueryRoleSettingsErrorObs e
0 commit comments