refactor: dry timings calculation for openapi

This commit is contained in:
steve-chavez
2024-03-28 18:31:42 -05:00
committed by Steve Chavez
parent b75cc853b4
commit c33ca4e60c
5 changed files with 64 additions and 58 deletions
+3 -3
View File
@@ -94,10 +94,10 @@ data DbAction
= ActRelationRead {dbActQi :: QualifiedIdentifier, actHeadersOnly :: Bool} = ActRelationRead {dbActQi :: QualifiedIdentifier, actHeadersOnly :: Bool}
| ActRelationMut {dbActQi :: QualifiedIdentifier, actMutation :: Mutation} | ActRelationMut {dbActQi :: QualifiedIdentifier, actMutation :: Mutation}
| ActRoutine {dbActQi :: QualifiedIdentifier, actInvMethod :: InvokeMethod} | ActRoutine {dbActQi :: QualifiedIdentifier, actInvMethod :: InvokeMethod}
| ActSchemaRead Schema Bool
data Action data Action
= ActDb DbAction = ActDb DbAction
| ActSchemaRead Schema Bool
| ActRelationInfo QualifiedIdentifier | ActRelationInfo QualifiedIdentifier
| ActRoutineInfo QualifiedIdentifier | ActRoutineInfo QualifiedIdentifier
| ActSchemaInfo | ActSchemaInfo
@@ -189,8 +189,8 @@ getAction resource schema method =
(ResourceRelation rel, "DELETE") -> Right . ActDb $ ActRelationMut (qi rel) MutationDelete (ResourceRelation rel, "DELETE") -> Right . ActDb $ ActRelationMut (qi rel) MutationDelete
(ResourceRelation rel, "OPTIONS") -> Right $ ActRelationInfo (qi rel) (ResourceRelation rel, "OPTIONS") -> Right $ ActRelationInfo (qi rel)
(ResourceSchema, "HEAD") -> Right $ ActSchemaRead schema True (ResourceSchema, "HEAD") -> Right . ActDb $ ActSchemaRead schema True
(ResourceSchema, "GET") -> Right $ ActSchemaRead schema False (ResourceSchema, "GET") -> Right . ActDb $ ActSchemaRead schema False
(ResourceSchema, "OPTIONS") -> Right ActSchemaInfo (ResourceSchema, "OPTIONS") -> Right ActSchemaInfo
_ -> Left $ UnsupportedMethod method _ -> Left $ UnsupportedMethod method
+4 -10
View File
@@ -172,14 +172,8 @@ handleRequest AuthResult{..} conf appState authenticated prepared pgVer apiReq@A
case iAction of case iAction of
ActDb dbAct -> do ActDb dbAct -> do
(planTime', plan) <- withTiming $ liftEither $ Plan.actionPlan dbAct conf apiReq sCache (planTime', plan) <- withTiming $ liftEither $ Plan.actionPlan dbAct conf apiReq sCache
(txTime', resultSet) <- withTiming $ runQuery (planIsoLvl plan) (planFunSettings plan) (Plan.pTxMode plan) $ Query.actionQuery plan conf apiReq pgVer (txTime', queryResult) <- withTiming $ runQuery (planIsoLvl plan) (planFunSettings plan) (Plan.actionPlanTxMode plan) $ Query.actionQuery plan conf apiReq pgVer sCache
(respTime', pgrst) <- withTiming $ liftEither $ Response.actionResponse plan (dbActQi dbAct) apiReq resultSet (respTime', pgrst) <- withTiming $ liftEither $ Response.actionResponse queryResult (dbActQi dbAct) apiReq (T.decodeUtf8 prettyVersion, docsVersion) conf sCache iSchema iNegotiatedByProfile
return $ pgrstResponse (ServerTiming jwtTime parseTime planTime' txTime' respTime') pgrst
ActSchemaRead tSchema headersOnly -> do
(planTime', iPlan) <- withTiming $ liftEither $ Plan.inspectPlan apiReq headersOnly tSchema
(txTime', oaiResult) <- withTiming $ runQuery roleIsoLvl mempty (Plan.ipTxmode iPlan) $ Query.openApiQuery iPlan conf sCache pgVer
(respTime', pgrst) <- withTiming $ liftEither $ Response.openApiResponse iPlan (T.decodeUtf8 prettyVersion, docsVersion) oaiResult conf sCache iSchema iNegotiatedByProfile
return $ pgrstResponse (ServerTiming jwtTime parseTime planTime' txTime' respTime') pgrst return $ pgrstResponse (ServerTiming jwtTime parseTime planTime' txTime' respTime') pgrst
ActRelationInfo identifier -> do ActRelationInfo identifier -> do
@@ -204,10 +198,10 @@ handleRequest AuthResult{..} conf appState authenticated prepared pgVer apiReq@A
Query.runPreReq conf Query.runPreReq conf
query query
planIsoLvl (Plan.CallReadPlan{crProc}) = fromMaybe roleIsoLvl $ pdIsoLvl crProc planIsoLvl (Plan.Db Plan.CallReadPlan{crProc}) = fromMaybe roleIsoLvl $ pdIsoLvl crProc
planIsoLvl _ = roleIsoLvl planIsoLvl _ = roleIsoLvl
planFunSettings (Plan.CallReadPlan{crProc}) = pdFuncSettings crProc planFunSettings (Plan.Db Plan.CallReadPlan{crProc}) = pdFuncSettings crProc
planFunSettings _ = mempty planFunSettings _ = mempty
pgrstResponse :: ServerTiming -> Response.PgrstResponse -> Wai.Response pgrstResponse :: ServerTiming -> Response.PgrstResponse -> Wai.Response
+17 -7
View File
@@ -18,9 +18,11 @@ resource.
module PostgREST.Plan module PostgREST.Plan
( actionPlan ( actionPlan
, ActionPlan(..) , ActionPlan(..)
, DbActionPlan(..)
, InspectPlan(..) , InspectPlan(..)
, inspectPlan , inspectPlan
, callReadPlan , callReadPlan
, actionPlanTxMode
) where ) where
import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy as LBS
@@ -90,7 +92,7 @@ import Protolude hiding (from)
-- Setup for doctests -- Setup for doctests
-- >>> import Data.Ranged.Ranges (fullRange) -- >>> import Data.Ranged.Ranges (fullRange)
data ActionPlan data DbActionPlan
= WrappedReadPlan = WrappedReadPlan
{ wrReadPlan :: ReadPlanTree { wrReadPlan :: ReadPlanTree
, pTxMode :: SQL.Mode , pTxMode :: SQL.Mode
@@ -123,23 +125,31 @@ data InspectPlan = InspectPlan {
, ipSchema :: Schema , ipSchema :: Schema
} }
data ActionPlan = Db DbActionPlan | MaybeDb InspectPlan
actionPlanTxMode :: ActionPlan -> SQL.Mode
actionPlanTxMode (Db x) = pTxMode x
actionPlanTxMode (MaybeDb x) = ipTxmode x
actionPlan :: DbAction -> AppConfig -> ApiRequest -> SchemaCache -> Either Error ActionPlan actionPlan :: DbAction -> AppConfig -> ApiRequest -> SchemaCache -> Either Error ActionPlan
actionPlan dbAct conf apiReq sCache = case dbAct of actionPlan dbAct conf apiReq sCache = case dbAct of
ActRelationRead identifier headersOnly -> ActRelationRead identifier headersOnly ->
wrappedReadPlan identifier conf sCache apiReq headersOnly Db <$> wrappedReadPlan identifier conf sCache apiReq headersOnly
ActRelationMut identifier mut -> ActRelationMut identifier mut ->
mutateReadPlan mut apiReq identifier conf sCache Db <$> mutateReadPlan mut apiReq identifier conf sCache
ActRoutine identifier invMethod -> ActRoutine identifier invMethod ->
callReadPlan identifier conf sCache apiReq invMethod Db <$> callReadPlan identifier conf sCache apiReq invMethod
ActSchemaRead tSchema headersOnly ->
MaybeDb <$> inspectPlan apiReq headersOnly tSchema
wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Bool -> Either Error ActionPlan wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Bool -> Either Error DbActionPlan
wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} headersOnly = do wrappedReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} headersOnly = do
rPlan <- readPlan identifier conf sCache apiRequest rPlan <- readPlan identifier conf sCache apiRequest
(handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) (handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan)
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right () if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
return $ WrappedReadPlan rPlan SQL.Read handler mediaType headersOnly return $ WrappedReadPlan rPlan SQL.Read handler mediaType headersOnly
mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error ActionPlan mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error DbActionPlan
mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} identifier conf sCache = do mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..} identifier conf sCache = do
rPlan <- readPlan identifier conf sCache apiRequest rPlan <- readPlan identifier conf sCache apiRequest
mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan
@@ -147,7 +157,7 @@ mutateReadPlan mutation apiRequest@ApiRequest{iPreferences=Preferences{..},..}
(handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan) (handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan)
return $ MutateReadPlan rPlan mPlan SQL.Write handler mediaType mutation return $ MutateReadPlan rPlan mPlan SQL.Write handler mediaType mutation
callReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> InvokeMethod -> Either Error ActionPlan callReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> InvokeMethod -> Either Error DbActionPlan
callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} invMethod = do callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferences{..},..} invMethod = do
let paramKeys = case invMethod of let paramKeys = case invMethod of
InvRead _ -> S.fromList $ fst <$> qsParams' InvRead _ -> S.fromList $ fst <$> qsParams'
+24 -21
View File
@@ -1,11 +1,11 @@
{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE RecordWildCards #-}
module PostgREST.Query module PostgREST.Query
( openApiQuery ( actionQuery
, actionQuery
, setPgLocals , setPgLocals
, runPreReq , runPreReq
, DbHandler , DbHandler
, QueryResult (..)
) where ) where
import qualified Data.Aeson as JSON import qualified Data.Aeson as JSON
@@ -41,6 +41,7 @@ import PostgREST.Config.PgVersion (PgVersion (..))
import PostgREST.Error (Error) import PostgREST.Error (Error)
import PostgREST.MediaType (MediaType (..)) import PostgREST.MediaType (MediaType (..))
import PostgREST.Plan (ActionPlan (..), import PostgREST.Plan (ActionPlan (..),
DbActionPlan (..),
InspectPlan (..)) InspectPlan (..))
import PostgREST.Plan.MutatePlan (MutatePlan (..)) import PostgREST.Plan.MutatePlan (MutatePlan (..))
import PostgREST.Plan.ReadPlan (ReadPlanTree) import PostgREST.Plan.ReadPlan (ReadPlanTree)
@@ -59,9 +60,13 @@ import Protolude hiding (Handler)
type DbHandler = ExceptT Error SQL.Transaction type DbHandler = ExceptT Error SQL.Transaction
actionQuery :: ActionPlan -> AppConfig -> ApiRequest -> PgVersion -> DbHandler ResultSet data QueryResult
= DbResult DbActionPlan ResultSet
| MaybeDbResult InspectPlan (Maybe (TablesMap, RoutineMap, Maybe Text))
actionQuery WrappedReadPlan{..} conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ = do actionQuery :: ActionPlan -> AppConfig -> ApiRequest -> PgVersion -> SchemaCache -> DbHandler QueryResult
actionQuery (Db plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ _ = do
let countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan let countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan
resultSet <- resultSet <-
lift . SQL.statement mempty $ lift . SQL.statement mempty $
@@ -79,37 +84,37 @@ actionQuery WrappedReadPlan{..} conf@AppConfig{..} apiReq@ApiRequest{iPreference
configDbPreparedStatements configDbPreparedStatements
failNotSingular wrMedia resultSet failNotSingular wrMedia resultSet
optionalRollback conf apiReq optionalRollback conf apiReq
resultSetWTotal conf apiReq resultSet countQuery DbResult plan <$> resultSetWTotal conf apiReq resultSet countQuery
actionQuery MutateReadPlan{mrMutation=MutationCreate, ..} conf apiReq _ = do actionQuery (Db plan@MutateReadPlan{mrMutation=MutationCreate, ..}) conf apiReq _ _ = do
resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf
failNotSingular mrMedia resultSet failNotSingular mrMedia resultSet
optionalRollback conf apiReq optionalRollback conf apiReq
pure resultSet pure $ DbResult plan resultSet
actionQuery MutateReadPlan{mrMutation=MutationUpdate, ..} conf apiReq@ApiRequest{iPreferences=Preferences{..}, ..} _ = do actionQuery (Db plan@MutateReadPlan{mrMutation=MutationUpdate, ..}) conf apiReq@ApiRequest{iPreferences=Preferences{..}, ..} _ _ = do
resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf
failNotSingular mrMedia resultSet failNotSingular mrMedia resultSet
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
failsChangesOffLimits (RangeQuery.rangeLimit iTopLevelRange) resultSet failsChangesOffLimits (RangeQuery.rangeLimit iTopLevelRange) resultSet
optionalRollback conf apiReq optionalRollback conf apiReq
pure resultSet pure $ DbResult plan resultSet
actionQuery MutateReadPlan{mrMutation=MutationSingleUpsert, ..} conf apiReq _ = do actionQuery (Db plan@MutateReadPlan{mrMutation=MutationSingleUpsert, ..}) conf apiReq _ _ = do
resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf
failPut resultSet failPut resultSet
optionalRollback conf apiReq optionalRollback conf apiReq
pure resultSet pure $ DbResult plan resultSet
actionQuery MutateReadPlan{mrMutation=MutationDelete, ..} conf apiReq@ApiRequest{iPreferences=Preferences{..}, ..} _ = do actionQuery (Db plan@MutateReadPlan{mrMutation=MutationDelete, ..}) conf apiReq@ApiRequest{iPreferences=Preferences{..}, ..} _ _ = do
resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf resultSet <- writeQuery mrReadPlan mrMutatePlan mrMedia mrHandler apiReq conf
failNotSingular mrMedia resultSet failNotSingular mrMedia resultSet
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
failsChangesOffLimits (RangeQuery.rangeLimit iTopLevelRange) resultSet failsChangesOffLimits (RangeQuery.rangeLimit iTopLevelRange) resultSet
optionalRollback conf apiReq optionalRollback conf apiReq
pure resultSet pure $ DbResult plan resultSet
actionQuery CallReadPlan{..} conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} pgVer = do actionQuery (Db plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} pgVer _ = do
resultSet <- resultSet <-
lift . SQL.statement mempty $ lift . SQL.statement mempty $
Statements.prepareCall Statements.prepareCall
@@ -125,25 +130,23 @@ actionQuery CallReadPlan{..} conf@AppConfig{..} apiReq@ApiRequest{iPreferences=P
optionalRollback conf apiReq optionalRollback conf apiReq
failNotSingular crMedia resultSet failNotSingular crMedia resultSet
failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet failExceedsMaxAffectedPref (preferMaxAffected,preferHandling) resultSet
pure resultSet pure $ DbResult plan resultSet
openApiQuery :: InspectPlan -> AppConfig -> SchemaCache -> PgVersion -> DbHandler (Maybe (TablesMap, RoutineMap, Maybe Text)) actionQuery (MaybeDb plan@InspectPlan{ipSchema=tSchema}) AppConfig{..} _ pgVer sCache =
openApiQuery InspectPlan{ipSchema=tSchema} AppConfig{..} sCache pgVer =
lift $ case configOpenApiMode of lift $ case configOpenApiMode of
OAFollowPriv -> do OAFollowPriv -> do
tableAccess <- SQL.statement [tSchema] (SchemaCache.accessibleTables pgVer configDbPreparedStatements) tableAccess <- SQL.statement [tSchema] (SchemaCache.accessibleTables pgVer configDbPreparedStatements)
Just <$> ((,,) MaybeDbResult plan . Just <$> ((,,)
(HM.filterWithKey (\qi _ -> S.member qi tableAccess) $ SchemaCache.dbTables sCache) (HM.filterWithKey (\qi _ -> S.member qi tableAccess) $ SchemaCache.dbTables sCache)
<$> SQL.statement tSchema (SchemaCache.accessibleFuncs pgVer configDbPreparedStatements) <$> SQL.statement tSchema (SchemaCache.accessibleFuncs pgVer configDbPreparedStatements)
<*> SQL.statement tSchema (SchemaCache.schemaDescription configDbPreparedStatements)) <*> SQL.statement tSchema (SchemaCache.schemaDescription configDbPreparedStatements))
OAIgnorePriv -> OAIgnorePriv ->
Just <$> ((,,) MaybeDbResult plan . Just <$> ((,,)
(HM.filterWithKey (\(QualifiedIdentifier sch _) _ -> sch == tSchema) $ SchemaCache.dbTables sCache) (HM.filterWithKey (\(QualifiedIdentifier sch _) _ -> sch == tSchema) $ SchemaCache.dbTables sCache)
(HM.filterWithKey (\(QualifiedIdentifier sch _) _ -> sch == tSchema) $ SchemaCache.dbRoutines sCache) (HM.filterWithKey (\(QualifiedIdentifier sch _) _ -> sch == tSchema) $ SchemaCache.dbRoutines sCache)
<$> SQL.statement tSchema (SchemaCache.schemaDescription configDbPreparedStatements)) <$> SQL.statement tSchema (SchemaCache.schemaDescription configDbPreparedStatements))
OADisabled -> OADisabled ->
pure Nothing pure $ MaybeDbResult plan Nothing
writeQuery :: ReadPlanTree -> MutatePlan -> MediaType -> MediaHandler -> ApiRequest -> AppConfig -> DbHandler ResultSet writeQuery :: ReadPlanTree -> MutatePlan -> MediaType -> MediaHandler -> ApiRequest -> AppConfig -> DbHandler ResultSet
writeQuery readPlan mutatePlan mType mHandler ApiRequest{iPreferences=Preferences{..}} conf = writeQuery readPlan mutatePlan mType mHandler ApiRequest{iPreferences=Preferences{..}} conf =
+16 -17
View File
@@ -8,7 +8,6 @@ module PostgREST.Response
( infoIdentResponse ( infoIdentResponse
, infoProcResponse , infoProcResponse
, infoRootResponse , infoRootResponse
, openApiResponse
, actionResponse , actionResponse
, PgrstResponse(..) , PgrstResponse(..)
) where ) where
@@ -39,17 +38,18 @@ import PostgREST.ApiRequest.Preferences (PreferRepresentation (..),
import PostgREST.ApiRequest.QueryParams (QueryParams (..)) import PostgREST.ApiRequest.QueryParams (QueryParams (..))
import PostgREST.Config (AppConfig (..)) import PostgREST.Config (AppConfig (..))
import PostgREST.MediaType (MediaType (..)) import PostgREST.MediaType (MediaType (..))
import PostgREST.Plan (ActionPlan (..), import PostgREST.Plan (DbActionPlan (..),
InspectPlan (..)) InspectPlan (..))
import PostgREST.Plan.MutatePlan (MutatePlan (..)) import PostgREST.Plan.MutatePlan (MutatePlan (..))
import PostgREST.Query (QueryResult (..))
import PostgREST.Query.Statements (ResultSet (..)) import PostgREST.Query.Statements (ResultSet (..))
import PostgREST.Response.GucHeader (GucHeader, unwrapGucHeader) import PostgREST.Response.GucHeader (GucHeader, unwrapGucHeader)
import PostgREST.SchemaCache (SchemaCache (..)) import PostgREST.SchemaCache (SchemaCache (..))
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..), import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..),
Schema) Schema)
import PostgREST.SchemaCache.Routine (FuncVolatility (..), import PostgREST.SchemaCache.Routine (FuncVolatility (..),
Routine (..), RoutineMap) Routine (..))
import PostgREST.SchemaCache.Table (Table (..), TablesMap) import PostgREST.SchemaCache.Table (Table (..))
import qualified PostgREST.ApiRequest.Types as ApiRequestTypes import qualified PostgREST.ApiRequest.Types as ApiRequestTypes
import qualified PostgREST.SchemaCache.Routine as Routine import qualified PostgREST.SchemaCache.Routine as Routine
@@ -63,9 +63,9 @@ data PgrstResponse = PgrstResponse {
, pgrstBody :: LBS.ByteString , pgrstBody :: LBS.ByteString
} }
actionResponse :: ActionPlan -> QualifiedIdentifier -> ApiRequest -> ResultSet -> Either Error.Error PgrstResponse actionResponse :: QueryResult -> QualifiedIdentifier -> ApiRequest -> (Text, Text) -> AppConfig -> SchemaCache -> Schema -> Bool -> Either Error.Error PgrstResponse
actionResponse WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly} identifier ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} resultSet = actionResponse (DbResult WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly} resultSet) identifier ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ =
case resultSet of case resultSet of
RSStandard{..} -> do RSStandard{..} -> do
let let
@@ -94,7 +94,7 @@ actionResponse WrappedReadPlan{wrMedia, wrHdrsOnly=headersOnly} identifier ctxAp
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders wrMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders wrMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia} QualifiedIdentifier{..} ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} resultSet = case resultSet of actionResponse (DbResult MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia} resultSet) QualifiedIdentifier{..} ctxApiRequest@ApiRequest{iPreferences=Preferences{..}, ..} _ _ _ _ _ = case resultSet of
RSStandard{..} -> do RSStandard{..} -> do
let let
pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;} pkCols = case mrMutatePlan of { Insert{insPkCols} -> insPkCols; _ -> mempty;}
@@ -134,7 +134,7 @@ actionResponse MutateReadPlan{mrMutation=MutationCreate, mrMutatePlan, mrMedia}
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse MutateReadPlan{mrMutation=MutationUpdate, mrMedia} _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} resultSet = case resultSet of actionResponse (DbResult MutateReadPlan{mrMutation=MutationUpdate, mrMedia} resultSet) _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of
RSStandard{..} -> do RSStandard{..} -> do
let let
contentRangeHeader = contentRangeHeader =
@@ -156,7 +156,7 @@ actionResponse MutateReadPlan{mrMutation=MutationUpdate, mrMedia} _ ctxApiReques
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse MutateReadPlan{mrMutation=MutationSingleUpsert, mrMedia} _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} resultSet = case resultSet of actionResponse (DbResult MutateReadPlan{mrMutation=MutationSingleUpsert, mrMedia} resultSet) _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of
RSStandard {..} -> do RSStandard {..} -> do
let let
prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing [] prefHeader = maybeToList . prefAppliedHeader $ Preferences Nothing preferRepresentation Nothing preferCount preferTransaction Nothing preferHandling preferTimezone Nothing []
@@ -176,7 +176,7 @@ actionResponse MutateReadPlan{mrMutation=MutationSingleUpsert, mrMedia} _ ctxApi
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse MutateReadPlan{mrMutation=MutationDelete, mrMedia} _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} resultSet = case resultSet of actionResponse (DbResult MutateReadPlan{mrMutation=MutationDelete, mrMedia} resultSet) _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..}} _ _ _ _ _ = case resultSet of
RSStandard {..} -> do RSStandard {..} -> do
let let
contentRangeHeader = contentRangeHeader =
@@ -198,7 +198,7 @@ actionResponse MutateReadPlan{mrMutation=MutationDelete, mrMedia} _ ctxApiReques
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders mrMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} resultSet = case resultSet of actionResponse (DbResult CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} resultSet) _ ctxApiRequest@ApiRequest{iPreferences=Preferences{..},..} _ _ _ _ _ = case resultSet of
RSStandard {..} -> do RSStandard {..} -> do
let let
(status, contentRange) = (status, contentRange) =
@@ -225,6 +225,11 @@ actionResponse CallReadPlan{crMedia, crInvMthd=invMethod, crProc=proc} _ ctxApiR
RSPlan plan -> RSPlan plan ->
Right $ PgrstResponse HTTP.status200 (contentTypeHeaders crMedia ctxApiRequest) $ LBS.fromStrict plan Right $ PgrstResponse HTTP.status200 (contentTypeHeaders crMedia ctxApiRequest) $ LBS.fromStrict plan
actionResponse (MaybeDbResult InspectPlan{ipHdrsOnly=headersOnly} body) _ _ versions conf sCache schema negotiatedByProfile =
Right $ PgrstResponse HTTP.status200
(MediaType.toContentType MTOpenAPI : maybeToList (profileHeader schema negotiatedByProfile))
(maybe mempty (\(x, y, z) -> if headersOnly then mempty else OpenAPI.encode versions conf sCache x y z) body)
infoIdentResponse :: QualifiedIdentifier -> SchemaCache -> Either Error.Error PgrstResponse infoIdentResponse :: QualifiedIdentifier -> SchemaCache -> Either Error.Error PgrstResponse
infoIdentResponse identifier sCache = do infoIdentResponse identifier sCache = do
@@ -253,12 +258,6 @@ respondInfo allowHeader =
let allOrigins = ("Access-Control-Allow-Origin", "*") in let allOrigins = ("Access-Control-Allow-Origin", "*") in
Right $ PgrstResponse HTTP.status200 [allOrigins, (HTTP.hAllow, allowHeader)] mempty Right $ PgrstResponse HTTP.status200 [allOrigins, (HTTP.hAllow, allowHeader)] mempty
openApiResponse :: InspectPlan -> (Text, Text) -> Maybe (TablesMap, RoutineMap, Maybe Text) -> AppConfig -> SchemaCache -> Schema -> Bool -> Either Error.Error PgrstResponse
openApiResponse InspectPlan{ipHdrsOnly=headersOnly} versions body conf sCache schema negotiatedByProfile =
Right $ PgrstResponse HTTP.status200
(MediaType.toContentType MTOpenAPI : maybeToList (profileHeader schema negotiatedByProfile))
(maybe mempty (\(x, y, z) -> if headersOnly then mempty else OpenAPI.encode versions conf sCache x y z) body)
-- Status and headers can be overridden as per https://postgrest.org/en/stable/references/transactions.html#response-headers -- Status and headers can be overridden as per https://postgrest.org/en/stable/references/transactions.html#response-headers
overrideStatusHeaders :: Maybe Text -> Maybe BS.ByteString -> HTTP.Status -> [HTTP.Header]-> Either Error.Error (HTTP.Status, [HTTP.Header]) overrideStatusHeaders :: Maybe Text -> Maybe BS.ByteString -> HTTP.Status -> [HTTP.Header]-> Either Error.Error (HTTP.Status, [HTTP.Header])
overrideStatusHeaders rsGucStatus rsGucHeaders pgrstStatus pgrstHeaders = do overrideStatusHeaders rsGucStatus rsGucHeaders pgrstStatus pgrstHeaders = do