refactor: asJsonF/asJsonSingleF Routine param
This commit is contained in:
committed by
Steve Chavez
parent
fad47324c3
commit
5c372df487
+7
-10
@@ -28,12 +28,11 @@ import qualified Hasql.Encoders as HE
|
|||||||
import qualified Hasql.Statement as SQL
|
import qualified Hasql.Statement as SQL
|
||||||
import qualified Hasql.Transaction as SQL
|
import qualified Hasql.Transaction as SQL
|
||||||
|
|
||||||
import qualified PostgREST.Error as Error
|
import qualified PostgREST.Error as Error
|
||||||
import qualified PostgREST.Query.QueryBuilder as QueryBuilder
|
import qualified PostgREST.Query.QueryBuilder as QueryBuilder
|
||||||
import qualified PostgREST.Query.Statements as Statements
|
import qualified PostgREST.Query.Statements as Statements
|
||||||
import qualified PostgREST.RangeQuery as RangeQuery
|
import qualified PostgREST.RangeQuery as RangeQuery
|
||||||
import qualified PostgREST.SchemaCache as SchemaCache
|
import qualified PostgREST.SchemaCache as SchemaCache
|
||||||
import qualified PostgREST.SchemaCache.Routine as Routine
|
|
||||||
|
|
||||||
import Data.Scientific (FPFormat (..), formatScientific, isInteger)
|
import Data.Scientific (FPFormat (..), formatScientific, isInteger)
|
||||||
|
|
||||||
@@ -153,13 +152,11 @@ deleteQuery mrPlan apiReq@ApiRequest{..} conf = do
|
|||||||
pure resultSet
|
pure resultSet
|
||||||
|
|
||||||
invokeQuery :: Routine -> CallReadPlan -> ApiRequest -> AppConfig -> PgVersion -> DbHandler ResultSet
|
invokeQuery :: Routine -> CallReadPlan -> ApiRequest -> AppConfig -> PgVersion -> DbHandler ResultSet
|
||||||
invokeQuery proc CallReadPlan{crReadPlan, crCallPlan, crBinField} apiReq@ApiRequest{iPreferences=Preferences{..}, ..} conf@AppConfig{..} pgVer = do
|
invokeQuery rout CallReadPlan{crReadPlan, crCallPlan, crBinField} apiReq@ApiRequest{iPreferences=Preferences{..}, ..} conf@AppConfig{..} pgVer = do
|
||||||
resultSet <-
|
resultSet <-
|
||||||
lift . SQL.statement mempty $
|
lift . SQL.statement mempty $
|
||||||
Statements.prepareCall
|
Statements.prepareCall
|
||||||
(Routine.funcReturnsScalar proc)
|
rout
|
||||||
(Routine.funcReturnsSingleComposite proc)
|
|
||||||
(Routine.funcReturnsSetOfScalar proc)
|
|
||||||
(QueryBuilder.callPlanToQuery crCallPlan pgVer)
|
(QueryBuilder.callPlanToQuery crCallPlan pgVer)
|
||||||
(QueryBuilder.readPlanToQuery crReadPlan)
|
(QueryBuilder.readPlanToQuery crReadPlan)
|
||||||
(QueryBuilder.readPlanToCountQuery crReadPlan)
|
(QueryBuilder.readPlanToCountQuery crReadPlan)
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ import PostgREST.RangeQuery (NonnegRange, allRange,
|
|||||||
rangeLimit, rangeOffset)
|
rangeLimit, rangeOffset)
|
||||||
import PostgREST.SchemaCache.Identifiers (FieldName,
|
import PostgREST.SchemaCache.Identifiers (FieldName,
|
||||||
QualifiedIdentifier (..))
|
QualifiedIdentifier (..))
|
||||||
|
import PostgREST.SchemaCache.Routine (Routine (..),
|
||||||
|
funcReturnsScalar,
|
||||||
|
funcReturnsSetOfScalar,
|
||||||
|
funcReturnsSingleComposite)
|
||||||
|
|
||||||
import Protolude hiding (cast)
|
import Protolude hiding (cast)
|
||||||
|
|
||||||
@@ -183,17 +187,23 @@ asCsvF = asCsvHeaderF <> " || '\n' || " <> asCsvBodyF
|
|||||||
")"
|
")"
|
||||||
asCsvBodyF = "coalesce(string_agg(substring(_postgrest_t::text, 2, length(_postgrest_t::text) - 2), '\n'), '')"
|
asCsvBodyF = "coalesce(string_agg(substring(_postgrest_t::text, 2, length(_postgrest_t::text) - 2), '\n'), '')"
|
||||||
|
|
||||||
asJsonSingleF :: Bool -> SqlFragment
|
asJsonSingleF :: Maybe Routine -> SqlFragment
|
||||||
asJsonSingleF returnsScalar
|
asJsonSingleF rout
|
||||||
| returnsScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar)->0, 'null')"
|
| returnsScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar)->0, 'null')"
|
||||||
| otherwise = "coalesce(json_agg(_postgrest_t)->0, 'null')"
|
| otherwise = "coalesce(json_agg(_postgrest_t)->0, 'null')"
|
||||||
|
where
|
||||||
|
returnsScalar = maybe False funcReturnsScalar rout
|
||||||
|
|
||||||
asJsonF :: Bool -> Bool -> Bool -> SqlFragment
|
asJsonF :: Maybe Routine -> SqlFragment
|
||||||
asJsonF returnsScalar returnsSetOfScalar returnsSingleComposite
|
asJsonF rout
|
||||||
| returnsSingleComposite = "coalesce(json_agg(_postgrest_t)->0, 'null')"
|
| returnsSingleComposite = "coalesce(json_agg(_postgrest_t)->0, 'null')"
|
||||||
| returnsScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar)->0, 'null')"
|
| returnsScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar)->0, 'null')"
|
||||||
| returnsSetOfScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar), '[]')"
|
| returnsSetOfScalar = "coalesce(json_agg(_postgrest_t.pgrst_scalar), '[]')"
|
||||||
| otherwise = "coalesce(json_agg(_postgrest_t), '[]')"
|
| otherwise = "coalesce(json_agg(_postgrest_t), '[]')"
|
||||||
|
where
|
||||||
|
(returnsSingleComposite, returnsScalar, returnsSetOfScalar) = case rout of
|
||||||
|
Just r -> (funcReturnsSingleComposite r, funcReturnsScalar r, funcReturnsSetOfScalar r)
|
||||||
|
Nothing -> (False, False, False)
|
||||||
|
|
||||||
asXmlF :: FieldName -> SqlFragment
|
asXmlF :: FieldName -> SqlFragment
|
||||||
asXmlF fieldName = "coalesce(xmlagg(_postgrest_t." <> pgFmtIdent fieldName <> "), '')"
|
asXmlF fieldName = "coalesce(xmlagg(_postgrest_t." <> pgFmtIdent fieldName <> "), '')"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import PostgREST.MediaType (MTPlanAttrs (..),
|
|||||||
getMediaType)
|
getMediaType)
|
||||||
import PostgREST.Query.SqlFragment
|
import PostgREST.Query.SqlFragment
|
||||||
import PostgREST.SchemaCache.Identifiers (FieldName)
|
import PostgREST.SchemaCache.Identifiers (FieldName)
|
||||||
|
import PostgREST.SchemaCache.Routine (Routine)
|
||||||
|
|
||||||
import Protolude
|
import Protolude
|
||||||
|
|
||||||
@@ -86,8 +87,8 @@ prepareWrite selectQuery mutateQuery isInsert mt rep pKeys =
|
|||||||
| rep /= Full = "''"
|
| rep /= Full = "''"
|
||||||
| getMediaType mt == MTTextCSV = asCsvF
|
| getMediaType mt == MTTextCSV = asCsvF
|
||||||
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
||||||
| getMediaType mt == MTSingularJSON = asJsonSingleF False
|
| getMediaType mt == MTSingularJSON = asJsonSingleF Nothing
|
||||||
| otherwise = asJsonF False False False
|
| otherwise = asJsonF Nothing
|
||||||
|
|
||||||
selectF
|
selectF
|
||||||
-- prevent using any of the column names in ?select= when no response is returned from the CTE
|
-- prevent using any of the column names in ?select= when no response is returned from the CTE
|
||||||
@@ -119,21 +120,21 @@ prepareRead selectQuery countQuery countTotal mt binaryField =
|
|||||||
|
|
||||||
bodyF
|
bodyF
|
||||||
| getMediaType mt == MTTextCSV = asCsvF
|
| getMediaType mt == MTTextCSV = asCsvF
|
||||||
| getMediaType mt == MTSingularJSON = asJsonSingleF False
|
| getMediaType mt == MTSingularJSON = asJsonSingleF Nothing
|
||||||
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
||||||
| isJust binaryField && getMediaType mt == MTTextXML = asXmlF $ fromJust binaryField
|
| isJust binaryField && getMediaType mt == MTTextXML = asXmlF $ fromJust binaryField
|
||||||
| isJust binaryField = asBinaryF $ fromJust binaryField
|
| isJust binaryField = asBinaryF $ fromJust binaryField
|
||||||
| otherwise = asJsonF False False False
|
| otherwise = asJsonF Nothing
|
||||||
|
|
||||||
decodeIt :: HD.Result ResultSet
|
decodeIt :: HD.Result ResultSet
|
||||||
decodeIt = case mt of
|
decodeIt = case mt of
|
||||||
MTPlan{} -> planRow
|
MTPlan{} -> planRow
|
||||||
_ -> HD.singleRow $ standardRow True
|
_ -> HD.singleRow $ standardRow True
|
||||||
|
|
||||||
prepareCall :: Bool -> Bool -> Bool -> SQL.Snippet -> SQL.Snippet -> SQL.Snippet -> Bool ->
|
prepareCall :: Routine -> SQL.Snippet -> SQL.Snippet -> SQL.Snippet -> Bool ->
|
||||||
MediaType -> Maybe FieldName -> Bool ->
|
MediaType -> Maybe FieldName -> Bool ->
|
||||||
SQL.Statement () ResultSet
|
SQL.Statement () ResultSet
|
||||||
prepareCall returnsScalar returnsSingleComposite returnsSetOfScalar callProcQuery selectQuery countQuery countTotal mt binaryField =
|
prepareCall rout callProcQuery selectQuery countQuery countTotal mt binaryField =
|
||||||
SQL.dynamicallyParameterized (mtSnippet mt snippet) decodeIt
|
SQL.dynamicallyParameterized (mtSnippet mt snippet) decodeIt
|
||||||
where
|
where
|
||||||
snippet =
|
snippet =
|
||||||
@@ -151,12 +152,12 @@ prepareCall returnsScalar returnsSingleComposite returnsSetOfScalar callProcQuer
|
|||||||
(countCTEF, countResultF) = countF countQuery countTotal
|
(countCTEF, countResultF) = countF countQuery countTotal
|
||||||
|
|
||||||
bodyF
|
bodyF
|
||||||
| getMediaType mt == MTSingularJSON = asJsonSingleF returnsScalar
|
| getMediaType mt == MTSingularJSON = asJsonSingleF $ Just rout
|
||||||
| getMediaType mt == MTTextCSV = asCsvF
|
| getMediaType mt == MTTextCSV = asCsvF
|
||||||
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
| getMediaType mt == MTGeoJSON = asGeoJsonF
|
||||||
| isJust binaryField && getMediaType mt == MTTextXML = asXmlF $ fromJust binaryField
|
| isJust binaryField && getMediaType mt == MTTextXML = asXmlF $ fromJust binaryField
|
||||||
| isJust binaryField = asBinaryF $ fromJust binaryField
|
| isJust binaryField = asBinaryF $ fromJust binaryField
|
||||||
| otherwise = asJsonF returnsScalar returnsSetOfScalar returnsSingleComposite
|
| otherwise = asJsonF $ Just rout
|
||||||
|
|
||||||
decodeIt :: HD.Result ResultSet
|
decodeIt :: HD.Result ResultSet
|
||||||
decodeIt = case mt of
|
decodeIt = case mt of
|
||||||
|
|||||||
Reference in New Issue
Block a user