]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0639.schema.asset_merge_record_assets.sql
LP1889113 Staff catalog record holds sticky org select
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0639.schema.asset_merge_record_assets.sql
1 -- Evergreen DB patch XXXX.schema.asset_merge_record_assets.sql
2 --
3 --
4 BEGIN;
5
6
7 -- check whether patch can be applied
8 SELECT evergreen.upgrade_deps_block_check('0639', :eg_version);
9
10 CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
11 DECLARE
12     moved_objects INT := 0;
13     source_cn     asset.call_number%ROWTYPE;
14     target_cn     asset.call_number%ROWTYPE;
15     metarec       metabib.metarecord%ROWTYPE;
16     hold          action.hold_request%ROWTYPE;
17     ser_rec       serial.record_entry%ROWTYPE;
18     uri_count     INT := 0;
19     counter       INT := 0;
20     uri_datafield TEXT;
21     uri_text      TEXT := '';
22 BEGIN
23
24     -- move any 856 entries on records that have at least one MARC-mapped URI entry
25     SELECT  INTO uri_count COUNT(*)
26       FROM  asset.uri_call_number_map m
27             JOIN asset.call_number cn ON (m.call_number = cn.id)
28       WHERE cn.record = source_record;
29
30     IF uri_count > 0 THEN
31         
32         -- This returns more nodes than you might expect:
33         -- 7 instead of 1 for an 856 with $u $y $9
34         SELECT  COUNT(*) INTO counter
35           FROM  oils_xpath_table(
36                     'id',
37                     'marc',
38                     'biblio.record_entry',
39                     '//*[@tag="856"]',
40                     'id=' || source_record
41                 ) as t(i int,c text);
42     
43         FOR i IN 1 .. counter LOOP
44             SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
45                         ' tag="856"' ||
46                         ' ind1="' || FIRST(ind1) || '"'  ||
47                         ' ind2="' || FIRST(ind2) || '">' ||
48                         array_to_string(
49                             array_accum(
50                                 '<subfield code="' || subfield || '">' ||
51                                 regexp_replace(
52                                     regexp_replace(
53                                         regexp_replace(data,'&','&amp;','g'),
54                                         '>', '&gt;', 'g'
55                                     ),
56                                     '<', '&lt;', 'g'
57                                 ) || '</subfield>'
58                             ), ''
59                         ) || '</datafield>' INTO uri_datafield
60               FROM  oils_xpath_table(
61                         'id',
62                         'marc',
63                         'biblio.record_entry',
64                         '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
65                         '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
66                         '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
67                         '//*[@tag="856"][position()=' || i || ']/*[@code]',
68                         'id=' || source_record
69                     ) as t(id int,ind1 text, ind2 text,subfield text,data text);
70
71             -- As most of the results will be NULL, protect against NULLifying
72             -- the valid content that we do generate
73             uri_text := uri_text || COALESCE(uri_datafield, '');
74         END LOOP;
75
76         IF uri_text <> '' THEN
77             UPDATE  biblio.record_entry
78               SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
79               WHERE id = target_record;
80         END IF;
81
82     END IF;
83
84         -- Find and move metarecords to the target record
85         SELECT  INTO metarec *
86           FROM  metabib.metarecord
87           WHERE master_record = source_record;
88
89         IF FOUND THEN
90                 UPDATE  metabib.metarecord
91                   SET   master_record = target_record,
92                         mods = NULL
93                   WHERE id = metarec.id;
94
95                 moved_objects := moved_objects + 1;
96         END IF;
97
98         -- Find call numbers attached to the source ...
99         FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
100
101                 SELECT  INTO target_cn *
102                   FROM  asset.call_number
103                   WHERE label = source_cn.label
104                         AND owning_lib = source_cn.owning_lib
105                         AND record = target_record;
106
107                 -- ... and if there's a conflicting one on the target ...
108                 IF FOUND THEN
109
110                         -- ... move the copies to that, and ...
111                         UPDATE  asset.copy
112                           SET   call_number = target_cn.id
113                           WHERE call_number = source_cn.id;
114
115                         -- ... move V holds to the move-target call number
116                         FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
117                 
118                                 UPDATE  action.hold_request
119                                   SET   target = target_cn.id
120                                   WHERE id = hold.id;
121                 
122                                 moved_objects := moved_objects + 1;
123                         END LOOP;
124
125                 -- ... if not ...
126                 ELSE
127                         -- ... just move the call number to the target record
128                         UPDATE  asset.call_number
129                           SET   record = target_record
130                           WHERE id = source_cn.id;
131                 END IF;
132
133                 moved_objects := moved_objects + 1;
134         END LOOP;
135
136         -- Find T holds targeting the source record ...
137         FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
138
139                 -- ... and move them to the target record
140                 UPDATE  action.hold_request
141                   SET   target = target_record
142                   WHERE id = hold.id;
143
144                 moved_objects := moved_objects + 1;
145         END LOOP;
146
147         -- Find serial records targeting the source record ...
148         FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
149                 -- ... and move them to the target record
150                 UPDATE  serial.record_entry
151                   SET   record = target_record
152                   WHERE id = ser_rec.id;
153
154                 moved_objects := moved_objects + 1;
155         END LOOP;
156
157     -- Finally, "delete" the source record
158     DELETE FROM biblio.record_entry WHERE id = source_record;
159
160         -- That's all, folks!
161         RETURN moved_objects;
162 END;
163 $func$ LANGUAGE plpgsql;
164
165 COMMIT;