minor bugfix with 'commit' option
[koha.git] / misc / migration_tools / bulkmarcimport.pl
1 #!/usr/bin/perl
2 # small script that import an iso2709 file into koha 2.0
3
4 use strict;
5
6 # Koha modules used
7 use MARC::File::USMARC;
8 use MARC::Record;
9 use MARC::Batch;
10 use C4::Context;
11 use C4::Biblio;
12 use Time::HiRes qw(gettimeofday);
13
14 use Getopt::Long;
15
16 my $Zconn = C4::Context->Zconn or die "unable to set Zconn";
17
18 my ( $input_marc_file, $number) = ('',0);
19 my ($version, $delete, $test_parameter,$char_encoding, $verbose, $commit);
20
21 GetOptions(
22         'commit:f'      => \$commit,
23     'file:s'    => \$input_marc_file,
24     'n:f' => \$number,
25     'h' => \$version,
26     'd' => \$delete,
27     't' => \$test_parameter,
28     'c:s' => \$char_encoding,
29     'v:s' => \$verbose,
30 );
31
32 if ($version || ($input_marc_file eq '')) {
33         print <<EOF
34 small script to import an iso2709 file into Koha.
35 parameters :
36 \th : this version/help screen
37 \tfile /path/to/file/to/dump : the file to dump
38 \tv : verbose mode. 1 means "some infos", 2 means "MARC dumping"
39 \tn : the number of records to import. If missing, all the file is imported
40 \tcommit : the number of records to wait before performing a 'commit' operation
41 \tt : test mode : parses the file, saying what he would do, but doing nothing.
42 \tc : the char encoding. At the moment, only MARC21 and UNIMARC supported. MARC21 by default.
43 \td : delete EVERYTHING related to biblio in koha-DB before import  :tables :
44 \t\tbiblio, \t\tbiblioitems, \t\tsubjects,\titems
45 \t\tadditionalauthors, \tbibliosubtitles, \tmarc_biblio,
46 \t\tmarc_subfield_table, \tmarc_word, \t\tmarc_blob_subfield
47 IMPORTANT : don't use this script before you've entered and checked your MARC parameters tables twice (or more!).
48 Otherwise, the import won't work correctly and you will get invalid data.
49
50 SAMPLE : 
51 \t\$ export KOHA_CONF=/etc/koha.conf
52 \t\$ perl misc/migration_tools/bulkmarcimport.pl -d -commit 1000 -file /home/jmf/koha.mrc -n 3000
53 EOF
54 ;#'
55 die;
56 }
57
58 my $dbh = C4::Context->dbh;
59
60 if ($delete) {
61         print "deleting biblios\n";
62         $dbh->do("delete from biblio");
63         $dbh->do("delete from biblioitems");
64         $dbh->do("delete from items");
65         $dbh->do("delete from bibliosubject");
66         $dbh->do("delete from additionalauthors");
67         $dbh->do("delete from bibliosubtitle");
68         $dbh->do("delete from marc_biblio");
69         $dbh->do("delete from marc_subfield_table");
70         $dbh->do("delete from marc_word");
71         $dbh->do("delete from marc_blob_subfield");
72 }
73 if ($test_parameter) {
74         print "TESTING MODE ONLY\n    DOING NOTHING\n===============\n";
75 }
76
77 $char_encoding = 'MARC21' unless ($char_encoding);
78 print "CHAR : $char_encoding\n" if $verbose;
79 my $starttime = gettimeofday;
80 my $batch = MARC::Batch->new( 'USMARC', $input_marc_file );
81 $batch->warnings_off();
82 $batch->strict_off();
83 my $i=0;
84 my $commitnum = 50;
85
86 if ($commit) {
87
88 $commitnum = $commit;
89
90 }
91
92 #1st of all, find item MARC tag.
93 my ($tagfield,$tagsubfield) = &MARCfind_marc_from_kohafield($dbh,"items.itemnumber",'');
94 # $dbh->do("lock tables biblio write, biblioitems write, items write, marc_biblio write, marc_subfield_table write, marc_blob_subfield write, marc_word write, marc_subfield_structure write, stopwords write");
95 while ( my $record = $batch->next() ) {
96 warn "I:".$i;
97 warn "NUM:".$number;
98         $i++;
99
100         if ($i==$number) {
101                 z3950_extended_services($Zconn,'commit',set_service_options('commit'));
102                 print "COMMIT OPERATION SUCCESSFUL\n";
103
104                 my $timeneeded = gettimeofday - $starttime;
105                 die "$i MARC records imported in $timeneeded seconds\n";
106         }
107         # perform the commit operation ever so often
108         if ($i==$commit) {
109                 z3950_extended_services($Zconn,'commit',set_service_options('commit'));
110                 $commit+=$commitnum;
111                 print "COMMIT OPERATION SUCCESSFUL\n";
112         }
113         #now, parse the record, extract the item fields, and store them in somewhere else.
114
115     ## create an empty record object to populate
116     my $newRecord = MARC::Record->new();
117         $newRecord->leader($record->leader());
118
119     # go through each field in the existing record
120     foreach my $oldField ( $record->fields() ) {
121
122         # just reproduce tags < 010 in our new record
123         if ( $oldField->tag() < 10 ) {
124             $newRecord->append_fields( $oldField );
125             next();
126         }
127
128         # store our new subfield data in this list
129         my @newSubfields = ();
130
131         # go through each subfield code/data pair
132         foreach my $pair ( $oldField->subfields() ) { 
133                 #$pair->[1] =~ s/\<//g;
134                 #$pair->[1] =~ s/\>//g;
135                 push( @newSubfields, $pair->[0], $pair->[1] ); #char_decode($pair->[1],$char_encoding) );
136         }
137
138         # add the new field to our new record
139         my $newField = MARC::Field->new(
140             $oldField->tag(),
141             $oldField->indicator(1),
142             $oldField->indicator(2),
143             @newSubfields
144         );
145
146         $newRecord->append_fields( $newField );
147
148     }
149
150         warn "$i ==>".$newRecord->as_formatted() if $verbose eq 2;
151         my @fields = $newRecord->field($tagfield);
152         my @items;
153         my $nbitems=0;
154
155         foreach my $field (@fields) {
156                 my $item = MARC::Record->new();
157                 $item->append_fields($field);
158                 push @items,$item;
159                 $newRecord->delete_field($field);
160                 $nbitems++;
161         }
162         print "$i : $nbitems items found\n" if $verbose;
163         # now, create biblio and items with NEWnewXX call.
164         unless ($test_parameter) {
165                 my ($bibid,$oldbibnum,$oldbibitemnum) = NEWnewbiblio($dbh,$Zconn,$newRecord,'');
166                 warn "ADDED biblio NB $bibid in DB\n" if $verbose;
167                 for (my $i=0;$i<=$#items;$i++) {
168                         NEWnewitem($dbh,$Zconn,$items[$i],$bibid);
169                 }
170         }
171 }
172 # final commit of the changes
173 z3950_extended_services($Zconn,'commit',set_service_options('commit'));
174 print "COMMIT OPERATION SUCCESSFUL\n";
175
176 my $timeneeded = gettimeofday - $starttime;
177 print "$i MARC records done in $timeneeded seconds\n";