]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/XXXX.function.biblio.extract_located_uris.sql
LP#1482757: Speed Up the Delete of Orphaned URIs in upgrade script
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.function.biblio.extract_located_uris.sql
1 BEGIN;
2
3 CREATE OR REPLACE FUNCTION biblio.extract_located_uris( bib_id BIGINT, marcxml TEXT, editor_id INT ) RETURNS VOID AS $func$
4 DECLARE
5     uris            TEXT[];
6     uri_xml         TEXT;
7     uri_label       TEXT;
8     uri_href        TEXT;
9     uri_use         TEXT;
10     uri_owner_list  TEXT[];
11     uri_owner       TEXT;
12     uri_owner_id    INT;
13     uri_id          INT;
14     uri_cn_id       INT;
15     uri_map_id      INT;
16     current_uri     INT;
17     current_map     INT;
18     uri_map_count   INT;
19     current_uri_map_list    INT[];
20     current_map_owner_list  INT[];
21
22 BEGIN
23
24     uris := oils_xpath('//*[@tag="856" and (@ind1="4" or @ind1="1") and (@ind2="0" or @ind2="1")]',marcxml);
25     IF ARRAY_UPPER(uris,1) > 0 THEN
26         FOR i IN 1 .. ARRAY_UPPER(uris, 1) LOOP
27             -- First we pull info out of the 856
28             uri_xml     := uris[i];
29
30             uri_href    := (oils_xpath('//*[@code="u"]/text()',uri_xml))[1];
31             uri_label   := (oils_xpath('//*[@code="y"]/text()|//*[@code="3"]/text()',uri_xml))[1];
32             uri_use     := (oils_xpath('//*[@code="z"]/text()|//*[@code="2"]/text()|//*[@code="n"]/text()',uri_xml))[1];
33
34             IF uri_label IS NULL THEN
35                 uri_label := uri_href;
36             END IF;
37             CONTINUE WHEN uri_href IS NULL;
38
39             -- Get the distinct list of libraries wanting to use 
40             SELECT  ARRAY_AGG(
41                         DISTINCT REGEXP_REPLACE(
42                             x,
43                             $re$^.*?\((\w+)\).*$$re$,
44                             E'\\1'
45                         )
46                     ) INTO uri_owner_list
47               FROM  UNNEST(
48                         oils_xpath(
49                             '//*[@code="9"]/text()|//*[@code="w"]/text()|//*[@code="n"]/text()',
50                             uri_xml
51                         )
52                     )x;
53
54             IF ARRAY_UPPER(uri_owner_list,1) > 0 THEN
55
56                 -- look for a matching uri
57                 IF uri_use IS NULL THEN
58                     SELECT id INTO uri_id
59                         FROM asset.uri
60                         WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active
61                         ORDER BY id LIMIT 1;
62                     IF NOT FOUND THEN -- create one
63                         INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
64                         SELECT id INTO uri_id
65                             FROM asset.uri
66                             WHERE label = uri_label AND href = uri_href AND use_restriction IS NULL AND active;
67                     END IF;
68                 ELSE
69                     SELECT id INTO uri_id
70                         FROM asset.uri
71                         WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active
72                         ORDER BY id LIMIT 1;
73                     IF NOT FOUND THEN -- create one
74                         INSERT INTO asset.uri (label, href, use_restriction) VALUES (uri_label, uri_href, uri_use);
75                         SELECT id INTO uri_id
76                             FROM asset.uri
77                             WHERE label = uri_label AND href = uri_href AND use_restriction = uri_use AND active;
78                     END IF;
79                 END IF;
80
81                 FOR j IN 1 .. ARRAY_UPPER(uri_owner_list, 1) LOOP
82                     uri_owner := uri_owner_list[j];
83
84                     SELECT id INTO uri_owner_id FROM actor.org_unit WHERE shortname = BTRIM(REPLACE(uri_owner,chr(160),''));
85                     CONTINUE WHEN NOT FOUND;
86
87                     -- we need a call number to link through
88                     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;
89                     IF NOT FOUND THEN
90                         INSERT INTO asset.call_number (owning_lib, record, create_date, edit_date, creator, editor, label)
91                             VALUES (uri_owner_id, bib_id, 'now', 'now', editor_id, editor_id, '##URI##');
92                         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;
93                     END IF;
94
95                     -- now, link them if they're not already
96                     SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
97                     IF NOT FOUND THEN
98                         INSERT INTO asset.uri_call_number_map (call_number, uri) VALUES (uri_cn_id, uri_id);
99                         SELECT id INTO uri_map_id FROM asset.uri_call_number_map WHERE call_number = uri_cn_id AND uri = uri_id;
100                     END IF;
101
102                     current_uri_map_list := current_uri_map_list || uri_map_id;
103                     current_map_owner_list := current_map_owner_list || uri_cn_id;
104
105                 END LOOP;
106
107             END IF;
108
109         END LOOP;
110     END IF;
111
112     -- Clear any orphaned URIs, URI mappings and call
113     -- numbers for this bib that weren't mapped above.
114     FOR current_map IN
115         SELECT  m.id
116           FROM  asset.uri_call_number_map m
117                 LEFT JOIN asset.call_number cn ON (cn.id = m.call_number)
118           WHERE cn.record = bib_id
119                 AND cn.label = '##URI##'
120                 AND (NOT (m.id = ANY (current_uri_map_list))
121                      OR current_uri_map_list is NULL)
122     LOOP
123         SELECT uri INTO current_uri FROM asset.uri_call_number_map WHERE id = current_map;
124         DELETE FROM asset.uri_call_number_map WHERE id = current_map;
125
126         SELECT COUNT(*) INTO uri_map_count FROM asset.uri_call_number_map WHERE uri = current_uri;
127         IF uri_map_count = 0 THEN
128             DELETE FROM asset.uri WHERE id = current_uri;
129         END IF;
130     END LOOP;
131
132     UPDATE asset.call_number
133     SET deleted = TRUE, edit_date = now(), editor = editor_id
134     WHERE id IN (
135         SELECT  id
136           FROM  asset.call_number
137           WHERE record = bib_id
138                 AND label = '##URI##'
139                 AND NOT deleted
140                 AND (NOT (id = ANY (current_map_owner_list))
141                      OR current_map_owner_list is NULL)
142     );
143
144     RETURN;
145 END;
146 $func$ LANGUAGE PLPGSQL;
147
148 -- Remove existing orphaned URIs from the database.
149 DELETE FROM asset.uri
150 WHERE id IN
151 (
152 SELECT uri.id
153 FROM asset.uri
154 LEFT JOIN asset.uri_call_number_map
155 ON uri_call_number_map.uri = uri.id
156 LEFT JOIN serial.item
157 ON item.uri = uri.id
158 WHERE uri_call_number_map IS NULL
159 AND item IS NULL
160 );
161
162 COMMIT;
163