]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/version-upgrade/2.4.3-2.4.4-upgrade-db.sql
4d7c08cf3a62f2c7829a90ef4b09cb63e7d1ed82
[working/Evergreen.git] / Open-ILS / src / sql / Pg / version-upgrade / 2.4.3-2.4.4-upgrade-db.sql
1 --Upgrade Script for 2.4.3 to 2.4.4
2 \set eg_version '''2.4.4'''
3 BEGIN;
4 INSERT INTO config.upgrade_log (version, applied_to) VALUES ('2.4.4', :eg_version);
5
6 -- check whether patch can be applied
7 SELECT evergreen.upgrade_deps_block_check('0838', :eg_version);
8
9 DELETE FROM config.metabib_field_index_norm_map
10     WHERE field = 25 AND norm IN (
11         SELECT id
12         FROM config.index_normalizer
13         WHERE func IN ('search_normalize','split_date_range')
14     );
15
16 \qecho If your site's bibcn searches are affected by this issue, you may wish
17 \qecho to reingest your bib records now.  It's probably not worth it for many
18 \qecho sites.
19
20
21 SELECT evergreen.upgrade_deps_block_check('0840', :eg_version);
22
23 INSERT INTO config.usr_setting_type (name,grp,opac_visible,label,description,datatype) VALUES (
24     'ui.grid_columns.conify.config.circ_matrix_matchpoint',
25     'gui',
26     FALSE,
27     oils_i18n_gettext(
28         'ui.grid_columns.conify.config.circ_matrix_matchpoint',
29         'Circulation Policy Configuration',
30         'cust',
31         'label'
32     ),
33     oils_i18n_gettext(
34         'ui.grid_columns.conify.config.circ_matrix_matchpoint',
35         'Circulation Policy Configuration Column Settings',
36         'cust',
37         'description'
38     ),
39     'string'
40 );
41
42
43 -- check whether patch can be applied
44 SELECT evergreen.upgrade_deps_block_check('0841', :eg_version);
45
46 ALTER TABLE config.metabib_field_ts_map DROP CONSTRAINT metabib_field_ts_map_metabib_field_fkey;
47 ALTER TABLE config.metabib_search_alias DROP CONSTRAINT metabib_search_alias_field_fkey;
48 ALTER TABLE metabib.browse_entry_def_map DROP CONSTRAINT browse_entry_def_map_def_fkey;
49
50 ALTER TABLE config.metabib_field_ts_map ADD CONSTRAINT metabib_field_ts_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
51 ALTER TABLE config.metabib_search_alias ADD CONSTRAINT metabib_search_alias_field_fkey FOREIGN KEY (field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
52 ALTER TABLE metabib.browse_entry_def_map ADD CONSTRAINT browse_entry_def_map_def_fkey FOREIGN KEY (def) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
53
54
55 DROP FUNCTION IF EXISTS config.modify_metabib_field(source INT, target INT);
56 CREATE FUNCTION config.modify_metabib_field(v_source INT, target INT) RETURNS INT AS $func$
57 DECLARE
58     f_class TEXT;
59     check_id INT;
60     target_id INT;
61 BEGIN
62     SELECT field_class INTO f_class FROM config.metabib_field WHERE id = v_source;
63     IF NOT FOUND THEN
64         RETURN 0;
65     END IF;
66     IF target IS NULL THEN
67         target_id = v_source + 1000;
68     ELSE
69         target_id = target;
70     END IF;
71     SELECT id FROM config.metabib_field INTO check_id WHERE id = target_id;
72     IF FOUND THEN
73         RAISE NOTICE 'Cannot bump config.metabib_field.id from % to %; the target ID already exists.', v_source, target_id;
74         RETURN 0;
75     END IF;
76     UPDATE config.metabib_field SET id = target_id WHERE id = v_source;
77     EXECUTE ' UPDATE metabib.' || f_class || '_field_entry SET field = ' || target_id || ' WHERE field = ' || v_source;
78     UPDATE config.metabib_field_ts_map SET metabib_field = target_id WHERE metabib_field = v_source;
79     UPDATE config.metabib_field_index_norm_map SET field = target_id WHERE field = v_source;
80     UPDATE search.relevance_adjustment SET field = target_id WHERE field = v_source;
81     UPDATE config.metabib_search_alias SET field = target_id WHERE field = v_source;
82     UPDATE metabib.browse_entry_def_map SET def = target_id WHERE def = v_source;
83     RETURN 1;
84 END;
85 $func$ LANGUAGE PLPGSQL;
86
87 SELECT config.modify_metabib_field(id, NULL)
88     FROM config.metabib_field
89     WHERE id > 30;
90
91 SELECT SETVAL('config.metabib_field_id_seq', GREATEST(1000, (SELECT MAX(id) FROM config.metabib_field)));
92
93
94 -- check whether patch can be applied
95 SELECT evergreen.upgrade_deps_block_check('0842', :eg_version);
96
97 -- this upgrade is only for people coming from 2_3, and is a NO-OP for those on 2_4 or later
98 ALTER TABLE config.metabib_field_ts_map DROP CONSTRAINT metabib_field_ts_map_metabib_field_fkey;
99
100 ALTER TABLE config.metabib_field_ts_map ADD CONSTRAINT metabib_field_ts_map_metabib_field_fkey FOREIGN KEY (metabib_field) REFERENCES config.metabib_field(id) ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
101
102
103 SELECT evergreen.upgrade_deps_block_check('0846', :eg_version);
104
105 CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT, force_add INT ) RETURNS TEXT AS $_$
106
107     use MARC::Record;
108     use MARC::File::XML (BinaryEncoding => 'UTF-8');
109     use MARC::Charset;
110     use strict;
111
112     MARC::Charset->assume_unicode(1);
113
114     my $target_xml = shift;
115     my $source_xml = shift;
116     my $field_spec = shift;
117     my $force_add = shift || 0;
118
119     my $target_r = MARC::Record->new_from_xml( $target_xml );
120     my $source_r = MARC::Record->new_from_xml( $source_xml );
121
122     return $target_xml unless ($target_r && $source_r);
123
124     my @field_list = split(',', $field_spec);
125
126     my %fields;
127     for my $f (@field_list) {
128         $f =~ s/^\s*//; $f =~ s/\s*$//;
129         if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
130             my $field = $1;
131             $field =~ s/\s+//;
132             my $sf = $2;
133             $sf =~ s/\s+//;
134             my $match = $3;
135             $match =~ s/^\s*//; $match =~ s/\s*$//;
136             $fields{$field} = { sf => [ split('', $sf) ] };
137             if ($match) {
138                 my ($msf,$mre) = split('~', $match);
139                 if (length($msf) > 0 and length($mre) > 0) {
140                     $msf =~ s/^\s*//; $msf =~ s/\s*$//;
141                     $mre =~ s/^\s*//; $mre =~ s/\s*$//;
142                     $fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
143                 }
144             }
145         }
146     }
147
148     for my $f ( keys %fields) {
149         if ( @{$fields{$f}{sf}} ) {
150             for my $from_field ($source_r->field( $f )) {
151                 my @tos = $target_r->field( $f );
152                 if (!@tos) {
153                     next if (exists($fields{$f}{match}) and !$force_add);
154                     my @new_fields = map { $_->clone } $source_r->field( $f );
155                     $target_r->insert_fields_ordered( @new_fields );
156                 } else {
157                     for my $to_field (@tos) {
158                         if (exists($fields{$f}{match})) {
159                             next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
160                         }
161                         for my $old_sf ($from_field->subfields) {
162                             $to_field->add_subfields( @$old_sf ) if grep(/$$old_sf[0]/,@{$fields{$f}{sf}});
163                         }
164                     }
165                 }
166             }
167         } else {
168             my @new_fields = map { $_->clone } $source_r->field( $f );
169             $target_r->insert_fields_ordered( @new_fields );
170         }
171     }
172
173     $target_xml = $target_r->as_xml_record;
174     $target_xml =~ s/^<\?.+?\?>$//mo;
175     $target_xml =~ s/\n//sgo;
176     $target_xml =~ s/>\s+</></sgo;
177
178     return $target_xml;
179
180 $_$ LANGUAGE PLPERLU;
181
182
183
184 SELECT evergreen.upgrade_deps_block_check('0847', :eg_version);
185
186 CREATE OR REPLACE FUNCTION authority.generate_overlay_template (source_xml TEXT) RETURNS TEXT AS $f$
187 DECLARE
188     cset                INT;
189     main_entry          authority.control_set_authority_field%ROWTYPE;
190     bib_field           authority.control_set_bib_field%ROWTYPE;
191     auth_id             INT DEFAULT oils_xpath_string('//*[@tag="901"]/*[local-name()="subfield" and @code="c"]', source_xml)::INT;
192     tmp_data            XML;
193     replace_data        XML[] DEFAULT '{}'::XML[];
194     replace_rules       TEXT[] DEFAULT '{}'::TEXT[];
195     auth_field          XML[];
196     auth_i1             TEXT;
197     auth_i2             TEXT;
198 BEGIN
199     IF auth_id IS NULL THEN
200         RETURN NULL;
201     END IF;
202
203     -- Default to the LoC controll set
204     SELECT control_set INTO cset FROM authority.record_entry WHERE id = auth_id;
205
206     -- if none, make a best guess
207     IF cset IS NULL THEN
208         SELECT  control_set INTO cset
209           FROM  authority.control_set_authority_field
210           WHERE tag IN (
211                     SELECT  UNNEST(XPATH('//*[starts-with(@tag,"1")]/@tag',marc::XML)::TEXT[])
212                       FROM  authority.record_entry
213                       WHERE id = auth_id
214                 )
215           LIMIT 1;
216     END IF;
217
218     -- if STILL none, no-op change
219     IF cset IS NULL THEN
220         RETURN XMLELEMENT(
221             name record,
222             XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
223             XMLELEMENT( name leader, '00881nam a2200193   4500'),
224             XMLELEMENT(
225                 name datafield,
226                 XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
227                 XMLELEMENT(
228                                       name subfield,
229                     XMLATTRIBUTES('d' AS code),
230                     '901c'
231                 )
232             )
233         )::TEXT;
234     END IF;
235
236     FOR main_entry IN SELECT * FROM authority.control_set_authority_field acsaf WHERE acsaf.control_set = cset AND acsaf.main_entry IS NULL LOOP
237         auth_field := XPATH('//*[@tag="'||main_entry.tag||'"][1]',source_xml::XML);
238         auth_i1 = (XPATH('@ind1',auth_field[1]))[1];
239         auth_i2 = (XPATH('@ind2',auth_field[1]))[1];
240         IF ARRAY_LENGTH(auth_field,1) > 0 THEN
241             FOR bib_field IN SELECT * FROM authority.control_set_bib_field WHERE authority_field = main_entry.id LOOP
242                 SELECT XMLELEMENT( -- XMLAGG avoids magical <element> creation, but requires unnest subquery
243                     name datafield,
244                     XMLATTRIBUTES(bib_field.tag AS tag, auth_i1 AS ind1, auth_i2 AS ind2),
245                     XMLAGG(UNNEST)
246                 ) INTO tmp_data FROM UNNEST(XPATH('//*[local-name()="subfield"]', auth_field[1]));
247                 replace_data := replace_data || tmp_data;
248                 replace_rules := replace_rules || ( bib_field.tag || main_entry.sf_list || E'[0~\\)' || auth_id || '$]' );
249                 tmp_data = NULL;
250             END LOOP;
251             EXIT;
252         END IF;
253     END LOOP;
254
255     SELECT XMLAGG(UNNEST) INTO tmp_data FROM UNNEST(replace_data);
256
257     RETURN XMLELEMENT(
258         name record,
259         XMLATTRIBUTES('http://www.loc.gov/MARC21/slim' AS xmlns),
260         XMLELEMENT( name leader, '00881nam a2200193   4500'),
261         tmp_data,
262         XMLELEMENT(
263             name datafield,
264                          XMLATTRIBUTES( '905' AS tag, ' ' AS ind1, ' ' AS ind2),
265             XMLELEMENT(
266                 name subfield,
267                 XMLATTRIBUTES('r' AS code),
268                 ARRAY_TO_STRING(replace_rules,',')
269             )
270         )
271     )::TEXT;
272 END;
273 $f$ STABLE LANGUAGE PLPGSQL;
274
275 COMMIT;