--- trunk/lib/WebPAC/Input/ISIS.pm 2005/07/16 20:35:30 10 +++ trunk/lib/WebPAC/Input/ISIS.pm 2005/12/19 19:55:21 298 @@ -3,295 +3,148 @@ use warnings; use strict; -use WebPAC::Common; -use base qw/WebPAC::Input WebPAC::Common/; -use Text::Iconv; +use blib; +use WebPAC::Input; =head1 NAME -WebPAC::Input::ISIS - support for CDS/ISIS source files +WebPAC::Input::ISIS - support for CDS/ISIS database files =head1 VERSION -Version 0.01 +Version 0.03 =cut -our $VERSION = '0.01'; +our $VERSION = '0.03'; -# 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 ($@); -} - =head1 SYNOPSIS -Open CDS/ISIS, WinISIS or IsisMarc database using Biblio::Isis or OpenIsis -module and read all records to memory. +Open CDS/ISIS, WinISIS or IsisMarc database using C or +C module and read all records to memory. my $isis = new WebPAC::Input::ISIS(); - $isis->open( filename => '/path/to/ISIS/ISIS' ); + $isis->open( path => '/path/to/ISIS/ISIS' ); =head1 FUNCTIONS -=head2 open +=head2 init -This function will read whole database in memory and produce lookups. +Autoconfigure this module to use C or C. - $isis->open( - filename => '/data/ISIS/ISIS', - code_page => '852', - limit_mfn => 500, - start_mfn => 6000, - lookup => $lookup_obj, - ); +=cut -By default, ISIS code page is assumed to be C<852>. +sub init { + my $self = shift; -If optional parametar C is set, this will be first MFN to read -from database (so you can skip beginning of your database if you need to). + eval "use Biblio::Isis;"; + unless ($@) { + $self->{have_biblio_isis} = 1 + } else { + eval "use OpenIsis;"; + $self->{have_openisis} = 1 unless ($@); + } +} -If optional parametar C is set, it will read just 500 records -from database in example above. +=head2 open_db -Returns number of last record read into memory (size of database, really). +Returns handle to database + + my $db = $open_db( + path => '/path/to/LIBRI' + } =cut -sub open { +sub open_db { my $self = shift; + my $arg = {@_}; my $log = $self->_get_logger(); - $log->logcroak("need filename") if (! $arg->{'filename'}); - my $code_page = $arg->{'code_page'} || '852'; + $log->info("opening ISIS database '$arg->{path}'"); - $log->logdie("can't find database ",$arg->{'filename'}) unless (glob($arg->{'filename'}.'.*')); + my ($isis_db,$db_size); - # store data in object - $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) { + if ($self->{have_openisis}) { $log->debug("using OpenIsis perl bindings"); - $isis_db = OpenIsis::open($arg->{'filename'}); - $maxmfn = OpenIsis::maxRowid( $isis_db ) || 1; - } elsif ($have_biblio_isis) { + $isis_db = OpenIsis::open($arg->{path}); + $db_size = OpenIsis::maxRowid( $isis_db ) || 1; + } elsif ($self->{have_biblio_isis}) { $log->debug("using Biblio::Isis"); use Biblio::Isis; $isis_db = new Biblio::Isis( - isisdb => $arg->{'filename'}, + isisdb => $arg->{path}, include_deleted => 1, hash_filter => sub { my $l = shift || return; - $l = $cp->convert($l); + $l = $self->{iconv}->convert($l) if ($self->{iconv}); return $l; }, - ); - $maxmfn = $isis_db->count; + ) or $log->logdie("can't find database $arg->{path}"); - unless ($maxmfn) { - $log->logwarn("no records in database ", $arg->{'filename'}, ", skipping..."); - return; - } + $db_size = $isis_db->count; } else { $log->logdie("Can't find supported ISIS library for perl. I suggent that you install Bilbio::Isis from CPAN."); } - - 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; + return ($isis_db, $db_size); } -=head2 fetch +=head2 fetch_rec -Fetch next record from database. It will also displays progress bar. +Return record with ID C<$mfn> from database - my $rec = $isis->fetch; + my $rec = $self->fetch_rec( $db, $mfn ); -Record from this function should probably go to C 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'}; } - -=head2 size - -Returns number of records in database - - print $isis->size; - =cut -sub size { +sub fetch_rec { my $self = shift; - return $self->{'max_mfn'}; -} -=head2 seek + my ($isis_db, $mfn) = @_; -Seek to specified MFN in file. + my $rec; - $isis->seek(42); + if ($self->{have_openisis}) { -First record in database has position 1. + # read record using OpenIsis + my $row = OpenIsis::read( $isis_db, $mfn ); -=cut - -sub seek { - my $self = shift; - my $pos = shift || return; - - my $log = $self->_get_logger(); + # convert record to hash + foreach my $k (keys %{$row}) { + if ($k ne "mfn") { + foreach my $l (@{$row->{$k}}) { + $l = $self->{iconv}->convert($l) if ($self->{iconv}); + # 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; + } + } - 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'}; + } elsif ($self->{have_biblio_isis}) { + $rec = $isis_db->to_hash($mfn); + } else { + $self->_get_logger()->logdie("hum? implementation missing?"); } - return $self->{'current_mfn'} = (($pos - 1) || -1); + return $rec; } =head1 AUTHOR