Be more prepared for malformed serial holding code data in upgrade scripts
authorLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Fri, 11 May 2012 19:59:37 +0000 (15:59 -0400)
committerLebbeous Fogle-Weekley <lebbeous@esilibrary.com>
Fri, 11 May 2012 20:02:13 +0000 (16:02 -0400)
Signed-off-by: Lebbeous Fogle-Weekley <lebbeous@esilibrary.com>

Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/upgrade/0710.schema.stricter-could-be-holding-code.sql [new file with mode: 0644]
Open-ILS/src/sql/Pg/version-upgrade/2.1-2.2-upgrade-db.sql

index 2bf618d..eae6810 100644 (file)
@@ -87,7 +87,7 @@ CREATE TRIGGER no_overlapping_deps
     BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
     FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
 
-INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0709', :eg_version); -- berick/senator
+INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0710', :eg_version); -- senator
 
 CREATE TABLE config.bib_source (
        id              SERIAL  PRIMARY KEY,
diff --git a/Open-ILS/src/sql/Pg/upgrade/0710.schema.stricter-could-be-holding-code.sql b/Open-ILS/src/sql/Pg/upgrade/0710.schema.stricter-could-be-holding-code.sql
new file mode 100644 (file)
index 0000000..5736a4f
--- /dev/null
@@ -0,0 +1,27 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('0710', :eg_version);
+
+CREATE OR REPLACE FUNCTION evergreen.could_be_serial_holding_code(TEXT) RETURNS BOOL AS $$
+    use JSON::XS;
+    use MARC::Field;
+
+    eval {
+        my $holding_code = (new JSON::XS)->decode(shift);
+        new MARC::Field('999', @$holding_code);
+    };
+    return $@ ? 0 : 1;
+$$ LANGUAGE PLPERLU;
+
+-- This throws away data, but only data that causes breakage anyway.
+UPDATE serial.issuance
+    SET holding_code = NULL
+    WHERE NOT could_be_serial_holding_code(holding_code);
+
+ALTER TABLE serial.issuance
+    DROP CONSTRAINT IF EXISTS issuance_holding_code_check;
+
+ALTER TABLE serial.issuance
+    ADD CHECK (holding_code IS NULL OR could_be_serial_holding_code(holding_code));
+
+COMMIT;
index 59a59af..6d1a138 100644 (file)
@@ -11698,14 +11698,29 @@ INSERT INTO config.org_unit_setting_type ( name, label, description, datatype, g
 
 SELECT evergreen.upgrade_deps_block_check('0700', :eg_version);
 SELECT evergreen.upgrade_deps_block_check('0706', :eg_version);
+SELECT evergreen.upgrade_deps_block_check('0710', :eg_version);
+
+CREATE OR REPLACE FUNCTION evergreen.could_be_serial_holding_code(TEXT) RETURNS BOOL AS $$
+    use JSON::XS;
+    use MARC::Field;
+
+    eval {
+        my $holding_code = (new JSON::XS)->decode(shift);
+        new MARC::Field('999', @$holding_code);
+    };  
+    return $@ ? 0 : 1;
+$$ LANGUAGE PLPERLU;
 
 -- This throws away data, but only data that causes breakage anyway.
-UPDATE serial.issuance SET holding_code = NULL WHERE NOT is_json(holding_code);
+UPDATE serial.issuance SET holding_code = NULL WHERE NOT could_be_serial_holding_code(holding_code);
 
 -- If we don't do this, we have unprocessed triggers and we can't alter the table
 SET CONSTRAINTS serial.issuance_caption_and_pattern_fkey IMMEDIATE;
 
-ALTER TABLE serial.issuance ADD CHECK (holding_code IS NULL OR is_json(holding_code));
+ALTER TABLE serial.issuance
+    DROP CONSTRAINT IF EXISTS issuance_holding_code_check;
+
+ALTER TABLE serial.issuance ADD CHECK (holding_code IS NULL OR could_be_serial_holding_code(holding_code));
 
 INSERT INTO config.internal_flag (name, value, enabled) VALUES (
     'serial.rematerialize_on_same_holding_code', NULL, FALSE