From c19f5d34ef53b4543f39ccb0b4b2b3b234c1e9fc Mon Sep 17 00:00:00 2001 From: dbs Date: Thu, 15 Jul 2010 19:22:19 +0000 Subject: [PATCH] Protect authority records from real deletion and add a "merge authorities" function git-svn-id: svn://svn.open-ils.org/ILS/trunk@16942 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/sql/Pg/002.schema.config.sql | 2 +- Open-ILS/src/sql/Pg/011.schema.authority.sql | 41 +++++++++++++++++++ .../Pg/upgrade/0339.schema.authority_records.sql | 46 ++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/0339.schema.authority_records.sql diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql index 26667491d..7e6b3f106 100644 --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@ -68,7 +68,7 @@ CREATE TABLE config.upgrade_log ( install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); -INSERT INTO config.upgrade_log (version) VALUES ('0338'); -- dbs +INSERT INTO config.upgrade_log (version) VALUES ('0339'); -- dbs CREATE TABLE config.bib_source ( id SERIAL PRIMARY KEY, diff --git a/Open-ILS/src/sql/Pg/011.schema.authority.sql b/Open-ILS/src/sql/Pg/011.schema.authority.sql index 4c99321c0..ebbee0f58 100644 --- a/Open-ILS/src/sql/Pg/011.schema.authority.sql +++ b/Open-ILS/src/sql/Pg/011.schema.authority.sql @@ -1,7 +1,9 @@ /* * Copyright (C) 2004-2008 Georgia Public Library Service * Copyright (C) 2008 Equinox Software, Inc. + * Copyright (C) 2010 Laurentian University * Mike Rylander + * Dan Scott * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -41,6 +43,7 @@ CREATE UNIQUE INDEX authority_record_unique_tcn ON authority.record_entry (arn_s CREATE TRIGGER a_marcxml_is_well_formed BEFORE INSERT OR UPDATE ON authority.record_entry FOR EACH ROW EXECUTE PROCEDURE biblio.check_marcxml_well_formed(); CREATE TRIGGER b_maintain_901 BEFORE INSERT OR UPDATE ON authority.record_entry FOR EACH ROW EXECUTE PROCEDURE maintain_901(); CREATE TRIGGER c_maintain_control_numbers BEFORE INSERT OR UPDATE ON authority.record_entry FOR EACH ROW EXECUTE PROCEDURE maintain_control_numbers(); +CREATE RULE protect_authority_rec_delete AS ON DELETE TO authority.record_entry DO INSTEAD (UPDATE authority.record_entry SET deleted = TRUE WHERE OLD.id = authority.record_entry.id); CREATE TABLE authority.bib_linking ( id BIGSERIAL PRIMARY KEY, @@ -192,5 +195,43 @@ CREATE OR REPLACE FUNCTION authority.generate_overlay_template ( TEXT ) RETURNS SELECT authority.generate_overlay_template( $1, NULL ); $func$ LANGUAGE SQL; +CREATE OR REPLACE FUNCTION authority.merge_records ( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$ +DECLARE + moved_objects INT := 0; + bib_id INT := 0; + bib_rec biblio.record_entry%ROWTYPE; + auth_link authority.bib_linking%ROWTYPE; +BEGIN + + -- 1. Make source_record MARC a copy of the target_record to get auto-sync in linked bib records + UPDATE authority.record_entry + SET marc = ( + SELECT marc + FROM authority.record_entry + WHERE id = target_record + ) + WHERE id = source_record; + + -- 2. Update all bib records with the ID from target_record in their $0 + FOR bib_rec IN SELECT bre.* FROM biblio.record_entry bre + INNER JOIN authority.bib_linking abl ON abl.bib = bre.id + WHERE abl.authority = target_record LOOP + + UPDATE biblio.record_entry + SET marc = REGEXP_REPLACE(marc, + E'([^<]*?\\))' || source_record || '<', + E'\\1' || target_record || '<', 'g') + WHERE id = bib_rec.id; + + moved_objects := moved_objects + 1; + END LOOP; + + -- 3. "Delete" source_record + DELETE FROM authority.record_entry + WHERE id = source_record; + + RETURN moved_objects; +END; +$func$ LANGUAGE plpgsql; COMMIT; diff --git a/Open-ILS/src/sql/Pg/upgrade/0339.schema.authority_records.sql b/Open-ILS/src/sql/Pg/upgrade/0339.schema.authority_records.sql new file mode 100644 index 000000000..d44e96e57 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0339.schema.authority_records.sql @@ -0,0 +1,46 @@ +BEGIN; + +INSERT INTO config.upgrade_log (version) VALUES ('0339'); -- dbs + +CREATE RULE protect_authority_rec_delete AS ON DELETE TO authority.record_entry DO INSTEAD (UPDATE authority.record_entry SET deleted = TRUE WHERE OLD.id = authority.record_entry.id); + +CREATE OR REPLACE FUNCTION authority.merge_records ( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$ +DECLARE + moved_objects INT := 0; + bib_id INT := 0; + bib_rec biblio.record_entry%ROWTYPE; + auth_link authority.bib_linking%ROWTYPE; +BEGIN + + -- 1. Make source_record MARC a copy of the target_record to get auto-sync in linked bib records + UPDATE authority.record_entry + SET marc = ( + SELECT marc + FROM authority.record_entry + WHERE id = target_record + ) + WHERE id = source_record; + + -- 2. Update all bib records with the ID from target_record in their $0 + FOR bib_rec IN SELECT bre.* FROM biblio.record_entry bre + INNER JOIN authority.bib_linking abl ON abl.bib = bre.id + WHERE abl.authority = target_record LOOP + + UPDATE biblio.record_entry + SET marc = REGEXP_REPLACE(marc, + E'([^<]*?\\))' || source_record || '<', + E'\\1' || target_record || '<', 'g') + WHERE id = bib_rec.id; + + moved_objects := moved_objects + 1; + END LOOP; + + -- 3. "Delete" source_record + DELETE FROM authority.record_entry + WHERE id = source_record; + + RETURN moved_objects; +END; +$func$ LANGUAGE plpgsql; + +COMMIT; -- 2.11.0