1 package Koha::Indexer::RecordReader;
5 with 'MooseX::RW::Reader';
10 use Moose::Util::TypeConstraints;
18 subtype 'Koha::RecordType'
20 => where { /biblio|authority/i },
21 => message { "$_ is not a valid Koha::RecordType (biblio or authority" };
23 subtype 'Koha::RecordSelect'
25 => where { /all|queue|queue_update|queue_delete/ },
27 "$_ is not a valide Koha::RecordSelect " .
28 "(all or queue or queue_update or queue_delete)"
34 isa => 'Koha::RecordType',
41 isa => 'Koha::RecordSelect',
46 has xml => ( is => 'rw', isa => 'Bool', default => '0' );
48 has sth => ( is => 'rw' );
50 # Last returned record biblionumber;
51 has id => ( is => 'rw' );
53 # Biblio records normalizer, if necessary
54 has normalizer => ( is => 'rw' );
56 # Read all records? (or queued records)
57 has allrecords => ( is => 'rw', isa => 'Bool', default => 1 );
59 # Mark as done an entry is Zebra queue
60 has sth_queue_done => ( is => 'rw' );
63 has itemtag => ( is => 'rw' );
65 # Las returned record frameworkcode
66 # FIXME: a KohaRecord class should contain this information
67 has frameworkcode => ( is => 'rw', isa => 'Str' );
72 my $dbh = C4::Context->dbh();
74 # Tag containing items
75 my ( $itemtag, $itemsubfield ) = GetMarcFromKohaField("items.itemnumber",'');
76 $self->itemtag($itemtag);
78 if ( $self->source =~ /biblio/i &&
79 C4::Context->preference('IncludeSeeFromInSearches') )
81 require Koha::RecordProcessor;
82 my $normalizer = Koha::RecordProcessor->new( { filters => 'EmbedSeeFromHeadings' } );
83 $self->normalizer($normalizer);
84 # Necessary for as_xml method
85 MARC::File::XML->default_record_format( C4::Context->preference('marcflavour') );
88 my $operation = $self->select =~ /update/i
91 $self->allrecords( $self->select =~ /all/i ? 1 : 0 );
93 $self->source =~ /biblio/i
95 ? "SELECT NULL, biblionumber FROM biblio"
96 : "SELECT id, biblio_auth_number FROM zebraqueue
97 WHERE server = 'biblioserver'
98 AND operation = '$operation' AND done = 0"
100 ? "SELECT NULL, authid FROM auth_header"
101 : "SELECT id, biblio_auth_number FROM zebraqueue
102 WHERE server = 'authorityserver'
103 AND operation = '$operation' AND done = 0";
104 my $sth = $dbh->prepare( $sql );
108 unless ( $self->allrecords ) {
109 $self->sth_queue_done( $dbh->prepare(
110 "UPDATE zebraqueue SET done=1 WHERE id=?" ) );
113 __PACKAGE__->meta->add_method( 'get' =>
114 $self->source =~ /biblio/i
115 ? $self->xml && !$self->normalizer
128 while ( my ($queue_id, $id) = $self->sth->fetchrow ) {
129 # Suppress entry in zebraqueue table
130 $self->sth_queue_done->execute($queue_id) if $queue_id;
131 if ( my $record = $self->get( $id ) ) {
132 $record = $self->normalizer->process($record) if $self->normalizer;
133 $self->count($self->count+1);
144 my ( $self, $id ) = @_;
145 my$dbh = C4::Context->dbh();
146 my $sth = $dbh->prepare(
147 "SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
148 $sth->execute( $id );
149 my ($marcxml) = $sth->fetchrow;
151 # If biblio isn't found in biblioitems, it is searched in
152 # deletedbilioitems. Usefull for delete Zebra requests
153 unless ( $marcxml ) {
154 $sth = $dbh->prepare(
155 "SELECT marcxml FROM deletedbiblioitems WHERE biblionumber=? ");
156 $sth->execute( $id );
157 ($marcxml) = $sth->fetchrow;
161 # FIXME: It slows down drastically biblio records export
163 my @items = @{ $dbh->selectall_arrayref(
164 "SELECT * FROM items WHERE biblionumber=$id",
167 my $record = MARC::Record->new;
168 $record->encoding('UTF-8');
170 foreach my $item (@items) {
171 my $record = Item2Marc($item, $id);
172 push @itemsrecord, $record->field($self->itemtag);
174 $record->insert_fields_ordered(@itemsrecord);
175 my $itemsxml = $record->as_xml_record();
177 substr($marcxml, 0, length($marcxml)-10) .
178 substr($itemsxml, index($itemsxml, "</leader>\n", 0) + 10);
185 # Get biblio record, if the record doesn't exist in biblioitems, it is searched
186 # in deletedbiblioitems.
187 sub get_biblio_marc {
188 my ( $self, $id ) = @_;
190 my $dbh = C4::Context->dbh();
191 my $sth = $dbh->prepare(
192 "SELECT marcxml FROM biblioitems WHERE biblionumber=? ");
193 $sth->execute( $id );
194 my ($marcxml) = $sth->fetchrow;
196 unless ( $marcxml ) {
197 $sth = $dbh->prepare(
198 "SELECT marcxml FROM deletedbiblioitems WHERE biblionumber=? ");
199 $sth->execute( $id );
200 ($marcxml) = $sth->fetchrow;
203 $marcxml =~ s/[^\x09\x0A\x0D\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]//g;
204 my $record = MARC::Record->new();
207 MARC::Record::new_from_xml( $marcxml, "utf8" ) };
208 if ($@) { warn " problem with: $id : $@ \n$marcxml"; }
210 # Items extraction if Koha v3.4 and above
211 # FIXME: It slows down drastically biblio records export
212 if ( $self->itemsextraction ) {
213 my @items = @{ $dbh->selectall_arrayref(
214 "SELECT * FROM items WHERE biblionumber=$id",
218 foreach my $item (@items) {
219 my $record = Item2Marc($item, $id);
220 push @itemsrecord, $record->field($self->itemtag);
222 $record->insert_fields_ordered(@itemsrecord);
232 my ( $self, $id ) = @_;
234 my $dbh = C4::Context->dbh();
235 my $sth = $dbh->prepare(
236 "select marcxml from auth_header where authid=? " );
237 $sth->execute( $id );
238 my ($xml) = $sth->fetchrow;
240 # If authority isn't found we build a mimimalist record
241 # Usefull for delete Zebra requests
245 xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
246 xsi:schemaLocation=\"http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd\"
247 xmlns=\"http://www.loc.gov/MARC21/slim\">
249 <controlfield tag=\"001\">$id</controlfield>
254 foreach ( split /\n/, $xml ) {
255 next if /^<collection|^<\/collection/;