From 7dfcdd814f60a20c1b8b4522e69c0a27c23123b5 Mon Sep 17 00:00:00 2001 From: Rogan Hamby Date: Fri, 23 Mar 2018 09:51:59 -0400 Subject: [PATCH] LP#1387722: Update MARC leader when deleting a record When merging bib records, in the Leader, position 05 - Record Status of the deleted record, the code should be changed to "d," for deleted, as it is when a record is simply deleted within the client. Rogan's squashed branch for updating record status in leader, along with pgtap test and release notes. Signed-off-by: Rogan Hamby Signed-off-by: Ben Shum --- Open-ILS/src/sql/Pg/010.schema.biblio.sql | 32 +++++++++++++++ .../Pg/t/lp1387722_record_leader_updates.pg | 39 +++++++++++++++++++ ...ma.set_record_status_in_leader_trigger.sql | 37 ++++++++++++++++++ ...der_updated_on_delete_creation_update.adoc | 7 ++++ 4 files changed, 115 insertions(+) create mode 100644 Open-ILS/src/sql/Pg/t/lp1387722_record_leader_updates.pg create mode 100644 Open-ILS/src/sql/Pg/upgrade/xxxx.schema.set_record_status_in_leader_trigger.sql create mode 100644 docs/RELEASE_NOTES_NEXT/Cataloging/leader_updated_on_delete_creation_update.adoc diff --git a/Open-ILS/src/sql/Pg/010.schema.biblio.sql b/Open-ILS/src/sql/Pg/010.schema.biblio.sql index 857307e499..7ce4490e98 100644 --- a/Open-ILS/src/sql/Pg/010.schema.biblio.sql +++ b/Open-ILS/src/sql/Pg/010.schema.biblio.sql @@ -123,4 +123,36 @@ $$ LANGUAGE PLPGSQL; CREATE TRIGGER norm_sort_label BEFORE INSERT OR UPDATE ON biblio.monograph_part FOR EACH ROW EXECUTE PROCEDURE biblio.normalize_biblio_monograph_part_sortkey(); +CREATE OR REPLACE FUNCTION biblio.set_record_status_in_leader() RETURNS TRIGGER AS $func$ +use strict; +use MARC::Record; +use MARC::Field; +use MARC::File::XML (BinaryEncoding => 'utf8'); +use Unicode::Normalize; + +my $old_marc = MARC::Record->new_from_xml($_TD->{new}{marc}); +my $old_leader = $old_marc->leader(); +my $old_status = substr($old_leader,5,1); + +my $status; +if ($_TD->{event} eq 'INSERT') {$status = 'n';} +elsif ($_TD->{event} eq 'UPDATE' && $_TD->{new}{deleted} eq 't') {$status = 'd';} +elsif ($_TD->{event} eq 'UPDATE' && $_TD->{new}{deleted} eq 'f') {$status = 'c';} + +if ($old_status ne $status) { + my $marc = MARC::Record->new_from_xml($_TD->{new}{marc}); + my $leader = $marc->leader(); + substr($leader,5,1) = $status; + $marc->leader($leader); + my $marc_xml = $marc->as_xml_record(); + $marc_xml = NFC($marc_xml); + $_TD->{new}{marc} = $marc_xml; +} + +return "MODIFY"; + +$func$ LANGUAGE PLPERLU; + +CREATE TRIGGER set_record_status_in_leader BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE biblio.set_record_status_in_leader(); + COMMIT; diff --git a/Open-ILS/src/sql/Pg/t/lp1387722_record_leader_updates.pg b/Open-ILS/src/sql/Pg/t/lp1387722_record_leader_updates.pg new file mode 100644 index 0000000000..ff845ce50a --- /dev/null +++ b/Open-ILS/src/sql/Pg/t/lp1387722_record_leader_updates.pg @@ -0,0 +1,39 @@ +BEGIN; + +SELECT plan(4); + +---------------------------------- +-- Setup Test environment and data +---------------------------------- + +-- create bib 70,000 +INSERT into biblio.record_entry (id, marc, last_xact_id) + VALUES (70000, + $$ + 00934|jm a2200241 a 450003-000374519991118131708.0971016n nyuuuu eng 4539Bartók, Béla,1881-1945.Concertos,piano,no. 1,Sz. 83(1926) Concertos,piano,no. 1,Sz. 83,(1926)Piano concerto no. 1 (1926) ; Rhapsody, op. 1 (1904)New York, NY :Vox + $$, + 'PGTAP' + ); + +----------------------------------- +-- Test biblio.set_record_status_in_leader() +----------------------------------- + +-- initially the status is undefined so now it should be 'n' +SELECT is((SELECT SUBSTR(ARRAY_TO_STRING(oils_xpath('//*[local-name()="leader"]/text()',marc),''),6,1) FROM biblio.record_entry WHERE id = 70000), 'n', 'Record is marked new.'); + +-- check to see if it sets to 'c' correctly upon editing +UPDATE biblio.record_entry SET marc = REPLACE(marc,'piano','dydraulophone') WHERE id = 70000; +SELECT is((SELECT SUBSTR(ARRAY_TO_STRING(oils_xpath('//*[local-name()="leader"]/text()',marc),''),6,1) FROM biblio.record_entry WHERE id = 70000), 'c', 'Record is marked updated.'); + +-- see if the record correctly marks as deleted 'd' +UPDATE biblio.record_entry SET deleted = TRUE WHERE id = 70000; +SELECT is((SELECT SUBSTR(ARRAY_TO_STRING(oils_xpath('//*[local-name()="leader"]/text()',marc),''),6,1) FROM biblio.record_entry WHERE id = 70000), 'd', 'Record is marked deleted.'); + +-- see if the record is correctly set to 'c' when undeleted +UPDATE biblio.record_entry SET deleted = FALSE WHERE id = 70000; +SELECT is((SELECT SUBSTR(ARRAY_TO_STRING(oils_xpath('//*[local-name()="leader"]/text()',marc),''),6,1) FROM biblio.record_entry WHERE id = 70000), 'c', 'Record is marked updated.'); + +SELECT * FROM finish(); + +ROLLBACK; diff --git a/Open-ILS/src/sql/Pg/upgrade/xxxx.schema.set_record_status_in_leader_trigger.sql b/Open-ILS/src/sql/Pg/upgrade/xxxx.schema.set_record_status_in_leader_trigger.sql new file mode 100644 index 0000000000..d7f72066ef --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/xxxx.schema.set_record_status_in_leader_trigger.sql @@ -0,0 +1,37 @@ +BEGIN; + +SELECT evergreen.upgrade_deps_block_check('xxxx', :eg_version); + +CREATE OR REPLACE FUNCTION biblio.set_record_status_in_leader() RETURNS TRIGGER AS $func$ +use strict; +use MARC::Record; +use MARC::Field; +use MARC::File::XML (BinaryEncoding => 'utf8'); +use Unicode::Normalize; + +my $old_marc = MARC::Record->new_from_xml($_TD->{new}{marc}); +my $old_leader = $old_marc->leader(); +my $old_status = substr($old_leader,5,1); + +my $status; +if ($_TD->{event} eq 'INSERT') {$status = 'n';} +elsif ($_TD->{event} eq 'UPDATE' && $_TD->{new}{deleted} eq 't') {$status = 'd';} +elsif ($_TD->{event} eq 'UPDATE' && $_TD->{new}{deleted} eq 'f') {$status = 'c';} + +if ($old_status ne $status) { + my $marc = MARC::Record->new_from_xml($_TD->{new}{marc}); + my $leader = $marc->leader(); + substr($leader,5,1) = $status; + $marc->leader($leader); + my $marc_xml = $marc->as_xml_record(); + $marc_xml = NFC($marc_xml); + $_TD->{new}{marc} = $marc_xml; +} + +return "MODIFY"; + +$func$ LANGUAGE PLPERLU; + +CREATE TRIGGER set_record_status_in_leader BEFORE INSERT OR UPDATE ON biblio.record_entry FOR EACH ROW EXECUTE PROCEDURE biblio.set_record_status_in_leader(); + +COMMIT; diff --git a/docs/RELEASE_NOTES_NEXT/Cataloging/leader_updated_on_delete_creation_update.adoc b/docs/RELEASE_NOTES_NEXT/Cataloging/leader_updated_on_delete_creation_update.adoc new file mode 100644 index 0000000000..527ef7c093 --- /dev/null +++ b/docs/RELEASE_NOTES_NEXT/Cataloging/leader_updated_on_delete_creation_update.adoc @@ -0,0 +1,7 @@ +MARC Leader Updated on Bib Deletion, Creation and Update +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +There is now a trigger in place on the bibliographic record table that +will update the Leader/05 when a new record is inserted, when a record +is updated or deleted. On insert (created new or imported) it will be +marked as 'n' for new, on update (including undeletion) it will be +marked 'c' for modified and on deletion will be marked 'd' for deleted. -- 2.43.2