Based on input from Mike Rylander regarding the call number issue, biblio.extract_loc... user/mmorgan/LP1482757_reworked_extract_located_uri
authorMichele Morgan <mmorgan@noblenet.org>
Fri, 29 Jul 2016 19:32:19 +0000 (15:32 -0400)
committerMichele Morgan <mmorgan@noblenet.org>
Mon, 1 Aug 2016 18:55:27 +0000 (14:55 -0400)
reworked to:

- preserve call numbers rather than delete and readd
- better manage extracted uris by removing unused entries

Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
Open-ILS/src/sql/Pg/030.schema.metabib.sql
Open-ILS/src/sql/Pg/upgrade/xxxx.function.biblio.extract_located_uris.sql [new file with mode: 0644]

index f7aa05a..1c4d478 100644 (file)
@@ -1126,16 +1126,31 @@ DECLARE
     uri_id          INT;
     uri_cn_id       INT;
     uri_map_id      INT;
+    uri_delete      INT;
+    mapped_uris     INT[];
+    call_number_uris       INT[];
+    current_map_owner_list INT[];
 BEGIN
 
-    -- Clear any URI mappings and call numbers for this bib.
-    -- This leads to acn / auricnm inflation, but also enables
-    -- old acn/auricnm's to go away and for bibs to be deleted.
+    -- Clear any URIs and URI mappings for this bib.
+    -- Find the currently mapped URIs using the call numbers and the map, save them as the map is deleted
+
     FOR uri_cn_id IN SELECT id FROM asset.call_number WHERE record = bib_id AND label = '##URI##' AND NOT deleted LOOP
+        mapped_uris := mapped_uris || ARRAY(SELECT uri FROM asset.uri_call_number_map WHERE call_number = uri_cn_id);
         DELETE FROM asset.uri_call_number_map WHERE call_number = uri_cn_id;
-        DELETE FROM asset.call_number WHERE id = uri_cn_id;
     END LOOP;
 
+    -- Now that the map is gone, delete the saved URIs, if any were found
+
+    IF ARRAY_UPPER(mapped_URIS,1) > 0 THEN
+        FOR m IN 1 .. ARRAY_UPPER(mapped_uris,1) LOOP
+            uri_delete := mapped_uris[m];
+            DELETE FROM asset.uri WHERE id = uri_delete;
+        END LOOP;
+    END IF;
+
+    -- Get URI info from the 856 fields
+
     uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
     IF ARRAY_UPPER(uris,1) > 0 THEN
         FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
@@ -1168,29 +1183,17 @@ BEGIN
 
             IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
 
-                -- look for a matching uri
+                -- add URIs to asset.uri
                 IF uri_use IS NULL THEN
+                    INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
                     SELECT id INTO uri_id
                         FROM asset.uri
-                        WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
-                        ORDER BY id LIMIT 1;
-                    IF NOT FOUND THEN -- create one
-                        INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
-                        SELECT id INTO uri_id
-                            FROM asset.uri
-                            WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
-                    END IF;
+                        WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
                 ELSE
+                    INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
                     SELECT id INTO uri_id
                         FROM asset.uri
-                        WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
-                        ORDER BY id LIMIT 1;
-                    IF NOT FOUND THEN -- create one
-                        INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
-                        SELECT id INTO uri_id
-                            FROM asset.uri
-                            WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
-                    END IF;
+                        WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
                 END IF;
 
                 FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
@@ -1212,6 +1215,7 @@ BEGIN
                     IF NOT FOUND THEN
                         INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
                     END IF;
+                current_map_owner_list := current_map_owner_list || uri_cn_id;
 
                 END LOOP;
 
@@ -1220,6 +1224,18 @@ BEGIN
         END LOOP;
     END IF;
 
+    -- Clear call numbers for this bib that weren't mapped above.
+    FOR uri_cn_id IN
+        SELECT  id
+            FROM  asset.call_number
+            WHERE record = bib_id
+                AND label = '##URI##'
+                AND NOT deleted
+                AND NOT (id = ANY (current_map_owner_list))
+    LOOP
+        DELETE FROM asset.call_number WHERE id = uri_cn_id;
+    END LOOP;
+
     RETURN;
 END;
 $func$ LANGUAGE PLPGSQL;
diff --git a/Open-ILS/src/sql/Pg/upgrade/xxxx.function.biblio.extract_located_uris.sql b/Open-ILS/src/sql/Pg/upgrade/xxxx.function.biblio.extract_located_uris.sql
new file mode 100644 (file)
index 0000000..bf0dfd9
--- /dev/null
@@ -0,0 +1,129 @@
+BEGIN;
+
+CREATE OR REPLACE FUNCTION biblio.extract_located_uris( bib_id BIGINT, marcxml TEXT, editor_id INT ) RETURNS VOID AS $func$
+DECLARE
+    uris            TEXT[];
+    uri_xml         TEXT;
+    uri_label       TEXT;
+    uri_href        TEXT;
+    uri_use         TEXT;
+    uri_owner_list  TEXT[];
+    uri_owner       TEXT;
+    uri_owner_id    INT;
+    uri_id          INT;
+    uri_cn_id       INT;
+    uri_map_id      INT;
+    uri_delete      INT;
+    mapped_uris     INT[];
+    call_number_uris       INT[];
+    current_map_owner_list INT[];
+BEGIN
+
+    -- Clear any URIs and URI mappings for this bib.
+    -- Find the currently mapped URIs using the call numbers and the map, save them as the map is deleted
+
+    FOR uri_cn_id IN SELECT id FROM asset.call_number WHERE record = bib_id AND label = '##URI##' AND NOT deleted LOOP
+        mapped_uris := mapped_uris || ARRAY(SELECT uri FROM asset.uri_call_number_map WHERE call_number = uri_cn_id);
+        DELETE FROM asset.uri_call_number_map WHERE call_number = uri_cn_id;
+    END LOOP;
+
+    -- Now that the map is gone, delete the saved URIs, if any were found
+
+    IF ARRAY_UPPER(mapped_URIS,1) > 0 THEN
+        FOR m IN 1 .. ARRAY_UPPER(mapped_uris,1) LOOP
+            uri_delete := mapped_uris[m];
+            DELETE FROM asset.uri WHERE id = uri_delete;
+        END LOOP;
+    END IF;
+
+    -- Get URI info from the 856 fields
+
+    uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
+    IF ARRAY_UPPER(uris,1) > 0 THEN
+        FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
+            -- First we pull info out of the 856
+            uri_xml     := uris[i];
+
+            uri_href    := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
+            uri_label   := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
+            uri_use     := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
+
+            IF uri_label IS NULL THEN
+                uri_label := uri_href;
+            END IF;
+            CONTINUE WHEN uri_href IS NULL;
+
+            -- Get the distinct list of libraries wanting to use 
+            SELECT  ARRAY_AGG(
+                        DISTINCT REGEXP_REPLACE(
+                            x,
+                            $re$^.*?\((\w+)\).*$$re$,
+                            E'\\1'
+                        )
+                    ) INTO uri_owner_list
+              FROM  UNNEST(
+                        oils_xpath(
+                            '//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
+                            uri_xml
+                        )
+                    )x;
+
+            IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
+
+                -- add URIs to asset.uri
+                IF uri_use IS NULL THEN
+                    INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
+                    SELECT id INTO uri_id
+                        FROM asset.uri
+                        WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
+                ELSE
+                    INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
+                    SELECT id INTO uri_id
+                        FROM asset.uri
+                        WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
+                END IF;
+
+                FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
+                    uri_owner := uri_owner_list[j];
+
+                    SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = uri_owner;
+                    CONTINUE WHEN NOT FOUND;
+
+                    -- we need a call number to link through
+                    SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
+                    IF NOT FOUND THEN
+                        INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
+                            VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
+                        SELECT id INTO uri_cn_id FROM asset.call_number WHERE owning_lib = uri_owner_id AND record = bib_id AND label = '##URI##' AND NOT deleted;
+                    END IF;
+
+                    -- now, link them if they're not already
+                    SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
+                    IF NOT FOUND THEN
+                        INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
+                    END IF;
+                current_map_owner_list := current_map_owner_list || uri_cn_id;
+
+                END LOOP;
+
+            END IF;
+
+        END LOOP;
+    END IF;
+
+    -- Clear call numbers for this bib that weren't mapped above.
+    FOR uri_cn_id IN
+        SELECT  id
+            FROM  asset.call_number
+            WHERE record = bib_id
+                AND label = '##URI##'
+                AND NOT deleted
+                AND NOT (id = ANY (current_map_owner_list))
+    LOOP
+        DELETE FROM asset.call_number WHERE id = uri_cn_id;
+    END LOOP;
+
+    RETURN;
+END;
+
+COMMIT;
\ No newline at end of file