--- /dev/null
+-- Only consider main entry headings for bib overlay
+
+BEGIN;
+
+-- 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;
+
+COMMIT;