1 # This file is part of Koha.
3 # Copyright (C) 2013 Tamil s.a.r.l.
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
18 package Koha::Indexer::RecordReader;
22 with 'MooseX::RW::Reader';
27 use Moose::Util::TypeConstraints;
35 subtype 'Koha::RecordType'
37 => where { /biblio|authority/i },
38 => message { "$_ is not a valid Koha::RecordType (biblio or authority" };
40 subtype 'Koha::RecordSelect'
42 => where { /all|queue|queue_update|queue_delete/ },
44 "$_ is not a valide Koha::RecordSelect " .
45 "(all or queue or queue_update or queue_delete)"
51 isa => 'Koha::RecordType',
58 isa => 'Koha::RecordSelect',
63 has xml => ( is => 'rw', isa => 'Bool', default => '0' );
65 has sth => ( is => 'rw' );
67 # Last returned record biblionumber;
68 has id => ( is => 'rw' );
70 # Biblio records normalizer, if necessary
71 has normalizer => ( is => 'rw' );
73 # Read all records? (or queued records)
74 has allrecords => ( is => 'rw', isa => 'Bool', default => 1 );
76 # Mark as done an entry is Zebra queue
77 has sth_queue_done => ( is => 'rw' );
80 has itemtag => ( is => 'rw' );
82 # Las returned record frameworkcode
83 # FIXME: a KohaRecord class should contain this information
84 has frameworkcode => ( is => 'rw', isa => 'Str' );
89 my $dbh = C4::Context->dbh();
91 # Tag containing items
92 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",'');
93 $self->itemtag($itemtag);
95 if ( $self->source =~ /biblio/i &&
96 C4::Context->preference('IncludeSeeFromInSearches') )
98 require Koha::RecordProcessor;
99 my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
100 $self->normalizer($normalizer);
101 # Necessary for as_xml method
102 MARC::File::XML->default_record_format( C4::Context->preference('marcflavour') );
105 my $operation = $self->select =~ /update/i
108 $self->allrecords( $self->select =~ /all/i ? 1 : 0 );
110 $self->source =~ /biblio/i
112 ? "SELECT NULL, biblionumber FROM biblio"
113 : "SELECT id, biblio_auth_number FROM zebraqueue
114 WHERE server = 'biblioserver'
115 AND operation = '$operation' AND done = 0"
117 ? "SELECT NULL, authid FROM auth_header"
118 : "SELECT id, biblio_auth_number FROM zebraqueue
119 WHERE server = 'authorityserver'
120 AND operation = '$operation' AND done = 0";
121 my $sth = $dbh->prepare( $sql );
125 unless ( $self->allrecords ) {
126 $self->sth_queue_done( $dbh->prepare(
127 "UPDATE zebraqueue SET done=1 WHERE id=?" ) );
130 __PACKAGE__->meta->add_method( 'get' =>
131 $self->source =~ /biblio/i
132 ? $self->xml && !$self->normalizer
145 while ( my ($queue_id, $id) = $self->sth->fetchrow ) {
146 # Suppress entry in zebraqueue table
147 $self->sth_queue_done->execute($queue_id) if $queue_id;
148 if ( my $record = $self->get( $id ) ) {
149 $record = $self->normalizer->process($record) if $self->normalizer;
150 $self->count($self->count+1);
161 my ( $self, $id ) = @_;
162 my$dbh = C4::Context->dbh();
163 my $sth = $dbh->prepare(
164 "SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
165 $sth->execute( $id );
166 my ($marcxml) = $sth->fetchrow;
168 # If biblio isn't found in biblioitems, it is searched in
169 # deletedbilioitems. Usefull for delete Zebra requests
170 unless ( $marcxml ) {
171 $sth = $dbh->prepare(
172 "SELECT marcxml FROM deletedbiblioitems WHERE biblionumber=? ");
173 $sth->execute( $id );
174 ($marcxml) = $sth->fetchrow;
178 # FIXME: It slows down drastically biblio records export
180 my @items = @{ $dbh->selectall_arrayref(
181 "SELECT * FROM items WHERE biblionumber=$id",
184 my $record = MARC::Record->new;
185 $record->encoding('UTF-8');
187 foreach my $item (@items) {
188 my $record = Item2Marc($item, $id);
189 push @itemsrecord, $record->field($self->itemtag);
191 $record->insert_fields_ordered(@itemsrecord);
192 my $itemsxml = $record->as_xml_record();
194 substr($marcxml, 0, length($marcxml)-10) .
195 substr($itemsxml, index($itemsxml, "</leader>\n", 0) + 10);
202 # Get biblio record, if the record doesn't exist in biblioitems, it is searched
203 # in deletedbiblioitems.
204 sub get_biblio_marc {
205 my ( $self, $id ) = @_;
207 my $dbh = C4::Context->dbh();
208 my $sth = $dbh->prepare(
209 "SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
210 $sth->execute( $id );
211 my ($marcxml) = $sth->fetchrow;
213 unless ( $marcxml ) {
214 $sth = $dbh->prepare(
215 "SELECT marcxml FROM deletedbiblioitems WHERE biblionumber=? ");
216 $sth->execute( $id );
217 ($marcxml) = $sth->fetchrow;
220 $marcxml =~ s/[^\x09\x0A\x0D\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//g;
221 my $record = MARC::Record->new();
224 MARC::Record::new_from_xml( $marcxml, "utf8" ) };
225 if ($@) { warn " problem with: $id : $@ \n$marcxml"; }
227 # Items extraction if Koha v3.4 and above
228 # FIXME: It slows down drastically biblio records export
229 if ( $self->itemsextraction ) {
230 my @items = @{ $dbh->selectall_arrayref(
231 "SELECT * FROM items WHERE biblionumber=$id",
235 foreach my $item (@items) {
236 my $record = Item2Marc($item, $id);
237 push @itemsrecord, $record->field($self->itemtag);
239 $record->insert_fields_ordered(@itemsrecord);
249 my ( $self, $id ) = @_;
251 my $dbh = C4::Context->dbh();
252 my $sth = $dbh->prepare(
253 "select marcxml from auth_header where authid=? " );
254 $sth->execute( $id );
255 my ($xml) = $sth->fetchrow;
257 # If authority isn't found we build a mimimalist record
258 # Usefull for delete Zebra requests
262 xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
263 xsi:schemaLocation=\"http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\"
264 xmlns=\"http://www.loc.gov/MARC21/slim\">
266 <controlfield tag=\"001\">$id</controlfield>
271 foreach ( split /\n/, $xml ) {
272 next if /^<collection|^<\/collection/;