From 0acf5a30e67835f6877f10c8963dd1a60c962c78 Mon Sep 17 00:00:00 2001 From: steve-chavez Date: Thu, 11 Sep 2025 18:59:40 -0500 Subject: [PATCH] refactor: remove unnecessary RSPlan constructor This also removes some unreachable paths in Query module logic. --- src/PostgREST/Query.hs | 76 +++++------ src/PostgREST/Response.hs | 272 +++++++++++++++++--------------------- 2 files changed, 158 insertions(+), 190 deletions(-) diff --git a/src/PostgREST/Query.hs b/src/PostgREST/Query.hs index 378719007..25be85fd2 100644 --- a/src/PostgREST/Query.hs +++ b/src/PostgREST/Query.hs @@ -80,6 +80,7 @@ data Query data QueryResult = DbCrudResult CrudPlan ResultSet | DbCallResult CallReadPlan ResultSet + | DbPlanResult MediaType BS.ByteString | MaybeDbResult InspectPlan (Maybe (TablesMap, RoutineMap, Maybe Text)) | NoDbResult InfoPlan @@ -93,7 +94,7 @@ data MainQuery = MainQuery , mqOpenAPI :: (SQL.Snippet, SQL.Snippet, SQL.Snippet) } --- | Standard result set format used for all queries +-- | Standard result set format used for the mqMain query data ResultSet = RSStandard { rsTableTotal :: Maybe Int64 @@ -112,7 +113,6 @@ data ResultSet , rsInserted :: Maybe Int64 -- ^ the number of rows inserted (Only used for upserts) } - | RSPlan BS.ByteString -- ^ the plan of the query mainTx :: MainQuery -> AppConfig -> AuthResult -> ApiRequest -> ActionPlan -> SchemaCache -> Query mainTx _ _ _ _ (NoDb x) _ = NoDbQuery $ NoDbResult x @@ -161,24 +161,32 @@ mainQuery (Db plan) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preference -- TODO: Generate the Hasql Statement in a diferent module after the OpenAPI functionality is removed actionQuery :: MainQuery -> DbActionPlan -> AppConfig -> ApiRequest -> SchemaCache -> DbHandler QueryResult actionQuery MainQuery{..} (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq _ = - mainActionQuery - where - result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements - mainActionQuery = do - resultSet <- lift $ SQL.statement mempty result + case wrMedia of + MTVndPlan{} -> do + explRes <- lift $ SQL.statement mempty $ dynStmt planRow + optionalRollback conf apiReq + pure $ DbPlanResult wrMedia explRes + _ -> do + resultSet <- lift $ SQL.statement mempty $ dynStmt (HD.singleRow $ standardRow True) failNotSingular wrMedia resultSet optionalRollback conf apiReq DbCrudResult plan <$> resultSetWTotal conf apiReq resultSet mqCount - - decodeIt :: HD.Result ResultSet - decodeIt = case wrMedia of - MTVndPlan{} -> planRow - _ -> HD.singleRow $ standardRow True + where + dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements actionQuery MainQuery{..} (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ = - mainActionQuery + case mrMedia of + MTVndPlan{} -> do + explRes <- lift $ SQL.statement mempty $ dynStmt planRow + optionalRollback conf apiReq + pure $ DbPlanResult mrMedia explRes + _ -> do + resultSet <- lift $ SQL.statement mempty $ dynStmt decodeRow + failMutation resultSet + optionalRollback conf apiReq + pure $ DbCrudResult plan resultSet where - result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements + dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements failMutation resultSet = case mrMutation of MutationCreate -> do failNotSingular mrMedia resultSet @@ -190,33 +198,23 @@ actionQuery MainQuery{..} (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} ap MutationDelete -> do failNotSingular mrMedia resultSet failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet - mainActionQuery = do - resultSet <- lift $ SQL.statement mempty result - failMutation resultSet - optionalRollback conf apiReq - pure $ DbCrudResult plan resultSet - - decodeIt :: HD.Result ResultSet - decodeIt = case mrMedia of - MTVndPlan{} -> planRow - _ -> fromMaybe (RSStandard Nothing 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow False) + decodeRow = fromMaybe (RSStandard Nothing 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow False) actionQuery MainQuery{..} (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ = - mainActionQuery - where - result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements - - mainActionQuery = do - resultSet <- lift $ SQL.statement mempty result + case crMedia of + MTVndPlan{} -> do + explRes <- lift $ SQL.statement mempty $ dynStmt planRow + optionalRollback conf apiReq + pure $ DbPlanResult crMedia explRes + _ -> do + resultSet <- lift $ SQL.statement mempty $ dynStmt decodeRow optionalRollback conf apiReq failNotSingular crMedia resultSet failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet pure $ DbCallResult plan resultSet - - decodeIt :: HD.Result ResultSet - decodeIt = case crMedia of - MTVndPlan{} -> planRow - _ -> fromMaybe (RSStandard (Just 0) 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow True) + where + dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements + decodeRow = fromMaybe (RSStandard (Just 0) 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow True) actionQuery MainQuery{mqOpenAPI=(tblsQ, funcsQ, schQ)} (MayUseDb plan@InspectPlan{ipSchema=tSchema}) AppConfig{..} _ sCache = mainActionQuery @@ -258,14 +256,12 @@ actionQuery MainQuery{mqOpenAPI=(tblsQ, funcsQ, schQ)} (MayUseDb plan@InspectPla -- If this condition is not satisfied then nothing is inserted, -- check the WHERE for INSERT in QueryBuilder.hs to see how it's done failPut :: ResultSet -> DbHandler () -failPut RSPlan{} = pure () failPut RSStandard{rsQueryTotal=queryTotal} = when (queryTotal /= 1) $ do lift SQL.condemn throwError $ Error.ApiRequestError Error.PutMatchingPkError resultSetWTotal :: AppConfig -> ApiRequest -> ResultSet -> SQL.Snippet -> DbHandler ResultSet -resultSetWTotal _ _ rs@RSPlan{} _ = return rs resultSetWTotal AppConfig{..} ApiRequest{iPreferences=Preferences{..}} rs@RSStandard{rsTableTotal=tableTotal} countQuery = case preferCount of Just PlannedCount -> do @@ -297,7 +293,6 @@ resultSetWTotal AppConfig{..} ApiRequest{iPreferences=Preferences{..}} rs@RSStan -- Fail a response if a single JSON object was requested and not exactly one -- was found. failNotSingular :: MediaType -> ResultSet -> DbHandler () -failNotSingular _ RSPlan{} = pure () failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} = when (elem mediaType [MTVndSingularJSON True, MTVndSingularJSON False] && queryTotal /= 1) $ do lift SQL.condemn @@ -305,7 +300,6 @@ failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} = failExceedsMaxAffectedPref :: (Maybe PreferMaxAffected, Maybe PreferHandling) -> ResultSet -> DbHandler () failExceedsMaxAffectedPref (Nothing,_) _ = pure () -failExceedsMaxAffectedPref _ RSPlan{} = pure () failExceedsMaxAffectedPref (Just (PreferMaxAffected n), handling) RSStandard{rsQueryTotal=queryTotal} = when ((queryTotal > n) && (handling == Just Strict)) $ do lift SQL.condemn throwError $ Error.ApiRequestError . Error.MaxAffectedViolationError $ toInteger queryTotal @@ -323,8 +317,8 @@ optionalRollback AppConfig{..} ApiRequest{iPreferences=Preferences{..}} = do preferTransaction == Just Rollback -- | We use rowList because when doing EXPLAIN (FORMAT TEXT), the result comes as many rows. FORMAT JSON comes as one. -planRow :: HD.Result ResultSet -planRow = RSPlan . BS.unlines <$> HD.rowList (column HD.bytea) +planRow :: HD.Result BS.ByteString +planRow = BS.unlines <$> HD.rowList (column HD.bytea) column :: HD.Value a -> HD.Row a column = HD.column . HD.nonNullable diff --git a/src/PostgREST/Response.hs b/src/PostgREST/Response.hs index c2dc2287b..7d4d2b955 100644 --- a/src/PostgREST/Response.hs +++ b/src/PostgREST/Response.hs @@ -63,171 +63,145 @@ data PgrstResponse = PgrstResponse { actionResponse :: QueryResult -> ApiRequest -> (Text, Text) -> AppConfig -> SchemaCache -> Schema -> Bool -> Either Error.Error PgrstResponse -actionResponse (DbCrudResult WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly, crudQi=identifier} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = - case resultSet of - RSStandard{..} -> do - let - (status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal - cLHeader = if headersOnly then mempty else [contentLengthHeaderStrict rsBody] - prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing [] - headers = - [ contentRange - , ( "Content-Location" - , "/" - <> toUtf8 (qiName identifier) - <> if BS.null (qsCanonical iQueryParams) then mempty else "?" <> qsCanonical iQueryParams - ) - ] - ++ cLHeader - ++ contentTypeHeaders wrMedia ctxApiRequest - ++ prefHeader +actionResponse (DbCrudResult WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly, crudQi=identifier} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = do + let + (status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal + cLHeader = if headersOnly then mempty else [contentLengthHeaderStrict rsBody] + prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing [] + headers = + [ contentRange + , ( "Content-Location" + , "/" + <> toUtf8 (qiName identifier) + <> if BS.null (qsCanonical iQueryParams) then mempty else "?" <> qsCanonical iQueryParams + ) + ] + ++ cLHeader + ++ contentTypeHeaders wrMedia ctxApiRequest + ++ prefHeader + bod | status == HTTP.status416 = Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange $ + Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) + | headersOnly = mempty + | otherwise = LBS.fromStrict rsBody - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers - let bod | status == HTTP.status416 = Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange $ - Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) - | headersOnly = mempty - | otherwise = LBS.fromStrict rsBody + Right $ PgrstResponse ovStatus ovHeaders bod - Right $ PgrstResponse ovStatus ovHeaders bod - - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders wrMedia ctxApiRequest) $ LBS.fromStrict plan - -actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia, crudQi=QualifiedIdentifier{..}} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} _ _ _ _ _ = case resultSet of - RSStandard{..} -> do - let - pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;} - prefHeader = prefAppliedHeader $ - Preferences (if null pkCols && isNothing (qsOnConflict iQueryParams) then Nothing else preferResolution) - preferRepresentation preferCount preferTransaction preferMissing preferHandling preferTimezone Nothing [] - headers = - catMaybes - [ if null rsLocation then - Nothing - else - Just - ( HTTP.hLocation - , "/" - <> toUtf8 qiName - <> HTTP.renderSimpleQuery True rsLocation - ) - , Just . RangeQuery.contentRangeH 1 0 $ - if shouldCount preferCount then Just rsQueryTotal else Nothing - , Just $ contentLengthHeaderStrict rsBody - , prefHeader ] - - let isInsertIfGTZero i = - if i <= 0 && preferResolution == Just MergeDuplicates then - HTTP.status200 +actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia, crudQi=QualifiedIdentifier{..}} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} _ _ _ _ _ = do + let + pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;} + prefHeader = prefAppliedHeader $ + Preferences (if null pkCols && isNothing (qsOnConflict iQueryParams) then Nothing else preferResolution) + preferRepresentation preferCount preferTransaction preferMissing preferHandling preferTimezone Nothing [] + headers = + catMaybes + [ if null rsLocation then + Nothing else - HTTP.status201 - status = maybe HTTP.status200 isInsertIfGTZero rsInserted - (headers', bod) = case preferRepresentation of - Just Full -> (headers ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody) - Just None -> (headers, mempty) - Just HeadersOnly -> (headers, mempty) - Nothing -> (headers, mempty) + Just + ( HTTP.hLocation + , "/" + <> toUtf8 qiName + <> HTTP.renderSimpleQuery True rsLocation + ) + , Just . RangeQuery.contentRangeH 1 0 $ + if shouldCount preferCount then Just rsQueryTotal else Nothing + , Just $ contentLengthHeaderStrict rsBody + , prefHeader ] - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' + isInsertIfGTZero i = + if i <= 0 && preferResolution == Just MergeDuplicates then + HTTP.status200 + else + HTTP.status201 + status = maybe HTTP.status200 isInsertIfGTZero rsInserted + (headers', bod) = case preferRepresentation of + Just Full -> (headers ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody) + Just None -> (headers, mempty) + Just HeadersOnly -> (headers, mempty) + Nothing -> (headers, mempty) - Right $ PgrstResponse ovStatus ovHeaders bod - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' -actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationUpdate, mrMedia} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of - RSStandard{..} -> do - let - contentRangeHeader = - Just . RangeQuery.contentRangeH 0 (rsQueryTotal - 1) $ - if shouldCount preferCount then Just rsQueryTotal else Nothing - prefHeader = prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction preferMissing preferHandling preferTimezone preferMaxAffected [] - headers = catMaybes [contentRangeHeader, prefHeader] + Right $ PgrstResponse ovStatus ovHeaders bod - let (status, headers', body) = - case preferRepresentation of +actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationUpdate, mrMedia} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = do + let + contentRangeHeader = + Just . RangeQuery.contentRangeH 0 (rsQueryTotal - 1) $ + if shouldCount preferCount then Just rsQueryTotal else Nothing + prefHeader = prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction preferMissing preferHandling preferTimezone preferMaxAffected [] + headers = catMaybes [contentRangeHeader, prefHeader] + + let (status, headers', body) = + case preferRepresentation of + Just Full -> (HTTP.status200, headers ++ [contentLengthHeaderStrict rsBody] ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody) + Just None -> (HTTP.status204, headers, mempty) + _ -> (HTTP.status204, headers, mempty) + + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' + + Right $ PgrstResponse ovStatus ovHeaders body + +actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationSingleUpsert, mrMedia} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = do + let + prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction Nothing preferHandling preferTimezone Nothing [] + cLHeader = [contentLengthHeaderStrict rsBody] + cTHeader = contentTypeHeaders mrMedia ctxApiRequest + + let isInsertIfGTZero i = if i > 0 then HTTP.status201 else HTTP.status200 + upsertStatus = isInsertIfGTZero $ fromJust rsInserted + (status, headers, body) = + case preferRepresentation of + Just Full -> (upsertStatus, cLHeader ++ cTHeader ++ prefHeader, LBS.fromStrict rsBody) + Just None -> (HTTP.status204, prefHeader, mempty) + _ -> (HTTP.status204, prefHeader, mempty) + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers + + Right $ PgrstResponse ovStatus ovHeaders body + +actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationDelete, mrMedia} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = do + let + contentRangeHeader = RangeQuery.contentRangeH 1 0 $ if shouldCount preferCount then Just rsQueryTotal else Nothing + prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction Nothing preferHandling preferTimezone preferMaxAffected [] + headers = contentRangeHeader : prefHeader + (status, headers', body) = + case preferRepresentation of Just Full -> (HTTP.status200, headers ++ [contentLengthHeaderStrict rsBody] ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody) Just None -> (HTTP.status204, headers, mempty) - _ -> (HTTP.status204, headers, mempty) + _ -> (HTTP.status204, headers, mempty) - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' - Right $ PgrstResponse ovStatus ovHeaders body + Right $ PgrstResponse ovStatus ovHeaders body - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan +actionResponse (DbCallResult CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} RSStandard {..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = do + let + (status, contentRange) = + RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal + rsOrErrBody = if status == HTTP.status416 + then Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange + $ Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) + else LBS.fromStrict rsBody + isHeadMethod = invMethod == InvRead True + prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone preferMaxAffected [] + cLHeader = if isHeadMethod then mempty else [contentLengthHeaderLazy rsOrErrBody] + headers = contentRange : prefHeader + (status', headers', body) = + if Routine.funcReturnsVoid proc then + (HTTP.status204, headers, mempty) + else + (status, + headers ++ cLHeader ++ contentTypeHeaders crMedia ctxApiRequest, + if isHeadMethod then mempty else rsOrErrBody) -actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationSingleUpsert, mrMedia} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of - RSStandard {..} -> do - let - prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction Nothing preferHandling preferTimezone Nothing [] - cLHeader = [contentLengthHeaderStrict rsBody] - cTHeader = contentTypeHeaders mrMedia ctxApiRequest + (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status' headers' - let isInsertIfGTZero i = if i > 0 then HTTP.status201 else HTTP.status200 - upsertStatus = isInsertIfGTZero $ fromJust rsInserted - (status, headers, body) = - case preferRepresentation of - Just Full -> (upsertStatus, cLHeader ++ cTHeader ++ prefHeader, LBS.fromStrict rsBody) - Just None -> (HTTP.status204, prefHeader, mempty) - _ -> (HTTP.status204, prefHeader, mempty) - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers + Right $ PgrstResponse ovStatus ovHeaders body - Right $ PgrstResponse ovStatus ovHeaders body - - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan - -actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationDelete, mrMedia} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of - RSStandard {..} -> do - let - contentRangeHeader = - RangeQuery.contentRangeH 1 0 $ - if shouldCount preferCount then Just rsQueryTotal else Nothing - prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation preferCount preferTransaction Nothing preferHandling preferTimezone preferMaxAffected [] - headers = contentRangeHeader : prefHeader - - let (status, headers', body) = - case preferRepresentation of - Just Full -> (HTTP.status200, headers ++ [contentLengthHeaderStrict rsBody] ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody) - Just None -> (HTTP.status204, headers, mempty) - _ -> (HTTP.status204, headers, mempty) - - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers' - - Right $ PgrstResponse ovStatus ovHeaders body - - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan - -actionResponse (DbCallResult CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = case resultSet of - RSStandard {..} -> do - let - (status, contentRange) = - RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal - rsOrErrBody = if status == HTTP.status416 - then Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange - $ Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal) - else LBS.fromStrict rsBody - isHeadMethod = invMethod == InvRead True - prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone preferMaxAffected [] - cLHeader = if isHeadMethod then mempty else [contentLengthHeaderLazy rsOrErrBody] - headers = contentRange : prefHeader - - let (status', headers', body) = - if Routine.funcReturnsVoid proc then - (HTTP.status204, headers, mempty) - else - (status, - headers ++ cLHeader ++ contentTypeHeaders crMedia ctxApiRequest, - if isHeadMethod then mempty else rsOrErrBody) - - (ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status' headers' - - Right $ PgrstResponse ovStatus ovHeaders body - - RSPlan plan -> - Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders crMedia ctxApiRequest) $ LBS.fromStrict plan +actionResponse (DbPlanResult media plan) ctxApiRequest _ _ _ _ _ = + Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders media ctxApiRequest) $ LBS.fromStrict plan actionResponse (MaybeDbResult InspectPlan{ipHdrsOnly=headersOnly} body) _ versions conf sCache schema negotiatedByProfile = let