added join_subfields_with and include_subfields [0.21]
authorDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 9 Jul 2006 12:12:57 +0000 (12:12 +0000)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Sun, 9 Jul 2006 12:12:57 +0000 (12:12 +0000)
git-svn-id: file:///home/dpavlin/svn/Biblio-Isis/trunk@57 4670fa4d-42ec-0310-ab5b-a66af6943492

lib/Biblio/Isis.pm
t/2_isis.t

index a87994f..e4de0f6 100644 (file)
@@ -7,7 +7,7 @@ use File::Glob qw(:globally :nocase);
 BEGIN {
        use Exporter ();
        use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
-       $VERSION     = 0.20;
+       $VERSION     = 0.21;
        @ISA         = qw (Exporter);
        #Give a hoot don't pollute, do not export more than needed by default
        @EXPORT      = qw ();
@@ -88,6 +88,7 @@ Open ISIS database
                $v =~ s#foo#bar#g;
        },
        debug => 1,
+       join_subfields_with => ' ; ',
  );
 
 Options are described below:
@@ -119,6 +120,12 @@ Filter code ref which will be used before data is converted to hash.
 
 Dump a B<lot> of debugging output even at level 1. For even more increase level.
 
+=item join_subfields_with
+
+Define delimiter which will be used to join repeatable subfields. This
+option is included to support lagacy application written against version
+older than 0.21 of this module. By default, it disabled. See L</to_hash>.
+
 =back
 
 =cut
@@ -489,15 +496,58 @@ following structure:
        'a' => [ 'foo', 'bar', 'baz' ],
   }]
 
+Or in more complex example of
+
+  902  ^aa1^aa2^aa3^bb1^aa4^bb2^cc1^aa5
+
+it will create
+
+  902   => [
+       { a => ["a1", "a2", "a3", "a4", "a5"], b => ["b1", "b2"], c => "c1" },
+  ],
+
+This behaviour can be changed using C<join_subfields_with> option to L</new>,
+in which case C<to_hash> will always create single value for each subfield.
+This will change result to:
+
+
+
 This method will also create additional field C<000> with MFN.
 
 There is also more elaborative way to call C<to_hash> like this:
 
   my $hash = $isis->to_hash({
        mfn => 42,
-       include_empty_subfields => 1,
+       include_subfields => 1,
   });
 
+Each option controll creation of hash:
+
+=over 4
+
+=item mfn
+
+Specify MFN number of record
+
+=item include_subfields
+
+This option will create additional key in hash called C<subfields> which will
+have original record subfield order and index to that subfield like this:
+
+  902   => [ {
+       a => ["a1", "a2", "a3", "a4", "a5"],
+       b => ["b1", "b2"],
+       c => "c1",
+       subfields => ["a", 0, "a", 1, "a", 2, "b", 0, "a", 3, "b", 1, "c", 0, "a", 4],
+  } ],
+
+=item join_subfields_with
+
+Define delimiter which will be used to join repeatable subfields. You can
+specify option here instead in L</new> if you want to have per-record controll.
+
+=back
+
 =cut
 
 sub to_hash {
@@ -517,8 +567,12 @@ sub to_hash {
 
        my $row = $self->fetch($mfn) || return;
 
-       foreach my $k (keys %{$row}) {
-               foreach my $l (@{$row->{$k}}) {
+       my $j_rs = $arg->{join_repeatable_subfields};
+       $j_rs = $self->{join_repeatable_subfields} unless(defined($j_rs));
+       my $i_sf = $arg->{include_subfields};
+
+       foreach my $f_nr (keys %{$row}) {
+               foreach my $l (@{$row->{$f_nr}}) {
 
                        # filter output
                        if ($self->{'hash_filter'}) {
@@ -527,6 +581,7 @@ sub to_hash {
                        }
 
                        my $val;
+                       my $r_sf;       # repeatable subfields in this record
 
                        # has identifiers?
                        ($val->{'i1'},$val->{'i2'}) = ($1,$2) if ($l =~ s/^([01 #])([01 #])\^/\^/);
@@ -536,26 +591,42 @@ sub to_hash {
                                foreach my $t (split(/\^/,$l)) {
                                        next if (! $t);
                                        my ($sf,$v) = (substr($t,0,1), substr($t,1));
-                                       # FIXME make this option !
+                                       # XXX this might be option, but why?
                                        next unless ($v);
-#                                      warn "### $k^$sf:$v",$/ if ($self->{debug} > 1);
+#                                      warn "### $f_nr^$sf:$v",$/ if ($self->{debug} > 1);
 
-                                       # FIXME array return optional, by default unroll to ' ; '
                                        if (ref( $val->{$sf} ) eq 'ARRAY') {
 
                                                push @{ $val->{$sf} }, $v;
+
+                                               # record repeatable subfield it it's offset
+                                               push @{ $val->{subfields} }, ( $sf, $#{ $val->{$sf} } ) if (! $j_rs && $i_sf);
+                                               $r_sf->{$sf}++;
+
                                        } elsif (defined( $val->{$sf} )) {
+
                                                # convert scalar field to array
                                                $val->{$sf} = [ $val->{$sf}, $v ];
+
+                                               push @{ $val->{subfields} }, ( $sf, 1 ) if (! $j_rs && $i_sf);
+                                               $r_sf->{$sf}++;
+
                                        } else {
                                                $val->{$sf} = $v;
+                                               push @{ $val->{subfields} }, ( $sf, 0 ) if ($i_sf);
                                        }
                                }
                        } else {
                                $val = $l;
                        }
 
-                       push @{$rec->{$k}}, $val;
+                       if ($j_rs) {
+                               map {
+                                       $val->{$_} = join($j_rs, @{ $val->{$_} });
+                               } keys %$r_sf
+                       }
+
+                       push @{$rec->{$f_nr}}, $val;
                }
        }
 
@@ -670,10 +741,22 @@ know any details about it's version.
 
 =head1 VERSIONS
 
-You can find version dependencies documented here
+As this is young module, new features are added in subsequent version. It's
+a good idea to specify version when using this module like this:
+
+  use Biblio::Isis 0.21
+
+Below is list of changes in specific version of module (so you can target
+older versions if you really have to):
 
 =over 8 
 
+=item 0.21
+
+Added C<join_subfields_with> to L</new> and L</to_hash>.
+
+Added C<include_subfields> to L</to_hash>.
+
 =item 0.20
 
 Added C<< $isis->mfn >>, support for repeatable subfields and
index a7b9405..239bbe7 100755 (executable)
@@ -3,7 +3,7 @@
 use strict;
 use blib;
 
-use Test::More tests => 130;
+use Test::More tests => 132;
 use File::Spec;
 
 BEGIN {
@@ -18,7 +18,8 @@ BEGIN {
 }
 
 
-my $debug = length( shift @ARGV );
+my $debug = shift @ARGV;
+$debug = length( $debug ) if ($debug);
 my $isis;
 
 my $path_winisis = File::Spec->catfile('data', 'winisis', 'BIBL');
@@ -237,6 +238,25 @@ cmp_ok($ascii, 'eq', <<'__END_OF_ASCII__', 'to_ascii output');
 902    ^aa1^aa2^aa3^bb1^aa4^bb2^cc1^aa5
 __END_OF_ASCII__
 
-
 ok(my $hash2 = $isis->to_hash({ mfn => $isis->mfn }), 'to_hash(mfn)');
 is_deeply( $hash2, $hash, 'same hash' );
+
+ok($hash = $isis->to_hash({ mfn => $isis->mfn, include_subfields => 1 }), 'to_hash(mfn,include_subfields)');
+diag "to_hash = ",Dumper( $hash ) if ($debug);
+is_deeply( $hash, {
+  "000" => [42],
+  900   => [
+       { a => "900a", b => "900b", c => "900c", subfields => ["a", 0, "b", 0, "c", 0] },
+  ],
+  901   => [
+       { a => "901a-1", b => "901b-1", c => "901c-1", subfields => ["a", 0, "b", 0, "c", 0] },
+       { a => "901a-2", b => "901b-2", subfields => ["a", 0, "b", 0] },
+       { a => "901a-3", subfields => ["a", 0] },
+  ],
+  902   => [
+       { a => ["a1", "a2", "a3", "a4", "a5"], b => ["b1", "b2"], c => "c1",
+         subfields => ["a", 0, "a", 1, "a", 2, "b", 0, "a", 3, "b", 1, "c", 0, "a", 4],
+       },
+  ],
+}, 'hash is_deeply');
+