1 CREATE OR REPLACE FUNCTION migration_tools.set_leader (TEXT, INT, TEXT) RETURNS TEXT AS $$
2 my ($marcxml, $pos, $value) = @_;
9 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
10 my $leader = $marc->leader();
11 substr($leader, $pos, 1) = $value;
12 $marc->leader($leader);
13 $xml = $marc->as_xml_record;
14 $xml =~ s/^<\?.+?\?>$//mo;
16 $xml =~ s/>\s+</></sgo;
19 $$ LANGUAGE PLPERLU STABLE;
21 CREATE OR REPLACE FUNCTION migration_tools.set_008 (TEXT, INT, TEXT) RETURNS TEXT AS $$
22 my ($marcxml, $pos, $value) = @_;
29 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
30 my $f008 = $marc->field('008');
33 my $field = $f008->data();
34 substr($field, $pos, 1) = $value;
35 $f008->update($field);
36 $xml = $marc->as_xml_record;
37 $xml =~ s/^<\?.+?\?>$//mo;
39 $xml =~ s/>\s+</></sgo;
43 $$ LANGUAGE PLPERLU STABLE;
45 CREATE OR REPLACE FUNCTION migration_tools.insert_tags (TEXT, TEXT) RETURNS TEXT AS $$
47 my ($marcxml, $tags) = @_;
55 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
56 my $to_insert = MARC::Record->new_from_xml("<record>$tags</record>", 'UTF-8');
60 foreach my $field ( $marc->fields() ) {
61 push @incumbents, $field->as_formatted();
64 foreach $field ( $to_insert->fields() ) {
65 if (!grep {$_ eq $field->as_formatted()} @incumbents) {
66 $marc->insert_fields_ordered( ($field) );
70 $xml = $marc->as_xml_record;
71 $xml =~ s/^<\?.+?\?>$//mo;
73 $xml =~ s/>\s+</></sgo;
78 $$ LANGUAGE PLPERLU STABLE;
80 CREATE OR REPLACE FUNCTION migration_tools.marc_parses( TEXT ) RETURNS BOOLEAN AS $func$
83 use MARC::File::XML (BinaryEncoding => 'UTF-8');
86 MARC::Charset->assume_unicode(1);
91 my $r = MARC::Record->new_from_xml( $xml );
92 my $output_xml = $r->as_xml_record();
100 $func$ LANGUAGE PLPERLU;
101 COMMENT ON FUNCTION migration_tools.marc_parses(TEXT) IS 'Return boolean indicating if MARCXML string is parseable by MARC::File::XML';
103 CREATE OR REPLACE FUNCTION migration_tools.merge_marc_fields( TEXT, TEXT, TEXT[] ) RETURNS TEXT AS $func$
109 use MARC::File::XML (BinaryEncoding => 'UTF-8');
112 MARC::Charset->assume_unicode(1);
114 my $target_xml = shift;
115 my $source_xml = shift;
121 eval { $target = MARC::Record->new_from_xml( $target_xml ); };
125 eval { $source = MARC::Record->new_from_xml( $source_xml ); };
130 my $source_id = $source->subfield('901', 'c');
131 $source_id = $source->subfield('903', 'a') unless $source_id;
132 my $target_id = $target->subfield('901', 'c');
133 $target_id = $target->subfield('903', 'a') unless $target_id;
136 foreach my $tag (@$tags) {
137 my %existing_fields = map { $_->as_formatted() => 1 } $target->field($tag);
138 my @to_add = grep { not exists $existing_fields{$_->as_formatted()} } $source->field($tag);
139 $target->insert_fields_ordered(map { $_->clone() } @to_add);
141 elog(NOTICE, "Merged $tag tag(s) from $source_id to $target_id");
145 my $xml = $target->as_xml_record;
146 $xml =~ s/^<\?.+?\?>$//mo;
148 $xml =~ s/>\s+</></sgo;
152 $func$ LANGUAGE PLPERLU;
153 COMMENT ON FUNCTION migration_tools.merge_marc_fields( TEXT, TEXT, TEXT[] ) IS 'Given two MARCXML strings and an array of tags, returns MARCXML representing the merge of the specified fields from the second MARCXML record into the first.';
155 CREATE OR REPLACE FUNCTION migration_tools.make_stub_bib (text[], text[]) RETURNS TEXT AS $func$
161 use MARC::File::XML (BinaryEncoding => 'UTF-8');
165 my $in_values = shift;
167 # hack-and-slash parsing of array-passed-as-string;
168 # this can go away once everybody is running Postgres 9.1+
169 my $csv = Text::CSV->new({binary => 1});
172 my $status = $csv->parse($in_tags);
173 my $tags = [ $csv->fields() ];
174 $in_values =~ s/^{//;
175 $in_values =~ s/}$//;
176 $status = $csv->parse($in_values);
177 my $values = [ $csv->fields() ];
179 my $marc = MARC::Record->new();
181 $marc->leader('00000nam a22000007 4500');
182 $marc->append_fields(MARC::Field->new('008', '000000s 000 eng d'));
184 foreach my $i (0..$#$tags) {
186 if ($tags->[$i] =~ /^(\d{3})([0-9a-z])$/) {
189 $marc->append_fields(MARC::Field->new($tag, ' ', ' ', $sf => $values->[$i])) if $values->[$i] !~ /^\s*$/ and $values->[$i] ne 'NULL';
190 } elsif ($tags->[$i] =~ /^(\d{3})$/) {
192 $marc->append_fields(MARC::Field->new($tag, $values->[$i])) if $values->[$i] !~ /^\s*$/ and $values->[$i] ne 'NULL';
196 my $xml = $marc->as_xml_record;
197 $xml =~ s/^<\?.+?\?>$//mo;
199 $xml =~ s/>\s+</></sgo;
203 $func$ LANGUAGE PLPERLU;
204 COMMENT ON FUNCTION migration_tools.make_stub_bib (text[], text[]) IS $$Simple function to create a stub MARCXML bib from a set of columns.
205 The first argument is an array of tag/subfield specifiers, e.g., ARRAY['001', '245a', '500a'].
206 The second argument is an array of text containing the values to plug into each field.
207 If the value for a given field is NULL or the empty string, it is not inserted.
210 CREATE OR REPLACE FUNCTION migration_tools.make_stub_bib (text[], text[], text[], text[]) RETURNS TEXT AS $func$
216 use MARC::File::XML (BinaryEncoding => 'UTF-8');
222 my $in_values = shift;
224 # hack-and-slash parsing of array-passed-as-string;
225 # this can go away once everybody is running Postgres 9.1+
226 my $csv = Text::CSV->new({binary => 1});
229 my $status = $csv->parse($in_tags);
230 my $tags = [ $csv->fields() ];
233 $status = $csv->parse($in_ind1);
234 my $ind1s = [ $csv->fields() ];
237 $status = $csv->parse($in_ind2);
238 my $ind2s = [ $csv->fields() ];
239 $in_values =~ s/^{//;
240 $in_values =~ s/}$//;
241 $status = $csv->parse($in_values);
242 my $values = [ $csv->fields() ];
244 my $marc = MARC::Record->new();
246 $marc->leader('00000nam a22000007 4500');
247 $marc->append_fields(MARC::Field->new('008', '000000s 000 eng d'));
249 foreach my $i (0..$#$tags) {
251 if ($tags->[$i] =~ /^(\d{3})([0-9a-z])$/) {
254 $marc->append_fields(MARC::Field->new($tag, $ind1s->[$i], $ind2s->[$i], $sf => $values->[$i])) if $values->[$i] !~ /^\s*$/ and $values->[$i] ne 'NULL';
255 } elsif ($tags->[$i] =~ /^(\d{3})$/) {
257 $marc->append_fields(MARC::Field->new($tag, $values->[$i])) if $values->[$i] !~ /^\s*$/ and $values->[$i] ne 'NULL';
261 my $xml = $marc->as_xml_record;
262 $xml =~ s/^<\?.+?\?>$//mo;
264 $xml =~ s/>\s+</></sgo;
268 $func$ LANGUAGE PLPERLU;
269 COMMENT ON FUNCTION migration_tools.make_stub_bib (text[], text[], text[], text[]) IS $$Simple function to create a stub MARCXML bib from a set of columns.
270 The first argument is an array of tag/subfield specifiers, e.g., ARRAY['001', '245a', '500a'].
271 The second argument is an array of text containing the values to plug into indicator 1 for each field.
272 The third argument is an array of text containing the values to plug into indicator 2 for each field.
273 The fourth argument is an array of text containing the values to plug into each field.
274 If the value for a given field is NULL or the empty string, it is not inserted.
277 CREATE OR REPLACE FUNCTION migration_tools.set_indicator (TEXT, TEXT, INTEGER, CHAR(1)) RETURNS TEXT AS $func$
279 my ($marcxml, $tag, $pos, $value) = @_;
282 use MARC::File::XML (BinaryEncoding => 'UTF-8');
286 MARC::Charset->assume_unicode(1);
288 elog(ERROR, 'indicator position must be either 1 or 2') unless $pos =~ /^[12]$/;
289 elog(ERROR, 'MARC tag must be numeric') unless $tag =~ /^\d{3}$/;
290 elog(ERROR, 'MARC tag must not be control field') if $tag =~ /^00/;
291 elog(ERROR, 'Value must be exactly one character') unless $value =~ /^.$/;
295 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
297 foreach my $field ($marc->field($tag)) {
298 $field->update("ind$pos" => $value);
300 $xml = $marc->as_xml_record;
301 $xml =~ s/^<\?.+?\?>$//mo;
303 $xml =~ s/>\s+</></sgo;
307 $func$ LANGUAGE PLPERLU;
309 COMMENT ON FUNCTION migration_tools.set_indicator(TEXT, TEXT, INTEGER, CHAR(1)) IS $$Set indicator value of a specified MARC field.
310 The first argument is a MARCXML string.
311 The second argument is a MARC tag.
312 The third argument is the indicator position, either 1 or 2.
313 The fourth argument is the character to set the indicator value to.
314 All occurences of the specified field will be changed.
315 The function returns the revised MARCXML string.$$;
317 CREATE OR REPLACE FUNCTION migration_tools.get_marc_leader (TEXT) RETURNS TEXT AS $$
326 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
327 $field = $marc->leader();
330 $$ LANGUAGE PLPERLU STABLE;
332 CREATE OR REPLACE FUNCTION migration_tools.get_marc_tag (TEXT, TEXT, TEXT, TEXT) RETURNS TEXT AS $$
333 my ($marcxml, $tag, $subfield, $delimiter) = @_;
341 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
342 $field = $marc->field($tag);
344 return $field->as_string($subfield,$delimiter) if $field;
346 $$ LANGUAGE PLPERLU STABLE;
348 CREATE OR REPLACE FUNCTION migration_tools.get_marc_tags (TEXT, TEXT, TEXT, TEXT) RETURNS TEXT[] AS $$
349 my ($marcxml, $tag, $subfield, $delimiter) = @_;
357 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
358 @fields = $marc->field($tag);
361 foreach my $field (@fields) {
362 push @texts, $field->as_string($subfield,$delimiter);
365 $$ LANGUAGE PLPERLU STABLE;
367 CREATE OR REPLACE FUNCTION migration_tools.get_marc_tags_filtered (TEXT, TEXT, TEXT, TEXT, TEXT) RETURNS TEXT[] AS $$
368 my ($marcxml, $tag, $subfield, $delimiter, $match) = @_;
376 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
377 @fields = $marc->field($tag);
380 foreach my $field (@fields) {
381 if ($field->as_string() =~ qr/$match/) {
382 push @texts, $field->as_string($subfield,$delimiter);
386 $$ LANGUAGE PLPERLU STABLE;
388 DROP FUNCTION IF EXISTS migration_tools.munge_sf9(INTEGER,TEXT,TEXT);
389 CREATE OR REPLACE FUNCTION migration_tools.merge_sf9(bib_id INTEGER,new_sf9 TEXT,force TEXT DEFAULT 'false')
396 SELECT marc FROM biblio.record_entry WHERE id = bib_id INTO marc_xml;
398 SELECT munge_sf9(marc_xml,new_sf9,force) INTO new_marc;
399 UPDATE biblio.record_entry SET marc = new_marc WHERE id = bib_id;
403 $BODY$ LANGUAGE plpgsql;
405 DROP FUNCTION IF EXISTS migration_tools.munge_sf9(TEXT,TEXT,TEXT);
406 CREATE OR REPLACE FUNCTION migration_tools.munge_sf9(marc_xml TEXT, new_9_to_set TEXT, force TEXT)
414 use MARC::File::XML (BinaryEncoding => 'utf8');
416 binmode(STDERR, ':bytes');
417 binmode(STDOUT, ':utf8');
418 binmode(STDERR, ':utf8');
420 my $marc_xml = shift;
421 my $new_9_to_set = shift;
424 $marc_xml =~ s/(<leader>.........)./${1}a/;
427 $marc_xml = MARC::Record->new_from_xml($marc_xml);
430 #elog("could not parse $bibid: $@\n");
431 import MARC::File::XML (BinaryEncoding => 'utf8');
435 my @uris = $marc_xml->field('856');
436 return $marc_xml->as_xml_record() unless @uris;
438 foreach my $field (@uris) {
439 my $ind1 = $field->indicator('1');
440 if (!defined $ind1) { next; }
441 if ($ind1 ne '1' && $ind1 ne '4' && $force eq 'false') { next; }
442 if ($ind1 ne '1' && $ind1 ne '4' && $force eq 'true') { $field->set_indicator(1,'4'); }
443 my $ind2 = $field->indicator('2');
444 if (!defined $ind2) { next; }
445 if ($ind2 ne '0' && $ind2 ne '1' && $force eq 'false') { next; }
446 if ($ind2 ne '0' && $ind2 ne '1' && $force eq 'true') { $field->set_indicator(2,'0'); }
447 $field->add_subfields( '9' => $new_9_to_set );
450 return $marc_xml->as_xml_record();
454 DROP FUNCTION IF EXISTS migration_tools.munge_sf9_qualifying_match(TEXT,TEXT,TEXT);
455 CREATE OR REPLACE FUNCTION migration_tools.munge_sf9_qualifying_match(marc_xml TEXT, qualifying_match TEXT, new_9_to_set TEXT, force TEXT)
463 use MARC::File::XML (BinaryEncoding => 'utf8');
465 binmode(STDERR, ':bytes');
466 binmode(STDOUT, ':utf8');
467 binmode(STDERR, ':utf8');
469 my $marc_xml = shift;
470 my $qualifying_match = shift;
471 my $new_9_to_set = shift;
474 $marc_xml =~ s/(<leader>.........)./${1}a/;
477 $marc_xml = MARC::Record->new_from_xml($marc_xml);
480 #elog("could not parse $bibid: $@\n");
481 import MARC::File::XML (BinaryEncoding => 'utf8');
485 my @uris = $marc_xml->field('856');
486 return $marc_xml->as_xml_record() unless @uris;
488 foreach my $field (@uris) {
489 if ($field->as_string() =~ qr/$qualifying_match/) {
490 my $ind1 = $field->indicator('1');
491 if (!defined $ind1) { next; }
492 if ($ind1 ne '1' && $ind1 ne '4' && $force eq 'false') { next; }
493 if ($ind1 ne '1' && $ind1 ne '4' && $force eq 'true') { $field->set_indicator(1,'4'); }
494 my $ind2 = $field->indicator('2');
495 if (!defined $ind2) { next; }
496 if ($ind2 ne '0' && $ind2 ne '1' && $force eq 'false') { next; }
497 if ($ind2 ne '0' && $ind2 ne '1' && $force eq 'true') { $field->set_indicator(2,'0'); }
498 $field->add_subfields( '9' => $new_9_to_set );
502 return $marc_xml->as_xml_record();
506 DROP FUNCTION IF EXISTS migration_tools.owner_change_sf9_substring_match(TEXT,TEXT,TEXT,TEXT);
507 CREATE OR REPLACE FUNCTION migration_tools.owner_change_sf9_substring_match (marc_xml TEXT, substring_old_value TEXT, new_value TEXT, fix_indicators TEXT)
515 use MARC::File::XML (BinaryEncoding => 'utf8');
517 binmode(STDERR, ':bytes');
518 binmode(STDOUT, ':utf8');
519 binmode(STDERR, ':utf8');
521 my $marc_xml = shift;
522 my $substring_old_value = shift;
523 my $new_value = shift;
524 my $fix_indicators = shift;
526 $marc_xml =~ s/(<leader>.........)./${1}a/;
529 $marc_xml = MARC::Record->new_from_xml($marc_xml);
532 #elog("could not parse $bibid: $@\n");
533 import MARC::File::XML (BinaryEncoding => 'utf8');
537 my @uris = $marc_xml->field('856');
538 return $marc_xml->as_xml_record() unless @uris;
540 foreach my $field (@uris) {
541 my $ind1 = $field->indicator('1');
543 if ($ind1 ne '1' && $ind1 ne '4' && $fix_indicators eq 'true') {
544 $field->set_indicator(1,'4');
547 my $ind2 = $field->indicator('2');
549 if ($ind2 ne '0' && $ind2 ne '1' && $fix_indicators eq 'true') {
550 $field->set_indicator(2,'0');
553 if ($field->as_string('9') =~ qr/$substring_old_value/) {
554 $field->delete_subfield('9');
555 $field->add_subfields( '9' => $new_value );
557 $marc_xml->delete_field($field); # -- we're going to dedup and add them back
560 my %hash = (map { ($_->as_usmarc => $_) } @uris); # -- courtesy of an old Mike Rylander post :-)
561 $marc_xml->insert_fields_ordered( values( %hash ) );
563 return $marc_xml->as_xml_record();
567 DROP FUNCTION IF EXISTS migration_tools.owner_change_sf9_substring_match2(TEXT,TEXT,TEXT,TEXT,TEXT);
568 CREATE OR REPLACE FUNCTION migration_tools.owner_change_sf9_substring_match2 (marc_xml TEXT, qualifying_match TEXT, substring_old_value TEXT, new_value TEXT, fix_indicators TEXT)
576 use MARC::File::XML (BinaryEncoding => 'utf8');
578 binmode(STDERR, ':bytes');
579 binmode(STDOUT, ':utf8');
580 binmode(STDERR, ':utf8');
582 my $marc_xml = shift;
583 my $qualifying_match = shift;
584 my $substring_old_value = shift;
585 my $new_value = shift;
586 my $fix_indicators = shift;
588 $marc_xml =~ s/(<leader>.........)./${1}a/;
591 $marc_xml = MARC::Record->new_from_xml($marc_xml);
594 #elog("could not parse $bibid: $@\n");
595 import MARC::File::XML (BinaryEncoding => 'utf8');
599 my @unqualified_uris = $marc_xml->field('856');
601 foreach my $field (@unqualified_uris) {
602 if ($field->as_string() =~ qr/$qualifying_match/) {
606 return $marc_xml->as_xml_record() unless @uris;
608 foreach my $field (@uris) {
609 my $ind1 = $field->indicator('1');
611 if ($ind1 ne '1' && $ind1 ne '4' && $fix_indicators eq 'true') {
612 $field->set_indicator(1,'4');
615 my $ind2 = $field->indicator('2');
617 if ($ind2 ne '0' && $ind2 ne '1' && $fix_indicators eq 'true') {
618 $field->set_indicator(2,'0');
621 if ($field->as_string('9') =~ qr/$substring_old_value/) {
622 $field->delete_subfield('9');
623 $field->add_subfields( '9' => $new_value );
625 $marc_xml->delete_field($field); # -- we're going to dedup and add them back
628 my %hash = (map { ($_->as_usmarc => $_) } @uris); # -- courtesy of an old Mike Rylander post :-)
629 $marc_xml->insert_fields_ordered( values( %hash ) );
631 return $marc_xml->as_xml_record();
636 DROP FUNCTION IF EXISTS migration_tools.strip_tag(TEXT,TEXT);
637 CREATE OR REPLACE FUNCTION migration_tools.strip_tag(marc TEXT, tag TEXT)
645 use MARC::File::XML (BinaryEncoding => 'utf8');
647 binmode(STDERR, ':bytes');
648 binmode(STDOUT, ':utf8');
649 binmode(STDERR, ':utf8');
651 my $marc_xml = shift;
654 $marc_xml =~ s/(<leader>.........)./${1}a/;
657 $marc_xml = MARC::Record->new_from_xml($marc_xml);
660 #elog("could not parse $bibid: $@\n");
661 import MARC::File::XML (BinaryEncoding => 'utf8');
665 my @fields = $marc_xml->field($tag);
666 return $marc_xml->as_xml_record() unless @fields;
668 $marc_xml->delete_fields(@fields);
670 return $marc_xml->as_xml_record();
674 -- removes tags from record based on tag, subfield and evidence
675 -- example: strip_tag(marc, '500', 'a', 'gift') will remove 500s with 'gift' as a part of the $a
676 DROP FUNCTION IF EXISTS migration_tools.strip_tag(TEXT,TEXT,TEXT,TEXT);
677 CREATE OR REPLACE FUNCTION migration_tools.strip_tag(marc TEXT, tag TEXT, subfield TEXT, evidence TEXT)
685 use MARC::File::XML (BinaryEncoding => 'utf8');
687 binmode(STDERR, ':bytes');
688 binmode(STDOUT, ':utf8');
689 binmode(STDERR, ':utf8');
691 my $marc_xml = shift;
693 my $subfield = shift;
694 my $evidence = shift;
696 $marc_xml =~ s/(<leader>.........)./${1}a/;
699 $marc_xml = MARC::Record->new_from_xml($marc_xml);
702 #elog("could not parse $bibid: $@\n");
703 import MARC::File::XML (BinaryEncoding => 'utf8');
707 my @fields = $marc_xml->field($tag);
708 return $marc_xml->as_xml_record() unless @fields;
710 my @fields_to_delete;
712 foreach my $f (@fields) {
713 my $sf = lc($f->as_string($subfield));
714 if ($sf =~ m/$evidence/) { push @fields_to_delete, $f; }
717 $marc_xml->delete_fields(@fields_to_delete);
719 return $marc_xml->as_xml_record();
723 -- consolidate marc tag
724 DROP FUNCTION IF EXISTS migration_tools.consolidate_tag(TEXT,TEXT);
725 CREATE OR REPLACE FUNCTION migration_tools.consolidate_tag(marc TEXT, tag TEXT)
733 use MARC::File::XML (BinaryEncoding => 'utf8');
735 binmode(STDERR, ':bytes');
736 binmode(STDOUT, ':utf8');
737 binmode(STDERR, ':utf8');
739 my $marc_xml = shift;
742 $marc_xml =~ s/(<leader>.........)./${1}a/;
745 $marc_xml = MARC::Record->new_from_xml($marc_xml);
748 #elog("could not parse $bibid: $@\n");
749 import MARC::File::XML (BinaryEncoding => 'utf8');
753 my @fields = $marc_xml->field($tag);
754 return $marc_xml->as_xml_record() unless @fields;
756 my @combined_subfield_refs = ();
757 my @combined_subfields = ();
758 foreach my $field (@fields) {
759 my @subfield_refs = $field->subfields();
760 push @combined_subfield_refs, @subfield_refs;
763 my @sorted_subfield_refs = reverse sort { $a->[0] <=> $b->[0] } @combined_subfield_refs;
765 while ( my $tuple = pop( @sorted_subfield_refs ) ) {
766 my ($code,$data) = @$tuple;
767 unshift( @combined_subfields, $code, $data );
770 $marc_xml->delete_fields(@fields);
772 my $new_field = new MARC::Field(
774 $fields[0]->indicator(1),
775 $fields[0]->indicator(2),
779 $marc_xml->insert_grouped_field( $new_field );
781 return $marc_xml->as_xml_record();
785 CREATE OR REPLACE FUNCTION migration_tools.set_leader (TEXT, INT, TEXT) RETURNS TEXT AS $$
786 my ($marcxml, $pos, $value) = @_;
793 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
794 my $leader = $marc->leader();
795 substr($leader, $pos, 1) = $value;
796 $marc->leader($leader);
797 $xml = $marc->as_xml_record;
798 $xml =~ s/^<\?.+?\?>$//mo;
800 $xml =~ s/>\s+</></sgo;
803 $$ LANGUAGE PLPERLU STABLE;
805 CREATE OR REPLACE FUNCTION migration_tools.set_008 (TEXT, INT, TEXT) RETURNS TEXT AS $$
806 my ($marcxml, $pos, $value) = @_;
813 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
814 my $f008 = $marc->field('008');
817 my $field = $f008->data();
818 substr($field, $pos, 1) = $value;
819 $f008->update($field);
820 $xml = $marc->as_xml_record;
821 $xml =~ s/^<\?.+?\?>$//mo;
823 $xml =~ s/>\s+</></sgo;
827 $$ LANGUAGE PLPERLU STABLE;
829 CREATE OR REPLACE FUNCTION migration_tools.insert_tags (TEXT, TEXT) RETURNS TEXT AS $$
831 my ($marcxml, $tags) = @_;
839 my $marc = MARC::Record->new_from_xml($marcxml, 'UTF-8');
840 my $to_insert = MARC::Record->new_from_xml("<record>$tags</record>", 'UTF-8');
844 foreach my $field ( $marc->fields() ) {
845 push @incumbents, $field->as_formatted();
848 foreach $field ( $to_insert->fields() ) {
849 if (!grep {$_ eq $field->as_formatted()} @incumbents) {
850 $marc->insert_fields_ordered( ($field) );
854 $xml = $marc->as_xml_record;
855 $xml =~ s/^<\?.+?\?>$//mo;
857 $xml =~ s/>\s+</></sgo;
862 $$ LANGUAGE PLPERLU STABLE;