3635dbc386271eed7487d32b4794f0b68175e219
[koha-equinox.git] / misc / migration_tools / 22_to_30 / move_marc_to_biblioitems.pl
1 #!/usr/bin/perl
2 #use strict;
3 #use warnings; FIXME - Bug 2505
4 # script to shift marc to biblioitems
5 # scraped from updatedatabase for dev week by chris@katipo.co.nz
6 BEGIN {
7     # find Koha's Perl modules
8     # test carefully before changing this
9     use FindBin;
10     eval { require "$FindBin::Bin/../../kohalib.pl" };
11 }
12 use C4::Context;
13 use C4::Biblio;
14 use MARC::Record;
15 use MARC::File::XML ( BinaryEncoding => 'utf8' );
16
17 print "moving MARC record to biblioitems table\n";
18
19 my $dbh = C4::Context->dbh();
20
21 #
22 # moving MARC data from marc_subfield_table to biblioitems.marc
23 #
24
25 # changing marc field type
26 $dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` LONGBLOB NULL DEFAULT NULL ');
27 # adding marc xml, just for convenience
28 $dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` LONGTEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ');
29 # moving data from marc_subfield_value to biblio
30 $sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
31 $sth->execute;
32 my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
33 my $totaldone=0;
34
35 $|=1;
36
37 while (my ($bibid,$biblionumber) = $sth->fetchrow) {
38     my $record = LocalMARCgetbiblio($dbh,$bibid);
39     #Force UTF-8 in record leader
40     $record->encoding('UTF-8');
41     my $marcflavour;
42     if (C4::Context->preference("marcflavour")=~/unimarc/i){
43       $marcflavour="UNIMARC";
44     } else {
45      $marcflavour="USMARC";
46     }
47     $sth_update->execute($record->as_usmarc(),$record->as_xml_record($marcflavour),$biblionumber);
48     $totaldone++;
49     print ".";
50     print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
51 }
52 print "\rdone\n";
53
54
55 #
56 # this sub is a copy of Biblio.pm, version 2.2.4
57 # It is useful only once, for moving from 2.2 to 3.0
58 # the MARCgetbiblio in Biblio.pm
59 # is still here, but uses other tables
60 # (the ones that are filled by updatedatabase !)
61 #
62
63 sub LocalMARCgetbiblio {
64
65     # Returns MARC::Record of the biblio passed in parameter.
66     my ( $dbh, $bibid ) = @_;
67     my $record = MARC::Record->new();
68 #    warn "". $bidid;
69
70     my $sth =
71       $dbh->prepare(
72 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
73                   from marc_subfield_table
74                   where bibid=? order by tag,tagorder,subfieldorder
75               "
76     );
77     my $sth2 =
78       $dbh->prepare(
79         "select subfieldvalue from marc_blob_subfield where blobidlink=?");
80     $sth->execute($bibid);
81     my $prevtagorder = 1;
82     my $prevtag      = 'XXX';
83     my $previndicator;
84     my $field;        # for >=10 tags
85     my $prevvalue;    # for <10 tags
86     while ( my $row = $sth->fetchrow_hashref ) {
87
88         if ( $row->{'valuebloblink'} ) {    #---- search blob if there is one
89             $sth2->execute( $row->{'valuebloblink'} );
90             my $row2 = $sth2->fetchrow_hashref;
91             $sth2->finish;
92             $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
93         }
94         if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
95             $previndicator .= "  ";
96             if ( $prevtag < 10 ) {
97                 if ($prevtag ne '000') {
98                     $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX";    # ignore the 1st loop
99                 } else {
100                     $record->leader(sprintf("%24s",$prevvalue));
101                 }
102             }
103             else {
104                 $record->add_fields($field) unless $prevtag eq "XXX";
105             }
106             undef $field;
107             $prevtagorder  = $row->{tagorder};
108             $prevtag       = $row->{tag};
109             $previndicator = $row->{tag_indicator};
110             if ( $row->{tag} < 10 ) {
111                 $prevvalue = $row->{subfieldvalue};
112             }
113             else {
114                 $field = MARC::Field->new(
115                     ( sprintf "%03s", $prevtag ),
116                     substr( $row->{tag_indicator} . '  ', 0, 1 ),
117                     substr( $row->{tag_indicator} . '  ', 1, 1 ),
118                     $row->{'subfieldcode'},
119                     $row->{'subfieldvalue'}
120                 );
121             }
122         }
123         else {
124             if ( $row->{tag} < 10 ) {
125                 $record->add_fields( ( sprintf "%03s", $row->{tag} ),
126                     $row->{'subfieldvalue'} );
127             }
128             else {
129                 $field->add_subfields( $row->{'subfieldcode'},
130                     $row->{'subfieldvalue'} );
131             }
132             $prevtag       = $row->{tag};
133             $previndicator = $row->{tag_indicator};
134         }
135     }
136
137     # the last has not been included inside the loop... do it now !
138     if ( $prevtag ne "XXX" )
139     { # check that we have found something. Otherwise, prevtag is still XXX and we
140          # must return an empty record, not make MARC::Record fail because we try to
141          # create a record with XXX as field :-(
142         if ( $prevtag < 10 ) {
143             $record->add_fields( $prevtag, $prevvalue );
144         }
145         else {
146
147             #          my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
148             $record->add_fields($field);
149         }
150     }
151     if (C4::Context->preference('marcflavour')=~/unimarc/i){
152       $record->leader('     nac  22     1u 4500');
153       $update=1;
154       my $string;
155       if ($record->field(100)) {
156         $string = substr($record->subfield(100,"a")."                                   ",0,35);
157         my $f100 = $record->field(100);
158         $record->delete_field($f100);
159       } else {
160         $string = POSIX::strftime("%Y%m%d", localtime);
161         $string=~s/\-//g;
162         $string = sprintf("%-*s",35, $string);
163       }
164       substr($string,22,6,"frey50");
165       unless ($record->subfield(100,"a")){
166         $record->insert_fields_ordered(MARC::Field->new(100,"","","a"=>"$string"));
167       }
168     }
169
170     return $record;
171 }