rebuild_zebra now handle correctly improper authorities records
[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 passw.passwd
251 shadow
252 register: $authorityserverdir/register:4G
253 shadow: $authorityserverdir/shadow:4G
254
255 # Temp File area for result sets
256 setTmpDir: $authorityserverdir/tmp
257
258 # Temp File area for index program
259 keyTmpDir: $authorityserverdir/key
260
261 # Approx. Memory usage during indexing
262 memMax: 40M
263 rank:rank-1
264     ";
265         print "Info: creating zebra-authorities.cfg\n";
266         $created_dir_or_file++;
267     }
268     
269     if ($created_dir_or_file) {
270         print "Info: created : $created_dir_or_file directories & files\n";
271     } else {
272         print "Info: file & directories OK\n";
273     }
274     
275     #
276     # exporting authorities
277     #
278     if ($skip_export) {
279         print "====================\n";
280         print "SKIPPING authorities export\n";
281         print "====================\n";
282     } else {
283         print "====================\n";
284         print "exporting authorities\n";
285         print "====================\n";
286         mkdir "$directory" unless (-d $directory);
287         mkdir "$directory/authorities" unless (-d "$directory/authorities");
288         open(OUT,">:utf8","$directory/authorities/authorities.iso2709") or die $!;
289         my $dbh=C4::Context->dbh;
290         my $sth;
291         $sth=$dbh->prepare("select authid,marc from auth_header $limit");
292         $sth->execute();
293         my $i=0;
294         while (my ($authid,$record) = $sth->fetchrow) {
295             # FIXME : we retrieve the iso2709 record. if the GetAuthority (that uses the XML) fails
296             # due to some MARC::File::XML failure, then try the iso2709, 
297             # (add authid & authtype if needed)
298             my $record;
299             eval {
300                 $record = GetAuthority($authid);
301             };
302             next unless $record;
303             # force authid in case it's not here, otherwise, zebra will die on this authority
304             unless ($record->field('001')->data() eq $authid){
305                 print "$authid don't exist for this authority :".$record->as_formatted;
306                 $record->delete_field($record->field('001'));
307                 $record->insert_fields_ordered(MARC::Field->new('001',$authid));
308             }
309             if($@){
310                 print "  There was some pb getting authority : ".$authid."\n";
311             next;
312             }
313                 
314             print ".";
315             print "\r$i" unless ($i++ %100);
316 #            # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
317 #            # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
318             my $leader=$record->leader;
319             substr($leader,0,5)='     ';
320             substr($leader,10,7)='22     ';
321             $record->leader(substr($leader,0,24));
322             print OUT $record->as_usmarc;
323         }
324         close(OUT);
325     }
326     
327     #
328     # and reindexing everything
329     #
330     print "====================\n";
331     print "REINDEXING zebra\n";
332     print "====================\n";
333     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities init") if ($reset);
334     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities update $directory/authorities");
335     system("zebraidx -c ".C4::Context->zebraconfig('authorityserver')->{config}." -g iso2709 -d authorities commit");
336 } else {
337     print "skipping authorities\n";
338 }
339 #################################################################################################################
340 #                        BIBLIOS 
341 #################################################################################################################
342
343 if ($biblios) {
344     print "====================\n";
345     print "checking directories & files for biblios\n";
346     print "====================\n";
347     
348     #
349     # BIBLIOS : creating directory structure
350     #
351     unless (-d "$biblioserverdir") {
352         system("mkdir -p $biblioserverdir");
353         print "Info: created $biblioserverdir\n";
354         $created_dir_or_file++;
355     }
356     unless (-d "$biblioserverdir/lock") {
357         mkdir "$biblioserverdir/lock";
358         print "Info: created $biblioserverdir/lock\n";
359         $created_dir_or_file++;
360     }
361     unless (-d "$biblioserverdir/register") {
362         mkdir "$biblioserverdir/register";
363         print "Info: created $biblioserverdir/register\n";
364         $created_dir_or_file++;
365     }
366     unless (-d "$biblioserverdir/shadow") {
367         mkdir "$biblioserverdir/shadow";
368         print "Info: created $biblioserverdir/shadow\n";
369         $created_dir_or_file++;
370     }
371     unless (-d "$biblioserverdir/tab") {
372         mkdir "$biblioserverdir/tab";
373         print "Info: created $biblioserverdir/tab\n";
374         $created_dir_or_file++;
375     }
376     unless (-d "$biblioserverdir/key") {
377         mkdir "$biblioserverdir/key";
378         print "Info: created $biblioserverdir/key\n";
379         $created_dir_or_file++;
380     }
381     unless (-d "$biblioserverdir/etc") {
382         mkdir "$biblioserverdir/etc";
383         print "Info: created $biblioserverdir/etc\n";
384         $created_dir_or_file++;
385     }
386     
387     #
388     # BIBLIOS : copying mandatory files
389     #
390     # the record model, depending on marc flavour
391     unless (-f "$biblioserverdir/tab/record.abs") {
392         if (C4::Context->preference("marcflavour") eq "UNIMARC") {
393             system("cp -f $kohadir/misc/zebra/record_biblios_unimarc.abs $biblioserverdir/tab/record.abs");
394             print "Info: copied record.abs for UNIMARC\n";
395         } else {
396             system("cp -f $kohadir/misc/zebra/record_biblios_usmarc.abs $biblioserverdir/tab/record.abs");
397             print "Info: copied record.abs for USMARC\n";
398         }
399         $created_dir_or_file++;
400     }
401     unless (-f "$biblioserverdir/tab/sort-string-utf.chr") {
402         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/sort-string-utf.chr");
403         print "Info: copied sort-string-utf.chr\n";
404         $created_dir_or_file++;
405     }
406     unless (-f "$biblioserverdir/tab/word-phrase-utf.chr") {
407         system("cp -f $kohadir/misc/zebra/sort-string-utf_french.chr $biblioserverdir/tab/word-phrase-utf.chr");
408         print "Info: copied word-phase-utf.chr\n";
409         $created_dir_or_file++;
410     }
411     unless (-f "$biblioserverdir/tab/bib1.att") {
412         system("cp -f $kohadir/misc/zebra/bib1_biblios.att $biblioserverdir/tab/bib1.att");
413         print "Info: copied bib1.att\n";
414         $created_dir_or_file++;
415     }
416     unless (-f "$biblioserverdir/tab/default.idx") {
417         system("cp -f $kohadir/misc/zebra/default.idx $biblioserverdir/tab/default.idx");
418         print "Info: copied default.idx\n";
419         $created_dir_or_file++;
420     }
421     unless (-f "$biblioserverdir/etc/ccl.properties") {
422 #         system("cp -f $kohadir/misc/zebra/ccl.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
423         system("cp -f $kohadir/misc/zebra/ccl.properties $biblioserverdir/etc/ccl.properties");
424         print "Info: copied ccl.properties\n";
425         $created_dir_or_file++;
426     }
427     unless (-f "$biblioserverdir/etc/pqf.properties") {
428 #         system("cp -f $kohadir/misc/zebra/pqf.properties ".C4::Context->zebraconfig('biblioserver')->{ccl2rpn});
429         system("cp -f $kohadir/misc/zebra/pqf.properties $biblioserverdir/etc/pqf.properties");
430         print "Info: copied pqf.properties\n";
431         $created_dir_or_file++;
432     }
433     
434     #
435     # BIBLIOS : copying mandatory files
436     #
437     unless (-f C4::Context->zebraconfig('biblioserver')->{config}) {
438     open ZD,">:utf8 ",C4::Context->zebraconfig('biblioserver')->{config};
439     print ZD "
440 # generated by KOHA/misc/migrtion_tools/rebuild_zebra.pl 
441 profilePath:\${srcdir:-.}:$biblioserverdir/tab/:$tabdir/tab/:\${srcdir:-.}/tab/
442
443 encoding: UTF-8
444 # Files that describe the attribute sets supported.
445 attset:bib1.att
446 attset:explain.att
447 attset:gils.att
448
449 modulePath:$modulesdir/modules/
450 # Specify record type
451 iso2709.recordType:grs.marcxml.record
452 recordType:grs.xml
453 recordId: (bib1,Local-Number)
454 storeKeys:1
455 storeData:1
456
457
458 # Lock File Area
459 lockDir: $biblioserverdir/lock
460 perm.anonymous:r
461 perm.kohaadmin:rw
462 passw.passwd
463 shadow
464 register: $biblioserverdir/register:4G
465 shadow: $biblioserverdir/shadow:4G
466
467 # Temp File area for result sets
468 setTmpDir: $biblioserverdir/tmp
469
470 # Temp File area for index program
471 keyTmpDir: $biblioserverdir/key
472
473 # Approx. Memory usage during indexing
474 memMax: 40M
475 rank:rank-1
476     ";
477         print "Info: creating zebra-biblios.cfg\n";
478         $created_dir_or_file++;
479     }
480     
481     if ($created_dir_or_file) {
482         print "Info: created : $created_dir_or_file directories & files\n";
483     } else {
484         print "Info: file & directories OK\n";
485     }
486     
487     # die;
488     #
489     # exporting biblios
490     #
491     if ($skip_export) {
492         print "====================\n";
493         print "SKIPPING biblio export\n";
494         print "====================\n";
495     } else {
496         print "====================\n";
497         print "exporting biblios\n";
498         print "====================\n";
499         mkdir "$directory" unless (-d $directory);
500         mkdir "$directory/biblios" unless (-d "$directory/biblios");
501         open(OUT,">:utf8 ","$directory/biblios/export") or die $!;
502         my $dbh=C4::Context->dbh;
503         my $sth;
504         if ($noxml){
505         $sth=$dbh->prepare("select biblionumber,marc from biblioitems order by biblionumber $limit");
506         $sth->execute();
507         my $i=0;
508         while (my ($biblionumber,$marc) = $sth->fetchrow) {
509             my $record;
510             $record=MARC::Record->new_from_usmarc($marc);
511             my $record_correct=1;
512             # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
513             # FIXME next unless $record->field($biblionumbertagfield);
514             # check if biblionumber is present, otherwise, add it on the fly
515             if ($biblionumbertagfield eq '001') {
516                 unless ($record->field($biblionumbertagfield)->data()) {
517                     $record_correct=0;
518                     my $field;
519                     # if the field where biblionumber is already exist, just update it, otherwise create it
520                 if ($record->field($biblionumbertagfield)) {
521                 $field =  $record->field($biblionumbertagfield);
522                 $field->update($biblionumber);
523                 } else {
524                 my $newfield;
525                 $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
526                 $record->append_fields($newfield);
527                 }
528             }
529             } else {
530             unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
531                 $record_correct=0;
532                 my $field;
533                 # if the field where biblionumber is already exist, just update it, otherwise create it
534                 if ($record->field($biblionumbertagfield)) {
535                 $field =  $record->field($biblionumbertagfield);
536                 $field->add_subfields($biblionumbertagsubfield => $biblionumber);
537                 } else {
538                 my $newfield;
539                 $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
540                 $record->append_fields($newfield);
541                 }
542             }
543     #             warn "FIXED BIBLIONUMBER".$record->as_formatted;
544             }
545             unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
546                 $record_correct=0;
547             #             warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
548             my $field;
549                 # if the field where biblionumber is already exist, just update it, otherwise create it
550                 if ($record->field($biblioitemnumbertagfield)) {
551                     $field =  $record->field($biblioitemnumbertagfield);
552                     if ($biblioitemnumbertagfield <10) {
553                     $field->update($biblionumber);
554                     } else {
555                     $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
556                     }
557                 } else {
558                     my $newfield;
559                     if ($biblioitemnumbertagfield <10) {
560                     $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
561                     } else {
562                     $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
563                     }
564                     $record->insert_grouped_field($newfield);
565             }
566         #             warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
567             }
568             my $leader=$record->leader;
569             substr($leader,0,5)='     ';
570             substr($leader,10,7)='22     ';
571             $record->leader(substr($leader,0,24));
572                 print OUT $record->as_usmarc();
573         }
574         close (OUT);
575     } else {
576         $sth=$dbh->prepare("select biblionumber from biblioitems order by biblionumber $limit");
577         $sth->execute();
578         my $i=0;
579         while (my ($biblionumber) = $sth->fetchrow) {
580             my $record;
581             eval {
582                 $record = GetMarcBiblio($biblionumber);
583             };
584             if($@){
585                 print "  There was some pb getting biblio : #".$biblionumber."\n";
586                 next;
587             }
588             next unless $record;
589 #             warn $record->as_formatted;
590 # die if $record->subfield('090','9') eq 11;
591     #         print $record;
592             # check that biblionumber & biblioitemnumber are stored in the MARC record, otherwise, add them & update the biblioitems.marcxml data.
593             my $record_correct=1;
594             # skip uncorrect records : isn't this bogus, as just after we reintroduce biblionumber if it's missing ?
595             # FIXME next unless $record->field($biblionumbertagfield);
596             # check if biblionumber is present, otherwise, add it on the fly
597             if ($biblionumbertagfield eq '001') {
598                 unless ($record->field($biblionumbertagfield)->data()) {
599                     $record_correct=0;
600                     my $field;
601                     # if the field where biblionumber is already exist, just update it, otherwise create it
602                     if ($record->field($biblionumbertagfield)) {
603                         $field =  $record->field($biblionumbertagfield);
604                         $field->update($biblionumber);
605                     } else {
606                         my $newfield;
607                         $newfield = MARC::Field->new( $biblionumbertagfield, $biblionumber);
608                         $record->append_fields($newfield);
609                     }
610                 }
611             } else {
612                 unless ($record->subfield($biblionumbertagfield,$biblionumbertagsubfield)) {
613                     $record_correct=0;
614                     my $field;
615                     # if the field where biblionumber is already exist, just update it, otherwise create it
616                     if ($record->field($biblionumbertagfield)) {
617                         $field =  $record->field($biblionumbertagfield);
618                         $field->add_subfields($biblionumbertagsubfield => $biblionumber);
619                     } else {
620                         my $newfield;
621                         $newfield = MARC::Field->new( $biblionumbertagfield,'','', $biblionumbertagsubfield => $biblionumber);
622                         $record->append_fields($newfield);
623                     }
624                 }
625     #             warn "FIXED BIBLIONUMBER".$record->as_formatted;
626             }
627             unless ($record->subfield($biblioitemnumbertagfield,$biblioitemnumbertagsubfield)) {
628                 $record_correct=0;
629     #             warn "INCORRECT BIBLIOITEMNUMBER :".$record->as_formatted;
630                 my $field;
631                 # if the field where biblionumber is already exist, just update it, otherwise create it
632                 if ($record->field($biblioitemnumbertagfield)) {
633                     $field =  $record->field($biblioitemnumbertagfield);
634                     if ($biblioitemnumbertagfield <10) {
635                         $field->update($biblionumber);
636                     } else {
637                         $field->add_subfields($biblioitemnumbertagsubfield => $biblionumber);
638                     }
639                 } else {
640                     my $newfield;
641                     if ($biblioitemnumbertagfield <10) {
642                         $newfield = MARC::Field->new( $biblioitemnumbertagfield, $biblionumber);
643                     } else {
644                         $newfield = MARC::Field->new( $biblioitemnumbertagfield,'','', $biblioitemnumbertagsubfield => $biblionumber);
645                     }
646                     $record->insert_grouped_field($newfield);
647                 }
648     #             warn "FIXED BIBLIOITEMNUMBER".$record->as_formatted;
649             }
650             unless ($record_correct) {
651                 my $update_xml = $dbh->prepare("update biblioitems set marcxml=? where biblionumber=?");
652                 warn "UPDATING $biblionumber (missing biblionumber or biblioitemnumber in MARC record : ".$record->as_xml;
653                 $update_xml->execute($record->as_xml,$biblionumber);
654             }
655             print ".";
656             print "\r$i" unless ($i++ %100);
657             # remove leader length, that could be wrong, it will be calculated automatically by as_usmarc
658             # otherwise, if it's wron, zebra will fail miserabily (and never index what is after the failing record)
659             my $leader=$record->leader;
660             substr($leader,0,5)='     ';
661             substr($leader,10,7)='22     ';
662             $record->leader(substr($leader,0,24));
663             print OUT $record->as_usmarc();
664         }
665         close(OUT);
666         }
667     }
668     
669     #
670     # and reindexing everything
671     #
672     print "====================\n";
673     print "REINDEXING zebra\n";
674     print "====================\n";
675     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios init") if ($reset);
676     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios update $directory/biblios");
677     system("zebraidx -g iso2709 -c ".C4::Context->zebraconfig('biblioserver')->{config}." -d biblios commit");
678 } else {
679     print "skipping biblios\n";
680 }
681
682 print "====================\n";
683 print "CLEANING\n";
684 print "====================\n";
685 if ($keep_export) {
686     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";
687 } else {
688     system("rm -rf $directory");
689     print "directory $directory deleted\n";
690 }