From 5ef7657cf5763844fea54c1feb7a99146b96e3d8 Mon Sep 17 00:00:00 2001 From: djfiander Date: Tue, 11 Nov 2008 02:46:30 +0000 Subject: [PATCH] Check for compressibility at parse/load time, not during formatting.. Compress across volume boundaries when issues are numbered continuously (eg, Economist) git-svn-id: svn://svn.open-ils.org/ILS/trunk@11126 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm | 54 ++++++---------------- .../src/perlmods/OpenILS/Utils/MFHD/Caption.pm | 28 +++++++++++ .../src/perlmods/OpenILS/Utils/MFHD/Holding.pm | 24 ++++++++++ 3 files changed, 67 insertions(+), 39 deletions(-) diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm index 42911c4436..6a6d6103b9 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD.pm @@ -16,6 +16,7 @@ sub new { $self->{RECORD} = $rec; $self->{CAPTIONS} = {}; + $self->{COMPRESSIBLE} = (substr($rec->leader, 17, 1) =~ /[45]/); foreach my $field ('853', '854', '855') { my $captions = {}; @@ -27,6 +28,9 @@ sub new { carp "Multiple unlabelled MFHD captions"; } $captions->{$cap_id} = new MFHD::Caption($caption); + if ($self->{COMPRESSIBLE}) { + $self->{COMPRESSIBLE} &&= $captions->{$cap_id}->compressible; + } } $self->{CAPTIONS}->{$field} = $captions; } @@ -37,18 +41,24 @@ sub new { ($cap_field = $field) =~ s/6/5/; - foreach my $holding ($rec->field($field)) { + foreach my $hfield ($rec->field($field)) { my $linkage; my ($link_id, $seqno); + my $holding; - $linkage = $holding->subfield('8'); + $linkage = $hfield->subfield('8'); ($link_id, $seqno) = split(/\./, $linkage); if (!exists $holdings->{$link_id}) { $holdings->{$link_id} = {}; } - $holdings->{$link_id}->{$seqno} = - new MFHD::Holding($seqno, $holding, $self->{CAPTIONS}->{$cap_field}->{$link_id}); + $holding = new MFHD::Holding($seqno, $hfield, + $self->{CAPTIONS}->{$cap_field}->{$link_id}); + $holdings->{$link_id}->{$seqno} = $holding; + + if ($self->{COMPRESSIBLE}) { + $self->{COMPRESSIBLE} &&= $holding->validate; + } } $self->{HOLDINGS}->{$field} = $holdings; } @@ -57,44 +67,10 @@ sub new { return $self; } -# -# validate_captions: confirm that fields specified for holdings -# data all have captions assigned to them -# -sub validate_captions { - my $self = shift; - - foreach my $cap_fieldno ('853' .. '855') { - foreach my $cap_id ($self->captions($cap_fieldno)) { - my $enum_fieldno; - ($enum_fieldno = $cap_fieldno) =~ s/5/6/; - foreach my $enum ($self->holdings($enum_fieldno, $cap_id)) { - foreach my $key (keys %{$enum->{ENUMS}}) { - if (!exists $enum->{CAPTION}->{ENUMS}->{$key}) { - print "$key doesn't exist: ", Dumper($enum); - return 0; - } - } - } - } - return 1; - } -} - sub compressible { my $self = shift; - my $leader = $self->{RECORD}->leader; - my $holdings_level = substr($leader, 17, 1); - - # Can only compress level 4 detailed holdings - # or detailed holdings with piece designation - return 0 unless (($holdings_level == 4) || ($holdings_level = 5)); - - # Can only compress if fields specified in each enumeration are - # defined in the corresponding caption - return 0 unless $self->validate_captions; - return 1; + return $self->{COMPRESSIBLE}; } sub captions { diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm index b1abc20f54..345ab52fca 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Caption.pm @@ -19,6 +19,7 @@ sub new $self->{PATTERN} = {}; $self->{COPY} = undef; $self->{UNIT} = undef; + $self->{COMPRESSIBLE} = 1; # until proven otherwise foreach my $subfield ($caption->subfields) { my ($key, $val) = @$subfield; @@ -59,10 +60,37 @@ sub new } } + # subsequent levels of enumeration (primary and alternate) + # If an enumeration level doesn't document the number + # of "issues" per "volume", or whether numbering of issues + # restarts, then we can't compress. + foreach my $key ('b', 'c', 'd', 'e', 'f', 'h') { + if (exists $self->{ENUMS}->{$key}) { + my $pattern = $self->{ENUMS}->{$key}; + if (!$pattern->{RESTART} || !$pattern->{COUNT} + || ($pattern->{COUNT} eq 'var') + || ($pattern->{COUNT} eq 'und')) { + $self->{COMPRESSIBLE} = 0; + last; + } + } + } + + # If there's a $x subfield and a $j, then it's compressible + if (exists $self->{PATTERN}->{x} && exists $self->{CHRONS}->{'j'}) { + $self->{COMPRESSIBLE} = 1; + } + bless ($self, $class); return $self; } +sub compressible { + my $self = shift; + + return $self->{COMPRESSIBLE}; +} + sub caption { my $self = shift; my $key; diff --git a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm index 422e73143c..395de87343 100755 --- a/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm +++ b/Open-ILS/src/perlmods/OpenILS/Utils/MFHD/Holding.pm @@ -165,8 +165,18 @@ sub next { sub match { my $self = shift; my $pat = shift; + my $caption = $self->{CAPTION}; foreach my $key ('a'..'f') { + my $nextkey; + + ($nextkey = $key)++; + # If the next smaller enumeration exists, and is numbered + # continuously, then we don't need to check this one, because + # gaps in issue numbering matter, not changes in volume numbering + next if (exists $self->{ENUMS}->{$nextkey} + && !$caption->{ENUMS}->{$nextkey}->{RESTART}); + # If a subfield exists in $self but not in $pat, or vice versa # or if the field has different values, then fail if (exists($self->{ENUMS}->{$key}) != exists($pat->{$key}) @@ -178,4 +188,18 @@ sub match { return 1; } +# +# Check that all the fields in a holdings statement are +# included in the corresponding caption. +# +sub validate { + my $self = shift; + + foreach my $key (keys %{$self->{ENUMS}}) { + if (!exists $self->{CAPTION}->{ENUMS}->{$key}) { + return 0; + } + } + return 1; +} 1; -- 2.11.0