]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/xxxx.schema.protect_special_ids.sql
lp827356 new rules protect bre -1, acn -1 and acl 1 as well as marc editing buttons...
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / xxxx.schema.protect_special_ids.sql
1 BEGIN;
2
3 -- SELECT evergreen.upgrade_deps_block_check('xxxx', :eg_version);
4
5 UPDATE asset.call_number SET record = -1 WHERE id = -1 AND record != -1;
6
7 CREATE RULE protect_bre_id_neg1 AS ON UPDATE TO biblio.record_entry WHERE OLD.id = -1 DO INSTEAD NOTHING;
8 CREATE RULE protect_acl_id_1 AS ON UPDATE TO asset.copy_location WHERE OLD.id = 1 DO INSTEAD NOTHING;
9 CREATE RULE protect_acn_id_neg1 AS ON UPDATE TO asset.call_number WHERE OLD.id = -1 DO INSTEAD NOTHING;
10
11 CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
12 DECLARE
13     moved_objects INT := 0;
14     source_cn     asset.call_number%ROWTYPE;
15     target_cn     asset.call_number%ROWTYPE;
16     metarec       metabib.metarecord%ROWTYPE;
17     hold          action.hold_request%ROWTYPE;
18     ser_rec       serial.record_entry%ROWTYPE;
19     ser_sub       serial.subscription%ROWTYPE;
20     acq_lineitem  acq.lineitem%ROWTYPE;
21     acq_request   acq.user_request%ROWTYPE;
22     booking       booking.resource_type%ROWTYPE;
23     source_part   biblio.monograph_part%ROWTYPE;
24     target_part   biblio.monograph_part%ROWTYPE;
25     multi_home    biblio.peer_bib_copy_map%ROWTYPE;
26     uri_count     INT := 0;
27     counter       INT := 0;
28     uri_datafield TEXT;
29     uri_text      TEXT := '';
30 BEGIN
31
32     -- we don't merge bib -1 
33     IF target_record = -1 OR source_record = -1 THEN 
34        RETURN 0;
35     END IF;
36
37     -- move any 856 entries on records that have at least one MARC-mapped URI entry
38     SELECT  INTO uri_count COUNT(*)
39       FROM  asset.uri_call_number_map m
40             JOIN asset.call_number cn ON (m.call_number = cn.id)
41       WHERE cn.record = source_record;
42
43     IF uri_count > 0 THEN
44         
45         -- This returns more nodes than you might expect:
46         -- 7 instead of 1 for an 856 with $u $y $9
47         SELECT  COUNT(*) INTO counter
48           FROM  oils_xpath_table(
49                     'id',
50                     'marc',
51                     'biblio.record_entry',
52                     '//*[@tag="856"]',
53                     'id=' || source_record
54                 ) as t(i int,c text);
55     
56         FOR i IN 1 .. counter LOOP
57             SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
58             ' tag="856"' ||
59             ' ind1="' || FIRST(ind1) || '"'  ||
60             ' ind2="' || FIRST(ind2) || '">' ||
61                         STRING_AGG(
62                             '<subfield code="' || subfield || '">' ||
63                             regexp_replace(
64                                 regexp_replace(
65                                     regexp_replace(data,'&','&amp;','g'),
66                                     '>', '&gt;', 'g'
67                                 ),
68                                 '<', '&lt;', 'g'
69                             ) || '</subfield>', ''
70                         ) || '</datafield>' INTO uri_datafield
71               FROM  oils_xpath_table(
72                         'id',
73                         'marc',
74                         'biblio.record_entry',
75                         '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
76                         '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
77                         '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
78                         '//*[@tag="856"][position()=' || i || ']/*[@code]',
79                         'id=' || source_record
80                     ) as t(id int,ind1 text, ind2 text,subfield text,data text);
81
82             -- As most of the results will be NULL, protect against NULLifying
83             -- the valid content that we do generate
84             uri_text := uri_text || COALESCE(uri_datafield, '');
85         END LOOP;
86
87         IF uri_text <> '' THEN
88             UPDATE  biblio.record_entry
89               SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
90               WHERE id = target_record;
91         END IF;
92
93     END IF;
94
95     -- Find and move metarecords to the target record
96     SELECT    INTO metarec *
97       FROM    metabib.metarecord
98       WHERE    master_record = source_record;
99
100     IF FOUND THEN
101         UPDATE    metabib.metarecord
102           SET    master_record = target_record,
103             mods = NULL
104           WHERE    id = metarec.id;
105
106         moved_objects := moved_objects + 1;
107     END IF;
108
109     -- Find call numbers attached to the source ...
110     FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
111
112         SELECT    INTO target_cn *
113           FROM    asset.call_number
114           WHERE    label = source_cn.label
115             AND prefix = source_cn.prefix
116             AND suffix = source_cn.suffix
117             AND owning_lib = source_cn.owning_lib
118             AND record = target_record
119             AND NOT deleted;
120
121         -- ... and if there's a conflicting one on the target ...
122         IF FOUND THEN
123
124             -- ... move the copies to that, and ...
125             UPDATE    asset.copy
126               SET    call_number = target_cn.id
127               WHERE    call_number = source_cn.id;
128
129             -- ... move V holds to the move-target call number
130             FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
131         
132                 UPDATE    action.hold_request
133                   SET    target = target_cn.id
134                   WHERE    id = hold.id;
135         
136                 moved_objects := moved_objects + 1;
137             END LOOP;
138         
139             UPDATE asset.call_number SET deleted = TRUE WHERE id = source_cn.id;
140
141         -- ... if not ...
142         ELSE
143             -- ... just move the call number to the target record
144             UPDATE    asset.call_number
145               SET    record = target_record
146               WHERE    id = source_cn.id;
147         END IF;
148
149         moved_objects := moved_objects + 1;
150     END LOOP;
151
152     -- Find T holds targeting the source record ...
153     FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
154
155         -- ... and move them to the target record
156         UPDATE    action.hold_request
157           SET    target = target_record
158           WHERE    id = hold.id;
159
160         moved_objects := moved_objects + 1;
161     END LOOP;
162
163     -- Find serial records targeting the source record ...
164     FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
165         -- ... and move them to the target record
166         UPDATE    serial.record_entry
167           SET    record = target_record
168           WHERE    id = ser_rec.id;
169
170         moved_objects := moved_objects + 1;
171     END LOOP;
172
173     -- Find serial subscriptions targeting the source record ...
174     FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
175         -- ... and move them to the target record
176         UPDATE    serial.subscription
177           SET    record_entry = target_record
178           WHERE    id = ser_sub.id;
179
180         moved_objects := moved_objects + 1;
181     END LOOP;
182
183     -- Find booking resource types targeting the source record ...
184     FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
185         -- ... and move them to the target record
186         UPDATE    booking.resource_type
187           SET    record = target_record
188           WHERE    id = booking.id;
189
190         moved_objects := moved_objects + 1;
191     END LOOP;
192
193     -- Find acq lineitems targeting the source record ...
194     FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
195         -- ... and move them to the target record
196         UPDATE    acq.lineitem
197           SET    eg_bib_id = target_record
198           WHERE    id = acq_lineitem.id;
199
200         moved_objects := moved_objects + 1;
201     END LOOP;
202
203     -- Find acq user purchase requests targeting the source record ...
204     FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
205         -- ... and move them to the target record
206         UPDATE    acq.user_request
207           SET    eg_bib = target_record
208           WHERE    id = acq_request.id;
209
210         moved_objects := moved_objects + 1;
211     END LOOP;
212
213     -- Find parts attached to the source ...
214     FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
215
216         SELECT    INTO target_part *
217           FROM    biblio.monograph_part
218           WHERE    label = source_part.label
219             AND record = target_record;
220
221         -- ... and if there's a conflicting one on the target ...
222         IF FOUND THEN
223
224             -- ... move the copy-part maps to that, and ...
225             UPDATE    asset.copy_part_map
226               SET    part = target_part.id
227               WHERE    part = source_part.id;
228
229             -- ... move P holds to the move-target part
230             FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
231         
232                 UPDATE    action.hold_request
233                   SET    target = target_part.id
234                   WHERE    id = hold.id;
235         
236                 moved_objects := moved_objects + 1;
237             END LOOP;
238
239         -- ... if not ...
240         ELSE
241             -- ... just move the part to the target record
242             UPDATE    biblio.monograph_part
243               SET    record = target_record
244               WHERE    id = source_part.id;
245         END IF;
246
247         moved_objects := moved_objects + 1;
248     END LOOP;
249
250     -- Find multi_home items attached to the source ...
251     FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
252         -- ... and move them to the target record
253         UPDATE    biblio.peer_bib_copy_map
254           SET    peer_record = target_record
255           WHERE    id = multi_home.id;
256
257         moved_objects := moved_objects + 1;
258     END LOOP;
259
260     -- And delete mappings where the item's home bib was merged with the peer bib
261     DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
262         SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
263         FROM asset.copy WHERE id = target_copy
264     );
265
266     -- Apply merge tracking
267     UPDATE biblio.record_entry 
268         SET merge_date = NOW() WHERE id = target_record;
269
270     UPDATE biblio.record_entry
271         SET merge_date = NOW(), merged_to = target_record
272         WHERE id = source_record;
273
274     -- replace book bag entries of source_record with target_record
275     UPDATE container.biblio_record_entry_bucket_item
276         SET target_biblio_record_entry = target_record
277         WHERE bucket IN (SELECT id FROM container.biblio_record_entry_bucket WHERE btype = 'bookbag')
278         AND target_biblio_record_entry = source_record;
279
280     -- Finally, "delete" the source record
281     UPDATE biblio.record_entry SET active = FALSE WHERE id = source_record;
282     DELETE FROM biblio.record_entry WHERE id = source_record;
283
284     -- That's all, folks!
285     RETURN moved_objects;
286 END;
287 $func$ LANGUAGE plpgsql;
288
289 COMMIT;
290
291