refactor: remove unnecessary RSPlan constructor
This also removes some unreachable paths in Query module logic.
This commit is contained in:
committed by
Steve Chavez
parent
4650e7299f
commit
0acf5a30e6
+35
-41
@@ -80,6 +80,7 @@ data Query
|
|||||||
data QueryResult
|
data QueryResult
|
||||||
= DbCrudResult CrudPlan ResultSet
|
= DbCrudResult CrudPlan ResultSet
|
||||||
| DbCallResult CallReadPlan ResultSet
|
| DbCallResult CallReadPlan ResultSet
|
||||||
|
| DbPlanResult MediaType BS.ByteString
|
||||||
| MaybeDbResult InspectPlan (Maybe (TablesMap, RoutineMap, Maybe Text))
|
| MaybeDbResult InspectPlan (Maybe (TablesMap, RoutineMap, Maybe Text))
|
||||||
| NoDbResult InfoPlan
|
| NoDbResult InfoPlan
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ data MainQuery = MainQuery
|
|||||||
, mqOpenAPI :: (SQL.Snippet, SQL.Snippet, SQL.Snippet)
|
, 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
|
data ResultSet
|
||||||
= RSStandard
|
= RSStandard
|
||||||
{ rsTableTotal :: Maybe Int64
|
{ rsTableTotal :: Maybe Int64
|
||||||
@@ -112,7 +113,6 @@ data ResultSet
|
|||||||
, rsInserted :: Maybe Int64
|
, rsInserted :: Maybe Int64
|
||||||
-- ^ the number of rows inserted (Only used for upserts)
|
-- ^ 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 :: MainQuery -> AppConfig -> AuthResult -> ApiRequest -> ActionPlan -> SchemaCache -> Query
|
||||||
mainTx _ _ _ _ (NoDb x) _ = NoDbQuery $ NoDbResult x
|
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
|
-- 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 -> DbActionPlan -> AppConfig -> ApiRequest -> SchemaCache -> DbHandler QueryResult
|
||||||
actionQuery MainQuery{..} (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq _ =
|
actionQuery MainQuery{..} (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq _ =
|
||||||
mainActionQuery
|
case wrMedia of
|
||||||
where
|
MTVndPlan{} -> do
|
||||||
result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements
|
explRes <- lift $ SQL.statement mempty $ dynStmt planRow
|
||||||
mainActionQuery = do
|
optionalRollback conf apiReq
|
||||||
resultSet <- lift $ SQL.statement mempty result
|
pure $ DbPlanResult wrMedia explRes
|
||||||
|
_ -> do
|
||||||
|
resultSet <- lift $ SQL.statement mempty $ dynStmt (HD.singleRow $ standardRow True)
|
||||||
failNotSingular wrMedia resultSet
|
failNotSingular wrMedia resultSet
|
||||||
optionalRollback conf apiReq
|
optionalRollback conf apiReq
|
||||||
DbCrudResult plan <$> resultSetWTotal conf apiReq resultSet mqCount
|
DbCrudResult plan <$> resultSetWTotal conf apiReq resultSet mqCount
|
||||||
|
where
|
||||||
decodeIt :: HD.Result ResultSet
|
dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements
|
||||||
decodeIt = case wrMedia of
|
|
||||||
MTVndPlan{} -> planRow
|
|
||||||
_ -> HD.singleRow $ standardRow True
|
|
||||||
|
|
||||||
actionQuery MainQuery{..} (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
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
|
where
|
||||||
result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements
|
dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements
|
||||||
failMutation resultSet = case mrMutation of
|
failMutation resultSet = case mrMutation of
|
||||||
MutationCreate -> do
|
MutationCreate -> do
|
||||||
failNotSingular mrMedia resultSet
|
failNotSingular mrMedia resultSet
|
||||||
@@ -190,33 +198,23 @@ actionQuery MainQuery{..} (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} ap
|
|||||||
MutationDelete -> do
|
MutationDelete -> do
|
||||||
failNotSingular mrMedia resultSet
|
failNotSingular mrMedia resultSet
|
||||||
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
|
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
|
||||||
mainActionQuery = do
|
decodeRow = fromMaybe (RSStandard Nothing 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow False)
|
||||||
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)
|
|
||||||
|
|
||||||
actionQuery MainQuery{..} (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
actionQuery MainQuery{..} (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||||
mainActionQuery
|
case crMedia of
|
||||||
where
|
MTVndPlan{} -> do
|
||||||
result = SQL.dynamicallyParameterized mqMain decodeIt configDbPreparedStatements
|
explRes <- lift $ SQL.statement mempty $ dynStmt planRow
|
||||||
|
optionalRollback conf apiReq
|
||||||
mainActionQuery = do
|
pure $ DbPlanResult crMedia explRes
|
||||||
resultSet <- lift $ SQL.statement mempty result
|
_ -> do
|
||||||
|
resultSet <- lift $ SQL.statement mempty $ dynStmt decodeRow
|
||||||
optionalRollback conf apiReq
|
optionalRollback conf apiReq
|
||||||
failNotSingular crMedia resultSet
|
failNotSingular crMedia resultSet
|
||||||
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
|
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
|
||||||
pure $ DbCallResult plan resultSet
|
pure $ DbCallResult plan resultSet
|
||||||
|
where
|
||||||
decodeIt :: HD.Result ResultSet
|
dynStmt decod = SQL.dynamicallyParameterized mqMain decod configDbPreparedStatements
|
||||||
decodeIt = case crMedia of
|
decodeRow = fromMaybe (RSStandard (Just 0) 0 mempty mempty Nothing Nothing Nothing) <$> HD.rowMaybe (standardRow True)
|
||||||
MTVndPlan{} -> planRow
|
|
||||||
_ -> 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 =
|
actionQuery MainQuery{mqOpenAPI=(tblsQ, funcsQ, schQ)} (MayUseDb plan@InspectPlan{ipSchema=tSchema}) AppConfig{..} _ sCache =
|
||||||
mainActionQuery
|
mainActionQuery
|
||||||
@@ -258,14 +256,12 @@ actionQuery MainQuery{mqOpenAPI=(tblsQ, funcsQ, schQ)} (MayUseDb plan@InspectPla
|
|||||||
-- If this condition is not satisfied then nothing is inserted,
|
-- If this condition is not satisfied then nothing is inserted,
|
||||||
-- check the WHERE for INSERT in QueryBuilder.hs to see how it's done
|
-- check the WHERE for INSERT in QueryBuilder.hs to see how it's done
|
||||||
failPut :: ResultSet -> DbHandler ()
|
failPut :: ResultSet -> DbHandler ()
|
||||||
failPut RSPlan{} = pure ()
|
|
||||||
failPut RSStandard{rsQueryTotal=queryTotal} =
|
failPut RSStandard{rsQueryTotal=queryTotal} =
|
||||||
when (queryTotal /= 1) $ do
|
when (queryTotal /= 1) $ do
|
||||||
lift SQL.condemn
|
lift SQL.condemn
|
||||||
throwError $ Error.ApiRequestError Error.PutMatchingPkError
|
throwError $ Error.ApiRequestError Error.PutMatchingPkError
|
||||||
|
|
||||||
resultSetWTotal :: AppConfig -> ApiRequest -> ResultSet -> SQL.Snippet -> DbHandler ResultSet
|
resultSetWTotal :: AppConfig -> ApiRequest -> ResultSet -> SQL.Snippet -> DbHandler ResultSet
|
||||||
resultSetWTotal _ _ rs@RSPlan{} _ = return rs
|
|
||||||
resultSetWTotal AppConfig{..} ApiRequest{iPreferences=Preferences{..}} rs@RSStandard{rsTableTotal=tableTotal} countQuery =
|
resultSetWTotal AppConfig{..} ApiRequest{iPreferences=Preferences{..}} rs@RSStandard{rsTableTotal=tableTotal} countQuery =
|
||||||
case preferCount of
|
case preferCount of
|
||||||
Just PlannedCount -> do
|
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
|
-- Fail a response if a single JSON object was requested and not exactly one
|
||||||
-- was found.
|
-- was found.
|
||||||
failNotSingular :: MediaType -> ResultSet -> DbHandler ()
|
failNotSingular :: MediaType -> ResultSet -> DbHandler ()
|
||||||
failNotSingular _ RSPlan{} = pure ()
|
|
||||||
failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} =
|
failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} =
|
||||||
when (elem mediaType [MTVndSingularJSON True, MTVndSingularJSON False] && queryTotal /= 1) $ do
|
when (elem mediaType [MTVndSingularJSON True, MTVndSingularJSON False] && queryTotal /= 1) $ do
|
||||||
lift SQL.condemn
|
lift SQL.condemn
|
||||||
@@ -305,7 +300,6 @@ failNotSingular mediaType RSStandard{rsQueryTotal=queryTotal} =
|
|||||||
|
|
||||||
failExceedsMaxAffectedPref :: (Maybe PreferMaxAffected, Maybe PreferHandling) -> ResultSet -> DbHandler ()
|
failExceedsMaxAffectedPref :: (Maybe PreferMaxAffected, Maybe PreferHandling) -> ResultSet -> DbHandler ()
|
||||||
failExceedsMaxAffectedPref (Nothing,_) _ = pure ()
|
failExceedsMaxAffectedPref (Nothing,_) _ = pure ()
|
||||||
failExceedsMaxAffectedPref _ RSPlan{} = pure ()
|
|
||||||
failExceedsMaxAffectedPref (Just (PreferMaxAffected n), handling) RSStandard{rsQueryTotal=queryTotal} = when ((queryTotal > n) && (handling == Just Strict)) $ do
|
failExceedsMaxAffectedPref (Just (PreferMaxAffected n), handling) RSStandard{rsQueryTotal=queryTotal} = when ((queryTotal > n) && (handling == Just Strict)) $ do
|
||||||
lift SQL.condemn
|
lift SQL.condemn
|
||||||
throwError $ Error.ApiRequestError . Error.MaxAffectedViolationError $ toInteger queryTotal
|
throwError $ Error.ApiRequestError . Error.MaxAffectedViolationError $ toInteger queryTotal
|
||||||
@@ -323,8 +317,8 @@ optionalRollback AppConfig{..} ApiRequest{iPreferences=Preferences{..}} = do
|
|||||||
preferTransaction == Just Rollback
|
preferTransaction == Just Rollback
|
||||||
|
|
||||||
-- | We use rowList because when doing EXPLAIN (FORMAT TEXT), the result comes as many rows. FORMAT JSON comes as one.
|
-- | 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 :: HD.Result BS.ByteString
|
||||||
planRow = RSPlan . BS.unlines <$> HD.rowList (column HD.bytea)
|
planRow = BS.unlines <$> HD.rowList (column HD.bytea)
|
||||||
|
|
||||||
column :: HD.Value a -> HD.Row a
|
column :: HD.Value a -> HD.Row a
|
||||||
column = HD.column . HD.nonNullable
|
column = HD.column . HD.nonNullable
|
||||||
|
|||||||
+123
-149
@@ -63,171 +63,145 @@ data PgrstResponse = PgrstResponse {
|
|||||||
|
|
||||||
actionResponse :: QueryResult -> ApiRequest -> (Text, Text) -> AppConfig -> SchemaCache -> Schema -> Bool -> Either Error.Error 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{..},..} _ _ _ _ _ =
|
actionResponse (DbCrudResult WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly, crudQi=identifier} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = do
|
||||||
case resultSet of
|
let
|
||||||
RSStandard{..} -> do
|
(status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal
|
||||||
let
|
cLHeader = if headersOnly then mempty else [contentLengthHeaderStrict rsBody]
|
||||||
(status, contentRange) = RangeQuery.rangeStatusHeader iTopLevelRange rsQueryTotal rsTableTotal
|
prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing []
|
||||||
cLHeader = if headersOnly then mempty else [contentLengthHeaderStrict rsBody]
|
headers =
|
||||||
prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing []
|
[ contentRange
|
||||||
headers =
|
, ( "Content-Location"
|
||||||
[ contentRange
|
, "/"
|
||||||
, ( "Content-Location"
|
<> toUtf8 (qiName identifier)
|
||||||
, "/"
|
<> if BS.null (qsCanonical iQueryParams) then mempty else "?" <> qsCanonical iQueryParams
|
||||||
<> toUtf8 (qiName identifier)
|
)
|
||||||
<> if BS.null (qsCanonical iQueryParams) then mempty else "?" <> qsCanonical iQueryParams
|
]
|
||||||
)
|
++ cLHeader
|
||||||
]
|
++ contentTypeHeaders wrMedia ctxApiRequest
|
||||||
++ cLHeader
|
++ prefHeader
|
||||||
++ contentTypeHeaders wrMedia ctxApiRequest
|
bod | status == HTTP.status416 = Error.errorPayload $ Error.ApiRequestError $ Error.InvalidRange $
|
||||||
++ prefHeader
|
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 $
|
Right $ PgrstResponse ovStatus ovHeaders bod
|
||||||
Error.OutOfBounds (show $ RangeQuery.rangeOffset iTopLevelRange) (maybe "0" show rsTableTotal)
|
|
||||||
| headersOnly = mempty
|
|
||||||
| otherwise = LBS.fromStrict rsBody
|
|
||||||
|
|
||||||
Right $ PgrstResponse ovStatus ovHeaders bod
|
actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia, crudQi=QualifiedIdentifier{..}} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} _ _ _ _ _ = do
|
||||||
|
let
|
||||||
RSPlan plan ->
|
pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;}
|
||||||
Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders wrMedia ctxApiRequest) $ LBS.fromStrict plan
|
prefHeader = prefAppliedHeader $
|
||||||
|
Preferences (if null pkCols && isNothing (qsOnConflict iQueryParams) then Nothing else preferResolution)
|
||||||
actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia, crudQi=QualifiedIdentifier{..}} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} _ _ _ _ _ = case resultSet of
|
preferRepresentation preferCount preferTransaction preferMissing preferHandling preferTimezone Nothing []
|
||||||
RSStandard{..} -> do
|
headers =
|
||||||
let
|
catMaybes
|
||||||
pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;}
|
[ if null rsLocation then
|
||||||
prefHeader = prefAppliedHeader $
|
Nothing
|
||||||
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
|
|
||||||
else
|
else
|
||||||
HTTP.status201
|
Just
|
||||||
status = maybe HTTP.status200 isInsertIfGTZero rsInserted
|
( HTTP.hLocation
|
||||||
(headers', bod) = case preferRepresentation of
|
, "/"
|
||||||
Just Full -> (headers ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody)
|
<> toUtf8 qiName
|
||||||
Just None -> (headers, mempty)
|
<> HTTP.renderSimpleQuery True rsLocation
|
||||||
Just HeadersOnly -> (headers, mempty)
|
)
|
||||||
Nothing -> (headers, mempty)
|
, 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
|
(ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status headers'
|
||||||
RSPlan plan ->
|
|
||||||
Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
|
|
||||||
|
|
||||||
actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationUpdate, mrMedia} resultSet) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of
|
Right $ PgrstResponse ovStatus ovHeaders bod
|
||||||
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]
|
|
||||||
|
|
||||||
let (status, headers', body) =
|
actionResponse (DbCrudResult MutateReadPlan{mrMutation=MutationUpdate, mrMedia} RSStandard{..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = do
|
||||||
case preferRepresentation of
|
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 Full -> (HTTP.status200, headers ++ [contentLengthHeaderStrict rsBody] ++ contentTypeHeaders mrMedia ctxApiRequest, LBS.fromStrict rsBody)
|
||||||
Just None -> (HTTP.status204, headers, mempty)
|
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 ->
|
actionResponse (DbCallResult CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} RSStandard {..}) ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = do
|
||||||
Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
|
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
|
(ovStatus, ovHeaders) <- overrideStatusHeaders rsGucStatus rsGucHeaders status' headers'
|
||||||
RSStandard {..} -> 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
|
Right $ PgrstResponse ovStatus ovHeaders body
|
||||||
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 (DbPlanResult media plan) ctxApiRequest _ _ _ _ _ =
|
||||||
|
Right $ PgrstResponse HTTP.status200 (contentLengthHeaderStrict plan : contentTypeHeaders media ctxApiRequest) $ LBS.fromStrict plan
|
||||||
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 (MaybeDbResult InspectPlan{ipHdrsOnly=headersOnly} body) _ versions conf sCache schema negotiatedByProfile =
|
actionResponse (MaybeDbResult InspectPlan{ipHdrsOnly=headersOnly} body) _ versions conf sCache schema negotiatedByProfile =
|
||||||
let
|
let
|
||||||
|
|||||||
Reference in New Issue
Block a user