/[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 10 by dpavlin, Sat Jul 16 20:35:30 2005 UTC revision 497 by dpavlin, Sun May 14 19:45:36 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;
 use base qw/WebPAC::Input WebPAC::Common/;  
 use Text::Iconv;  
7    
8  =head1 NAME  =head1 NAME
9    
10  WebPAC::Input::ISIS - support for CDS/ISIS source files  WebPAC::Input::ISIS - support for CDS/ISIS database files
11    
12  =head1 VERSION  =head1 VERSION
13    
14  Version 0.01  Version 0.03
15    
16  =cut  =cut
17    
18  our $VERSION = '0.01';  our $VERSION = '0.03';
19    
20    
 # 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 ($@);  
 }  
   
21  =head1 SYNOPSIS  =head1 SYNOPSIS
22    
23  Open CDS/ISIS, WinISIS or IsisMarc database using Biblio::Isis or OpenIsis  Open CDS/ISIS, WinISIS or IsisMarc database using C<Biblio::Isis> or
24  module and read all records to memory.  C<OpenIsis> module and read all records to memory.
25    
26   my $isis = new WebPAC::Input::ISIS();   my $isis = new WebPAC::Input::ISIS();
27   $isis->open( filename => '/path/to/ISIS/ISIS' );   $isis->open( path => '/path/to/ISIS/ISIS' );
28    
29  =head1 FUNCTIONS  =head1 FUNCTIONS
30    
31  =head2 open  =head2 init
32    
33  This function will read whole database in memory and produce lookups.  Autoconfigure this module to use C<Biblio::Isis> or C<OpenIsis>.
34    
35   $isis->open(  =cut
         filename => '/data/ISIS/ISIS',  
         code_page => '852',  
         limit_mfn => 500,  
         start_mfn => 6000,  
         lookup => $lookup_obj,  
  );  
36    
37  By default, ISIS code page is assumed to be C<852>.  sub init {
38            my $self = shift;
39    
40  If optional parametar C<start_mfn> is set, this will be first MFN to read          eval "use Biblio::Isis;";
41  from database (so you can skip beginning of your database if you need to).          unless ($@) {
42                    $self->{have_biblio_isis} = 1
43            } else {
44                    eval "use OpenIsis;";
45                    $self->{have_openisis} = 1 unless ($@);
46            }
47    }
48    
49  If optional parametar C<limit_mfn> is set, it will read just 500 records  =head2 open_db
 from database in example above.  
50    
51  Returns number of last record read into memory (size of database, really).  Returns handle to database and size in records
52    
53      my ($db,$size) = $open_db(
54            path => '/path/to/LIBRI'
55      }
56    
57  =cut  =cut
58    
59  sub open {  sub open_db {
60          my $self = shift;          my $self = shift;
61    
62          my $arg = {@_};          my $arg = {@_};
63    
64          my $log = $self->_get_logger();          my $log = $self->_get_logger();
65    
66          $log->logcroak("need filename") if (! $arg->{'filename'});          $log->info("opening ISIS database '$arg->{path}'");
         my $code_page = $arg->{'code_page'} || '852';  
67    
68          $log->logdie("can't find database ",$arg->{'filename'}) unless (glob($arg->{'filename'}.'.*'));          my ($isis_db,$db_size);
69    
70          # store data in object          if ($self->{have_openisis}) {
         $self->{'isis_filename'} = $arg->{'filename'};  
         $self->{'isis_code_page'} = $code_page;  
   
         #$self->{'isis_code_page'} = $code_page;  
   
         # 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,$maxmfn);  
   
         if ($have_openisis) {  
71                  $log->debug("using OpenIsis perl bindings");                  $log->debug("using OpenIsis perl bindings");
72                  $isis_db = OpenIsis::open($arg->{'filename'});                  $isis_db = OpenIsis::open($arg->{path});
73                  $maxmfn = OpenIsis::maxRowid( $isis_db ) || 1;                  $db_size = OpenIsis::maxRowid( $isis_db ) || 1;
74          } elsif ($have_biblio_isis) {          } elsif ($self->{have_biblio_isis}) {
75                  $log->debug("using Biblio::Isis");                  $log->debug("using Biblio::Isis");
76                  use Biblio::Isis;                  use Biblio::Isis;
77                  $isis_db = new Biblio::Isis(                  $isis_db = new Biblio::Isis(
78                          isisdb => $arg->{'filename'},                          isisdb => $arg->{path},
79                          include_deleted => 1,                          include_deleted => 1,
80                          hash_filter => sub {                          hash_filter => sub {
81                                  my $l = shift || return;                                  my $l = shift || return;
82                                  $l = $cp->convert($l);                                  $l = $self->{iconv}->convert($l) if ($self->{iconv});
83                                  return $l;                                  return $l;
84                          },                          },
85                  );                  ) or $log->logdie("can't find database $arg->{path}");
                 $maxmfn = $isis_db->count;  
86    
87                  unless ($maxmfn) {                  $db_size = $isis_db->count;
                         $log->logwarn("no records in database ", $arg->{'filename'}, ", skipping...");  
                         return;  
                 }  
88    
89          } else {          } else {
90                  $log->logdie("Can't find supported ISIS library for perl. I suggent that you install Bilbio::Isis from CPAN.");                  $log->logdie("Can't find supported ISIS library for perl. I suggent that you install Bilbio::Isis from CPAN.");
91          }          }
92    
93            return ($isis_db, $db_size);
         my $startmfn = 1;  
   
         if (my $s = $self->{'start_mfn'}) {  
                 $log->info("skipping to MFN $s");  
                 $startmfn = $s;  
         } else {  
                 $self->{'start_mfn'} = $startmfn;  
         }  
   
         $maxmfn = $startmfn + $self->{limit_mfn} if ($self->{limit_mfn});  
   
         $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?");  
                 }  
   
                 $log->confess("record $mfn empty?") unless ($rec);  
   
                 # 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.  
         return $self->{'max_mfn'} = $maxmfn;  
94  }  }
95    
96  =head2 fetch  =head2 fetch_rec
97    
98  Fetch next record from database. It will also displays progress bar.  Return record with ID C<$mfn> from database
99    
100   my $rec = $isis->fetch;    my $rec = $self->fetch_rec( $db, $mfn );
101    
 Record from this function should probably go to C<data_structure> for  
 normalisation.  
   
 =cut  
   
 sub fetch {  
         my $self = shift;  
   
         my $log = $self->_get_logger();  
   
         $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'});  
   
         if ($self->{'low_mem'}) {  
                 return $self->{'db'}->get($mfn);  
         } else {  
                 return $self->{'data'}->{$mfn};  
         }  
 }  
   
 =head2 pos  
   
 Returns current record number (MFN).  
   
  print $isis->pos;  
   
 First record in database has position 1.  
   
 =cut  
   
 sub pos {  
         my $self = shift;  
         return $self->{'current_mfn'};  
102  }  }
103    
   
 =head2 size  
   
 Returns number of records in database  
   
  print $isis->size;  
   
104  =cut  =cut
105    
106  sub size {  sub fetch_rec {
107          my $self = shift;          my $self = shift;
         return $self->{'max_mfn'};  
 }  
108    
109  =head2 seek          my ($isis_db, $mfn) = @_;
110    
111  Seek to specified MFN in file.          my $rec;
112    
113   $isis->seek(42);          if ($self->{have_openisis}) {
114    
115  First record in database has position 1.                  # read record using OpenIsis
116                    my $row = OpenIsis::read( $isis_db, $mfn );
117    
118  =cut                  # convert record to hash
119                    foreach my $k (keys %{$row}) {
120  sub seek {                          if ($k ne "mfn") {
121          my $self = shift;                                  foreach my $l (@{$row->{$k}}) {
122          my $pos = shift || return;                                          $l = $self->{iconv}->convert($l) if ($self->{iconv});
123                                            # has subfields?
124          my $log = $self->_get_logger();                                          my $val;
125                                            if ($l =~ m/\^/) {
126                                                    foreach my $t (split(/\^/,$l)) {
127                                                            next if (! $t);
128                                                            $val->{substr($t,0,1)} = substr($t,1);
129                                                    }
130                                            } else {
131                                                    $val = $l;
132                                            }
133                                            push @{$rec->{"$k"}}, $val;
134                                    }
135                            } else {
136                                    push @{$rec->{'000'}}, $mfn;
137                            }
138                    }
139    
140          if ($pos < 1) {          } elsif ($self->{have_biblio_isis}) {
141                  $log->warn("seek before first record");                  $rec = $isis_db->to_hash($mfn);
142                  $pos = 1;          } else {
143          } elsif ($pos > $self->{'max_mfn'}) {                  $self->_get_logger()->logdie("hum? implementation missing?");
                 $log->warn("seek beyond last record");  
                 $pos = $self->{'max_mfn'};  
144          }          }
145    
146          return $self->{'current_mfn'} = (($pos - 1) || -1);          return $rec;
147  }  }
148    
149  =head1 AUTHOR  =head1 AUTHOR

Legend:
Removed from v.10  
changed lines
  Added in v.497

  ViewVC Help
Powered by ViewVC 1.1.26