1 package C4
::ImportBatch
;
3 # Copyright (C) 2007 LibLime
5 # This file is part of Koha.
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License along
17 # with Koha; if not, write to the Free Software Foundation, Inc.,
18 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 use vars
qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
32 # set the version for version checking
45 BatchFindBibDuplicates
51 GetImportBatchRangeDesc
52 GetNumberOfNonZ3950ImportBatches
54 GetItemNumbersFromImportBatch
58 GetImportBatchOverlayAction
59 SetImportBatchOverlayAction
60 GetImportBatchNoMatchAction
61 SetImportBatchNoMatchAction
62 GetImportBatchItemAction
63 SetImportBatchItemAction
66 GetImportRecordOverlayStatus
67 SetImportRecordOverlayStatus
70 GetImportRecordMatches
71 SetImportRecordMatches
77 C4::ImportBatch - manage batches of imported MARC records
89 =head2 GetZ3950BatchId
93 my $batchid = GetZ3950BatchId($z3950server);
97 Retrieves the ID of the import batch for the Z39.50
98 reservoir for the given target. If necessary,
99 creates the import batch.
103 sub GetZ3950BatchId
{
104 my ($z3950server) = @_;
106 my $dbh = C4
::Context
->dbh;
107 my $sth = $dbh->prepare("SELECT import_batch_id FROM import_batches
108 WHERE batch_type = 'z3950'
110 $sth->execute($z3950server);
111 my $rowref = $sth->fetchrow_arrayref();
113 if (defined $rowref) {
116 my $batch_id = AddImportBatch
('create_new', 'staged', 'z3950', $z3950server, '');
122 =head2 GetImportRecordMarc
126 my ($marcblob, $encoding) = GetImportRecordMarc($import_record_id);
132 sub GetImportRecordMarc
{
133 my ($import_record_id) = @_;
135 my $dbh = C4
::Context
->dbh;
136 my $sth = $dbh->prepare("SELECT marc, encoding FROM import_records WHERE import_record_id = ?");
137 $sth->execute($import_record_id);
138 my ($marc, $encoding) = $sth->fetchrow();
140 return $marc, $encoding;
144 =head2 AddImportBatch
148 my $batch_id = AddImportBatch($overlay_action, $import_status, $type, $file_name, $comments);
155 my ($overlay_action, $import_status, $type, $file_name, $comments) = @_;
157 my $dbh = C4
::Context
->dbh;
158 my $sth = $dbh->prepare("INSERT INTO import_batches (overlay_action, import_status, batch_type,
160 VALUES (?, ?, ?, ?, ?)");
161 $sth->execute($overlay_action, $import_status, $type, $file_name, $comments);
162 my $batch_id = $dbh->{'mysql_insertid'};
169 =head2 GetImportBatch
173 my $row = GetImportBatch($batch_id);
177 Retrieve a hashref of an import_batches row.
184 my $dbh = C4
::Context
->dbh;
185 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches WHERE import_batch_id = ?");
186 $sth->bind_param(1, $batch_id);
188 my $result = $sth->fetchrow_hashref;
194 =head2 AddBiblioToBatch
198 my $import_record_id = AddBiblioToBatch($batch_id, $record_sequence, $marc_record, $encoding, $z3950random, $update_counts);
204 sub AddBiblioToBatch
{
205 my $batch_id = shift;
206 my $record_sequence = shift;
207 my $marc_record = shift;
208 my $encoding = shift;
209 my $z3950random = shift;
210 my $update_counts = @_ ?
shift : 1;
212 my $import_record_id = _create_import_record
($batch_id, $record_sequence, $marc_record, 'biblio', $encoding, $z3950random);
213 _add_biblio_fields
($import_record_id, $marc_record);
214 _update_batch_record_counts
($batch_id) if $update_counts;
215 return $import_record_id;
218 =head2 ModBiblioInBatch
222 ModBiblioInBatch($import_record_id, $marc_record);
228 sub ModBiblioInBatch
{
229 my ($import_record_id, $marc_record) = @_;
231 _update_import_record_marc
($import_record_id, $marc_record);
232 _update_biblio_fields
($import_record_id, $marc_record);
236 =head2 BatchStageMarcRecords
240 ($batch_id, $num_records, $num_items, @invalid_records) =
241 BatchStageMarcRecords($marc_flavor, $marc_records, $file_name,
242 $comments, $branch_code, $parse_items,
244 $progress_interval, $progress_callback);
250 sub BatchStageMarcRecords
{
251 my $marc_flavor = shift;
252 my $marc_records = shift;
253 my $file_name = shift;
254 my $comments = shift;
255 my $branch_code = shift;
256 my $parse_items = shift;
257 my $leave_as_staging = shift;
259 # optional callback to monitor status
261 my $progress_interval = 0;
262 my $progress_callback = undef;
264 $progress_interval = shift;
265 $progress_callback = shift;
266 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
267 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
270 my $batch_id = AddImportBatch
('create_new', 'staging', 'batch', $file_name, $comments);
272 SetImportBatchItemAction
($batch_id, 'always_add');
274 SetImportBatchItemAction
($batch_id, 'ignore');
277 my @invalid_records = ();
280 # FIXME - for now, we're dealing only with bibs
282 foreach my $marc_blob (split(/\x1D/, $marc_records)) {
283 $marc_blob =~ s/^\s+//g;
284 $marc_blob =~ s/\s+$//g;
285 next unless $marc_blob;
287 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
288 &$progress_callback($rec_num);
290 my ($marc_record, $charset_guessed, $char_errors) =
291 MarcToUTF8Record
($marc_blob, C4
::Context
->preference("marcflavour"));
292 my $import_record_id;
293 if (scalar($marc_record->fields()) == 0) {
294 push @invalid_records, $marc_blob;
297 $import_record_id = AddBiblioToBatch
($batch_id, $rec_num, $marc_record, $marc_flavor, int(rand(99999)), 0);
299 my @import_items_ids = AddItemsToImportBiblio
($batch_id, $import_record_id, $marc_record, 0);
300 $num_items += scalar(@import_items_ids);
304 unless ($leave_as_staging) {
305 SetImportBatchStatus
($batch_id, 'staged');
307 # FIXME branch_code, number of bibs, number of items
308 _update_batch_record_counts
($batch_id);
309 return ($batch_id, $num_valid, $num_items, @invalid_records);
312 =head2 AddItemsToImportBiblio
316 my @import_items_ids = AddItemsToImportBiblio($batch_id, $import_record_id, $marc_record, $update_counts);
322 sub AddItemsToImportBiblio
{
323 my $batch_id = shift;
324 my $import_record_id = shift;
325 my $marc_record = shift;
326 my $update_counts = @_ ?
shift : 0;
328 my @import_items_ids = ();
330 my $dbh = C4
::Context
->dbh;
331 my ($item_tag,$item_subfield) = &GetMarcFromKohaField
("items.itemnumber",'');
332 foreach my $item_field ($marc_record->field($item_tag)) {
333 my $item_marc = MARC
::Record
->new();
334 $item_marc->leader("00000 a "); # must set Leader/09 to 'a'
335 $item_marc->append_fields($item_field);
336 $marc_record->delete_field($item_field);
337 my $sth = $dbh->prepare_cached("INSERT INTO import_items (import_record_id, status, marcxml)
339 $sth->bind_param(1, $import_record_id);
340 $sth->bind_param(2, 'staged');
341 $sth->bind_param(3, $item_marc->as_xml());
343 push @import_items_ids, $dbh->{'mysql_insertid'};
347 if ($#import_items_ids > -1) {
348 _update_batch_record_counts
($batch_id) if $update_counts;
349 _update_import_record_marc
($import_record_id, $marc_record);
351 return @import_items_ids;
354 =head2 BatchFindBibDuplicates
358 my $num_with_matches = BatchFindBibDuplicates($batch_id, $matcher, $max_matches, $progress_interval, $progress_callback);
362 Goes through the records loaded in the batch and attempts to
363 find duplicates for each one. Sets the matching status
364 of each record to "no_match" or "auto_match" as appropriate.
366 The $max_matches parameter is optional; if it is not supplied,
369 The $progress_interval and $progress_callback parameters are
370 optional; if both are supplied, the sub referred to by
371 $progress_callback will be invoked every $progress_interval
372 records using the number of records processed as the
377 sub BatchFindBibDuplicates
{
378 my $batch_id = shift;
380 my $max_matches = @_ ?
shift : 10;
382 # optional callback to monitor status
384 my $progress_interval = 0;
385 my $progress_callback = undef;
387 $progress_interval = shift;
388 $progress_callback = shift;
389 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
390 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
393 my $dbh = C4
::Context
->dbh;
395 my $sth = $dbh->prepare("SELECT import_record_id, marc
397 JOIN import_biblios USING (import_record_id)
398 WHERE import_batch_id = ?");
399 $sth->execute($batch_id);
400 my $num_with_matches = 0;
402 while (my $rowref = $sth->fetchrow_hashref) {
404 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
405 &$progress_callback($rec_num);
407 my $marc_record = MARC
::Record
->new_from_usmarc($rowref->{'marc'});
409 if (defined $matcher) {
410 @matches = $matcher->get_matches($marc_record, $max_matches);
412 if (scalar(@matches) > 0) {
414 SetImportRecordMatches
($rowref->{'import_record_id'}, @matches);
415 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'auto_match');
417 SetImportRecordMatches
($rowref->{'import_record_id'}, ());
418 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'no_match');
422 return $num_with_matches;
425 =head2 BatchCommitBibRecords
429 my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) =
430 BatchCommitBibRecords($batch_id, $progress_interval, $progress_callback);
436 sub BatchCommitBibRecords
{
437 my $batch_id = shift;
439 # optional callback to monitor status
441 my $progress_interval = 0;
442 my $progress_callback = undef;
444 $progress_interval = shift;
445 $progress_callback = shift;
446 $progress_interval = 0 unless $progress_interval =~ /^\d+$/ and $progress_interval > 0;
447 $progress_interval = 0 unless 'CODE' eq ref $progress_callback;
452 my $num_items_added = 0;
453 my $num_items_errored = 0;
455 # commit (i.e., save, all records in the batch)
456 # FIXME biblio only at the moment
457 SetImportBatchStatus
('importing');
458 my $overlay_action = GetImportBatchOverlayAction
($batch_id);
459 my $nomatch_action = GetImportBatchNoMatchAction
($batch_id);
460 my $item_action = GetImportBatchItemAction
($batch_id);
461 my $dbh = C4
::Context
->dbh;
462 my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marc, encoding
464 JOIN import_biblios USING (import_record_id)
465 WHERE import_batch_id = ?");
466 $sth->execute($batch_id);
468 while (my $rowref = $sth->fetchrow_hashref) {
470 if ($progress_interval and (0 == ($rec_num % $progress_interval))) {
471 &$progress_callback($rec_num);
473 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'imported') {
478 my $marc_record = MARC
::Record
->new_from_usmarc($rowref->{'marc'});
480 # remove any item tags - rely on BatchCommitItems
481 my ($item_tag,$item_subfield) = &GetMarcFromKohaField
("items.itemnumber",'');
482 foreach my $item_field ($marc_record->field($item_tag)) {
483 $marc_record->delete_field($item_field);
486 # decide what what to do with the bib and item records
487 my ($bib_result, $item_result, $bib_match) =
488 _get_commit_action
($overlay_action, $nomatch_action, $item_action,
489 $rowref->{'overlay_status'}, $rowref->{'import_record_id'});
491 if ($bib_result eq 'create_new') {
493 my ($biblionumber, $biblioitemnumber) = AddBiblio
($marc_record, '');
494 my $sth = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
495 $sth->execute($biblionumber, $rowref->{'import_record_id'});
497 if ($item_result eq 'create_new') {
498 my ($bib_items_added, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $biblionumber);
499 $num_items_added += $bib_items_added;
500 $num_items_errored += $bib_items_errored;
502 SetImportRecordStatus
($rowref->{'import_record_id'}, 'imported');
503 } elsif ($bib_result eq 'replace') {
505 my $biblionumber = $bib_match;
506 my ($count, $oldbiblio) = GetBiblio
($biblionumber);
507 my $oldxml = GetXmlBiblio
($biblionumber);
509 # remove item fields so that they don't get
510 # added again if record is reverted
511 my $old_marc = MARC
::Record
->new_from_xml(StripNonXmlChars
($oldxml), 'UTF-8', $rowref->{'encoding'});
512 foreach my $item_field ($old_marc->field($item_tag)) {
513 $old_marc->delete_field($item_field);
516 ModBiblio
($marc_record, $biblionumber, $oldbiblio->{'frameworkcode'});
517 my $sth = $dbh->prepare_cached("UPDATE import_records SET marcxml_old = ? WHERE import_record_id = ?");
518 $sth->execute($old_marc->as_xml(), $rowref->{'import_record_id'});
520 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
521 $sth2->execute($biblionumber, $rowref->{'import_record_id'});
523 if ($item_result eq 'create_new') {
524 my ($bib_items_added, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $biblionumber);
525 $num_items_added += $bib_items_added;
526 $num_items_errored += $bib_items_errored;
528 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'match_applied');
529 SetImportRecordStatus
($rowref->{'import_record_id'}, 'imported');
530 } elsif ($bib_result eq 'ignore') {
532 my $biblionumber = $bib_match;
533 if (defined $biblionumber and $item_result eq 'create_new') {
534 my ($bib_items_added, $bib_items_errored) = BatchCommitItems
($rowref->{'import_record_id'}, $biblionumber);
535 $num_items_added += $bib_items_added;
536 $num_items_errored += $bib_items_errored;
537 # still need to record the matched biblionumber so that the
538 # items can be reverted
539 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = ? WHERE import_record_id = ?");
540 $sth2->execute($biblionumber, $rowref->{'import_record_id'});
541 SetImportRecordOverlayStatus
($rowref->{'import_record_id'}, 'match_applied');
543 SetImportRecordStatus
($rowref->{'import_record_id'}, 'ignored');
547 SetImportBatchStatus
($batch_id, 'imported');
548 return ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored);
551 =head2 BatchCommitItems
555 ($num_items_added, $num_items_errored) = BatchCommitItems($import_record_id, $biblionumber);
561 sub BatchCommitItems
{
562 my ($import_record_id, $biblionumber) = @_;
564 my $dbh = C4
::Context
->dbh;
566 my $num_items_added = 0;
567 my $num_items_errored = 0;
568 my $sth = $dbh->prepare("SELECT import_items_id, import_items.marcxml, encoding
570 JOIN import_records USING (import_record_id)
571 WHERE import_record_id = ?
572 ORDER BY import_items_id");
573 $sth->bind_param(1, $import_record_id);
575 while (my $row = $sth->fetchrow_hashref()) {
576 my $item_marc = MARC
::Record
->new_from_xml(StripNonXmlChars
($row->{'marcxml'}), 'UTF-8', $row->{'encoding'});
577 # FIXME - duplicate barcode check needs to become part of AddItemFromMarc()
578 my $item = TransformMarcToKoha
($dbh, $item_marc);
579 my $duplicate_barcode = exists($item->{'barcode'}) && GetItemnumberFromBarcode
($item->{'barcode'});
580 if ($duplicate_barcode) {
581 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, import_error = ? WHERE import_items_id = ?");
582 $updsth->bind_param(1, 'error');
583 $updsth->bind_param(2, 'duplicate item barcode');
584 $updsth->bind_param(3, $row->{'import_items_id'});
586 $num_items_errored++;
588 my ($item_biblionumber, $biblioitemnumber, $itemnumber) = AddItemFromMarc
($item_marc, $biblionumber);
589 my $updsth = $dbh->prepare("UPDATE import_items SET status = ?, itemnumber = ? WHERE import_items_id = ?");
590 $updsth->bind_param(1, 'imported');
591 $updsth->bind_param(2, $itemnumber);
592 $updsth->bind_param(3, $row->{'import_items_id'});
599 return ($num_items_added, $num_items_errored);
602 =head2 BatchRevertBibRecords
606 my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored) = BatchRevertBibRecords($batch_id);
612 sub BatchRevertBibRecords
{
613 my $batch_id = shift;
617 my $num_reverted = 0;
618 my $num_items_deleted = 0;
620 # commit (i.e., save, all records in the batch)
621 # FIXME biblio only at the moment
622 SetImportBatchStatus
('reverting');
623 my $overlay_action = GetImportBatchOverlayAction
($batch_id);
624 my $nomatch_action = GetImportBatchNoMatchAction
($batch_id);
625 my $dbh = C4
::Context
->dbh;
626 my $sth = $dbh->prepare("SELECT import_record_id, status, overlay_status, marcxml_old, encoding, matched_biblionumber
628 JOIN import_biblios USING (import_record_id)
629 WHERE import_batch_id = ?");
630 $sth->execute($batch_id);
631 while (my $rowref = $sth->fetchrow_hashref) {
632 if ($rowref->{'status'} eq 'error' or $rowref->{'status'} eq 'reverted') {
637 my $bib_result = _get_revert_action
($overlay_action, $rowref->{'overlay_status'}, $rowref->{'status'});
639 if ($bib_result eq 'delete') {
640 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
641 my $error = DelBiblio
($rowref->{'matched_biblionumber'});
642 if (defined $error) {
646 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
648 } elsif ($bib_result eq 'restore') {
650 my $old_record = MARC
::Record
->new_from_xml(StripNonXmlChars
($rowref->{'marcxml_old'}), 'UTF-8', $rowref->{'encoding'});
651 my $biblionumber = $rowref->{'matched_biblionumber'};
652 my ($count, $oldbiblio) = GetBiblio
($biblionumber);
653 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
654 ModBiblio
($old_record, $biblionumber, $oldbiblio->{'frameworkcode'});
655 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
656 } elsif ($bib_result eq 'ignore') {
657 $num_items_deleted += BatchRevertItems
($rowref->{'import_record_id'}, $rowref->{'matched_biblionumber'});
658 SetImportRecordStatus
($rowref->{'import_record_id'}, 'reverted');
660 my $sth2 = $dbh->prepare_cached("UPDATE import_biblios SET matched_biblionumber = NULL WHERE import_record_id = ?");
661 $sth2->execute($rowref->{'import_record_id'});
665 SetImportBatchStatus
($batch_id, 'reverted');
666 return ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored);
669 =head2 BatchRevertItems
673 my $num_items_deleted = BatchRevertItems($import_record_id, $biblionumber);
679 sub BatchRevertItems
{
680 my ($import_record_id, $biblionumber) = @_;
682 my $dbh = C4
::Context
->dbh;
683 my $num_items_deleted = 0;
685 my $sth = $dbh->prepare_cached("SELECT import_items_id, itemnumber
687 JOIN items USING (itemnumber)
688 WHERE import_record_id = ?");
689 $sth->bind_param(1, $import_record_id);
691 while (my $row = $sth->fetchrow_hashref()) {
692 DelItem
($dbh, $biblionumber, $row->{'itemnumber'});
693 my $updsth = $dbh->prepare("UPDATE import_items SET status = ? WHERE import_items_id = ?");
694 $updsth->bind_param(1, 'reverted');
695 $updsth->bind_param(2, $row->{'import_items_id'});
698 $num_items_deleted++;
701 return $num_items_deleted;
708 CleanBatch($batch_id)
712 Deletes all staged records from the import batch
713 and sets the status of the batch to 'cleaned'. Note
714 that deleting a stage record does *not* affect
715 any record that has been committed to the database.
720 my $batch_id = shift;
721 return unless defined $batch_id;
723 C4
::Context
->dbh->do('DELETE FROM import_records WHERE import_batch_id = ?', {}, $batch_id);
724 SetImportBatchStatus
($batch_id, 'cleaned');
727 =head2 GetAllImportBatches
731 my $results = GetAllImportBatches();
735 Returns a references to an array of hash references corresponding
736 to all import_batches rows (of batch_type 'batch'), sorted in
737 ascending order by import_batch_id.
741 sub GetAllImportBatches
{
742 my $dbh = C4
::Context
->dbh;
743 my $sth = $dbh->prepare_cached("SELECT * FROM import_batches
744 WHERE batch_type = 'batch'
745 ORDER BY import_batch_id ASC");
749 while (my $row = $sth->fetchrow_hashref) {
750 push @
$results, $row;
756 =head2 GetImportBatchRangeDesc
760 my $results = GetImportBatchRangeDesc($offset, $results_per_group);
764 Returns a reference to an array of hash references corresponding to
765 import_batches rows (sorted in descending order by import_batch_id)
766 start at the given offset.
770 sub GetImportBatchRangeDesc
{
771 my ($offset, $results_per_group) = @_;
773 my $dbh = C4
::Context
->dbh;
774 my $query = "SELECT * FROM import_batches
775 WHERE batch_type = 'batch'
776 ORDER BY import_batch_id DESC";
778 if ($results_per_group){
779 $query .= " LIMIT ?";
780 push(@params, $results_per_group);
783 $query .= " OFFSET ?";
784 push(@params, $offset);
786 my $sth = $dbh->prepare_cached($query);
787 $sth->execute(@params);
788 my $results = $sth->fetchall_arrayref({});
793 =head2 GetItemNumbersFromImportBatch
797 sub GetItemNumbersFromImportBatch
{
799 my $dbh = C4
::Context
->dbh;
800 my $sth = $dbh->prepare("SELECT itemnumber FROM import_batches,import_records,import_items WHERE import_batches.import_batch_id=import_records.import_batch_id AND import_records.import_record_id=import_items.import_record_id AND import_batches.import_batch_id=?");
801 $sth->execute($batch_id);
803 while ( my ($itm) = $sth->fetchrow_array ) {
809 =head2 GetNumberOfImportBatches
813 my $count = GetNumberOfImportBatches();
819 sub GetNumberOfNonZ3950ImportBatches
{
820 my $dbh = C4
::Context
->dbh;
821 my $sth = $dbh->prepare("SELECT COUNT(*) FROM import_batches WHERE batch_type='batch'");
823 my ($count) = $sth->fetchrow_array();
828 =head2 GetImportBibliosRange
832 my $results = GetImportBibliosRange($batch_id, $offset, $results_per_group);
836 Returns a reference to an array of hash references corresponding to
837 import_biblios/import_records rows for a given batch
838 starting at the given offset.
842 sub GetImportBibliosRange
{
843 my ($batch_id, $offset, $results_per_group, $status) = @_;
845 my $dbh = C4
::Context
->dbh;
846 my $query = "SELECT title, author, isbn, issn, import_record_id, record_sequence,
847 status, overlay_status, matched_biblionumber
849 JOIN import_biblios USING (import_record_id)
850 WHERE import_batch_id = ?";
852 push(@params, $batch_id);
854 $query .= " AND status=?";
855 push(@params,$status);
857 $query.=" ORDER BY import_record_id";
859 if($results_per_group){
860 $query .= " LIMIT ?";
861 push(@params, $results_per_group);
864 $query .= " OFFSET ?";
865 push(@params, $offset);
867 my $sth = $dbh->prepare_cached($query);
868 $sth->execute(@params);
869 my $results = $sth->fetchall_arrayref({});
875 =head2 GetBestRecordMatch
879 my $record_id = GetBestRecordMatch($import_record_id);
885 sub GetBestRecordMatch
{
886 my ($import_record_id) = @_;
888 my $dbh = C4
::Context
->dbh;
889 my $sth = $dbh->prepare("SELECT candidate_match_id
890 FROM import_record_matches
891 WHERE import_record_id = ?
892 ORDER BY score DESC, candidate_match_id DESC");
893 $sth->execute($import_record_id);
894 my ($record_id) = $sth->fetchrow_array();
899 =head2 GetImportBatchStatus
903 my $status = GetImportBatchStatus($batch_id);
909 sub GetImportBatchStatus
{
912 my $dbh = C4
::Context
->dbh;
913 my $sth = $dbh->prepare("SELECT import_status FROM import_batches WHERE import_batch_id = ?");
914 $sth->execute($batch_id);
915 my ($status) = $sth->fetchrow_array();
921 =head2 SetImportBatchStatus
925 SetImportBatchStatus($batch_id, $new_status);
931 sub SetImportBatchStatus
{
932 my ($batch_id, $new_status) = @_;
934 my $dbh = C4
::Context
->dbh;
935 my $sth = $dbh->prepare("UPDATE import_batches SET import_status = ? WHERE import_batch_id = ?");
936 $sth->execute($new_status, $batch_id);
941 =head2 GetImportBatchOverlayAction
945 my $overlay_action = GetImportBatchOverlayAction($batch_id);
951 sub GetImportBatchOverlayAction
{
954 my $dbh = C4
::Context
->dbh;
955 my $sth = $dbh->prepare("SELECT overlay_action FROM import_batches WHERE import_batch_id = ?");
956 $sth->execute($batch_id);
957 my ($overlay_action) = $sth->fetchrow_array();
959 return $overlay_action;
964 =head2 SetImportBatchOverlayAction
968 SetImportBatchOverlayAction($batch_id, $new_overlay_action);
974 sub SetImportBatchOverlayAction
{
975 my ($batch_id, $new_overlay_action) = @_;
977 my $dbh = C4
::Context
->dbh;
978 my $sth = $dbh->prepare("UPDATE import_batches SET overlay_action = ? WHERE import_batch_id = ?");
979 $sth->execute($new_overlay_action, $batch_id);
984 =head2 GetImportBatchNoMatchAction
988 my $nomatch_action = GetImportBatchNoMatchAction($batch_id);
994 sub GetImportBatchNoMatchAction
{
997 my $dbh = C4
::Context
->dbh;
998 my $sth = $dbh->prepare("SELECT nomatch_action FROM import_batches WHERE import_batch_id = ?");
999 $sth->execute($batch_id);
1000 my ($nomatch_action) = $sth->fetchrow_array();
1002 return $nomatch_action;
1007 =head2 SetImportBatchNoMatchAction
1011 SetImportBatchNoMatchAction($batch_id, $new_nomatch_action);
1017 sub SetImportBatchNoMatchAction
{
1018 my ($batch_id, $new_nomatch_action) = @_;
1020 my $dbh = C4
::Context
->dbh;
1021 my $sth = $dbh->prepare("UPDATE import_batches SET nomatch_action = ? WHERE import_batch_id = ?");
1022 $sth->execute($new_nomatch_action, $batch_id);
1027 =head2 GetImportBatchItemAction
1031 my $item_action = GetImportBatchItemAction($batch_id);
1037 sub GetImportBatchItemAction
{
1038 my ($batch_id) = @_;
1040 my $dbh = C4
::Context
->dbh;
1041 my $sth = $dbh->prepare("SELECT item_action FROM import_batches WHERE import_batch_id = ?");
1042 $sth->execute($batch_id);
1043 my ($item_action) = $sth->fetchrow_array();
1045 return $item_action;
1050 =head2 SetImportBatchItemAction
1054 SetImportBatchItemAction($batch_id, $new_item_action);
1060 sub SetImportBatchItemAction
{
1061 my ($batch_id, $new_item_action) = @_;
1063 my $dbh = C4
::Context
->dbh;
1064 my $sth = $dbh->prepare("UPDATE import_batches SET item_action = ? WHERE import_batch_id = ?");
1065 $sth->execute($new_item_action, $batch_id);
1070 =head2 GetImportBatchMatcher
1074 my $matcher_id = GetImportBatchMatcher($batch_id);
1080 sub GetImportBatchMatcher
{
1081 my ($batch_id) = @_;
1083 my $dbh = C4
::Context
->dbh;
1084 my $sth = $dbh->prepare("SELECT matcher_id FROM import_batches WHERE import_batch_id = ?");
1085 $sth->execute($batch_id);
1086 my ($matcher_id) = $sth->fetchrow_array();
1093 =head2 SetImportBatchMatcher
1097 SetImportBatchMatcher($batch_id, $new_matcher_id);
1103 sub SetImportBatchMatcher
{
1104 my ($batch_id, $new_matcher_id) = @_;
1106 my $dbh = C4
::Context
->dbh;
1107 my $sth = $dbh->prepare("UPDATE import_batches SET matcher_id = ? WHERE import_batch_id = ?");
1108 $sth->execute($new_matcher_id, $batch_id);
1113 =head2 GetImportRecordOverlayStatus
1117 my $overlay_status = GetImportRecordOverlayStatus($import_record_id);
1123 sub GetImportRecordOverlayStatus
{
1124 my ($import_record_id) = @_;
1126 my $dbh = C4
::Context
->dbh;
1127 my $sth = $dbh->prepare("SELECT overlay_status FROM import_records WHERE import_record_id = ?");
1128 $sth->execute($import_record_id);
1129 my ($overlay_status) = $sth->fetchrow_array();
1131 return $overlay_status;
1136 =head2 SetImportRecordOverlayStatus
1140 SetImportRecordOverlayStatus($import_record_id, $new_overlay_status);
1146 sub SetImportRecordOverlayStatus
{
1147 my ($import_record_id, $new_overlay_status) = @_;
1149 my $dbh = C4
::Context
->dbh;
1150 my $sth = $dbh->prepare("UPDATE import_records SET overlay_status = ? WHERE import_record_id = ?");
1151 $sth->execute($new_overlay_status, $import_record_id);
1156 =head2 GetImportRecordStatus
1160 my $overlay_status = GetImportRecordStatus($import_record_id);
1166 sub GetImportRecordStatus
{
1167 my ($import_record_id) = @_;
1169 my $dbh = C4
::Context
->dbh;
1170 my $sth = $dbh->prepare("SELECT status FROM import_records WHERE import_record_id = ?");
1171 $sth->execute($import_record_id);
1172 my ($overlay_status) = $sth->fetchrow_array();
1174 return $overlay_status;
1179 =head2 SetImportRecordStatus
1183 SetImportRecordStatus($import_record_id, $new_overlay_status);
1189 sub SetImportRecordStatus
{
1190 my ($import_record_id, $new_overlay_status) = @_;
1192 my $dbh = C4
::Context
->dbh;
1193 my $sth = $dbh->prepare("UPDATE import_records SET status = ? WHERE import_record_id = ?");
1194 $sth->execute($new_overlay_status, $import_record_id);
1199 =head2 GetImportRecordMatches
1203 my $results = GetImportRecordMatches($import_record_id, $best_only);
1209 sub GetImportRecordMatches
{
1210 my $import_record_id = shift;
1211 my $best_only = @_ ?
shift : 0;
1213 my $dbh = C4
::Context
->dbh;
1214 # FIXME currently biblio only
1215 my $sth = $dbh->prepare_cached("SELECT title, author, biblionumber, score
1217 JOIN import_record_matches USING (import_record_id)
1218 JOIN biblio ON (biblionumber = candidate_match_id)
1219 WHERE import_record_id = ?
1220 ORDER BY score DESC, biblionumber DESC");
1221 $sth->bind_param(1, $import_record_id);
1224 while (my $row = $sth->fetchrow_hashref) {
1225 push @
$results, $row;
1235 =head2 SetImportRecordMatches
1239 SetImportRecordMatches($import_record_id, @matches);
1245 sub SetImportRecordMatches
{
1246 my $import_record_id = shift;
1249 my $dbh = C4
::Context
->dbh;
1250 my $delsth = $dbh->prepare("DELETE FROM import_record_matches WHERE import_record_id = ?");
1251 $delsth->execute($import_record_id);
1254 my $sth = $dbh->prepare("INSERT INTO import_record_matches (import_record_id, candidate_match_id, score)
1256 foreach my $match (@matches) {
1257 $sth->execute($import_record_id, $match->{'record_id'}, $match->{'score'});
1262 # internal functions
1264 sub _create_import_record
{
1265 my ($batch_id, $record_sequence, $marc_record, $record_type, $encoding, $z3950random) = @_;
1267 my $dbh = C4
::Context
->dbh;
1268 my $sth = $dbh->prepare("INSERT INTO import_records (import_batch_id, record_sequence, marc, marcxml,
1269 record_type, encoding, z3950random)
1270 VALUES (?, ?, ?, ?, ?, ?, ?)");
1271 $sth->execute($batch_id, $record_sequence, $marc_record->as_usmarc(), $marc_record->as_xml(),
1272 $record_type, $encoding, $z3950random);
1273 my $import_record_id = $dbh->{'mysql_insertid'};
1275 return $import_record_id;
1278 sub _update_import_record_marc
{
1279 my ($import_record_id, $marc_record) = @_;
1281 my $dbh = C4
::Context
->dbh;
1282 my $sth = $dbh->prepare("UPDATE import_records SET marc = ?, marcxml = ?
1283 WHERE import_record_id = ?");
1284 $sth->execute($marc_record->as_usmarc(), $marc_record->as_xml(), $import_record_id);
1288 sub _add_biblio_fields
{
1289 my ($import_record_id, $marc_record) = @_;
1291 my ($title, $author, $isbn, $issn) = _parse_biblio_fields
($marc_record);
1292 my $dbh = C4
::Context
->dbh;
1293 # FIXME no controlnumber, originalsource
1294 $isbn = C4
::Koha
::_isbn_cleanup
($isbn); # FIXME C4::Koha::_isbn_cleanup should be made public
1295 my $sth = $dbh->prepare("INSERT INTO import_biblios (import_record_id, title, author, isbn, issn) VALUES (?, ?, ?, ?, ?)");
1296 $sth->execute($import_record_id, $title, $author, $isbn, $issn);
1301 sub _update_biblio_fields
{
1302 my ($import_record_id, $marc_record) = @_;
1304 my ($title, $author, $isbn, $issn) = _parse_biblio_fields
($marc_record);
1305 my $dbh = C4
::Context
->dbh;
1306 # FIXME no controlnumber, originalsource
1307 # FIXME 2 - should regularize normalization of ISBN wherever it is done
1311 my $sth = $dbh->prepare("UPDATE import_biblios SET title = ?, author = ?, isbn = ?, issn = ?
1312 WHERE import_record_id = ?");
1313 $sth->execute($title, $author, $isbn, $issn, $import_record_id);
1317 sub _parse_biblio_fields
{
1318 my ($marc_record) = @_;
1320 my $dbh = C4
::Context
->dbh;
1321 my $bibliofields = TransformMarcToKoha
($dbh, $marc_record, '');
1322 return ($bibliofields->{'title'}, $bibliofields->{'author'}, $bibliofields->{'isbn'}, $bibliofields->{'issn'});
1326 sub _update_batch_record_counts
{
1327 my ($batch_id) = @_;
1329 my $dbh = C4
::Context
->dbh;
1330 my $sth = $dbh->prepare_cached("UPDATE import_batches SET num_biblios = (
1333 WHERE import_batch_id = import_batches.import_batch_id
1334 AND record_type = 'biblio')
1335 WHERE import_batch_id = ?");
1336 $sth->bind_param(1, $batch_id);
1339 $sth = $dbh->prepare_cached("UPDATE import_batches SET num_items = (
1342 JOIN import_items USING (import_record_id)
1343 WHERE import_batch_id = import_batches.import_batch_id
1344 AND record_type = 'biblio')
1345 WHERE import_batch_id = ?");
1346 $sth->bind_param(1, $batch_id);
1352 sub _get_commit_action
{
1353 my ($overlay_action, $nomatch_action, $item_action, $overlay_status, $import_record_id) = @_;
1355 my ($bib_result, $bib_match, $item_result);
1357 if ($overlay_status ne 'no_match') {
1358 $bib_match = GetBestRecordMatch
($import_record_id);
1359 if ($overlay_action eq 'replace') {
1360 $bib_result = defined($bib_match) ?
'replace' : 'create_new';
1361 } elsif ($overlay_action eq 'create_new') {
1362 $bib_result = 'create_new';
1363 } elsif ($overlay_action eq 'ignore') {
1364 $bib_result = 'ignore';
1366 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_matches') ?
'create_new' : 'ignore';
1368 $bib_result = $nomatch_action;
1369 $item_result = ($item_action eq 'always_add' or $item_action eq 'add_only_for_new') ?
'create_new' : 'ignore';
1372 return ($bib_result, $item_result, $bib_match);
1375 sub _get_revert_action
{
1376 my ($overlay_action, $overlay_status, $status) = @_;
1380 if ($status eq 'ignored') {
1381 $bib_result = 'ignore';
1383 if ($overlay_action eq 'create_new') {
1384 $bib_result = 'delete';
1386 $bib_result = ($overlay_status eq 'match_applied') ?
'restore' : 'delete';
1397 Koha Development Team <info@koha.org>
1399 Galen Charlton <galen.charlton@liblime.com>