add new parallel field modifier to extract_holdings
authorGalen Charlton <gmc@esilibrary.com>
Tue, 7 Aug 2012 14:56:40 +0000 (10:56 -0400)
committerGalen Charlton <gmc@esilibrary.com>
Tue, 7 Aug 2012 14:56:40 +0000 (10:56 -0400)
Some systems embed holdings data in pairs of fields with different tags.

For example, given a record like this:

852 $h235.45 ABC$p12345
852 $h456.79 DEF$p78990
961 $t2
961 $t3

and a mapping file using the parallel modifier:

call    852 h
barcode 852 p
mattype 961 t   m:parallel

extract_holdings will extract two item records:

l_call           l_barcode    l_mattype
--------------   ----------   ---------
245.45 ABC       12345        2
456.79 DEF       78990        3

Signed-off-by: Galen Charlton <gmc@esilibrary.com>

Equinox-Migration/lib/Equinox/Migration/MapDrivenMARCXMLProc.pm
extract_holdings

index be44ade..8208b8b 100644 (file)
@@ -37,9 +37,10 @@ our $VERSION = '1.005';
 
 my $dstore;
 my $sfmap;
-my @modlist = qw( multi ignoremulti bib required first concatenate );
+my @modlist = qw( multi ignoremulti bib required first concatenate parallel );
 my %allmods = ();
 my $multis = {};
+my $parallel_fields = {};
 my $reccount;
 my $verbose = 0;
 
@@ -70,7 +71,9 @@ sub new {
 
     $verbose = 1 if $args{verbose};
 
-    my $self = bless { multis => \$multis,
+    my $self = bless {
+                        multis => \$multis,
+                        parallel_fields => \$parallel_fields,
                      }, $class;
 
     # initialize map and taglist
@@ -118,7 +121,13 @@ sub parse_record {
                 my $fieldname = $sfmap->field($mappedtag, $mappedsub);
                 my $mods = $sfmap->mods($fieldname);
                 next if $mods->{multi};
-                $crec->{tags}[-1]{uni}{$mappedsub} = '';
+                if ($mods->{parallel}) {
+                    push @{ $crec->{tags}[-1]{parallel}{$mappedsub} }, '';
+                    $crec->{tags}[-1]{uni} = undef;
+                } else {
+                    $crec->{tags}[-1]{uni}{$mappedsub} = '';
+                    $crec->{tags}[-1]{parallel} = undef;
+                }
                 $crec->{tags}[-1]{multi} = undef;
                 $crec->{tags}[-1]{tag} = $mappedtag;
             }
@@ -155,7 +164,7 @@ sub process_field {
         return;
     }
     if ($sfmap->has($tag)) {
-        push @{$crec->{tags}}, { tag => $tag, uni => undef, multi => undef };
+        push @{$crec->{tags}}, { tag => $tag, uni => undef, multi => undef, parallel => undef };
         push @{$crec->{tmap}{$tag}}, (@{$crec->{tags}} - 1);
         my @subs = $field->children('subfield');
         for my $sub (@subs)
@@ -166,8 +175,13 @@ sub process_field {
             my $fieldname = $sfmap->field($tag, $mappedsub);
             my $mods = $sfmap->mods($fieldname);
             next if $mods->{multi};
-            $crec->{tags}[-1]{uni}{$mappedsub} = ''
-              unless defined $crec->{tags}[-1]{uni}{$mappedsub};
+            if ($mods->{parallel}) {
+                push @{ $crec->{tags}[-1]{parallel}{$mappedsub} }, ''
+                    unless defined $crec->{tags}[-1]{parallel}{$mappedsub};
+            } else {
+                $crec->{tags}[-1]{uni}{$mappedsub} = ''
+                    unless defined $crec->{tags}[-1]{uni}{$mappedsub};
+            }
         }
     }
 }
@@ -191,6 +205,12 @@ sub process_subs {
         return if ($sub->text =~ /$filter/i);
     }
 
+    if ($mods->{parallel}) {
+        $parallel_fields->{$tag}{$code} = 1;
+        push @{$dataf->{parallel}{$code}}, $sub->text;
+        return;
+    }
+
     # handle multi modifier
     if ($mods->{multi}) {
         $multis->{$tag}{$code} = 1;
@@ -289,6 +309,17 @@ sub get_multis {
     return $multis;
 }
 
+=head2 get_parallel_fields
+
+Returns hashref of C<{tag}{code}> for all mapped parallel fields
+
+=cut
+
+sub get_parallel_fields {
+    my ($self) = @_;
+    return $parallel_fields;
+}
+
 =head1 MODIFIERS
 
 MapDrivenMARCXMLProc implements the following modifiers, and passes
index e75b4b3..2cce000 100755 (executable)
@@ -62,6 +62,8 @@ sub extract_holdings {
           { open my $fh, ">", ($c->{prefix} . "-HOLDINGS-MULT-$t$s.pg"); $MULTIFILE{"$t$s"} = $fh }
     }
 
+    my $parallel_fields = $m->get_parallel_fields;
+
     my $i = 0; # record counter
     my $j = 0; # holdings counter
 
@@ -102,6 +104,22 @@ sub extract_holdings {
                     push @out, '';
                     next;
                 }
+
+                # handle parallel fields
+                if (exists($parallel_fields->{$othertag})) {
+                    my $num_fields = $#{ $rec->{tmap}{$othertag} };
+                    my $tag_idx;
+                    if ($holdidx > $num_fields) {
+                        $tag_idx = -1;
+                    } else {
+                        $tag_idx = $rec->{tmap}{$othertag}[$holdidx];
+                    }
+                    for my $sub ( sort keys %{ $parallel_fields->{$othertag } } ) {
+                        push @out, $tag_idx > -1 ? $rec->{tags}[$tag_idx]{parallel}{$sub}->[0] : '';
+                        print HOLDINGS "l_", $m->name($rec->{tags}[$tag_idx]{tag}, $sub), ", " unless $j;
+                    }
+                }
+
                 # handle only first other tag unless it is known to be multi
                 my $limit = 0;
                 if (exists($multis->{$othertag})) {