/[webpac2]/trunk/lib/WebPAC/Normalize.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/lib/WebPAC/Normalize.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 721 by dpavlin, Fri Sep 29 12:27:47 2006 UTC revision 740 by dpavlin, Sat Oct 7 16:33:37 2006 UTC
# Line 2  package WebPAC::Normalize; Line 2  package WebPAC::Normalize;
2  use Exporter 'import';  use Exporter 'import';
3  @EXPORT = qw/  @EXPORT = qw/
4          _set_rec _set_lookup          _set_rec _set_lookup
5            _set_load_row
6          _get_ds _clean_ds          _get_ds _clean_ds
7          _debug          _debug
8          _pack_subfields_hash          _pack_subfields_hash
# Line 26  use strict; Line 27  use strict;
27  #use base qw/WebPAC::Common/;  #use base qw/WebPAC::Common/;
28  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
29  use Storable qw/dclone/;  use Storable qw/dclone/;
30    use Carp qw/confess/;
31    
32  # debugging warn(s)  # debugging warn(s)
33  my $debug = 0;  my $debug = 0;
# Line 37  WebPAC::Normalize - describe normalisato Line 39  WebPAC::Normalize - describe normalisato
39    
40  =head1 VERSION  =head1 VERSION
41    
42  Version 0.20  Version 0.22
43    
44  =cut  =cut
45    
46  our $VERSION = '0.20';  our $VERSION = '0.22';
47    
48  =head1 SYNOPSIS  =head1 SYNOPSIS
49    
# Line 67  All other functions are available for us Line 69  All other functions are available for us
69  Return data structure  Return data structure
70    
71    my $ds = WebPAC::Normalize::data_structure(    my $ds = WebPAC::Normalize::data_structure(
72          lookup => $lookup_variable,          lookup => $lookup_hash,
73          row => $row,          row => $row,
74          rules => $normalize_pl_config,          rules => $normalize_pl_config,
75          marc_encoding => 'utf-8',          marc_encoding => 'utf-8',
76          config => $config,          config => $config,
77            load_row_coderef => sub {
78                    my ($database,$input,$mfn) = shift;
79                    $store->load_row( database => $database, input => $input, id => $mfn );
80            },
81    );    );
82    
83  Options C<row>, C<rules> and C<log> are mandatory while all  Options C<row>, C<rules> and C<log> are mandatory while all
84  other are optional.  other are optional.
85    
86    C<load_row_coderef> is closure only used when executing lookups, so they will
87    die if it's not defined.
88    
89  This function will B<die> if normalizastion can't be evaled.  This function will B<die> if normalizastion can't be evaled.
90    
91  Since this function isn't exported you have to call it with  Since this function isn't exported you have to call it with
# Line 84  C<WebPAC::Normalize::data_structure>. Line 93  C<WebPAC::Normalize::data_structure>.
93    
94  =cut  =cut
95    
96    my $load_row_coderef;
97    
98  sub data_structure {  sub data_structure {
99          my $arg = {@_};          my $arg = {@_};
100    
# Line 91  sub data_structure { Line 102  sub data_structure {
102          die "need normalisation argument" unless ($arg->{rules});          die "need normalisation argument" unless ($arg->{rules});
103    
104          no strict 'subs';          no strict 'subs';
105          _set_lookup( $arg->{lookup} ) if (defined( $arg->{lookup} ));          _set_lookup( $arg->{lookup} ) if defined($arg->{lookup});
106          _set_rec( $arg->{row} );          _set_rec( $arg->{row} );
107          _set_config( $arg->{config} ) if (defined( $arg->{config} ));          _set_config( $arg->{config} ) if defined($arg->{config});
108          _clean_ds( %{ $arg } );          _clean_ds( %{ $arg } );
109            $load_row_coderef = $arg->{load_row_coderef};
110    
111          eval "$arg->{rules}";          eval "$arg->{rules}";
112          die "error evaling $arg->{rules}: $@\n" if ($@);          die "error evaling $arg->{rules}: $@\n" if ($@);
113    
# Line 199  sub _get_lookup { Line 212  sub _get_lookup {
212          return $lookup;          return $lookup;
213  }  }
214    
215    =head2 _set_load_row
216    
217    Setup code reference which will return L<data_structure> from
218    L<WebPAC::Store>
219    
220      _set_load_row(sub {
221                    my ($database,$input,$mfn) = @_;
222                    $store->load_row( database => $database, input => $input, id => $mfn );
223      });
224    
225    =cut
226    
227    sub _set_load_row {
228            my $coderef = shift;
229            confess "argument isn't CODE" unless ref($coderef) eq 'CODE';
230    
231            $load_row_coderef = $coderef;
232    }
233    
234  =head2 _get_marc_fields  =head2 _get_marc_fields
235    
236  Get all fields defined by calls to C<marc>  Get all fields defined by calls to C<marc>
# Line 941  sub first { Line 973  sub first {
973    
974  Consult lookup hashes for some value  Consult lookup hashes for some value
975    
976    @v = lookup( $v );    @v = lookup(
977    @v = lookup( @v );          sub {
978                    'ffkk/peri/mfn'.rec('000')
979            },
980            'ffkk','peri','200-a-200-e',
981            sub {
982                    first(rec(200,'a')).' '.first(rec('200','e'))
983            }
984      );
985    
986    Code like above will be B<automatically generated> using L<WebPAC::Parse> from
987    normal lookup definition in C<conf/lookup/something.pl> which looks like:
988    
989  FIXME B<currently this one is broken!>    lookup(
990            # which results to return from record recorded in lookup
991            sub { 'ffkk/peri/mfn' . rec('000') },
992            # from which database and input
993            'ffkk','peri',
994            # such that following values match
995            sub { first(rec(200,'a')) . ' ' . first(rec('200','e')) },
996            # if this part is missing, we will try to match same fields
997            # from lookup record and current one, or you can override
998            # which records to use from current record using
999            sub { rec('900','x') . ' ' . rec('900','y') },
1000      )
1001    
1002    You can think about this lookup as SQL (if that helps):
1003    
1004      select
1005            sub { what }
1006      from
1007            database, input
1008      where
1009        sub { filter from lookuped record }
1010      having
1011        sub { optional filter on current record }
1012    
1013    Easy as pie, right?
1014    
1015  =cut  =cut
1016    
1017  sub lookup {  sub lookup {
1018          my $k = shift or return;          my ($what, $database, $input, $key, $having) = @_;
1019          return unless (defined($lookup->{$k}));  
1020          if (ref($lookup->{$k}) eq 'ARRAY') {          confess "lookup needs 5 arguments: what, database, input, key, having" unless ($#_ == 4);
1021                  return @{ $lookup->{$k} };  
1022            warn "## lookup ($database, $input, $key)", $/ if ($debug > 1);
1023            return unless (defined($lookup->{$database}->{$input}->{$key}));
1024    
1025            confess "lookup really need load_row_coderef added to data_structure\n" unless ($load_row_coderef);
1026    
1027            my $mfns;
1028            my @having = $having->();
1029    
1030            warn "## having = ", dump( @having ) if ($debug > 2);
1031    
1032            foreach my $h ( @having ) {
1033                    if (defined($lookup->{$database}->{$input}->{$key}->{$h})) {
1034                            warn "lookup for $database/$input/$key/$h return ",dump($lookup->{$database}->{$input}->{$key}->{$h}),"\n";
1035                            $mfns->{$_}++ foreach keys %{ $lookup->{$database}->{$input}->{$key}->{$h} };
1036                    }
1037            }
1038    
1039            return unless ($mfns);
1040    
1041            my @mfns = sort keys %$mfns;
1042    
1043            warn "# lookup loading $database/$input/$key mfn ", join(",",@mfns)," having ",dump(@having),"\n";
1044    
1045            my $old_rec = $rec;
1046            my @out;
1047    
1048            foreach my $mfn (@mfns) {
1049                    $rec = $load_row_coderef->( $database, $input, $mfn );
1050    
1051                    warn "got $database/$input/$mfn = ", dump($rec), $/;
1052    
1053                    my @vals = $what->();
1054    
1055                    push @out, ( @vals );
1056    
1057                    warn "lookup for mfn $mfn returned ", dump(@vals), $/;
1058            }
1059    
1060    #       if (ref($lookup->{$k}) eq 'ARRAY') {
1061    #               return @{ $lookup->{$k} };
1062    #       } else {
1063    #               return $lookup->{$k};
1064    #       }
1065    
1066            $rec = $old_rec;
1067    
1068            warn "## lookup returns = ", dump(@out), $/;
1069    
1070            if ($#out == 0) {
1071                    return $out[0];
1072          } else {          } else {
1073                  return $lookup->{$k};                  return @out;
1074          }          }
1075  }  }
1076    
1077  =head2 save_into_lookup  =head2 save_into_lookup
1078    
1079  Save value into lookup.  Save value into lookup. It associates current database, input
1080    and specific keys with one or more values which will be
1081    associated over MFN.
1082    
1083    MFN will be extracted from first occurence current of field 000
1084    in current record, or if it doesn't exist from L<_set_config> C<_mfn>.
1085    
1086    save_into_lookup($database,$input,$key,sub {    my $nr = save_into_lookup($database,$input,$key,sub {
1087          # code which produce one or more values          # code which produce one or more values
1088    });    });
1089    
1090  This function shouldn't be called directly, it's called from code created by L<WebPAC::Parser>.  It returns number of items saved.
1091    
1092    This function shouldn't be called directly, it's called from code created by
1093    L<WebPAC::Parser>.
1094    
1095  =cut  =cut
1096    
# Line 976  sub save_into_lookup { Line 1100  sub save_into_lookup {
1100          die "save_into_lookup needs input" unless defined($input);          die "save_into_lookup needs input" unless defined($input);
1101          die "save_into_lookup needs key" unless defined($key);          die "save_into_lookup needs key" unless defined($key);
1102          die "save_into_lookup needs CODE" unless ( defined($coderef) && ref($coderef) eq 'CODE' );          die "save_into_lookup needs CODE" unless ( defined($coderef) && ref($coderef) eq 'CODE' );
1103          my $mfn = $rec->{'000'}->[0] || die "mfn not defined or zero";  
1104            warn "## save_into_lookup rec = ", dump($rec), " config = ", dump($config), $/ if ($debug > 2);
1105    
1106            my $mfn =
1107                    defined($rec->{'000'}->[0])     ?       $rec->{'000'}->[0]      :
1108                    defined($config->{_mfn})        ?       $config->{_mfn}         :
1109                                                                                    die "mfn not defined or zero";
1110    
1111            my $nr = 0;
1112    
1113          foreach my $v ( $coderef->() ) {          foreach my $v ( $coderef->() ) {
1114                  $lookup->{$database}->{$input}->{$key}->{$v}->{$mfn}++;                  $lookup->{$database}->{$input}->{$key}->{$v}->{$mfn}++;
1115                  warn "# saved lookup $database/$input/$key [$v] $mfn\n" if ($debug > 1);                  warn "# saved lookup $database/$input/$key [$v] $mfn\n" if ($debug > 1);
1116                    $nr++;
1117          }          }
1118    
1119            return $nr;
1120  }  }
1121    
1122  =head2 config  =head2 config

Legend:
Removed from v.721  
changed lines
  Added in v.740

  ViewVC Help
Powered by ViewVC 1.1.26