From: Dan Wells Date: Wed, 30 Oct 2013 19:33:28 +0000 (-0400) Subject: Stamping 0846: overlay subfield order fix X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=ab685448207ea0ae99b9c954d600090a44d5e640;p=evergreen%2Fequinox.git Stamping 0846: overlay subfield order fix Respect source XML subfield order during overlay Signed-off-by: Dan Wells --- diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql index 790e3947d3..e21d01fa55 100644 --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@ -91,7 +91,7 @@ CREATE TRIGGER no_overlapping_deps BEFORE INSERT OR UPDATE ON config.db_patch_dependencies FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates'); -INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0845', :eg_version); -- dbwells/csharp +INSERT INTO config.upgrade_log (version, applied_to) VALUES ('0846', :eg_version); -- eeevil/dbwells CREATE TABLE config.bib_source ( id SERIAL PRIMARY KEY, diff --git a/Open-ILS/src/sql/Pg/upgrade/0846.function.vand-add_field.sql b/Open-ILS/src/sql/Pg/upgrade/0846.function.vand-add_field.sql new file mode 100644 index 0000000000..eea8a306b7 --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0846.function.vand-add_field.sql @@ -0,0 +1,83 @@ +BEGIN; + +SELECT evergreen.upgrade_deps_block_check('0846', :eg_version); + +CREATE OR REPLACE FUNCTION vandelay.add_field ( target_xml TEXT, source_xml TEXT, field TEXT, force_add INT ) RETURNS TEXT AS $_$ + + use MARC::Record; + use MARC::File::XML (BinaryEncoding => 'UTF-8'); + use MARC::Charset; + use strict; + + MARC::Charset->assume_unicode(1); + + my $target_xml = shift; + my $source_xml = shift; + my $field_spec = shift; + my $force_add = shift || 0; + + my $target_r = MARC::Record->new_from_xml( $target_xml ); + my $source_r = MARC::Record->new_from_xml( $source_xml ); + + return $target_xml unless ($target_r && $source_r); + + my @field_list = split(',', $field_spec); + + my %fields; + for my $f (@field_list) { + $f =~ s/^\s*//; $f =~ s/\s*$//; + if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) { + my $field = $1; + $field =~ s/\s+//; + my $sf = $2; + $sf =~ s/\s+//; + my $match = $3; + $match =~ s/^\s*//; $match =~ s/\s*$//; + $fields{$field} = { sf => [ split('', $sf) ] }; + if ($match) { + my ($msf,$mre) = split('~', $match); + if (length($msf) > 0 and length($mre) > 0) { + $msf =~ s/^\s*//; $msf =~ s/\s*$//; + $mre =~ s/^\s*//; $mre =~ s/\s*$//; + $fields{$field}{match} = { sf => $msf, re => qr/$mre/ }; + } + } + } + } + + for my $f ( keys %fields) { + if ( @{$fields{$f}{sf}} ) { + for my $from_field ($source_r->field( $f )) { + my @tos = $target_r->field( $f ); + if (!@tos) { + next if (exists($fields{$f}{match}) and !$force_add); + my @new_fields = map { $_->clone } $source_r->field( $f ); + $target_r->insert_fields_ordered( @new_fields ); + } else { + for my $to_field (@tos) { + if (exists($fields{$f}{match})) { + next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf})); + } + for my $old_sf ($from_field->subfields) { + $to_field->add_subfields( @$old_sf ) if grep(/$$old_sf[0]/,@{$fields{$f}{sf}}); + } + } + } + } + } else { + my @new_fields = map { $_->clone } $source_r->field( $f ); + $target_r->insert_fields_ordered( @new_fields ); + } + } + + $target_xml = $target_r->as_xml_record; + $target_xml =~ s/^<\?.+?\?>$//mo; + $target_xml =~ s/\n//sgo; + $target_xml =~ s/>\s+ 'UTF-8'); - use MARC::Charset; - use strict; - - MARC::Charset->assume_unicode(1); - - my $target_xml = shift; - my $source_xml = shift; - my $field_spec = shift; - my $force_add = shift || 0; - - my $target_r = MARC::Record->new_from_xml( $target_xml ); - my $source_r = MARC::Record->new_from_xml( $source_xml ); - - return $target_xml unless ($target_r && $source_r); - - my @field_list = split(',', $field_spec); - - my %fields; - for my $f (@field_list) { - $f =~ s/^\s*//; $f =~ s/\s*$//; - if ($f =~ /^(.{3})(\w*)(?:\[([^]]*)\])?$/) { - my $field = $1; - $field =~ s/\s+//; - my $sf = $2; - $sf =~ s/\s+//; - my $match = $3; - $match =~ s/^\s*//; $match =~ s/\s*$//; - $fields{$field} = { sf => [ split('', $sf) ] }; - if ($match) { - my ($msf,$mre) = split('~', $match); - if (length($msf) > 0 and length($mre) > 0) { - $msf =~ s/^\s*//; $msf =~ s/\s*$//; - $mre =~ s/^\s*//; $mre =~ s/\s*$//; - $fields{$field}{match} = { sf => $msf, re => qr/$mre/ }; - } - } - } - } - - for my $f ( keys %fields) { - if ( @{$fields{$f}{sf}} ) { - for my $from_field ($source_r->field( $f )) { - my @tos = $target_r->field( $f ); - if (!@tos) { - next if (exists($fields{$f}{match}) and !$force_add); - my @new_fields = map { $_->clone } $source_r->field( $f ); - $target_r->insert_fields_ordered( @new_fields ); - } else { - for my $to_field (@tos) { - if (exists($fields{$f}{match})) { - next unless (grep { $_ =~ $fields{$f}{match}{re} } $to_field->subfield($fields{$f}{match}{sf})); - } - for my $old_sf ($from_field->subfields) { - $to_field->add_subfields( @$old_sf ) if grep(/$$old_sf[0]/,@{$fields{$f}{sf}}); - } - } - } - } - } else { - my @new_fields = map { $_->clone } $source_r->field( $f ); - $target_r->insert_fields_ordered( @new_fields ); - } - } - - $target_xml = $target_r->as_xml_record; - $target_xml =~ s/^<\?.+?\?>$//mo; - $target_xml =~ s/\n//sgo; - $target_xml =~ s/>\s+