Main Koha release repository
https://koha-community.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.3 KiB
163 lines
4.3 KiB
#!/usr/bin/perl
|
|
|
|
package Koha::Z3950Responder::ZebraSession;
|
|
|
|
# Copyright ByWater Solutions 2016
|
|
#
|
|
# This file is part of Koha.
|
|
#
|
|
# Koha is free software; you can redistribute it and/or modify it under the
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 3 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along
|
|
# with Koha; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
use Modern::Perl;
|
|
|
|
use base qw( Koha::Z3950Responder::Session );
|
|
|
|
use Koha::Logger;
|
|
|
|
use ZOOM;
|
|
|
|
=head1 NAME
|
|
|
|
Koha::Z3950Responder::ZebraSession
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
Zebra-specific session class that uses C<Koha::Session> as the base class.
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=head2 INSTANCE METHODS
|
|
|
|
=head3 start_search
|
|
|
|
my ($resultset, $hits) = $self->_start_search( $args, $self->{server}->{num_to_prefetch} );
|
|
|
|
Connect to Zebra and do the search
|
|
|
|
=cut
|
|
|
|
sub start_search {
|
|
my ( $self, $args, $num_to_prefetch, $in_retry ) = @_;
|
|
|
|
my $database = $args->{DATABASES}->[0];
|
|
my ( $connection, $results );
|
|
|
|
eval {
|
|
$connection = C4::Context->Zconn(
|
|
# We're depending on the caller to have done some validation.
|
|
$database eq 'biblios' ? 'biblioserver' : 'authorityserver',
|
|
0 # No, no async, doesn't really help much for single-server searching
|
|
);
|
|
|
|
$results = $connection->search_pqf( $args->{QUERY} );
|
|
|
|
$self->log_debug(' retry successful') if ($in_retry);
|
|
};
|
|
if ($@) {
|
|
die $@ if ( ref($@) ne 'ZOOM::Exception' );
|
|
|
|
if ( $@->diagset() eq 'ZOOM' && $@->code() == 10004 && !$in_retry ) {
|
|
$self->log_debug(' upstream server lost connection, retrying');
|
|
return $self->_start_search( $args, $num_to_prefetch, 1 );
|
|
}
|
|
|
|
$self->_set_error_from_zoom( $args, $@ );
|
|
$connection = undef;
|
|
}
|
|
|
|
my $hits = $results ? $results->size() : -1;
|
|
my $resultset = {
|
|
database => $database,
|
|
connection => $connection,
|
|
results => $results,
|
|
query => $args->{QUERY},
|
|
hits => $hits
|
|
};
|
|
|
|
return ( $resultset, $hits );
|
|
}
|
|
|
|
=head3 fetch_record
|
|
|
|
my $record = $self->_fetch_record( $resultset, $args, $offset, $server->{num_to_prefetch} );
|
|
|
|
Fetch a record from Zebra. Caches records in session to avoid too many fetches.
|
|
|
|
=cut
|
|
|
|
sub fetch_record {
|
|
my ( $self, $resultset, $args, $index, $num_to_prefetch ) = @_;
|
|
|
|
my $record;
|
|
|
|
eval {
|
|
if ( !$resultset->{results}->record_immediate( $index ) ) {
|
|
my $start = $num_to_prefetch ? int( $index / $num_to_prefetch ) * $num_to_prefetch : $index;
|
|
|
|
if ( $start + $num_to_prefetch >= $resultset->{results}->size() ) {
|
|
$num_to_prefetch = $resultset->{results}->size() - $start;
|
|
}
|
|
|
|
$self->log_debug(" fetch uncached, fetching $num_to_prefetch records starting at $start");
|
|
|
|
$resultset->{results}->records( $start, $num_to_prefetch, 0 );
|
|
}
|
|
|
|
$record = $resultset->{results}->record_immediate( $index )->raw();
|
|
};
|
|
if ($@) {
|
|
die $@ if ( ref($@) ne 'ZOOM::Exception' );
|
|
$self->_set_error_from_zoom( $args, $@ );
|
|
return;
|
|
} else {
|
|
return $record;
|
|
}
|
|
}
|
|
|
|
=head3 close_handler
|
|
|
|
Callback that is called when a session is terminated
|
|
|
|
=cut
|
|
|
|
sub close_handler {
|
|
my ( $self, $args ) = @_;
|
|
|
|
foreach my $resultset ( values %{ $self->{resultsets} } ) {
|
|
$resultset->{results}->destroy();
|
|
}
|
|
}
|
|
|
|
=head3 _set_error_from_zoom
|
|
|
|
$self->_set_error_from_zoom( $args, $@ );
|
|
|
|
Log and set error code and diagnostic message from a ZOOM exception
|
|
|
|
=cut
|
|
|
|
sub _set_error_from_zoom {
|
|
my ( $self, $args, $exception ) = @_;
|
|
|
|
$self->set_error( $args, $self->ERR_TEMPORARY_ERROR, 'Cannot connect to upstream server' );
|
|
$self->log_error(
|
|
"Zebra upstream error: " .
|
|
$exception->message() . " (" .
|
|
$exception->code() . ") " .
|
|
( $exception->addinfo() // '' ) . " " .
|
|
$exception->diagset()
|
|
);
|
|
}
|
|
|
|
1;
|
|
|