#!/usr/bin/perl use strict; use warnings; use XML::Twig; use YAML::Tiny; use Getopt::Long; use Equinox::Migration::SubfieldMapper; $| = 1; my $c = initialize(); my $marcxml = shift; my $copyid = 0; my $holdings; my $count = 0; my $total = `grep -c 'new; my $t = XML::Twig->new( twig_handlers => { record => \&record } ); $t->parsefile($marcxml); write_sample_fieds(); sub record { my($t, $r)= @_; $holdings = {}; my @dfields = $r->children('datafield'); for my $d (@dfields) { process_datafields($d); } write_data_out(); $r->purge; $count++; $percent = int(($count / $total) * 100); print "\r$percent% done ($count)";# if ($percent != $prevper); $prevper = $percent; } sub process_datafields { my ($d) = @_; my $tag = $d->{'att'}->{'tag'}; if ($tag == 903) { my $s = $d->first_child('subfield'); $holdings->{id} = $s->text;; } elsif ($c->{map}->has($tag)) { push @{$holdings->{copies}}, { tag => $tag }; my @subs = $d->children('subfield'); for my $sub (@subs) { process_subs($tag,$sub) } } } sub process_subs { my ($tag, $sub) = @_; my $code = $sub->{'att'}->{'code'}; unless ($c->{map}->has($tag, $code)) { # this is a subfield code we don't have mapped. report on it if this is a sample tag push @{$c->{sample}{$tag}}, $code if defined $c->{sample}{tag}; return; } my $copy = $holdings->{copies}[-1]; my $field = $c->{map}->field($tag, $code); if ($c->{map}->mod($field) eq 'multi') { my $name = $tag . $code; push @{$copy->{multi}{$name}}, $sub->text; } else { $copy->{uni}{$code} = $sub->text; } } #------------------------------------------------ sub write_data_out { my $i = 0; for my $copy (@{$holdings->{copies}}) { print HOLDINGS $holdings->{id}, "\t$i\t", $copy->{tag}; for ( sort keys %{ $c->{map}{fields} } ) { if (defined $copy->{uni}{$_->{sub}}) { print HOLDINGS "\t", $copy->{uni}{$_->{sub}}; } else { print HOLDINGS "\t"; } } print HOLDINGS "\n"; for my $m (sort keys %{$copy->{multi}}) { my $fh = $c->{files}{multi}{$m}; print $fh join("\t", $holdings->{id}, $i, @{$copy->{multi}{$m}}), "\n"; } $i++; } } sub write_sample_fields { } #------------------------------------------------ sub initialize { my $c = {}; my @missing = (); # set mode on existing filehandles binmode(STDIN, ':utf8'); my $rc = GetOptions( $c, 'sample|s=s', 'map|m=s', 'ils=s', 'prefix|p=s', 'help|h', ); show_help() unless $rc; show_help() if ($c->{help}); my @keys = keys %{$c}; show_help() unless (@ARGV and @keys); for my $key ('prefix', 'map', 'ils') { push @missing, $key unless $c->{$key} } if (@missing) { print "Required option: ", join(', ', @missing), " missing!\n"; show_help(); } # generate subfield map $c->{map} = Equinox::Migration::SubfieldMapper->new( file => $c->{map} ); # explode sample tags string if (defined $c->{sample}) { my $sample = $c->{sample}; $c->{sample} = {}; for (split /,/, $c->{sample}) { $c->{sample}{$_} = []; } } # open required files open HOLDINGS, '>', ($c->{prefix} . ".holdings.pg"); for my $f (keys %{$c->{map}{fields}}) { if ($c->{map}->mod($f)) { open my $mfh, '>', join('.', $c->{prefix}, "holdings", $c->{map}{fields}{$f}{tag}, $c->{map}{fields}{$f}{sub}, "pg"); $c->{files}{multi}{ ($c->{map}{fields}{$f}{tag} . $c->{map}{fields}{$f}{sub}) } = $mfh; } } # print file headers print HOLDINGS "BEGIN;\n"; print HOLDINGS "CREATE TABLE ", $c->{prefix}, ".asset_copy_", $c->{ils}; print HOLDINGS $c->{library} if (defined $c->{library}); print HOLDINGS " ("; for ( sort keys %{ $c->{map}{fields} } ) { print HOLDINGS "l_", $_, " TEXT, "; } print HOLDINGS ") INHERITS FROM (", $c->{prefix}, ".asset_copy);\n"; print HOLDINGS "COPY ", $c->{prefix}, ".asset_copy_", $c->{ils}; print HOLDINGS $c->{library} if (defined $c->{library}); print HOLDINGS " ("; for ( sort keys %{ $c->{map}{fields} } ) { print HOLDINGS "l_", $_, ", "; } print HOLDINGS ") FROM STDIN;\n"; return $c; } sub show_help { print <