b2992d9d6dc78baf509952a152327fb956b03893
[transitory.git] / Open-ILS / src / sql / Pg / upgrade / XXXX.function.merge_record_assets_meets_acq.sql
1 CREATE OR REPLACE FUNCTION asset.merge_record_assets( target_record BIGINT, source_record BIGINT ) RETURNS INT AS $func$
2 DECLARE
3     moved_objects INT := 0;
4     source_cn     asset.call_number%ROWTYPE;
5     target_cn     asset.call_number%ROWTYPE;
6     metarec       metabib.metarecord%ROWTYPE;
7     hold          action.hold_request%ROWTYPE;
8     ser_rec       serial.record_entry%ROWTYPE;
9     ser_sub       serial.subscription%ROWTYPE;
10     acq_lineitem  acq.lineitem%ROWTYPE;
11     acq_request   acq.user_request%ROWTYPE;
12     booking       booking.resource_type%ROWTYPE;
13     source_part   biblio.monograph_part%ROWTYPE;
14     target_part   biblio.monograph_part%ROWTYPE;
15     multi_home    biblio.peer_bib_copy_map%ROWTYPE;
16     uri_count     INT := 0;
17     counter       INT := 0;
18     uri_datafield TEXT;
19     uri_text      TEXT := '';
20 BEGIN
21
22     -- move any 856 entries on records that have at least one MARC-mapped URI entry
23     SELECT  INTO uri_count COUNT(*)
24       FROM  asset.uri_call_number_map m
25             JOIN asset.call_number cn ON (m.call_number = cn.id)
26       WHERE cn.record = source_record;
27
28     IF uri_count > 0 THEN
29         
30         SELECT  COUNT(*) INTO counter
31           FROM  oils_xpath_table(
32                     'id',
33                     'marc',
34                     'biblio.record_entry',
35                     '//*[@tag="856"]',
36                     'id=' || source_record
37                 ) as t(i int,c text);
38     
39         FOR i IN 1 .. counter LOOP
40             SELECT  '<datafield xmlns="http://www.loc.gov/MARC21/slim"' || 
41                         ' tag="856"' ||
42                         ' ind1="' || FIRST(ind1) || '"'  ||
43                         ' ind2="' || FIRST(ind2) || '">' ||
44                         array_to_string(
45                             array_accum(
46                                 '<subfield code="' || subfield || '">' ||
47                                 regexp_replace(
48                                     regexp_replace(
49                                         regexp_replace(data,'&','&amp;','g'),
50                                         '>', '&gt;', 'g'
51                                     ),
52                                     '<', '&lt;', 'g'
53                                 ) || '</subfield>'
54                             ), ''
55                         ) || '</datafield>' INTO uri_datafield
56               FROM  oils_xpath_table(
57                         'id',
58                         'marc',
59                         'biblio.record_entry',
60                         '//*[@tag="856"][position()=' || i || ']/@ind1|' ||
61                         '//*[@tag="856"][position()=' || i || ']/@ind2|' ||
62                         '//*[@tag="856"][position()=' || i || ']/*/@code|' ||
63                         '//*[@tag="856"][position()=' || i || ']/*[@code]',
64                         'id=' || source_record
65                     ) as t(id int,ind1 text, ind2 text,subfield text,data text);
66
67             uri_text := uri_text || uri_datafield;
68         END LOOP;
69
70         IF uri_text <> '' THEN
71             UPDATE  biblio.record_entry
72               SET   marc = regexp_replace(marc,'(</[^>]*record>)', uri_text || E'\\1')
73               WHERE id = target_record;
74         END IF;
75
76     END IF;
77
78         -- Find and move metarecords to the target record
79         SELECT  INTO metarec *
80           FROM  metabib.metarecord
81           WHERE master_record = source_record;
82
83         IF FOUND THEN
84                 UPDATE  metabib.metarecord
85                   SET   master_record = target_record,
86                         mods = NULL
87                   WHERE id = metarec.id;
88
89                 moved_objects := moved_objects + 1;
90         END IF;
91
92         -- Find call numbers attached to the source ...
93         FOR source_cn IN SELECT * FROM asset.call_number WHERE record = source_record LOOP
94
95                 SELECT  INTO target_cn *
96                   FROM  asset.call_number
97                   WHERE label = source_cn.label
98                         AND owning_lib = source_cn.owning_lib
99                         AND record = target_record;
100
101                 -- ... and if there's a conflicting one on the target ...
102                 IF FOUND THEN
103
104                         -- ... move the copies to that, and ...
105                         UPDATE  asset.copy
106                           SET   call_number = target_cn.id
107                           WHERE call_number = source_cn.id;
108
109                         -- ... move V holds to the move-target call number
110                         FOR hold IN SELECT * FROM action.hold_request WHERE target = source_cn.id AND hold_type = 'V' LOOP
111                 
112                                 UPDATE  action.hold_request
113                                   SET   target = target_cn.id
114                                   WHERE id = hold.id;
115                 
116                                 moved_objects := moved_objects + 1;
117                         END LOOP;
118
119                 -- ... if not ...
120                 ELSE
121                         -- ... just move the call number to the target record
122                         UPDATE  asset.call_number
123                           SET   record = target_record
124                           WHERE id = source_cn.id;
125                 END IF;
126
127                 moved_objects := moved_objects + 1;
128         END LOOP;
129
130         -- Find T holds targeting the source record ...
131         FOR hold IN SELECT * FROM action.hold_request WHERE target = source_record AND hold_type = 'T' LOOP
132
133                 -- ... and move them to the target record
134                 UPDATE  action.hold_request
135                   SET   target = target_record
136                   WHERE id = hold.id;
137
138                 moved_objects := moved_objects + 1;
139         END LOOP;
140
141         -- Find serial records targeting the source record ...
142         FOR ser_rec IN SELECT * FROM serial.record_entry WHERE record = source_record LOOP
143                 -- ... and move them to the target record
144                 UPDATE  serial.record_entry
145                   SET   record = target_record
146                   WHERE id = ser_rec.id;
147
148                 moved_objects := moved_objects + 1;
149         END LOOP;
150
151         -- Find serial subscriptions targeting the source record ...
152         FOR ser_sub IN SELECT * FROM serial.subscription WHERE record_entry = source_record LOOP
153                 -- ... and move them to the target record
154                 UPDATE  serial.subscription
155                   SET   record_entry = target_record
156                   WHERE id = ser_sub.id;
157
158                 moved_objects := moved_objects + 1;
159         END LOOP;
160
161         -- Find booking resource types targeting the source record ...
162         FOR booking IN SELECT * FROM booking.resource_type WHERE record = source_record LOOP
163                 -- ... and move them to the target record
164                 UPDATE  booking.resource_type
165                   SET   record = target_record
166                   WHERE id = booking.id;
167
168                 moved_objects := moved_objects + 1;
169         END LOOP;
170
171         -- Find acq lineitems targeting the source record ...
172         FOR acq_lineitem IN SELECT * FROM acq.lineitem WHERE eg_bib_id = source_record LOOP
173                 -- ... and move them to the target record
174                 UPDATE  acq.lineitem
175                   SET   eg_bib_id = target_record
176                   WHERE id = acq_lineitem.id;
177
178                 moved_objects := moved_objects + 1;
179         END LOOP;
180
181         -- Find acq user purchase requests targeting the source record ...
182         FOR acq_request IN SELECT * FROM acq.user_request WHERE eg_bib = source_record LOOP
183                 -- ... and move them to the target record
184                 UPDATE  acq.user_request
185                   SET   eg_bib = target_record
186                   WHERE id = acq_request.id;
187
188                 moved_objects := moved_objects + 1;
189         END LOOP;
190
191         -- Find parts attached to the source ...
192         FOR source_part IN SELECT * FROM biblio.monograph_part WHERE record = source_record LOOP
193
194                 SELECT  INTO target_part *
195                   FROM  biblio.monograph_part
196                   WHERE label = source_part.label
197                         AND record = target_record;
198
199                 -- ... and if there's a conflicting one on the target ...
200                 IF FOUND THEN
201
202                         -- ... move the copy-part maps to that, and ...
203                         UPDATE  asset.copy_part_map
204                           SET   part = target_part.id
205                           WHERE part = source_part.id;
206
207                         -- ... move P holds to the move-target part
208                         FOR hold IN SELECT * FROM action.hold_request WHERE target = source_part.id AND hold_type = 'P' LOOP
209                 
210                                 UPDATE  action.hold_request
211                                   SET   target = target_part.id
212                                   WHERE id = hold.id;
213                 
214                                 moved_objects := moved_objects + 1;
215                         END LOOP;
216
217                 -- ... if not ...
218                 ELSE
219                         -- ... just move the part to the target record
220                         UPDATE  biblio.monograph_part
221                           SET   record = target_record
222                           WHERE id = source_part.id;
223                 END IF;
224
225                 moved_objects := moved_objects + 1;
226         END LOOP;
227
228         -- Find multi_home items attached to the source ...
229         FOR multi_home IN SELECT * FROM biblio.peer_bib_copy_map WHERE peer_record = source_record LOOP
230                 -- ... and move them to the target record
231                 UPDATE  biblio.peer_bib_copy_map
232                   SET   peer_record = target_record
233                   WHERE id = multi_home.id;
234
235                 moved_objects := moved_objects + 1;
236         END LOOP;
237
238         -- And delete mappings where the item's home bib was merged with the peer bib
239         DELETE FROM biblio.peer_bib_copy_map WHERE peer_record = (
240                 SELECT (SELECT record FROM asset.call_number WHERE id = call_number)
241                 FROM asset.copy WHERE id = target_copy
242         );
243
244     -- Finally, "delete" the source record
245     DELETE FROM biblio.record_entry WHERE id = source_record;
246
247         -- That's all, folks!
248         RETURN moved_objects;
249 END;
250 $func$ LANGUAGE plpgsql;
251
252