]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0461.schema.vandelay.replace_field.sql
LP#1638299: Stamping upgrade scripts for authority infrastructure work
[working/Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0461.schema.vandelay.replace_field.sql
1
2 BEGIN;
3
4 INSERT INTO config.upgrade_log (version) VALUES ('0461'); --miker
5
6 CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT, force_add INT ) RETURNS TEXT AS $_$
7
8     use MARC::Record;
9     use MARC::File::XML (BinaryEncoding => 'UTF-8');
10     use strict;
11
12     my $target_xml = shift;
13     my $source_xml = shift;
14     my $field_spec = shift;
15     my $force_add = shift || 0;
16
17     my $target_r = MARC::Record->new_from_xml( $target_xml );
18     my $source_r = MARC::Record->new_from_xml( $source_xml );
19
20     return $target_xml unless ($target_r && $source_r);
21
22     my @field_list = split(',', $field_spec);
23
24     my %fields;
25     for my $f (@field_list) {
26         $f =~ s/^\s*//; $f =~ s/\s*$//;
27         if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) {
28             my $field = $1;
29             $field =~ s/\s+//;
30             my $sf = $2;
31             $sf =~ s/\s+//;
32             my $match = $3;
33             $match =~ s/^\s*//; $match =~ s/\s*$//;
34             $fields{$field} = { sf => [ split('', $sf) ] };
35             if ($match) {
36                 my ($msf,$mre) = split('~', $match);
37                 if (length($msf) > 0 and length($mre) > 0) {
38                     $msf =~ s/^\s*//; $msf =~ s/\s*$//;
39                     $mre =~ s/^\s*//; $mre =~ s/\s*$//;
40                     $fields{$field}{match} = { sf => $msf, re => qr/$mre/ };
41                 }
42             }
43         }
44     }
45
46     for my $f ( keys %fields) {
47         if ( @{$fields{$f}{sf}} ) {
48             for my $from_field ($source_r->field( $f )) {
49                 my @tos = $target_r->field( $f );
50                 if (!@tos) {
51                     next if (exists($fields{$f}{match}) and !$force_add);
52                     my @new_fields = map { $_->clone } $source_r->field( $f );
53                     $target_r->insert_fields_ordered( @new_fields );
54                 } else {
55                     for my $to_field (@tos) {
56                         if (exists($fields{$f}{match})) {
57                             next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf}));
58                         }
59                         my @new_sf = map { ($_ => $from_field->subfield($_)) } @{$fields{$f}{sf}};
60                         $to_field->add_subfields( @new_sf );
61                     }
62                 }
63             }
64         } else {
65             my @new_fields = map { $_->clone } $source_r->field( $f );
66             $target_r->insert_fields_ordered( @new_fields );
67         }
68     }
69
70     $target_xml = $target_r->as_xml_record;
71     $target_xml =~ s/^<\?.+?\?>$//mo;
72     $target_xml =~ s/\n//sgo;
73     $target_xml =~ s/>\s+</></sgo;
74
75     return $target_xml;
76
77 $_$ LANGUAGE PLPERLU;
78
79 CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT ) RETURNS TEXT AS $_$
80     SELECT vandelay.add_field( $1, $2, $3, 0 );
81 $_$ LANGUAGE SQL;
82
83 CREATE OR REPLACE FUNCTION vandelay.replace_field ( target_xml TEXT, source_xml TEXT, field TEXT ) RETURNS TEXT AS $_$
84 DECLARE
85     xml_output TEXT;
86 BEGIN
87     xml_output := vandelay.strip_field( target_xml, field);
88
89     IF xml_output <> target_xml  AND field ~ E'~' THEN
90         -- we removed something, and there was a regexp restriction in the field definition, so proceed
91         xml_output := vandelay.add_field( xml_output, source_xml, field, 1 );
92     ELSIF field !~ E'~' THEN
93         -- No regexp restriction, add the field
94         xml_output := vandelay.add_field( xml_output, source_xml, field, 0 );
95     END IF;
96
97     RETURN xml_output;
98 END;
99 $_$ LANGUAGE PLPGSQL;
100
101 COMMIT;