LP#1312945: authority.calculate_authority_linking and multiple linked tags
authorSrey Seng <sreyseng@gmail.com>
Wed, 30 Apr 2014 22:20:17 +0000 (15:20 -0700)
committerGalen Charlton <gmc@esilibrary.com>
Tue, 20 May 2014 22:53:41 +0000 (15:53 -0700)
The function "authority.calculate_authority_linking" was not able to deal with
situations where there are multiple marc tags that are linkable. The function
only process the first tag that contains a linking_subfield and returns that
to be inserted into the authority_linking table, even when there are more than
one of the same tag with linking_subfield.

Added an additional loop to loop through each tag, for situations where there are
multiples of each tag.

Signed-off-by: Srey Seng <sreyseng@gmail.com>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/src/sql/Pg/upgrade/XXXX.function.authority.calculate_authority_linking.sql [new file with mode: 0644]

diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.authority.calculate_authority_linking.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.authority.calculate_authority_linking.sql
new file mode 100644 (file)
index 0000000..4347aaa
--- /dev/null
@@ -0,0 +1,68 @@
+BEGIN;
+
+SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+CREATE OR REPLACE FUNCTION authority.calculate_authority_linking(
+    rec_id BIGINT, rec_control_set INT, rec_marc_xml XML
+) RETURNS SETOF authority.authority_linking AS $func$
+DECLARE
+    acsaf       authority.control_set_authority_field%ROWTYPE;
+    link        TEXT;
+    aal         authority.authority_linking%ROWTYPE;
+BEGIN
+    IF rec_control_set IS NULL THEN
+        -- No control_set on record?  Guess at one
+        SELECT control_set INTO rec_control_set
+            FROM authority.control_set_authority_field
+            WHERE tag IN (
+                SELECT UNNEST(
+                    XPATH('//*[starts-with(@tag,"1")]/@tag',rec_marc_xml)::TEXT[]
+                )
+            ) LIMIT 1;
+
+        IF NOT FOUND THEN
+            RAISE WARNING 'Could not even guess at control set for authority record %', rec_id;
+            RETURN;
+        END IF;
+    END IF;
+
+    aal.source := rec_id;
+
+    FOR acsaf IN
+        SELECT * FROM authority.control_set_authority_field
+        WHERE control_set = rec_control_set
+            AND linking_subfield IS NOT NULL
+            AND main_entry IS NOT NULL
+    LOOP
+        -- Loop over the trailing-number contents of all linking subfields
+        FOR link IN
+            SELECT  SUBSTRING( x::TEXT, '\d+$' )
+              FROM  UNNEST(
+                        XPATH(
+                            '//*[@tag="'
+                                || acsaf.tag
+                                || '"]/*[@code="'
+                                || acsaf.linking_subfield
+                                || '"]/text()',
+                            rec_marc_xml
+                        )
+                    ) x
+        LOOP
+
+            -- Ignore links that are null, malformed, circular, or point to
+            -- non-existent authority records.
+            IF link IS NOT NULL AND link::BIGINT <> rec_id THEN
+                PERFORM * FROM authority.record_entry WHERE id = link::BIGINT;
+                IF FOUND THEN
+                    aal.target := link::BIGINT;
+                    aal.field := acsaf.id;
+                    RETURN NEXT aal;
+                END IF;
+            END IF;
+        END LOOP;
+    END LOOP;
+END;
+$func$ LANGUAGE PLPGSQL;
+
+COMMIT;
+