refactor: move snippet logic inside Statements.hs
Some snippet logic was unnecessarily at the Query.hs level. This is better as we can see what inputs we need to form the main queries.
This commit is contained in:
committed by
Steve Chavez
parent
0844743c30
commit
b2ce322d56
+11
-37
@@ -45,8 +45,7 @@ import PostgREST.ApiRequest.Preferences (PreferCount (..),
|
|||||||
PreferHandling (..),
|
PreferHandling (..),
|
||||||
PreferMaxAffected (..),
|
PreferMaxAffected (..),
|
||||||
PreferTransaction (..),
|
PreferTransaction (..),
|
||||||
Preferences (..),
|
Preferences (..))
|
||||||
shouldCount)
|
|
||||||
import PostgREST.ApiRequest.Types (Mutation (..))
|
import PostgREST.ApiRequest.Types (Mutation (..))
|
||||||
import PostgREST.Auth.Types (AuthResult (..))
|
import PostgREST.Auth.Types (AuthResult (..))
|
||||||
import PostgREST.Config (AppConfig (..),
|
import PostgREST.Config (AppConfig (..),
|
||||||
@@ -59,7 +58,6 @@ import PostgREST.Plan (ActionPlan (..),
|
|||||||
DbActionPlan (..),
|
DbActionPlan (..),
|
||||||
InfoPlan (..),
|
InfoPlan (..),
|
||||||
InspectPlan (..))
|
InspectPlan (..))
|
||||||
import PostgREST.Plan.MutatePlan (MutatePlan (..))
|
|
||||||
import PostgREST.SchemaCache (SchemaCache (..))
|
import PostgREST.SchemaCache (SchemaCache (..))
|
||||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||||
import PostgREST.SchemaCache.Routine (Routine (..), RoutineMap)
|
import PostgREST.SchemaCache.Routine (Routine (..), RoutineMap)
|
||||||
@@ -139,18 +137,9 @@ actionQuery (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiReque
|
|||||||
(mainActionQuery, mainSQLQuery)
|
(mainActionQuery, mainSQLQuery)
|
||||||
where
|
where
|
||||||
countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan
|
countQuery = QueryBuilder.readPlanToCountQuery wrReadPlan
|
||||||
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized (Statements.prepareRead
|
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized
|
||||||
(QueryBuilder.readPlanToQuery wrReadPlan)
|
(Statements.mainRead wrReadPlan countQuery preferCount configDbMaxRows wrMedia wrHandler)
|
||||||
(if preferCount == Just EstimatedCount then
|
decodeIt configDbPreparedStatements
|
||||||
-- LIMIT maxRows + 1 so we can determine below that maxRows was surpassed
|
|
||||||
QueryBuilder.limitedQuery countQuery ((+ 1) <$> configDbMaxRows)
|
|
||||||
else
|
|
||||||
countQuery
|
|
||||||
)
|
|
||||||
(shouldCount preferCount)
|
|
||||||
wrMedia
|
|
||||||
wrHandler
|
|
||||||
) decodeIt configDbPreparedStatements
|
|
||||||
mainActionQuery = do
|
mainActionQuery = do
|
||||||
resultSet <- lift $ SQL.statement mempty result
|
resultSet <- lift $ SQL.statement mempty result
|
||||||
failNotSingular wrMedia resultSet
|
failNotSingular wrMedia resultSet
|
||||||
@@ -165,19 +154,9 @@ actionQuery (DbCrud plan@WrappedReadPlan{..}) conf@AppConfig{..} apiReq@ApiReque
|
|||||||
actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||||
(mainActionQuery, mainSQLQuery)
|
(mainActionQuery, mainSQLQuery)
|
||||||
where
|
where
|
||||||
(isPut, isInsert, pkCols) = case mrMutatePlan of
|
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized
|
||||||
Insert{where_,insPkCols} -> ((not . null) where_, True, insPkCols)
|
(Statements.mainWrite mrReadPlan mrMutatePlan mrMedia mrHandler preferRepresentation preferResolution)
|
||||||
_ -> (False,False, mempty);
|
decodeIt configDbPreparedStatements
|
||||||
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized (Statements.prepareWrite
|
|
||||||
(QueryBuilder.readPlanToQuery mrReadPlan)
|
|
||||||
(QueryBuilder.mutatePlanToQuery mrMutatePlan)
|
|
||||||
isInsert
|
|
||||||
isPut
|
|
||||||
mrMedia
|
|
||||||
mrHandler
|
|
||||||
preferRepresentation
|
|
||||||
preferResolution
|
|
||||||
pkCols) decodeIt configDbPreparedStatements
|
|
||||||
failMutation resultSet = case mrMutation of
|
failMutation resultSet = case mrMutation of
|
||||||
MutationCreate -> do
|
MutationCreate -> do
|
||||||
failNotSingular mrMedia resultSet
|
failNotSingular mrMedia resultSet
|
||||||
@@ -203,14 +182,9 @@ actionQuery (DbCrud plan@MutateReadPlan{..}) conf@AppConfig{..} apiReq@ApiReques
|
|||||||
actionQuery (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
actionQuery (DbCall plan@CallReadPlan{..}) conf@AppConfig{..} apiReq@ApiRequest{iPreferences=Preferences{..}} _ =
|
||||||
(mainActionQuery, mainSQLQuery)
|
(mainActionQuery, mainSQLQuery)
|
||||||
where
|
where
|
||||||
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized (Statements.prepareCall
|
result@(SQL.Statement mainSQLQuery _ _ _) = SQL.dynamicallyParameterized
|
||||||
crProc
|
(Statements.mainCall crProc crCallPlan crReadPlan preferCount crMedia crHandler)
|
||||||
(QueryBuilder.callPlanToQuery crCallPlan)
|
decodeIt configDbPreparedStatements
|
||||||
(QueryBuilder.readPlanToQuery crReadPlan)
|
|
||||||
(QueryBuilder.readPlanToCountQuery crReadPlan)
|
|
||||||
(shouldCount preferCount)
|
|
||||||
crMedia
|
|
||||||
crHandler) decodeIt configDbPreparedStatements
|
|
||||||
|
|
||||||
mainActionQuery = do
|
mainActionQuery = do
|
||||||
resultSet <- lift $ SQL.statement mempty result
|
resultSet <- lift $ SQL.statement mempty result
|
||||||
@@ -275,7 +249,7 @@ resultSetWTotal AppConfig{..} ApiRequest{iPreferences=Preferences{..}} rs@RSStan
|
|||||||
where
|
where
|
||||||
explain =
|
explain =
|
||||||
lift . SQL.statement mempty $
|
lift . SQL.statement mempty $
|
||||||
SQL.dynamicallyParameterized (Statements.preparePlanRows countQuery)
|
SQL.dynamicallyParameterized (Statements.postExplain countQuery)
|
||||||
decodeIt
|
decodeIt
|
||||||
configDbPreparedStatements
|
configDbPreparedStatements
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
{-# LANGUAGE NamedFieldPuns #-}
|
||||||
{-|
|
{-|
|
||||||
Module : PostgREST.Query.Statements
|
Module : PostgREST.Query.Statements
|
||||||
Description : PostgREST SQL statements.
|
Description : PostgREST main queries
|
||||||
-}
|
-}
|
||||||
module PostgREST.Query.Statements
|
module PostgREST.Query.Statements
|
||||||
( prepareWrite
|
( mainWrite
|
||||||
, prepareRead
|
, mainRead
|
||||||
, prepareCall
|
, mainCall
|
||||||
, preparePlanRows
|
, postExplain
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Hasql.DynamicStatements.Snippet as SQL
|
import qualified Hasql.DynamicStatements.Snippet as SQL
|
||||||
@@ -14,15 +15,19 @@ import qualified Hasql.DynamicStatements.Snippet as SQL
|
|||||||
import PostgREST.ApiRequest.Preferences
|
import PostgREST.ApiRequest.Preferences
|
||||||
import PostgREST.MediaType (MTVndPlanFormat (..),
|
import PostgREST.MediaType (MTVndPlanFormat (..),
|
||||||
MediaType (..))
|
MediaType (..))
|
||||||
|
import PostgREST.Plan.CallPlan
|
||||||
|
import PostgREST.Plan.MutatePlan as MTPlan
|
||||||
|
import PostgREST.Plan.ReadPlan
|
||||||
|
import PostgREST.Query.QueryBuilder
|
||||||
import PostgREST.Query.SqlFragment
|
import PostgREST.Query.SqlFragment
|
||||||
import PostgREST.SchemaCache.Routine (MediaHandler (..), Routine,
|
import PostgREST.SchemaCache.Routine (MediaHandler (..), Routine,
|
||||||
funcReturnsSingle)
|
funcReturnsSingle)
|
||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
|
|
||||||
prepareWrite :: SQL.Snippet -> SQL.Snippet -> Bool -> Bool -> MediaType -> MediaHandler ->
|
mainWrite :: ReadPlanTree -> MutatePlan -> MediaType -> MediaHandler ->
|
||||||
Maybe PreferRepresentation -> Maybe PreferResolution -> [Text] -> SQL.Snippet
|
Maybe PreferRepresentation -> Maybe PreferResolution -> SQL.Snippet
|
||||||
prepareWrite selectQuery mutateQuery isInsert isPut mt handler rep resolution pKeys = mtSnippet mt snippet
|
mainWrite rPlan mtplan mt handler rep resolution = mtSnippet mt snippet
|
||||||
where
|
where
|
||||||
checkUpsert snip = if isInsert && (isPut || resolution == Just MergeDuplicates) then snip else "''"
|
checkUpsert snip = if isInsert && (isPut || resolution == Just MergeDuplicates) then snip else "''"
|
||||||
pgrstInsertedF = checkUpsert "nullif(current_setting('pgrst.inserted', true),'')::int"
|
pgrstInsertedF = checkUpsert "nullif(current_setting('pgrst.inserted', true),'')::int"
|
||||||
@@ -42,7 +47,7 @@ prepareWrite selectQuery mutateQuery isInsert isPut mt handler rep resolution pK
|
|||||||
if isInsert && rep == Just HeadersOnly
|
if isInsert && rep == Just HeadersOnly
|
||||||
then
|
then
|
||||||
"CASE WHEN pg_catalog.count(_postgrest_t) = 1 " <>
|
"CASE WHEN pg_catalog.count(_postgrest_t) = 1 " <>
|
||||||
"THEN coalesce(" <> locationF pKeys <> ", " <> noLocationF <> ") " <>
|
"THEN coalesce(" <> locationF pkCols <> ", " <> noLocationF <> ") " <>
|
||||||
"ELSE " <> noLocationF <> " " <>
|
"ELSE " <> noLocationF <> " " <>
|
||||||
"END"
|
"END"
|
||||||
else noLocationF
|
else noLocationF
|
||||||
@@ -52,8 +57,15 @@ prepareWrite selectQuery mutateQuery isInsert isPut mt handler rep resolution pK
|
|||||||
| handler == NoAgg = "SELECT * FROM " <> sourceCTE
|
| handler == NoAgg = "SELECT * FROM " <> sourceCTE
|
||||||
| otherwise = selectQuery
|
| otherwise = selectQuery
|
||||||
|
|
||||||
prepareRead :: SQL.Snippet -> SQL.Snippet -> Bool -> MediaType -> MediaHandler -> SQL.Snippet
|
selectQuery = readPlanToQuery rPlan
|
||||||
prepareRead selectQuery countQuery countTotal mt handler = mtSnippet mt snippet
|
mutateQuery = mutatePlanToQuery mtplan
|
||||||
|
(isPut, isInsert, pkCols) = case mtplan of
|
||||||
|
MTPlan.Insert{MTPlan.where_,insPkCols} -> ((not . null) where_, True, insPkCols)
|
||||||
|
_ -> (False,False, mempty);
|
||||||
|
|
||||||
|
mainRead :: ReadPlanTree -> SQL.Snippet -> Maybe PreferCount -> Maybe Integer ->
|
||||||
|
MediaType -> MediaHandler -> SQL.Snippet
|
||||||
|
mainRead rPlan countQuery pCount maxRows mt handler = mtSnippet mt snippet
|
||||||
where
|
where
|
||||||
snippet =
|
snippet =
|
||||||
"WITH " <> sourceCTE <> " AS ( " <> selectQuery <> " ) " <>
|
"WITH " <> sourceCTE <> " AS ( " <> selectQuery <> " ) " <>
|
||||||
@@ -67,12 +79,18 @@ prepareRead selectQuery countQuery countTotal mt handler = mtSnippet mt snippet
|
|||||||
"''" <> " AS response_inserted " <>
|
"''" <> " AS response_inserted " <>
|
||||||
"FROM ( SELECT * FROM " <> sourceCTE <> " ) _postgrest_t"
|
"FROM ( SELECT * FROM " <> sourceCTE <> " ) _postgrest_t"
|
||||||
|
|
||||||
(countCTEF, countResultF) = countF countQuery countTotal
|
(countCTEF, countResultF) = countF countQ $ shouldCount pCount
|
||||||
|
selectQuery = readPlanToQuery rPlan
|
||||||
|
countQ =
|
||||||
|
if pCount == Just EstimatedCount then
|
||||||
|
-- LIMIT maxRows + 1 so we can determine below that maxRows was surpassed
|
||||||
|
limitedQuery countQuery ((+ 1) <$> maxRows)
|
||||||
|
else
|
||||||
|
countQuery
|
||||||
|
|
||||||
|
mainCall :: Routine -> CallPlan -> ReadPlanTree -> Maybe PreferCount ->
|
||||||
prepareCall :: Routine -> SQL.Snippet -> SQL.Snippet -> SQL.Snippet -> Bool ->
|
MediaType -> MediaHandler -> SQL.Snippet
|
||||||
MediaType -> MediaHandler -> SQL.Snippet
|
mainCall rout cPlan rPlan pCount mt handler = mtSnippet mt snippet
|
||||||
prepareCall rout callProcQuery selectQuery countQuery countTotal mt handler = mtSnippet mt snippet
|
|
||||||
where
|
where
|
||||||
snippet =
|
snippet =
|
||||||
"WITH " <> sourceCTE <> " AS (" <> callProcQuery <> ") " <>
|
"WITH " <> sourceCTE <> " AS (" <> callProcQuery <> ") " <>
|
||||||
@@ -88,11 +106,14 @@ prepareCall rout callProcQuery selectQuery countQuery countTotal mt handler = mt
|
|||||||
"''" <> " AS response_inserted " <>
|
"''" <> " AS response_inserted " <>
|
||||||
"FROM (" <> selectQuery <> ") _postgrest_t"
|
"FROM (" <> selectQuery <> ") _postgrest_t"
|
||||||
|
|
||||||
(countCTEF, countResultF) = countF countQuery countTotal
|
(countCTEF, countResultF) = countF countQuery $ shouldCount pCount
|
||||||
|
selectQuery = readPlanToQuery rPlan
|
||||||
|
callProcQuery = callPlanToQuery cPlan
|
||||||
|
countQuery = readPlanToCountQuery rPlan
|
||||||
|
|
||||||
|
-- This occurs after the main query runs, that's why it's prefixed with "post"
|
||||||
preparePlanRows :: SQL.Snippet -> SQL.Snippet
|
postExplain :: SQL.Snippet -> SQL.Snippet
|
||||||
preparePlanRows = explainF PlanJSON mempty
|
postExplain = explainF PlanJSON mempty
|
||||||
|
|
||||||
mtSnippet :: MediaType -> SQL.Snippet -> SQL.Snippet
|
mtSnippet :: MediaType -> SQL.Snippet -> SQL.Snippet
|
||||||
mtSnippet mediaType snippet = case mediaType of
|
mtSnippet mediaType snippet = case mediaType of
|
||||||
|
|||||||
Reference in New Issue
Block a user