r9064@llin: dpavlin | 2005-11-23 01:15:24 +0100
[webpac2] / lib / WebPAC / Input / ISIS.pm
index 2ef8194..5ab2a76 100644 (file)
@@ -5,6 +5,7 @@ use strict;
 
 use WebPAC::Common;
 use base qw/WebPAC::Input WebPAC::Common/;
+use Text::Iconv;
 
 =head1 NAME
 
@@ -61,7 +62,8 @@ from database (so you can skip beginning of your database if you need to).
 If optional parametar C<limit_mfn> is set, it will read just 500 records
 from database in example above.
 
-Returns number of last record read into memory (size of database, really).
+Returns size of database, regardless of C<start_mfn> and C<limit_mfn>
+parametars, see also C<$isis->size>.
 
 =cut
 
@@ -77,10 +79,10 @@ sub open {
        $log->logdie("can't find database ",$arg->{'filename'}) unless (glob($arg->{'filename'}.'.*'));
 
        # store data in object
-       $self->{'isis_filename'} = $arg->{'filename'};
        $self->{'isis_code_page'} = $code_page;
-
-       #$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'});
@@ -88,12 +90,12 @@ sub open {
        $log->info("reading ISIS database '",$arg->{'filename'},"'");
        $log->debug("isis code page: $code_page");
 
-       my ($isis_db,$maxmfn);
+       my ($isis_db,$db_size);
 
        if ($have_openisis) {
                $log->debug("using OpenIsis perl bindings");
                $isis_db = OpenIsis::open($arg->{'filename'});
-               $maxmfn = OpenIsis::maxRowid( $isis_db ) || 1;
+               $db_size = OpenIsis::maxRowid( $isis_db ) || 1;
        } elsif ($have_biblio_isis) {
                $log->debug("using Biblio::Isis");
                use Biblio::Isis;
@@ -106,9 +108,9 @@ sub open {
                                return $l;
                        },
                );
-               $maxmfn = $isis_db->count;
+               $db_size = $isis_db->count;
 
-               unless ($maxmfn) {
+               unless ($db_size) {
                        $log->logwarn("no records in database ", $arg->{'filename'}, ", skipping...");
                        return;
                }
@@ -119,6 +121,7 @@ sub open {
 
 
        my $startmfn = 1;
+       my $maxmfn = $db_size;
 
        if (my $s = $self->{'start_mfn'}) {
                $log->info("skipping to MFN $s");
@@ -127,7 +130,14 @@ sub open {
                $self->{'start_mfn'} = $startmfn;
        }
 
-       $maxmfn = $startmfn + $self->{limit_mfn} if ($self->{limit_mfn});
+       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'));
 
@@ -171,7 +181,10 @@ sub open {
                        $log->logdie("hum? implementation missing?");
                }
 
-               $log->confess("record $mfn empty?") unless ($rec);
+               if (! $rec) {
+                       $log->warn("record $mfn empty? skipping...");
+                       next;
+               }
 
                # store
                if ($self->{'low_mem'}) {
@@ -193,18 +206,23 @@ sub open {
        $log->debug("max mfn: $maxmfn");
 
        # store max mfn and return it.
-       return $self->{'max_mfn'} = $maxmfn;
+       $self->{'max_mfn'} = $maxmfn;
+
+       return $db_size;
 }
 
-=head2 fetch_rec
+=head2 fetch
 
 Fetch next record from database. It will also displays progress bar.
 
- my $rec = $webpac->fetch_rec;
+ my $rec = $isis->fetch;
+
+Record from this function should probably go to C<data_structure> for
+normalisation.
 
 =cut
 
-sub fetch_rec {
+sub fetch {
        my $self = shift;
 
        my $log = $self->_get_logger();
@@ -227,26 +245,79 @@ sub fetch_rec {
 
        $self->progress_bar($mfn,$self->{'max_mfn'});
 
+       my $rec;
+
        if ($self->{'low_mem'}) {
-               return $self->{'db'}->get($mfn);
+               $rec = $self->{'db'}->get($mfn);
        } else {
-               return $self->{'data'}->{$mfn};
+               $rec = $self->{'data'}->{$mfn};
        }
+
+       $rec ||= 0E0;
 }
 
-=head2 mfn
+=head2 pos
 
 Returns current record number (MFN).
 
- print $webpac->mfn;
+ print $isis->pos;
+
+First record in database has position 1.
 
 =cut
 
-sub mfn {
+sub pos {
        my $self = shift;
        return $self->{'current_mfn'};
 }
 
+
+=head2 size
+
+Returns number of records in database
+
+ print $isis->size;
+
+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>.
+
+=cut
+
+sub size {
+       my $self = shift;
+       return $self->{'size'};
+}
+
+=head2 seek
+
+Seek to specified MFN in file.
+
+ $isis->seek(42);
+
+First record in database has position 1.
+
+=cut
+
+sub seek {
+       my $self = shift;
+       my $pos = shift || return;
+
+       my $log = $self->_get_logger();
+
+       if ($pos < 1) {
+               $log->warn("seek before first record");
+               $pos = 1;
+       } elsif ($pos > $self->{'max_mfn'}) {
+               $log->warn("seek beyond last record");
+               $pos = $self->{'max_mfn'};
+       }
+
+       return $self->{'current_mfn'} = (($pos - 1) || -1);
+}
+
 =head1 AUTHOR
 
 Dobrica Pavlinusic, C<< <dpavlin@rot13.org> >>