-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: trigger on config_changes update (#1022)
* feat: trigger on config_changes update * feat: add on insert trigger on config changes * chore: address review comments * Update views/030_config_changes.sql --------- Co-authored-by: Moshe Immerman <[email protected]>
- Loading branch information
1 parent
debc16b
commit 8c8011f
Showing
2 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
CREATE OR REPLACE FUNCTION config_changes_update_trigger() | ||
RETURNS TRIGGER AS $$ | ||
DECLARE | ||
count_increment INT; | ||
BEGIN | ||
count_increment := NEW.count - OLD.count; | ||
|
||
UPDATE | ||
config_changes | ||
SET | ||
change_type = NEW.change_type, | ||
count = CASE | ||
WHEN NEW.details IS DISTINCT FROM OLD.details THEN NEW.count | ||
ELSE count | ||
END, | ||
created_at = NOW(), | ||
created_by = NEW.created_by, | ||
details = NEW.details, | ||
is_pushed = NEW.is_pushed, | ||
diff = NEW.diff, | ||
external_created_by = NEW.external_created_by, | ||
external_change_id = NEW.external_change_id, | ||
first_observed = LEAST(first_observed, created_at), | ||
patches = NEW.patches, | ||
severity = NEW.severity, | ||
source = NEW.source, | ||
summary = NEW.summary | ||
WHERE | ||
id = NEW.id; | ||
|
||
-- Prevent the original update by returning NULL | ||
RETURN NULL; | ||
EXCEPTION | ||
WHEN unique_violation THEN | ||
IF sqlerrm LIKE '%config_changes_config_id_external_change_id_key%' THEN | ||
UPDATE config_changes | ||
SET | ||
change_type = NEW.change_type, | ||
count = CASE | ||
WHEN NEW.details IS DISTINCT FROM OLD.details THEN config_changes.count + count_increment | ||
ELSE count | ||
END, | ||
created_at = NOW(), | ||
created_by = NEW.created_by, | ||
details = NEW.details, | ||
diff = NEW.diff, | ||
external_created_by = NEW.external_created_by, | ||
first_observed = LEAST(first_observed, created_at), | ||
patches = NEW.patches, | ||
severity = NEW.severity, | ||
source = NEW.source, | ||
summary = NEW.summary | ||
WHERE | ||
external_change_id = NEW.external_change_id AND config_id = NEW.config_id; | ||
|
||
RETURN NULL; | ||
ELSE | ||
RAISE; | ||
END IF; | ||
WHEN OTHERS THEN | ||
RAISE; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE OR REPLACE TRIGGER config_changes_update_trigger | ||
BEFORE UPDATE | ||
ON config_changes FOR EACH ROW | ||
WHEN (pg_trigger_depth() = 0) EXECUTE FUNCTION config_changes_update_trigger(); | ||
|
||
--- | ||
CREATE OR REPLACE FUNCTION config_changes_insert_trigger() | ||
RETURNS TRIGGER AS $$ | ||
DECLARE | ||
existing_details JSONB; | ||
existing_created_at TIMESTAMP WITH TIME ZONE; | ||
BEGIN | ||
-- run the original insert manually. | ||
INSERT INTO config_changes SELECT NEW.* | ||
ON CONFLICT (id) | ||
DO UPDATE | ||
SET | ||
details = excluded.details, | ||
created_by = excluded.created_by, | ||
diff = excluded.diff, | ||
external_created_by = excluded.external_created_by, | ||
patches = excluded.patches, | ||
severity = excluded.severity, | ||
fingerprint = excluded.fingerprint, | ||
count = excluded.count, | ||
source = excluded.source, | ||
created_at = excluded.created_at, | ||
summary = excluded.summary; | ||
|
||
-- Prevent the original insert by returning NULL | ||
RETURN NULL; | ||
EXCEPTION | ||
WHEN unique_violation THEN | ||
IF sqlerrm LIKE '%config_changes_config_id_external_change_id_key%' THEN | ||
SELECT details, created_at FROM config_changes | ||
WHERE external_change_id = NEW.external_change_id AND config_id = NEW.config_id | ||
INTO existing_details, existing_created_at; | ||
|
||
UPDATE config_changes | ||
SET | ||
change_type = NEW.change_type, | ||
count = CASE | ||
WHEN (NEW.details IS DISTINCT FROM existing_details OR NEW.created_at IS DISTINCT FROM existing_created_at) THEN config_changes.count + 1 | ||
ELSE count | ||
END, | ||
created_at = NEW.created_at, | ||
created_by = NEW.created_by, | ||
details = NEW.details, | ||
diff = NEW.diff, | ||
external_created_by = NEW.external_created_by, | ||
patches = NEW.patches, | ||
severity = NEW.severity, | ||
source = NEW.source, | ||
summary = NEW.summary | ||
WHERE | ||
external_change_id = NEW.external_change_id | ||
AND config_id = NEW.config_id; | ||
|
||
RETURN NULL; | ||
ELSE | ||
RAISE; | ||
END IF; | ||
WHEN OTHERS THEN | ||
RAISE; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE OR REPLACE TRIGGER config_changes_insert_trigger | ||
BEFORE INSERT | ||
ON config_changes FOR EACH ROW | ||
WHEN (pg_trigger_depth() = 0) EXECUTE FUNCTION config_changes_insert_trigger(); | ||
--- |