* Update resolver to lts-13.29 and add lock file to repository * Upgrade stack version * Save cache after building dependencies only to have faster feedback loop when tests fail * Move private functions from QueryBuilder to a separate Private module * Move more functions over to private trying to make compilation consume less memory * Split private in 4 modules * Remove unused LambdaCase pragma * Add profile to memory-tests.sh so it can find postgrest executable * Move save dependencies before building and running tests for faster feedback loop
54 lines
1.9 KiB
Haskell
54 lines
1.9 KiB
Haskell
module PostgREST.QueryBuilder.WriteStatement where
|
|
|
|
import Data.Maybe
|
|
import Data.Text (intercalate, unwords)
|
|
import qualified Hasql.Encoders as HE
|
|
import qualified Hasql.Statement as H
|
|
import PostgREST.ApiRequest (PreferRepresentation (..))
|
|
import PostgREST.QueryBuilder.Private
|
|
import PostgREST.Types
|
|
import Protolude hiding (cast,
|
|
intercalate, replace)
|
|
import Text.InterpolatedString.Perl6 (qc)
|
|
|
|
createWriteStatement :: SqlQuery -> SqlQuery -> Bool -> Bool -> Bool ->
|
|
PreferRepresentation -> [Text] ->
|
|
H.Statement ByteString (Maybe ResultsWithCount)
|
|
createWriteStatement selectQuery mutateQuery wantSingle isInsert asCsv rep pKeys =
|
|
unicodeStatement sql (param HE.unknown) decodeStandardMay True
|
|
|
|
where
|
|
sql = case rep of
|
|
None -> [qc|
|
|
WITH {sourceCTEName} AS ({mutateQuery})
|
|
SELECT '', 0, {noLocationF}, '' |]
|
|
HeadersOnly -> [qc|
|
|
WITH {sourceCTEName} AS ({mutateQuery})
|
|
SELECT {cols}
|
|
FROM (SELECT 1 FROM {sourceCTEName}) _postgrest_t |]
|
|
Full -> [qc|
|
|
WITH {sourceCTEName} AS ({mutateQuery})
|
|
SELECT {cols}
|
|
FROM ({selectQuery}) _postgrest_t |]
|
|
|
|
cols = intercalate ", " [
|
|
"'' AS total_result_set", -- when updateing it does not make sense
|
|
"pg_catalog.count(_postgrest_t) AS page_total",
|
|
if isInsert
|
|
then unwords [
|
|
"CASE",
|
|
"WHEN pg_catalog.count(_postgrest_t) = 1 THEN",
|
|
"coalesce(" <> locationF pKeys <> ", " <> noLocationF <> ")",
|
|
"ELSE " <> noLocationF,
|
|
"END AS header"]
|
|
else noLocationF <> "AS header",
|
|
if rep == Full
|
|
then bodyF <> " AS body"
|
|
else "''"
|
|
]
|
|
|
|
bodyF
|
|
| asCsv = asCsvF
|
|
| wantSingle = asJsonSingleF
|
|
| otherwise = asJsonF
|