/[webpac2]/trunk/lib/WebPAC/Input/ISIS.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/Input/ISIS.pm

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

revision 113 by dpavlin, Wed Nov 23 00:14:05 2005 UTC revision 623 by dpavlin, Sat Aug 26 12:00:25 2006 UTC
# Line 3  package WebPAC::Input::ISIS; Line 3  package WebPAC::Input::ISIS;
3  use warnings;  use warnings;
4  use strict;  use strict;
5    
6  use WebPAC::Common;  use WebPAC::Input;
7  use base qw/WebPAC::Input WebPAC::Common/;  use Biblio::Isis 0.23;
 use Text::Iconv;  
8    
9  =head1 NAME  =head1 NAME
10    
11  WebPAC::Input::ISIS - support for CDS/ISIS source files  WebPAC::Input::ISIS - support for CDS/ISIS database files
12    
13  =head1 VERSION  =head1 VERSION
14    
15  Version 0.01  Version 0.06
16    
17  =cut  =cut
18    
19  our $VERSION = '0.01';  our $VERSION = '0.06';
20    
21    
 # auto-configure  
   
 my ($have_biblio_isis, $have_openisis) = (0,0);  
   
 eval "use Biblio::Isis 0.13;";  
 unless ($@) {  
         $have_biblio_isis = 1  
 } else {  
         eval "use OpenIsis;";  
         $have_openisis = 1 unless ($@);  
 }  
   
22  =head1 SYNOPSIS  =head1 SYNOPSIS
23    
24  Open CDS/ISIS, WinISIS or IsisMarc database using Biblio::Isis or OpenIsis  Open CDS/ISIS, WinISIS or IsisMarc database using C<Biblio::Isis>
25  module and read all records to memory.  and read all records to memory.
26    
27   my $isis = new WebPAC::Input::ISIS();   my $isis = new WebPAC::Input::ISIS();
28   $isis->open( filename => '/path/to/ISIS/ISIS' );   $isis->open( path => '/path/to/ISIS/ISIS' );
29    
30  =head1 FUNCTIONS  =head1 FUNCTIONS
31    
32  =head2 open  =head2 open_db
   
 This function will read whole database in memory and produce lookups.  
   
  $isis->open(  
         filename => '/data/ISIS/ISIS',  
         code_page => '852',  
         limit_mfn => 500,  
         start_mfn => 6000,  
         lookup => $lookup_obj,  
  );  
   
 By default, ISIS code page is assumed to be C<852>.  
33    
34  If optional parametar C<start_mfn> is set, this will be first MFN to read  Returns handle to database and size in records
 from database (so you can skip beginning of your database if you need to).  
35    
36  If optional parametar C<limit_mfn> is set, it will read just 500 records    my ($db,$size) = $isis->open_db(
37  from database in example above.          path => '/path/to/LIBRI'
38            filter => sub {
39                    my ($l,$field_nr) = @_;
40                    # do something with $l which is line of input file
41                    return $l;
42            },
43      }
44    
45  Returns size of database, regardless of C<start_mfn> and C<limit_mfn>  Options:
 parametars, see also C<$isis->size>.  
46    
47  =cut  =over 4
   
 sub open {  
         my $self = shift;  
         my $arg = {@_};  
   
         my $log = $self->_get_logger();  
48    
49          $log->logcroak("need filename") if (! $arg->{'filename'});  =item path
         my $code_page = $arg->{'code_page'} || '852';  
50    
51          $log->logdie("can't find database ",$arg->{'filename'}) unless (glob($arg->{'filename'}.'.*'));  path to CDS/ISIS database
52    
53          # store data in object  =back
         $self->{'isis_code_page'} = $code_page;  
         foreach my $v (qw/isis_filename start_mfn limit_mfn/) {  
                 $self->{$v} = $arg->{$v} if ($arg->{$v});  
         }  
   
         # create Text::Iconv object  
         my $cp = Text::Iconv->new($code_page,$self->{'code_page'});  
   
         $log->info("reading ISIS database '",$arg->{'filename'},"'");  
         $log->debug("isis code page: $code_page");  
   
         my ($isis_db,$db_size);  
   
         if ($have_openisis) {  
                 $log->debug("using OpenIsis perl bindings");  
                 $isis_db = OpenIsis::open($arg->{'filename'});  
                 $db_size = OpenIsis::maxRowid( $isis_db ) || 1;  
         } elsif ($have_biblio_isis) {  
                 $log->debug("using Biblio::Isis");  
                 use Biblio::Isis;  
                 $isis_db = new Biblio::Isis(  
                         isisdb => $arg->{'filename'},  
                         include_deleted => 1,  
                         hash_filter => sub {  
                                 my $l = shift || return;  
                                 $l = $cp->convert($l);  
                                 return $l;  
                         },  
                 );  
                 $db_size = $isis_db->count;  
   
                 unless ($db_size) {  
                         $log->logwarn("no records in database ", $arg->{'filename'}, ", skipping...");  
                         return;  
                 }  
   
         } else {  
                 $log->logdie("Can't find supported ISIS library for perl. I suggent that you install Bilbio::Isis from CPAN.");  
         }  
   
   
         my $startmfn = 1;  
         my $maxmfn = $db_size;  
   
         if (my $s = $self->{'start_mfn'}) {  
                 $log->info("skipping to MFN $s");  
                 $startmfn = $s;  
         } else {  
                 $self->{'start_mfn'} = $startmfn;  
         }  
   
         if ($self->{limit_mfn}) {  
                 $log->info("limiting to ",$self->{limit_mfn}," records");  
                 $maxmfn = $startmfn + $self->{limit_mfn} - 1;  
                 $maxmfn = $db_size if ($maxmfn > $db_size);  
         }  
   
         # store size for later  
         $self->{'size'} = ($maxmfn - $startmfn) ? ($maxmfn - $startmfn + 1) : 0;  
   
         $log->info("processing ",($maxmfn-$startmfn)." records using ",( $have_openisis ? 'OpenIsis' : 'Biblio::Isis'));  
   
   
         # read database  
         for (my $mfn = $startmfn; $mfn <= $maxmfn; $mfn++) {  
   
                 $log->debug("mfn: $mfn\n");  
   
                 my $rec;  
   
                 if ($have_openisis) {  
   
                         # read record using OpenIsis  
                         my $row = OpenIsis::read( $isis_db, $mfn );  
                         foreach my $k (keys %{$row}) {  
                                 if ($k ne "mfn") {  
                                         foreach my $l (@{$row->{$k}}) {  
                                                 $l = $cp->convert($l);  
                                                 # has subfields?  
                                                 my $val;  
                                                 if ($l =~ m/\^/) {  
                                                         foreach my $t (split(/\^/,$l)) {  
                                                                 next if (! $t);  
                                                                 $val->{substr($t,0,1)} = substr($t,1);  
                                                         }  
                                                 } else {  
                                                         $val = $l;  
                                                 }  
   
                                                 push @{$rec->{$k}}, $val;  
                                         }  
                                 } else {  
                                         push @{$rec->{'000'}}, $mfn;  
                                 }  
                         }  
   
                 } elsif ($have_biblio_isis) {  
                         $rec = $isis_db->to_hash($mfn);  
                 } else {  
                         $log->logdie("hum? implementation missing?");  
                 }  
   
                 if (! $rec) {  
                         $log->warn("record $mfn empty? skipping...");  
                         next;  
                 }  
   
                 # store  
                 if ($self->{'low_mem'}) {  
                         $self->{'db'}->put($mfn, $rec);  
                 } else {  
                         $self->{'data'}->{$mfn} = $rec;  
                 }  
   
                 # create lookup  
                 $self->{'lookup'}->add( $rec ) if ($self->{'lookup'} && can($self->{'lookup'}->add));  
   
                 $self->progress_bar($mfn,$maxmfn);  
   
         }  
   
         $self->{'current_mfn'} = -1;  
         $self->{'last_pcnt'} = 0;  
   
         $log->debug("max mfn: $maxmfn");  
   
         # store max mfn and return it.  
         $self->{'max_mfn'} = $maxmfn;  
   
         return $db_size;  
 }  
   
 =head2 fetch  
   
 Fetch next record from database. It will also displays progress bar.  
   
  my $rec = $isis->fetch;  
   
 Record from this function should probably go to C<data_structure> for  
 normalisation.  
54    
55  =cut  =cut
56    
57  sub fetch {  sub open_db {
58          my $self = shift;          my $self = shift;
59    
60          my $log = $self->_get_logger();          my $arg = {@_};
   
         $log->logconfess("it seems that you didn't load database!") unless ($self->{'current_mfn'});  
   
         if ($self->{'current_mfn'} == -1) {  
                 $self->{'current_mfn'} = $self->{'start_mfn'};  
         } else {  
                 $self->{'current_mfn'}++;  
         }  
   
         my $mfn = $self->{'current_mfn'};  
   
         if ($mfn > $self->{'max_mfn'}) {  
                 $self->{'current_mfn'} = $self->{'max_mfn'};  
                 $log->debug("at EOF");  
                 return;  
         }  
   
         $self->progress_bar($mfn,$self->{'max_mfn'});  
   
         my $rec;  
   
         if ($self->{'low_mem'}) {  
                 $rec = $self->{'db'}->get($mfn);  
         } else {  
                 $rec = $self->{'data'}->{$mfn};  
         }  
   
         $rec ||= 0E0;  
 }  
   
 =head2 pos  
61    
62  Returns current record number (MFN).          my $log = $self->_get_logger();
63    
64   print $isis->pos;          $log->info("opening ISIS database '$arg->{path}'");
65    
66  First record in database has position 1.          $log->debug("using Biblio::Isis");
67            my $isis_db = new Biblio::Isis(
68                    isisdb => $arg->{path},
69                    include_deleted => 1,
70                    hash_filter => $arg->{filter} ? sub { return $arg->{filter}->(@_); } : undef,
71            ) or $log->logdie("can't find database $arg->{path}");
72    
73  =cut          my $size = $isis_db->count;
74    
75  sub pos {          return ($isis_db, $size);
         my $self = shift;  
         return $self->{'current_mfn'};  
76  }  }
77    
78    =head2 fetch_rec
79    
80  =head2 size  Return record with ID C<$mfn> from database
   
 Returns number of records in database  
81    
82   print $isis->size;    my $rec = $self->fetch_rec( $db, $mfn, $filter_coderef);
   
 Result from this function can be used to loop through all records  
   
  foreach my $mfn ( 1 ... $isis->size ) { ... }  
   
 because it takes into account C<start_mfn> and C<limit_mfn>.  
83    
84  =cut  =cut
85    
86  sub size {  sub fetch_rec {
87          my $self = shift;          my $self = shift;
         return $self->{'size'};  
 }  
   
 =head2 seek  
   
 Seek to specified MFN in file.  
88    
89   $isis->seek(42);          my ($isis_db, $mfn, $filter_coderef) = @_;
90    
91  First record in database has position 1.  use Data::Dump qw/dump/;
92    warn "fetch_rec filter_coderef = ", dump($filter_coderef), $/;
 =cut  
   
 sub seek {  
         my $self = shift;  
         my $pos = shift || return;  
   
         my $log = $self->_get_logger();  
93    
94          if ($pos < 1) {          my $rec = $isis_db->to_hash({
95                  $log->warn("seek before first record");                  mfn => $mfn,
96                  $pos = 1;                  include_subfields => 1,
97          } elsif ($pos > $self->{'max_mfn'}) {                  hash_filter => sub {
98                  $log->warn("seek beyond last record");                          my ($l,$f) = @_;
99                  $pos = $self->{'max_mfn'};                          warn "## in hash_filter ($l,$f)\n";
100          }                          my $o = $filter_coderef->($l,$f);
101                            warn "## out hash_filter = $o\n";
102                            return $o;
103                    },
104            });
105    
106          return $self->{'current_mfn'} = (($pos - 1) || -1);          return $rec;
107  }  }
108    
109  =head1 AUTHOR  =head1 AUTHOR

Legend:
Removed from v.113  
changed lines
  Added in v.623

  ViewVC Help
Powered by ViewVC 1.1.26