refactor: readTotal into ResultSet

This commit is contained in:
steve-chavez
2022-10-07 18:52:57 -05:00
committed by Steve Chavez
parent cfaeff8a5a
commit d37e14c4db
3 changed files with 22 additions and 20 deletions
+2 -2
View File
@@ -225,9 +225,9 @@ handleRead :: Bool -> QualifiedIdentifier -> RequestContext -> DbHandler Wai.Res
handleRead headersOnly identifier context@RequestContext{..} = do handleRead headersOnly identifier context@RequestContext{..} = do
req <- liftEither $ readPlan identifier context req <- liftEither $ readPlan identifier context
(resultSet, total) <- Query.readQuery req ctxConfig ctxApiRequest resultSet <- Query.readQuery req ctxConfig ctxApiRequest
pure $ Response.readResponse headersOnly identifier ctxApiRequest total resultSet pure $ Response.readResponse headersOnly identifier ctxApiRequest resultSet
handleCreate :: QualifiedIdentifier -> RequestContext -> DbHandler Wai.Response handleCreate :: QualifiedIdentifier -> RequestContext -> DbHandler Wai.Response
handleCreate identifier context@RequestContext{..} = do handleCreate identifier context@RequestContext{..} = do
+16 -13
View File
@@ -67,7 +67,7 @@ import Protolude hiding (Handler)
type DbHandler = ExceptT Error SQL.Transaction type DbHandler = ExceptT Error SQL.Transaction
readQuery :: ReadPlanTree -> AppConfig -> ApiRequest -> DbHandler (ResultSet, Maybe Int64) readQuery :: ReadPlanTree -> AppConfig -> ApiRequest -> DbHandler ResultSet
readQuery req conf@AppConfig{..} apiReq@ApiRequest{..} = do readQuery req conf@AppConfig{..} apiReq@ApiRequest{..} = do
let countQuery = QueryBuilder.readPlanToCountQuery req let countQuery = QueryBuilder.readPlanToCountQuery req
resultSet <- resultSet <-
@@ -85,22 +85,25 @@ readQuery req conf@AppConfig{..} apiReq@ApiRequest{..} = do
iBinaryField iBinaryField
configDbPreparedStatements configDbPreparedStatements
failNotSingular iAcceptMediaType resultSet failNotSingular iAcceptMediaType resultSet
total <- readTotal conf apiReq resultSet countQuery resultSetWTotal conf apiReq resultSet countQuery
pure (resultSet, total)
readTotal :: AppConfig -> ApiRequest -> ResultSet -> SQL.Snippet -> DbHandler (Maybe Int64) resultSetWTotal :: AppConfig -> ApiRequest -> ResultSet -> SQL.Snippet -> DbHandler ResultSet
readTotal _ _ RSPlan{} _ = pure Nothing resultSetWTotal _ _ rs@RSPlan{} _ = return rs
readTotal AppConfig{..} ApiRequest{..} RSStandard{rsTableTotal=tableTotal} countQuery = resultSetWTotal AppConfig{..} ApiRequest{..} rs@RSStandard{rsTableTotal=tableTotal} countQuery =
case iPreferCount of case iPreferCount of
Just PlannedCount -> Just PlannedCount -> do
explain total <- explain
return rs{rsTableTotal=total}
Just EstimatedCount -> Just EstimatedCount ->
if tableTotal > (fromIntegral <$> configDbMaxRows) then if tableTotal > (fromIntegral <$> configDbMaxRows) then do
max tableTotal <$> explain total <- max tableTotal <$> explain
return rs{rsTableTotal=total}
else else
return tableTotal return rs
_ -> Just ExactCount ->
return tableTotal return rs
Nothing ->
return rs
where where
explain = explain =
lift . SQL.statement mempty . Statements.preparePlanRows countQuery $ lift . SQL.statement mempty . Statements.preparePlanRows countQuery $
+4 -5
View File
@@ -56,12 +56,11 @@ import qualified PostgREST.Request.Types as ApiRequestTypes
import Protolude hiding (Handler, toS) import Protolude hiding (Handler, toS)
import Protolude.Conv (toS) import Protolude.Conv (toS)
readResponse :: Bool -> QualifiedIdentifier -> ApiRequest -> ResultSet -> Wai.Response
readResponse :: Bool -> QualifiedIdentifier -> ApiRequest -> Maybe Int64 -> ResultSet -> Wai.Response readResponse headersOnly identifier ctxApiRequest@ApiRequest{..} resultSet = case resultSet of
readResponse headersOnly identifier ctxApiRequest@ApiRequest{..} total resultSet = case resultSet of
RSStandard{..} -> do RSStandard{..} -> do
let let
(status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal total (status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal
response = gucResponse rsGucStatus rsGucHeaders response = gucResponse rsGucStatus rsGucHeaders
headers = headers =
[ contentRange [ contentRange
@@ -74,7 +73,7 @@ readResponse headersOnly identifier ctxApiRequest@ApiRequest{..} total resultSet
++ contentTypeHeaders ctxApiRequest ++ contentTypeHeaders ctxApiRequest
rsOrErrBody = if status == HTTP.status416 rsOrErrBody = if status == HTTP.status416
then Error.errorPayload $ Error.ApiRequestError $ ApiRequestTypes.InvalidRange then Error.errorPayload $ Error.ApiRequestError $ ApiRequestTypes.InvalidRange
$ ApiRequestTypes.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show total) $ ApiRequestTypes.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal)
else LBS.fromStrict rsBody else LBS.fromStrict rsBody
response status headers $ if headersOnly then mempty else rsOrErrBody response status headers $ if headersOnly then mempty else rsOrErrBody