From c86c856762175a83fd8889b1ddcd6fbe624f2014 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 16 Jan 2013 15:18:57 -0500 Subject: [PATCH] Forward-porting 2.3.2 -> 2.3.3 DB upgrade Signed-off-by: Bill Erickson Signed-off-by: Lebbeous Fogle-Weekley --- .../Pg/version-upgrade/2.3.2-2.3.3-upgrade-db.sql | 314 +++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 Open-ILS/src/sql/Pg/version-upgrade/2.3.2-2.3.3-upgrade-db.sql diff --git a/Open-ILS/src/sql/Pg/version-upgrade/2.3.2-2.3.3-upgrade-db.sql b/Open-ILS/src/sql/Pg/version-upgrade/2.3.2-2.3.3-upgrade-db.sql new file mode 100644 index 0000000000..1773eda700 --- /dev/null +++ b/Open-ILS/src/sql/Pg/version-upgrade/2.3.2-2.3.3-upgrade-db.sql @@ -0,0 +1,314 @@ +--Upgrade Script for 2.3.2 to 2.3.3 +\set eg_version '''2.3.3''' +BEGIN; +INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.3.3', :eg_version); +-- Use MARC relator codes (710 subfield 4) to index corporate authors, along +-- with the existing relator text (710 subfield e) + + +-- check whether patch can be applied +SELECT evergreen.upgrade_deps_block_check('0749', :eg_version); + +UPDATE config.metabib_field + SET xpath = $$//mods32:mods/mods32:name[@type='corporate' + and (mods32:role/mods32:roleTerm[text()='creator'] + or mods32:role/mods32:roleTerm[text()='aut'] + or mods32:role/mods32:roleTerm[text()='cre'] + )]$$ + WHERE id = 7 +; + +SELECT metabib.reingest_metabib_field_entries(record, TRUE, TRUE, FALSE) + FROM metabib.full_rec + WHERE tag = '710' + AND subfield = '4' + AND value IN ('cre', 'aut') +; + +-- Only consider main entry headings for bib overlay + + +-- check whether patch can be applied +SELECT evergreen.upgrade_deps_block_check('0750', :eg_version); + + +-- Function to generate an ephemeral overlay template from an authority record +CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$ +DECLARE + cset INT; + main_entry authority.control_set_authority_field%ROWTYPE; + bib_field authority.control_set_bib_field%ROWTYPE; + auth_id INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT; + replace_data XML[] DEFAULT '{}'::XML[]; + replace_rules TEXT[] DEFAULT '{}'::TEXT[]; + auth_field XML[]; +BEGIN + IF auth_id IS NULL THEN + RETURN NULL; + END IF; + + -- Default to the LoC controll set + SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id; + + -- if none, make a best guess + IF cset IS NULL THEN + SELECT control_set INTO cset + FROM authority.control_set_authority_field + WHERE tag IN ( + SELECT UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[]) + FROM authority.record_entry + WHERE id = auth_id + ) + LIMIT 1; + END IF; + + -- if STILL none, no-op change + IF cset IS NULL THEN + RETURN XMLELEMENT( + name record, + XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns), + XMLELEMENT( name leader, '00881nam a2200193 4500'), + XMLELEMENT( + name datafield, + XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2), + XMLELEMENT( + name subfield, + XMLATTRIBUTES('d' AS code), + '901c' + ) + ) + )::TEXT; + END IF; + + FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP + auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML); + IF ARRAY_LENGTH(auth_field,1) > 0 THEN + FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP + replace_data := replace_data || XMLELEMENT( name datafield, XMLATTRIBUTES(bib_field.tag AS tag), XPATH('//*[local-name()="subfield"]',auth_field[1])::XML[]); + replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' ); + END LOOP; + EXIT; + END IF; + END LOOP; + + RETURN XMLELEMENT( + name record, + XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns), + XMLELEMENT( name leader, '00881nam a2200193 4500'), + replace_data, + XMLELEMENT( + name datafield, + XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2), + XMLELEMENT( + name subfield, + XMLATTRIBUTES('r' AS code), + ARRAY_TO_STRING(replace_rules,',') + ) + ) + )::TEXT; +END; +$f$ STABLE LANGUAGE PLPGSQL; + +-- Change the two argument form of vandelay.merge_record_xml to +-- prevent bibliographic record destruction when there is nothing to +-- do. + + +CREATE OR REPLACE FUNCTION vandelay.merge_record_xml ( target_marc TEXT, template_marc TEXT ) RETURNS TEXT AS $$ +DECLARE + dyn_profile vandelay.compile_profile%ROWTYPE; + replace_rule TEXT; + tmp_marc TEXT; + trgt_marc TEXT; + tmpl_marc TEXT; + match_count INT; +BEGIN + + IF target_marc IS NULL OR template_marc IS NULL THEN + -- RAISE NOTICE 'no marc for target or template record'; + RETURN NULL; + END IF; + + dyn_profile := vandelay.compile_profile( template_marc ); + + IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN + -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule; + RETURN NULL; + END IF; + + IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' THEN + --Since we have nothing to do, just return what we were given. + RETURN target_marc; + ELSIF dyn_profile.replace_rule <> '' THEN + trgt_marc = target_marc; + tmpl_marc = template_marc; + replace_rule = dyn_profile.replace_rule; + ELSE + tmp_marc = target_marc; + trgt_marc = template_marc; + tmpl_marc = tmp_marc; + replace_rule = dyn_profile.preserve_rule; + END IF; + + RETURN vandelay.merge_record_xml( trgt_marc, tmpl_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule ); + +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION vandelay.template_overlay_bib_record ( v_marc TEXT, eg_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$ +DECLARE + merge_profile vandelay.merge_profile%ROWTYPE; + dyn_profile vandelay.compile_profile%ROWTYPE; + editor_string TEXT; + editor_id INT; + source_marc TEXT; + target_marc TEXT; + eg_marc TEXT; + replace_rule TEXT; + match_count INT; +BEGIN + + SELECT b.marc INTO eg_marc + FROM biblio.record_entry b + WHERE b.id = eg_id + LIMIT 1; + + IF eg_marc IS NULL OR v_marc IS NULL THEN + -- RAISE NOTICE 'no marc for template or bib record'; + RETURN FALSE; + END IF; + + dyn_profile := vandelay.compile_profile( v_marc ); + + IF merge_profile_id IS NOT NULL THEN + SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id; + IF FOUND THEN + dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ','); + dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ','); + dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ','); + dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ','); + END IF; + END IF; + + IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN + -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule; + RETURN FALSE; + END IF; + + IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' AND dyn_profile.strip_rule = '' THEN + --Since we have nothing to do, just return a NOOP "we did it" + RETURN TRUE; + ELSIF dyn_profile.replace_rule <> '' THEN + source_marc = v_marc; + target_marc = eg_marc; + replace_rule = dyn_profile.replace_rule; + ELSE + source_marc = eg_marc; + target_marc = v_marc; + replace_rule = dyn_profile.preserve_rule; + END IF; + + UPDATE biblio.record_entry + SET marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule ) + WHERE id = eg_id; + + IF NOT FOUND THEN + -- RAISE NOTICE 'update of biblio.record_entry failed'; + RETURN FALSE; + END IF; + + RETURN TRUE; + +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION vandelay.overlay_authority_record ( import_id BIGINT, eg_id BIGINT, merge_profile_id INT ) RETURNS BOOL AS $$ +DECLARE + merge_profile vandelay.merge_profile%ROWTYPE; + dyn_profile vandelay.compile_profile%ROWTYPE; + source_marc TEXT; + target_marc TEXT; + eg_marc TEXT; + v_marc TEXT; + replace_rule TEXT; + match_count INT; +BEGIN + + SELECT b.marc INTO eg_marc + FROM authority.record_entry b + JOIN vandelay.authority_match m ON (m.eg_record = b.id AND m.queued_record = import_id) + LIMIT 1; + + SELECT q.marc INTO v_marc + FROM vandelay.queued_record q + JOIN vandelay.authority_match m ON (m.queued_record = q.id AND q.id = import_id) + LIMIT 1; + + IF eg_marc IS NULL OR v_marc IS NULL THEN + -- RAISE NOTICE 'no marc for vandelay or authority record'; + RETURN FALSE; + END IF; + + dyn_profile := vandelay.compile_profile( v_marc ); + + IF merge_profile_id IS NOT NULL THEN + SELECT * INTO merge_profile FROM vandelay.merge_profile WHERE id = merge_profile_id; + IF FOUND THEN + dyn_profile.add_rule := BTRIM( dyn_profile.add_rule || ',' || COALESCE(merge_profile.add_spec,''), ','); + dyn_profile.strip_rule := BTRIM( dyn_profile.strip_rule || ',' || COALESCE(merge_profile.strip_spec,''), ','); + dyn_profile.replace_rule := BTRIM( dyn_profile.replace_rule || ',' || COALESCE(merge_profile.replace_spec,''), ','); + dyn_profile.preserve_rule := BTRIM( dyn_profile.preserve_rule || ',' || COALESCE(merge_profile.preserve_spec,''), ','); + END IF; + END IF; + + IF dyn_profile.replace_rule <> '' AND dyn_profile.preserve_rule <> '' THEN + -- RAISE NOTICE 'both replace [%] and preserve [%] specified', dyn_profile.replace_rule, dyn_profile.preserve_rule; + RETURN FALSE; + END IF; + + IF dyn_profile.replace_rule = '' AND dyn_profile.preserve_rule = '' AND dyn_profile.add_rule = '' AND dyn_profile.strip_rule = '' THEN + --Since we have nothing to do, just return a NOOP "we did it" + RETURN TRUE; + ELSIF dyn_profile.replace_rule <> '' THEN + source_marc = v_marc; + target_marc = eg_marc; + replace_rule = dyn_profile.replace_rule; + ELSE + source_marc = eg_marc; + target_marc = v_marc; + replace_rule = dyn_profile.preserve_rule; + END IF; + + UPDATE authority.record_entry + SET marc = vandelay.merge_record_xml( target_marc, source_marc, dyn_profile.add_rule, replace_rule, dyn_profile.strip_rule ) + WHERE id = eg_id; + + IF FOUND THEN + UPDATE vandelay.queued_authority_record + SET imported_as = eg_id, + import_time = NOW() + WHERE id = import_id; + RETURN TRUE; + END IF; + + -- RAISE NOTICE 'update of authority.record_entry failed'; + + RETURN FALSE; + +END; +$$ LANGUAGE PLPGSQL; + + +SELECT evergreen.upgrade_deps_block_check('0751', :eg_version); + +INSERT INTO acq.cancel_reason (keep_debits, id, org_unit, label, description) + VALUES ( + 'f', + 1007, + 1, + 'Not accepted', + 'This line item is not accepted by the seller.' + ); + + +COMMIT; -- 2.11.0