1 package Koha::OAI::Server::ListBase;
3 # Copyright The National Library of Finland, University of Helsinki 2016-2017
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
22 Koha::OAI::Server::ListBase - OAI ListIdentifiers/ListRecords shared functionality
26 Koha::OAI::Server::ListBase contains OAI-PMH functions shared by ListIdentifiers and ListRecords.
33 use Koha::OAI::Server::ResumptionToken;
34 use Koha::OAI::Server::Record;
35 use Koha::OAI::Server::DeletedRecord;
40 my ($class, $self, $repository, $metadata, %args) = @_;
42 my $token = Koha::OAI::Server::ResumptionToken->new( %args );
43 my $dbh = C4::Context->dbh;
45 if ( defined $token->{'set'} ) {
46 $set = GetOAISetBySpec($token->{'set'});
48 my $offset = $token->{offset};
49 my $deleted = defined $token->{deleted} ? $token->{deleted} : 0;
50 my $deleted_count = defined $token->{deleted_count} ? $token->{deleted_count} : 0;
51 my $max = $repository->{koha_max_count};
53 my $format = $args{metadataPrefix} || $token->{metadata_prefix};
54 my $include_items = $repository->items_included( $format );
56 # Since creating a union of normal and deleted record tables would be a heavy
57 # operation in a large database, build results in two stages:
58 # first deleted records ($deleted == 1), then normal records ($deleted == 0)
60 for ( ; $deleted >= 0; $deleted-- ) {
61 my $table = $deleted ? 'deletedbiblio_metadata' : 'biblio_metadata';
65 WHERE (timestamp >= ? AND timestamp <= ?)
67 my @bind_params = ($token->{'from_arg'}, $token->{'until_arg'});
71 OR biblionumber IN (SELECT biblionumber from deleteditems WHERE timestamp >= ? AND timestamp <= ?)
73 push @bind_params, ($token->{'from_arg'}, $token->{'until_arg'});
76 OR biblionumber IN (SELECT biblionumber from items WHERE timestamp >= ? AND timestamp <= ?)
78 push @bind_params, ($token->{'from_arg'}, $token->{'until_arg'});
86 # Use a subquery for sets since it allows us to use an index in
87 # biblioitems table and is quite a bit faster than a join.
90 SELECT bi.* FROM ($sql) bi
91 WHERE bi.biblionumber in (SELECT osb.biblionumber FROM oai_sets_biblios osb WHERE osb.set_id = ?)
93 push @bind_params, $set->{'id'};
97 LIMIT " . ($max + 1) . "
98 OFFSET " . ($offset - $deleted_count);
100 my $sth = $dbh->prepare( $sql ) || die( 'Could not prepare statement: ' . $dbh->errstr );
104 SELECT MAX(timestamp)
106 SELECT timestamp FROM deletedbiblio_metadata WHERE biblionumber = ?
108 SELECT timestamp FROM deleteditems WHERE biblionumber = ?
113 SELECT MAX(timestamp)
115 SELECT timestamp FROM biblio_metadata WHERE biblionumber = ?
117 SELECT timestamp FROM deleteditems WHERE biblionumber = ?
119 SELECT timestamp FROM items WHERE biblionumber = ?
123 my $record_sth = $dbh->prepare( $sql ) || die( 'Could not prepare statement: ' . $dbh->errstr );
125 $sth->execute( @bind_params ) || die( 'Could not execute statement: ' . $sth->errstr );
126 while ( my ($biblionumber) = $sth->fetchrow ) {
128 if ( $count > $max ) {
129 $self->resumptionToken(
130 Koha::OAI::Server::ResumptionToken->new(
131 metadataPrefix => $token->{metadata_prefix},
132 from => $token->{from},
133 until => $token->{until},
134 offset => $token->{offset} + $max,
135 set => $token->{set},
137 deleted_count => $deleted_count
142 my @params = $deleted ? ( $biblionumber, $biblionumber ) : ( $biblionumber, $biblionumber, $biblionumber );
143 $record_sth->execute( @params ) || die( 'Could not execute statement: ' . $sth->errstr );
145 my ($timestamp) = $record_sth->fetchrow;
147 my $oai_sets = GetOAISetsBiblio($biblionumber);
149 foreach ( @$oai_sets ) {
150 push @setSpecs, $_->{spec};
153 my $marcxml = !$deleted ? $repository->get_biblio_marcxml($biblionumber, $format) : undef;
155 $self->record( Koha::OAI::Server::Record->new(
156 $repository, $marcxml, $timestamp, \@setSpecs,
157 identifier => $repository->{ koha_identifier } . ':' . $biblionumber,
158 metadataPrefix => $token->{metadata_prefix}
161 $self->record( Koha::OAI::Server::DeletedRecord->new(
162 $timestamp, \@setSpecs, identifier => $repository->{ koha_identifier } . ':' . $biblionumber
166 $timestamp =~ s/ /T/;
168 $self->identifier( HTTP::OAI::Header->new(
169 identifier => $repository->{ koha_identifier} . ':' . $biblionumber,
170 datestamp => $timestamp,
171 status => $deleted ? 'deleted' : undef
175 # Store offset and deleted record count
177 $deleted_count = $offset if ($deleted);