bugfixes to config files for zebra 2.0.18
[koha.git] / misc / migration_tools / rebuild_zebra.pl
1 #!/usr/bin/perl
2
3 use C4::Context;
4 use Getopt::Long;
5 use C4::Biblio;
6 use C4::AuthoritiesMarc;
7
8 use strict;
9
10 # script that checks zebradir structure & create directories & mandatory files if needed
11 #
12 #
13
14 $|=1; # flushes output
15
16 # limit for database dumping
17 my $limit;# = "LIMIT 1";
18 my $directory;
19 my $skip_export;
20 my $keep_export;
21 my $reset;
22 my $biblios;
23 my $authorities;
24 my $noxml;
25 GetOptions(
26         'd:s'      => \$directory,
27         'reset'      => \$reset,
28         's'        => \$skip_export,
29         'k'        => \$keep_export,
30         'b'        => \$biblios,
31         'noxml'        => \$noxml,
32         'a'        => \$authorities,
33         );
34
35 $directory = "export" unless $directory;
36
37
38 my $biblioserverdir = C4::Context->zebraconfig('biblioserver')->{directory};
39 my $authorityserverdir = C4::Context->zebraconfig('authorityserver')->{directory};
40
41 my $kohadir = C4::Context->config('intranetdir');
42 my $dbh = C4::Context->dbh;
43 my ($biblionumbertagfield,$biblionumbertagsubfield) = &GetMarcFromKohaField("biblio.biblionumber","");
44 my ($biblioitemnumbertagfield,$biblioitemnumbertagsubfield) = &GetMarcFromKohaField("biblioitems.biblioitemnumber","");
45
46 print "some informations\n";
47 print "=================\n";
48 print "Zebra biblio directory =>$biblioserverdir\n";
49 print "Zebra authorities directory =>$authorityserverdir\n";
50 print "Koha directory =>$kohadir\n";
51 print "BIBLIONUMBER in : $biblionumbertagfield\$$biblionumbertagsubfield\n";
52 print "BIBLIOITEMNUMBER in : $biblioitemnumbertagfield\$$biblioitemnumbertagsubfield\n";
53 print "=================\n";
54 #
55 # creating zebra-biblios.cfg depending on system
56 #
57
58 # getting zebraidx directory
59 my $zebraidxdir;
60 foreach (qw(/usr/local/bin/zebraidx
61         /opt/bin/zebraidx
62         /usr/bin/zebraidx
63         )) {
64     if ( -f $_ ) {
65         $zebraidxdir=$_;
66     }
67 }
68
69 unless ($zebraidxdir) {
70     print qq|
71     ERROR: could not find zebraidx directory
72     ERROR: Either zebra is not installed,
73     ERROR: or it's in a directory I don't checked.
74     ERROR: do a which zebraidx and edit this file to add the result you get
75 |;
76     exit;
77 }
78 $zebraidxdir =~ s/\/bin\/.*//;
79 print "Info : zebra is in $zebraidxdir \n";
80
81 # getting modules directory
82 my $modulesdir;
83 foreach (qw(/usr/local/lib/idzebra-2.0/modules/mod-grs-xml.so
84             /usr/local/lib/idzebra/modules/mod-grs-xml.so
85             /usr/lib/idzebra/modules/mod-grs-xml.so
86             /usr/lib/idzebra-2.0/modules/mod-grs-xml.so
87         )) {
88     if ( -f $_ ) {
89         $modulesdir=$_;
90     }
91 }
92
93 unless ($modulesdir) {
94     print qq|
95     ERROR: could not find mod-grs-xml.so directory
96     ERROR: Either zebra is not properly compiled (libxml2 is not setup and you don t have mod-grs-xml.so,
97     ERROR: or it's in a directory I don't checked.
98     ERROR: find where mod-grs-xml.so is and edit this file to add the result you get
99 |;
100     exit;
101 }
102 $modulesdir =~ s/\/modules\/.*//;
103 print "Info: zebra modules dir : $modulesdir\n";
104
105 # getting tab directory
106 my $tabdir;
107 foreach (qw(/usr/local/share/idzebra/tab/explain.att
108             /usr/local/share/idzebra-2.0/tab/explain.att
109             /usr/share/idzebra/tab/explain.att
110             /usr/share/idzebra-2.0/tab/explain.att
111         )) {
112     if ( -f $_ ) {
113         $tabdir=$_;
114     }
115 }
116
117 unless ($tabdir) {
118     print qq|
119     ERROR: could not find explain.att directory
120     ERROR: Either zebra is not properly compiled,
121     ERROR: or it's in a directory I don't checked.
122     ERROR: find where explain.att is and edit this file to add the result you get
123 |;
124     exit;
125 }
126 $tabdir =~ s/\/tab\/.*//;
127 print "Info: tab dir : $tabdir\n";
128
129 #
130 # AUTHORITIES creating directory structure
131 #
132 my $created_dir_or_file = 0;
133 if ($authorities) {
134     print "====================\n";
135     print "checking directories & files for authorities\n";
136     print "====================\n";
137     unless (-d "$authorityserverdir") {
138         system("mkdir -p $authorityserverdir");
139         print "Info: created $authorityserverdir\n";
140         $created_dir_or_file++;
141     }
142     unless (-d "$authorityserverdir/lock") {
143         mkdir "$authorityserverdir/lock";
144         print "Info: created $authorityserverdir/lock\n";
145         $created_dir_or_file++;
146     }
147     unless (-d "$authorityserverdir/register") {
148         mkdir "$authorityserverdir/register";
149         print "Info: created $authorityserverdir/register\n";
150         $created_dir_or_file++;
151     }
152     unless (-d "$authorityserverdir/shadow") {
153         mkdir "$authorityserverdir/shadow";
154         print "Info: created $authorityserverdir/shadow\n";
155         $created_dir_or_file++;
156     }
157     unless (-d "$authorityserverdir/tab") {
158         mkdir "$authorityserverdir/tab";
159         print "Info: created $authorityserverdir/tab\n";
160         $created_dir_or_file++;
161     }
162     unless (-d "$authorityserverdir/key") {
163         mkdir "$authorityserverdir/key";
164         print "Info: created $authorityserverdir/key\n";
165         $created_dir_or_file++;
166     }
167     
168     unless (-d "$authorityserverdir/etc") {
169         mkdir "$authorityserverdir/etc";
170         print "Info: created $authorityserverdir/etc\n";
171         $created_dir_or_file++;
172     }
173     
174     #
175     # AUTHORITIES : copying mandatory files
176     #
177     # the record model, depending on marc flavour
178     unless (-f "$authorityserverdir/tab/record.abs") {
179         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
180             system("cp -f $kohadir/misc/zebra/record_authorities_unimarc.abs $authorityserverdir/tab/record.abs");
181             print "Info: copied record.abs for UNIMARC\n";
182         } else {
183             system("cp -f $kohadir/misc/zebra/record_authorities_usmarc.abs $authorityserverdir/tab/record.abs");
184             print "Info: copied record.abs for USMARC\n";
185         }
186         $created_dir_or_file++;
187     }
188     unless (-f "$authorityserverdir/tab/sort-string-utf.chr") {
189         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $authorityserverdir/tab/sort-string-utf.chr");
190         print "Info: copied sort-string-utf.chr\n";
191         $created_dir_or_file++;
192     }
193     unless (-f "$authorityserverdir/tab/word-phrase-utf.chr") {
194         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $authorityserverdir/tab/word-phrase-utf.chr");
195         print "Info: copied word-phase-utf.chr\n";
196         $created_dir_or_file++;
197     }
198     unless (-f "$authorityserverdir/tab/auth1.att") {
199         system("cp -f $kohadir/misc/zebra/bib1_authorities.att $authorityserverdir/tab/auth1.att");
200         print "Info: copied auth1.att\n";
201         $created_dir_or_file++;
202     }
203     unless (-f "$authorityserverdir/tab/default.idx") {
204         system("cp -f $kohadir/misc/zebra/default.idx $authorityserverdir/tab/default.idx");
205         print "Info: copied default.idx\n";
206         $created_dir_or_file++;
207     }
208     
209     unless (-f "$authorityserverdir/etc/ccl.properties") {
210 #         system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
211         system("cp -f $kohadir/misc/zebra/ccl.properties $authorityserverdir/etc/ccl.properties");
212         print "Info: copied ccl.properties\n";
213         $created_dir_or_file++;
214     }
215     unless (-f "$authorityserverdir/etc/pqf.properties") {
216 #         system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('authorityserver')->{ccl2rpn});
217         system("cp -f $kohadir/misc/zebra/pqf.properties $authorityserverdir/etc/pqf.properties");
218         print "Info: copied pqf.properties\n";
219         $created_dir_or_file++;
220     }
221     
222     #
223     # AUTHORITIES : copying mandatory files
224     #
225     unless (-f C4::Context->zebraconfig('authorityserver')->{config}) {
226     open ZD,">:utf8 ",C4::Context->zebraconfig('authorityserver')->{config};
227     print ZD "
228 # generated by KOHA/misc/migration_tools/rebuild_zebra.pl 
229 profilePath:\${srcdir:-.}:$authorityserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
230
231 encoding: UTF-8
232 # Files that describe the attribute sets supported.
233 attset: auth1.att
234 attset: explain.att
235 attset: gils.att
236
237 modulePath:$modulesdir/modules/
238 # Specify record type
239 iso2709.recordType:grs.marcxml.record
240 recordType:grs.xml
241 recordId: (auth1,Local-Number)
242 storeKeys:1
243 storeData:1
244
245
246 # Lock File Area
247 lockDir: $authorityserverdir/lock
248 perm.anonymous:r
249 perm.kohaadmin:rw
250 register: $authorityserverdir/register:4G
251 shadow: $authorityserverdir/shadow:4G
252
253 # Temp File area for result sets
254 setTmpDir: $authorityserverdir/tmp
255
256 # Temp File area for index program
257 keyTmpDir: $authorityserverdir/key
258
259 # Approx. Memory usage during indexing
260 memMax: 40M
261 rank:rank-1
262     ";
263         print "Info: creating zebra-authorities.cfg\n";
264         $created_dir_or_file++;
265     }
266     
267     if ($created_dir_or_file) {
268         print "Info: created : $created_dir_or_file directories & files\n";
269     } else {
270         print "Info: file & directories OK\n";
271     }
272     
273     #
274     # exporting authorities
275     #
276     if ($skip_export) {
277         print "====================\n";
278         print "SKIPPING authorities export\n";
279         print "====================\n";
280     } else {
281         print "====================\n";
282         print "exporting authorities\n";
283         print "====================\n";
284         mkdir "$directory" unless (-d $directory);
285         mkdir "$directory/authorities" unless (-d "$directory/authorities");
286         open(OUT,">:utf8","$directory/authorities/authorities.iso2709") or die $!;
287         my $dbh=C4::Context->dbh;
288         my $sth;
289         $sth=$dbh->prepare("select authid,marc from auth_header $limit");
290         $sth->execute();
291         my $i=0;
292         while (my ($authid,$record) = $sth->fetchrow) {
293             # FIXME : we retrieve the iso2709 record. if the GetAuthority (that uses the XML) fails
294             # due to some MARC::File::XML failure, then try the iso2709, 
295             # (add authid & authtype if needed)
296             my $record;
297             eval {
298                 $record = GetAuthority($authid);
299             };
300             next unless $record;
301             # force authid in case it's not here, otherwise, zebra will die on this authority
302             unless ($record->field('001')->data() eq $authid){
303                 print "$authid don't exist for this authority :".$record->as_formatted;
304                 $record->delete_field($record->field('001'));
305                 $record->insert_fields_ordered(MARC::Field->new('001',$authid));
306             }
307             if($@){
308                 print "  There was some pb getting authority : ".$authid."\n";
309             next;
310             }
311                 
312             print ".";
313             print "\r$i" unless ($i++ %100);
314 #            # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
315 #            # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
316             my $leader=$record->leader;
317             substr($leader,0,5)='     ';
318             substr($leader,10,7)='22     ';
319             $record->leader(substr($leader,0,24));
320             print OUT $record->as_usmarc;
321         }
322         close(OUT);
323     }
324     
325     #
326     # and reindexing everything
327     #
328     print "====================\n";
329     print "REINDEXING zebra\n";
330     print "====================\n";
331     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities init") if ($reset);
332     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities update $directory/authorities");
333     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities commit");
334 } else {
335     print "skipping authorities\n";
336 }
337 #################################################################################################################
338 #                        BIBLIOS 
339 #################################################################################################################
340
341 if ($biblios) {
342     print "====================\n";
343     print "checking directories & files for biblios\n";
344     print "====================\n";
345     
346     #
347     # BIBLIOS : creating directory structure
348     #
349     unless (-d "$biblioserverdir") {
350         system("mkdir -p $biblioserverdir");
351         print "Info: created $biblioserverdir\n";
352         $created_dir_or_file++;
353     }
354     unless (-d "$biblioserverdir/lock") {
355         mkdir "$biblioserverdir/lock";
356         print "Info: created $biblioserverdir/lock\n";
357         $created_dir_or_file++;
358     }
359     unless (-d "$biblioserverdir/register") {
360         mkdir "$biblioserverdir/register";
361         print "Info: created $biblioserverdir/register\n";
362         $created_dir_or_file++;
363     }
364     unless (-d "$biblioserverdir/shadow") {
365         mkdir "$biblioserverdir/shadow";
366         print "Info: created $biblioserverdir/shadow\n";
367         $created_dir_or_file++;
368     }
369     unless (-d "$biblioserverdir/tab") {
370         mkdir "$biblioserverdir/tab";
371         print "Info: created $biblioserverdir/tab\n";
372         $created_dir_or_file++;
373     }
374     unless (-d "$biblioserverdir/key") {
375         mkdir "$biblioserverdir/key";
376         print "Info: created $biblioserverdir/key\n";
377         $created_dir_or_file++;
378     }
379     unless (-d "$biblioserverdir/etc") {
380         mkdir "$biblioserverdir/etc";
381         print "Info: created $biblioserverdir/etc\n";
382         $created_dir_or_file++;
383     }
384     
385     #
386     # BIBLIOS : copying mandatory files
387     #
388     # the record model, depending on marc flavour
389     unless (-f "$biblioserverdir/tab/record.abs") {
390         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
391             system("cp -f $kohadir/misc/zebra/record_biblios_unimarc.abs $biblioserverdir/tab/record.abs");
392             print "Info: copied record.abs for UNIMARC\n";
393         } else {
394             system("cp -f $kohadir/misc/zebra/record_biblios_usmarc.abs $biblioserverdir/tab/record.abs");
395             print "Info: copied record.abs for USMARC\n";
396         }
397         $created_dir_or_file++;
398     }
399     unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
400         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/sort-string-utf.chr");
401         print "Info: copied sort-string-utf.chr\n";
402         $created_dir_or_file++;
403     }
404     unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
405         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/word-phrase-utf.chr");
406         print "Info: copied word-phase-utf.chr\n";
407         $created_dir_or_file++;
408     }
409     unless (-f "$biblioserverdir/tab/bib1.att") {
410         system("cp -f $kohadir/misc/zebra/bib1_biblios.att $biblioserverdir/tab/bib1.att");
411         print "Info: copied bib1.att\n";
412         $created_dir_or_file++;
413     }
414     unless (-f "$biblioserverdir/tab/default.idx") {
415         system("cp -f $kohadir/misc/zebra/default.idx $biblioserverdir/tab/default.idx");
416         print "Info: copied default.idx\n";
417         $created_dir_or_file++;
418     }
419     unless (-f "$biblioserverdir/etc/ccl.properties") {
420 #         system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
421         system("cp -f $kohadir/misc/zebra/ccl.properties $biblioserverdir/etc/ccl.properties");
422         print "Info: copied ccl.properties\n";
423         $created_dir_or_file++;
424     }
425     unless (-f "$biblioserverdir/etc/pqf.properties") {
426 #         system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
427         system("cp -f $kohadir/misc/zebra/pqf.properties $biblioserverdir/etc/pqf.properties");
428         print "Info: copied pqf.properties\n";
429         $created_dir_or_file++;
430     }
431     
432     #
433     # BIBLIOS : copying mandatory files
434     #
435     unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
436     open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config};
437     print ZD "
438 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl 
439 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
440
441 encoding: UTF-8
442 # Files that describe the attribute sets supported.
443 attset:bib1.att
444 attset:explain.att
445 attset:gils.att
446
447 modulePath:$modulesdir/modules/
448 # Specify record type
449 iso2709.recordType:grs.marcxml.record
450 recordType:grs.xml
451 recordId: (bib1,Local-Number)
452 storeKeys:1
453 storeData:1
454
455
456 # Lock File Area
457 lockDir: $biblioserverdir/lock
458 perm.anonymous:r
459 perm.kohaadmin:rw
460 register: $biblioserverdir/register:4G
461 shadow: $biblioserverdir/shadow:4G
462
463 # Temp File area for result sets
464 setTmpDir: $biblioserverdir/tmp
465
466 # Temp File area for index program
467 keyTmpDir: $biblioserverdir/key
468
469 # Approx. Memory usage during indexing
470 memMax: 40M
471 rank:rank-1
472     ";
473         print "Info: creating zebra-biblios.cfg\n";
474         $created_dir_or_file++;
475     }
476     
477     if ($created_dir_or_file) {
478         print "Info: created : $created_dir_or_file directories & files\n";
479     } else {
480         print "Info: file & directories OK\n";
481     }
482     
483     # die;
484     #
485     # exporting biblios
486     #
487     if ($skip_export) {
488         print "====================\n";
489         print "SKIPPING biblio export\n";
490         print "====================\n";
491     } else {
492         print "====================\n";
493         print "exporting biblios\n";
494         print "====================\n";
495         mkdir "$directory" unless (-d $directory);
496         mkdir "$directory/biblios" unless (-d "$directory/biblios");
497         open(OUT,">:utf8 ","$directory/biblios/export") or die $!;
498         my $dbh=C4::Context->dbh;
499         my $sth;
500         if ($noxml){
501         $sth=$dbh->prepare("select biblionumber,marc from biblioitems order by biblionumber $limit");
502         $sth->execute();
503         my $i=0;
504         while (my ($biblionumber,$marc) = $sth->fetchrow) {
505             my $record;
506             $record=MARC::Record->new_from_usmarc($marc);
507             my $record_correct=1;
508             # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
509             # FIXME next unless $record->field($biblionumbertagfield);
510             # check if biblionumber is present, otherwise, add it on the fly
511             if ($biblionumbertagfield eq '001') {
512                 unless ($record->field($biblionumbertagfield)->data()) {
513                     $record_correct=0;
514                     my $field;
515                     # if the field where biblionumber is already exist, just update it, otherwise create it
516                 if ($record->field($biblionumbertagfield)) {
517                 $field =  $record->field($biblionumbertagfield);
518                 $field->update($biblionumber);
519                 } else {
520                 my $newfield;
521                 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
522                 $record->append_fields($newfield);
523                 }
524             }
525             } else {
526             unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
527                 $record_correct=0;
528                 my $field;
529                 # if the field where biblionumber is already exist, just update it, otherwise create it
530                 if ($record->field($biblionumbertagfield)) {
531                 $field =  $record->field($biblionumbertagfield);
532                 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
533                 } else {
534                 my $newfield;
535                 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
536                 $record->append_fields($newfield);
537                 }
538             }
539     #             warn "FIXED BIBLIONUMBER".$record->as_formatted;
540             }
541             unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
542                 $record_correct=0;
543             #             warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
544             my $field;
545                 # if the field where biblionumber is already exist, just update it, otherwise create it
546                 if ($record->field($biblioitemnumbertagfield)) {
547                     $field =  $record->field($biblioitemnumbertagfield);
548                     if ($biblioitemnumbertagfield <10) {
549                     $field->update($biblionumber);
550                     } else {
551                     $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
552                     }
553                 } else {
554                     my $newfield;
555                     if ($biblioitemnumbertagfield <10) {
556                     $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
557                     } else {
558                     $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
559                     }
560                     $record->insert_grouped_field($newfield);
561             }
562         #             warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
563             }
564             my $leader=$record->leader;
565             substr($leader,0,5)='     ';
566             substr($leader,10,7)='22     ';
567             $record->leader(substr($leader,0,24));
568                 print OUT $record->as_usmarc();
569         }
570         close (OUT);
571     } else {
572         $sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
573         $sth->execute();
574         my $i=0;
575         while (my ($biblionumber) = $sth->fetchrow) {
576             my $record;
577             eval {
578                 $record = GetMarcBiblio($biblionumber);
579             };
580             if($@){
581                 print "  There was some pb getting biblio : #".$biblionumber."\n";
582                 next;
583             }
584             next unless $record;
585 #             warn $record->as_formatted;
586 # die if $record->subfield('090','9') eq 11;
587     #         print $record;
588             # check that biblionumber & biblioitemnumber are stored in the MARC record, otherwise, add them & update the biblioitems.marcxml data.
589             my $record_correct=1;
590             # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
591             # FIXME next unless $record->field($biblionumbertagfield);
592             # check if biblionumber is present, otherwise, add it on the fly
593             if ($biblionumbertagfield eq '001') {
594                 unless ($record->field($biblionumbertagfield)->data()) {
595                     $record_correct=0;
596                     my $field;
597                     # if the field where biblionumber is already exist, just update it, otherwise create it
598                     if ($record->field($biblionumbertagfield)) {
599                         $field =  $record->field($biblionumbertagfield);
600                         $field->update($biblionumber);
601                     } else {
602                         my $newfield;
603                         $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
604                         $record->append_fields($newfield);
605                     }
606                 }
607             } else {
608                 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
609                     $record_correct=0;
610                     my $field;
611                     # if the field where biblionumber is already exist, just update it, otherwise create it
612                     if ($record->field($biblionumbertagfield)) {
613                         $field =  $record->field($biblionumbertagfield);
614                         $field->add_subfields($biblionumbertagsubfield => $biblionumber);
615                     } else {
616                         my $newfield;
617                         $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
618                         $record->append_fields($newfield);
619                     }
620                 }
621     #             warn "FIXED BIBLIONUMBER".$record->as_formatted;
622             }
623             unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
624                 $record_correct=0;
625     #             warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
626                 my $field;
627                 # if the field where biblionumber is already exist, just update it, otherwise create it
628                 if ($record->field($biblioitemnumbertagfield)) {
629                     $field =  $record->field($biblioitemnumbertagfield);
630                     if ($biblioitemnumbertagfield <10) {
631                         $field->update($biblionumber);
632                     } else {
633                         $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
634                     }
635                 } else {
636                     my $newfield;
637                     if ($biblioitemnumbertagfield <10) {
638                         $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
639                     } else {
640                         $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
641                     }
642                     $record->insert_grouped_field($newfield);
643                 }
644     #             warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
645             }
646             unless ($record_correct) {
647                 my $update_xml = $dbh->prepare("update biblioitems set marcxml=? where biblionumber=?");
648                 warn "UPDATING $biblionumber (missing biblionumber or biblioitemnumber in MARC record : ".$record->as_xml;
649                 $update_xml->execute($record->as_xml,$biblionumber);
650             }
651             print ".";
652             print "\r$i" unless ($i++ %100);
653             # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
654             # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
655             my $leader=$record->leader;
656             substr($leader,0,5)='     ';
657             substr($leader,10,7)='22     ';
658             $record->leader(substr($leader,0,24));
659             print OUT $record->as_usmarc();
660         }
661         close(OUT);
662         }
663     }
664     
665     #
666     # and reindexing everything
667     #
668     print "====================\n";
669     print "REINDEXING zebra\n";
670     print "====================\n";
671     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios init") if ($reset);
672     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios update $directory/biblios");
673     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios commit");
674 } else {
675     print "skipping biblios\n";
676 }
677
678 print "====================\n";
679 print "CLEANING\n";
680 print "====================\n";
681 if ($keep_export) {
682     print "NOTHING cleaned : the $directory has been kept. You can re-run this script with the -s parameter if you just want to rebuild zebra after changing the record.abs or another zebra config file\n";
683 } else {
684     system("rm -rf $directory");
685     print "directory $directory deleted\n";
686 }