Remove pjType from QueryBuilder Insert/Update
* Refactor Insert onConflict
This commit is contained in:
committed by
Steve Chávez
parent
36e9d779fc
commit
00a0d8b9b7
@@ -321,7 +321,7 @@ addProperty f (targetNodeName:remainingPath, a) (Node rn forest) =
|
||||
mutateRequest :: ApiRequest -> TableName -> [Text] -> [FieldName] -> Either Response MutateRequest
|
||||
mutateRequest apiRequest tName pkCols fldNames = mapLeft apiRequestError $
|
||||
case action of
|
||||
ActionCreate -> Right $ Insert tName pkCols payload (iPreferResolution apiRequest) [] returnings
|
||||
ActionCreate -> Right $ Insert tName payload ((,) <$> iPreferResolution apiRequest <*> Just pkCols) [] returnings
|
||||
ActionUpdate -> Update tName payload <$> combinedLogic <*> pure returnings
|
||||
ActionSingleUpsert ->
|
||||
(\flts ->
|
||||
@@ -331,7 +331,7 @@ mutateRequest apiRequest tName pkCols fldNames = mapLeft apiRequestError $
|
||||
all (\case
|
||||
Filter _ (OpExpr False (Op "eq" _)) -> True
|
||||
_ -> False) flts
|
||||
then Insert tName pkCols payload (Just MergeDuplicates) <$> combinedLogic <*> pure returnings
|
||||
then Insert tName payload (Just (MergeDuplicates, pkCols)) <$> combinedLogic <*> pure returnings
|
||||
else
|
||||
Left InvalidFilters) =<< filters
|
||||
ActionDelete -> Delete tName <$> combinedLogic <*> pure returnings
|
||||
|
||||
@@ -263,44 +263,46 @@ requestToQuery schema isParent (DbRead (Node (Select colSelects tbl tblAlias imp
|
||||
--getQueryParts is not total but requestToQuery is called only after addJoinConditions which ensures the only
|
||||
--posible relations are Child Parent Many
|
||||
getQueryParts _ _ = witness
|
||||
requestToQuery schema _ (DbMutate (Insert mainTbl pkCols p@(PayloadJSON _ pType pKeys) onConflct logicForest returnings)) =
|
||||
requestToQuery schema _ (DbMutate (Insert mainTbl p@(PayloadJSON _ _ pKeys) onConflct putConditions returnings)) =
|
||||
unwords [
|
||||
("WITH " <> ignoredBody) `emptyOnFalse` not payloadIsEmpty,
|
||||
"WITH payload AS (SELECT $1::json AS json_data),",
|
||||
"vals AS (",
|
||||
unwords [
|
||||
"SELECT json_data AS val FROM payload WHERE json_typeof(json_data) = 'array'",
|
||||
"UNION ALL",
|
||||
"SELECT json_build_array(json_data) AS val FROM payload WHERE json_typeof(json_data) = 'object')"],
|
||||
"INSERT INTO ", fromQi qi, if payloadIsEmpty then " " else "(" <> cols <> ")",
|
||||
case (pType, payloadIsEmpty) of
|
||||
(PJArray _, True) -> "SELECT null WHERE false"
|
||||
(PJObject, True) -> "DEFAULT VALUES"
|
||||
_ -> unwords [
|
||||
"SELECT " <> cols <> " FROM",
|
||||
case pType of
|
||||
PJObject -> "json_populate_record"
|
||||
PJArray _ -> "json_populate_recordset", "(null::", fromQi qi, ", $1) _",
|
||||
-- Only used for PUT
|
||||
("WHERE " <> intercalate " AND " (pgFmtLogicTree (QualifiedIdentifier "" "_") <$> logicForest)) `emptyOnFalse` null logicForest],
|
||||
maybe "" (\x -> (
|
||||
"ON CONFLICT(" <> intercalate ", " (pgFmtIdent <$> pkCols) <> ") " <> case x of
|
||||
unwords [
|
||||
"SELECT " <> cols <> " FROM",
|
||||
"json_populate_recordset", "(null::", fromQi qi, ", (select val from vals)) _",
|
||||
-- Only used for PUT
|
||||
("WHERE " <> intercalate " AND " (pgFmtLogicTree (QualifiedIdentifier "" "_") <$> putConditions)) `emptyOnFalse` null putConditions],
|
||||
maybe "" (\(oncDo, oncCols) -> (
|
||||
"ON CONFLICT(" <> intercalate ", " (pgFmtIdent <$> oncCols) <> ") " <> case oncDo of
|
||||
IgnoreDuplicates ->
|
||||
"DO NOTHING"
|
||||
MergeDuplicates ->
|
||||
"DO UPDATE SET " <> intercalate ", " (pgFmtIdent <> const " = EXCLUDED." <> pgFmtIdent <$> S.toList pKeys)
|
||||
) `emptyOnFalse` null pkCols) onConflct,
|
||||
) `emptyOnFalse` null oncCols) onConflct,
|
||||
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings]
|
||||
where
|
||||
qi = QualifiedIdentifier schema mainTbl
|
||||
cols = intercalate ", " $ pgFmtIdent <$> S.toList pKeys
|
||||
payloadIsEmpty = pjIsEmpty p
|
||||
requestToQuery schema _ (DbMutate (Update mainTbl p@(PayloadJSON _ pType keys) logicForest returnings)) =
|
||||
requestToQuery schema _ (DbMutate (Update mainTbl p@(PayloadJSON _ _ keys) logicForest returnings)) =
|
||||
if pjIsEmpty p
|
||||
then "WITH " <> ignoredBody <> "SELECT ''"
|
||||
else
|
||||
unwords [
|
||||
"WITH payload AS (SELECT $1::json AS json_data),",
|
||||
"vals AS (",
|
||||
"SELECT json_data AS val FROM payload WHERE json_typeof(json_data) = 'array'",
|
||||
"UNION ALL",
|
||||
"SELECT json_build_array(json_data) AS val FROM payload WHERE json_typeof(json_data) = 'object')",
|
||||
"UPDATE " <> fromQi qi <> " SET " <> cols,
|
||||
"FROM (SELECT * FROM ",
|
||||
case pType of
|
||||
PJObject -> " json_populate_record"
|
||||
PJArray _ -> " json_populate_recordset", "(null::", fromQi qi, ", $1)) _ ",
|
||||
("WHERE " <> intercalate " AND " (map (pgFmtLogicTree qi) logicForest)) `emptyOnFalse` null logicForest,
|
||||
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings
|
||||
"FROM (SELECT * FROM json_populate_recordset", "(null::", fromQi qi, ", (select val from vals))) _ ",
|
||||
("WHERE " <> intercalate " AND " (pgFmtLogicTree qi <$> logicForest)) `emptyOnFalse` null logicForest,
|
||||
("RETURNING " <> intercalate ", " (pgFmtColumn qi <$> returnings)) `emptyOnFalse` null returnings
|
||||
]
|
||||
where
|
||||
qi = QualifiedIdentifier schema mainTbl
|
||||
|
||||
@@ -115,7 +115,7 @@ newtype ForeignKey = ForeignKey { fkCol :: Column } deriving (Show, Eq, Ord)
|
||||
data Column =
|
||||
Column {
|
||||
colTable :: Table
|
||||
, colName :: Text
|
||||
, colName :: ColumnName
|
||||
, colDescription :: Maybe Text
|
||||
, colPosition :: Int32
|
||||
, colNullable :: Bool
|
||||
@@ -134,6 +134,7 @@ instance Eq Column where
|
||||
-- | A view column that refers to a table column
|
||||
type Synonym = (Column, ViewColumn)
|
||||
type ViewColumn = Column
|
||||
type ColumnName = Text
|
||||
|
||||
data PrimaryKey = PrimaryKey {
|
||||
pkTable :: Table
|
||||
@@ -329,9 +330,8 @@ data ReadQuery = Select {
|
||||
data MutateQuery =
|
||||
Insert {
|
||||
in_ :: TableName
|
||||
, insPkCols :: [Text]
|
||||
, qPayload :: PayloadJSON
|
||||
, onConflict :: Maybe PreferResolution
|
||||
, onConflict :: Maybe (PreferResolution, [ColumnName])
|
||||
, where_ :: [LogicTree]
|
||||
, returning :: [FieldName]
|
||||
}|
|
||||
|
||||
Reference in New Issue
Block a user