Files

93 lines
2.9 KiB
SQL
Raw Permalink Normal View History

{{ define "count_trigger" -}}
-- In case the old trigger exists, drop it to prevent duplicated counts.
DROP TRIGGER IF EXISTS count_{{ .Resource }} ON {{ .Table }};
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_insert
AFTER INSERT
ON {{ .Table }}
FOR EACH ROW
-- Only count if the conditions are met in the newly added row.
{{if .Conditions}}WHEN ({{.Conditions.ToSQL "NEW" true}}){{end}}
EXECUTE FUNCTION projections.count_resource(
'{{ .ParentType }}',
'{{ .InstanceIDColumn }}',
'{{ .ParentIDColumn }}',
'{{ .Resource }}'
);
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_delete
AFTER DELETE
ON {{ .Table }}
FOR EACH ROW
-- Only count down if the conditions were met in the old / deleted row.
{{if .Conditions}}WHEN ({{.Conditions.ToSQL "OLD" true}}){{end}}
EXECUTE FUNCTION projections.count_resource(
'{{ .ParentType }}',
'{{ .InstanceIDColumn }}',
'{{ .ParentIDColumn }}',
'{{ .Resource }}'
);
{{if .TrackChange}}
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_update_up
AFTER UPDATE
ON {{ .Table }}
FOR EACH ROW
-- Only count up if the conditions are met in the new state, but were not in the old.
WHEN ({{.Conditions.ToSQL "NEW" true}} AND {{.Conditions.ToSQL "OLD" false}})
EXECUTE FUNCTION projections.count_resource(
'{{ .ParentType }}',
'{{ .InstanceIDColumn }}',
'{{ .ParentIDColumn }}',
'{{ .Resource }}',
'UP'
);
CREATE OR REPLACE TRIGGER count_{{ .Resource }}_update_down
AFTER UPDATE
ON {{ .Table }}
FOR EACH ROW
-- Only count down if the conditions are not met in the new state, but were in the old.
WHEN ({{.Conditions.ToSQL "NEW" false}} AND {{.Conditions.ToSQL "OLD" true}})
EXECUTE FUNCTION projections.count_resource(
'{{ .ParentType }}',
'{{ .InstanceIDColumn }}',
'{{ .ParentIDColumn }}',
'{{ .Resource }}',
'DOWN'
);
{{end}}
CREATE OR REPLACE TRIGGER truncate_{{ .Resource }}_counts
AFTER TRUNCATE
ON {{ .Table }}
FOR EACH STATEMENT
EXECUTE FUNCTION projections.delete_table_counts();
-- Prevent inserts and deletes while we populate the counts.
LOCK TABLE {{ .Table }} IN SHARE MODE;
-- Populate the resource counts for the existing data in the table.
INSERT INTO projections.resource_counts(
instance_id,
table_name,
parent_type,
parent_id,
resource_name,
amount
)
SELECT
{{ .InstanceIDColumn }},
'{{ .Table }}',
'{{ .ParentType }}',
{{ .ParentIDColumn }},
'{{ .Resource }}',
COUNT(*) AS amount
FROM {{ .Table }}
{{if .Conditions}}WHERE {{.Conditions.ToSQL .Table true}}{{end}}
GROUP BY ({{ .InstanceIDColumn }}, {{ .ParentIDColumn }})
ON CONFLICT (instance_id, table_name, parent_type, parent_id, resource_name) DO
UPDATE SET updated_at = now(), amount = EXCLUDED.amount;
{{- end -}}