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