From 00ccce0baba387bbe79dafd1d8e5927e043e0a84 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont <nicolas@dandrimont.eu> Date: Thu, 16 Feb 2017 13:21:14 +0100 Subject: [PATCH] archiver: fix brown paper bag bug for object counter --- sql/swh-archiver-schema.sql | 6 ++--- sql/upgrades/008.sql | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 sql/upgrades/008.sql diff --git a/sql/swh-archiver-schema.sql b/sql/swh-archiver-schema.sql index d6f7f16..aac607e 100644 --- a/sql/swh-archiver-schema.sql +++ b/sql/swh-archiver-schema.sql @@ -11,7 +11,7 @@ create table dbversion comment on table dbversion is 'Schema update tracking'; INSERT INTO dbversion(version, release, description) -VALUES(7, now(), 'Work In Progress'); +VALUES(8, now(), 'Work In Progress'); CREATE TABLE archive ( id text PRIMARY KEY @@ -74,7 +74,7 @@ CREATE TRIGGER update_num_present EXECUTE PROCEDURE update_num_present(); -- keep the content_archive_counts updated -CREATE FUNCTION update_content_archive_counts() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ +CREATE OR REPLACE FUNCTION update_content_archive_counts() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ DECLARE content_id sha1; content_bucket bucket; @@ -104,7 +104,7 @@ CREATE FUNCTION update_content_archive_counts() RETURNS TRIGGER LANGUAGE PLPGSQL from jsonb_each(old_row.copies) o full outer join lateral jsonb_each(new_row.copies) n on o.key = n.key LOOP -- the count didn't change - CONTINUE WHEN copies.old_status is distinct from copies.new_status OR + CONTINUE WHEN copies.old_status is not distinct from copies.new_status OR (copies.old_status != 'present' AND copies.new_status != 'present'); update content_archive_counts cac diff --git a/sql/upgrades/008.sql b/sql/upgrades/008.sql new file mode 100644 index 0000000..6527aca --- /dev/null +++ b/sql/upgrades/008.sql @@ -0,0 +1,49 @@ +-- SWH DB schema upgrade +-- from_version: 7 +-- to_version: 8 +-- description: Fix silly bug in update_content_archive_counts + +INSERT INTO dbversion(version, release, description) +VALUES(8, now(), 'Work In Progress'); + +-- keep the content_archive_counts updated +CREATE OR REPLACE FUNCTION update_content_archive_counts() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ + DECLARE + content_id sha1; + content_bucket bucket; + copies record; + old_row content_archive; + new_row content_archive; + BEGIN + -- default values for old or new row depending on trigger type + if tg_op = 'INSERT' then + old_row := (null::sha1, '{}'::jsonb, 0); + else + old_row := old; + end if; + if tg_op = 'DELETE' then + new_row := (null::sha1, '{}'::jsonb, 0); + else + new_row := new; + end if; + + -- get the content bucket + content_id := coalesce(old_row.content_id, new_row.content_id); + content_bucket := substring(content_id from 19)::bucket; + + -- compare copies present in old and new row for each archive type + FOR copies IN + select coalesce(o.key, n.key) as archive, o.value->>'status' as old_status, n.value->>'status' as new_status + from jsonb_each(old_row.copies) o full outer join lateral jsonb_each(new_row.copies) n on o.key = n.key + LOOP + -- the count didn't change + CONTINUE WHEN copies.old_status is not distinct from copies.new_status OR + (copies.old_status != 'present' AND copies.new_status != 'present'); + + update content_archive_counts cac + set count = count + (case when copies.old_status = 'present' then -1 else 1 end) + where archive = copies.archive and bucket = content_bucket; + END LOOP; + return null; + END; +$$; -- GitLab