Bug 18070: Extend sub merge to remove fields for deleted authorities
[koha.git] / misc / batchRebuildItemsTables.pl
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4
5 use Getopt::Long;
6 use MARC::Field;
7 use MARC::Record;
8 use Pod::Usage;
9 use Time::HiRes qw(gettimeofday);
10
11 use C4::Context;
12 use C4::Biblio;
13 use C4::Items;
14
15 =head1 NAME
16
17 batchRebuildBiblioTables.pl - rebuilds the non-MARC DB items table from the MARC values
18
19 You can/must use it when you change items mapping.
20
21 =head1 SYNOPSIS
22
23 batchRebuildItemsTables.pl [ -h ][ -c ][ -t ][ --where ]
24
25  Options:
26    -h --help       (or without arguments) shows this help message
27    -c              Confirm: rebuild non marc DB (may be long)
28    -t              test only, change nothing in DB
29    --where         add where condition on default query (eg. --where 'biblio.biblionumber<100')
30
31 =cut
32
33 my $count      = 0;
34 my $errorcount = 0;
35 my $starttime  = gettimeofday;
36 my @errors;
37 my ( $confirm, $help, $test_parameter, $where );
38 GetOptions(
39     'c'       => \$confirm,
40     'help|h'  => \$help,
41     't'       => \$test_parameter,
42     'where:s' => \$where,
43 ) or pod2usage(2);
44
45 pod2usage(1) if $help || ( !$confirm && !$test_parameter );
46 print "### Database will not be modified ###\n" if $test_parameter;
47
48 #dbh
49 my $dbh = C4::Context->dbh;
50 $dbh->{AutoCommit} = 0;
51
52 #sysprefs
53 C4::Context->disable_syspref_cache() if ( defined( C4::Context->disable_syspref_cache() ) );
54 my $CataloguingLog = C4::Context->preference('CataloguingLog');
55 my $dontmerge      = C4::Context->preference('dontmerge');
56 $dontmerge = "0" unless defnonull($dontmerge);
57 $dbh->do("UPDATE systempreferences SET value=0 WHERE variable='CataloguingLog'");
58 $dbh->do("UPDATE systempreferences SET value=1 where variable='dontmerge'");
59 $dbh->commit() unless $test_parameter;
60 my ( $itemfield, $itemnumbersubfield ) = &GetMarcFromKohaField( "items.itemnumber", '' );
61
62 #dbh query init
63 my $query =
64 qq{SELECT biblio.biblionumber AS biblionumber, biblioitems.biblioitemnumber AS biblioitemnumber, biblio.frameworkcode AS frameworkcode FROM biblio JOIN biblioitems ON biblio.biblionumber=biblioitems.biblionumber};
65 $query .= qq{ WHERE $where } if ($where);
66
67 my $sth = $dbh->prepare($query);
68 $sth->execute();
69 while ( my ( $biblionumber, $biblioitemnumber, $frameworkcode ) = $sth->fetchrow ) {
70     $count++;
71     warn $count unless $count % 1000;
72     my $record = GetMarcBiblio( $biblionumber, 1 );
73     unless ($record) { push @errors, "bad record biblionumber $biblionumber"; next; }
74
75     unless ($test_parameter) {
76         my $rqitemnumber = $dbh->prepare("SELECT itemnumber, biblionumber from items where itemnumber = ? and biblionumber = ?");
77         foreach my $itemfield ( $record->field($itemfield) ) {
78             my $marcitem = MARC::Record->new();
79             $marcitem->encoding('UTF-8');
80             $marcitem->append_fields($itemfield);
81             my $itemnum;
82             my @itemnumbers = $itemfield->subfield($itemnumbersubfield);
83             foreach my $itemnumber (@itemnumbers) {
84                 $rqitemnumber->execute( $itemnumber, $biblionumber );
85                 if ( my $row = $rqitemnumber->fetchrow_hashref ) { $itemnum = $row->{itemnumber}; }
86             }
87             eval {
88                 if ($itemnum) { ModItemFromMarc( $marcitem, $biblionumber, $itemnum ) }
89                 else          { die("$biblionumber"); }
90             };
91             if ($@) { warn "Problem with : $biblionumber : $@"; warn $record->as_formatted; }
92         }
93     }
94     unless ($test_parameter) {
95         $dbh->commit() unless $count % 1000;
96     }
97 }
98
99 my $sthCataloguingLog = $dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='CataloguingLog'");
100 $sthCataloguingLog->execute($CataloguingLog);
101 my $sthdontmerge = $dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='dontmerge'");
102 $sthdontmerge->execute($dontmerge);
103 $dbh->commit() unless $test_parameter;
104 my $timeneeded = time() - $starttime;
105 print "$count MARC record done in $timeneeded seconds\n";
106 if ( scalar(@errors) > 0 ) {
107     print "Some biblionumber could not be processed though: ", join( " ", @errors );
108 }
109
110 sub defnonull {
111     my $var = shift;
112     return defined $var && $var ne q{};
113 }