Lines 1-246
Link Here
|
1 |
#!/usr/bin/perl |
|
|
2 |
# script that rebuild thesaurus from biblio table. |
3 |
|
4 |
# delete FROM `marc_subfield_table` WHERE tag = "606" AND subfieldcode = 9; |
5 |
use strict; |
6 |
#use warnings; FIXME - Bug 2505 |
7 |
|
8 |
# Koha modules used |
9 |
use MARC::File::USMARC; |
10 |
use MARC::Record; |
11 |
use MARC::Batch; |
12 |
use C4::Context; |
13 |
use C4::Biblio; |
14 |
use C4::AuthoritiesMarc; |
15 |
use Time::HiRes qw(gettimeofday); |
16 |
|
17 |
use Getopt::Long; |
18 |
my ( $input_marc_file, $number) = ('',0); |
19 |
my ($version, $verbose, $test_parameter, $field,$delete,$category,$subfields); |
20 |
GetOptions( |
21 |
'h' => \$version, |
22 |
'd' => \$delete, |
23 |
't' => \$test_parameter, |
24 |
's:s' => \$subfields, |
25 |
'v' => \$verbose, |
26 |
'c:s' => \$category, |
27 |
); |
28 |
|
29 |
if ($version || ($category eq '')) { |
30 |
print <<EOF |
31 |
small script to recreate a authority table into Koha. |
32 |
parameters : |
33 |
\tc : thesaurus category. Can be filled with anything, the NC is hardcoded. But mandatory to confirm that you want to rebuild 6xx |
34 |
\d : delete every entry of the selected category before doing work. |
35 |
|
36 |
SAMPLES : |
37 |
./build6xx.pl -c NC -d |
38 |
EOF |
39 |
;# |
40 |
die; |
41 |
} |
42 |
|
43 |
my $dbh = C4::Context->dbh; |
44 |
my @subf = $subfields =~ /(##\d\d\d##.)/g; |
45 |
if ($delete) { |
46 |
print "deleting thesaurus\n"; |
47 |
my $del1 = $dbh->prepare("delete from auth_subfield_table where authid=?"); |
48 |
my $del2 = $dbh->prepare("delete from auth_word where authid=?"); |
49 |
my $sth = $dbh->prepare("select authid from auth_header where authtypecode='NC'"); |
50 |
$sth->execute; |
51 |
while (my ($authid) = $sth->fetchrow) { |
52 |
$del1->execute($authid); |
53 |
$del2->execute($authid); |
54 |
} |
55 |
$dbh->do("delete from auth_header where authtypecode='NC'"); |
56 |
$dbh->do("delete from marc_subfield_table where tag='606' and subfieldcode='9'"); |
57 |
$dbh->do("delete from marc_word where tagsubfield='6069'"); |
58 |
} |
59 |
|
60 |
if ($test_parameter) { |
61 |
print "TESTING MODE ONLY\n DOING NOTHING\n===============\n"; |
62 |
} |
63 |
$|=1; # flushes output |
64 |
my $starttime = gettimeofday; |
65 |
my $sth = $dbh->prepare("select bibid from marc_biblio"); |
66 |
$sth->execute; |
67 |
my $i=1; |
68 |
my %alreadydone; |
69 |
|
70 |
# search biblios to "connect" to an authority with any number of $x (limited to 4 $x in this script) |
71 |
my $sthBIBLIOS = $dbh->prepare("select distinct m1.bibid,m1.tag,m1.tagorder,m1.subfieldorder from marc_subfield_table as m1 where tag in (606) and subfieldcode='a' and subfieldvalue=?"); |
72 |
my $sthBIBLIOSx = $dbh->prepare("select distinct m1.bibid,m1.tag,m1.tagorder,m1.subfieldorder from marc_subfield_table as m1 left join marc_subfield_table as m2 on m1.bibid=m2.bibid where m1.tag in (606) and m1.subfieldcode='a' and m2.subfieldcode='x' and m1.subfieldvalue=? and m2.subfieldvalue=?"); |
73 |
my $sthBIBLIOSxx = $dbh->prepare("select distinct m1.bibid,m1.tag,m1.tagorder,m1.subfieldorder from marc_subfield_table as m1 left join marc_subfield_table as m2 on m1.bibid=m2.bibid left join marc_subfield_table as m3 on m1.bibid=m3.bibid where m1.tag in (606) and m1.subfieldcode='a' and m2.subfieldcode='x' and m3.subfieldcode='x' and m1.subfieldvalue=? and m2.subfieldvalue=? and m3.subfieldvalue=?"); |
74 |
my $sthBIBLIOSxxx = $dbh->prepare("select distinct m1.bibid,m1.tag,m1.tagorder,m1.subfieldorder from marc_subfield_table as m1 left join marc_subfield_table as m2 on m1.bibid=m2.bibid left join marc_subfield_table as m3 on m1.bibid=m4.bibid left join marc_subfield_table as m4 on m1.bibid=m4.bibid where m1.tag in (606) and m1.subfieldcode='a' and m2.subfieldcode='x' and m3.subfieldcode='x' and m4.subfieldcode='x' and m1.subfieldvalue=? and m2.subfieldvalue=? and m3.subfieldvalue=? and m4.subfieldvalue=?"); |
75 |
my $sthBIBLIOSxxxx = $dbh->prepare("select distinct m1.bibid,m1.tag,m1.tagorder,m1.subfieldorder from marc_subfield_table as m1 left join marc_subfield_table as m2 on m1.bibid=m2.bibid left join marc_subfield_table as m3 on m1.bibid=m4.bibid left join marc_subfield_table as m4 on m1.bibid=m4.bibid left join marc_subfield_table as m5 on m1.bibid=m5.bibid where m1.tag in (606) and m1.subfieldcode='a' and m2.subfieldcode='x' and m3.subfieldcode='x' and m4.subfieldcode='x' and m5.subfieldcode='x' and m1.subfieldvalue=? and m2.subfieldvalue=? and m3.subfieldvalue=? and m4.subfieldvalue=? and m5.subfieldvalue=?"); |
76 |
|
77 |
# loop through each biblio |
78 |
while (my ($bibid) = $sth->fetchrow) { |
79 |
my $record = GetMarcBiblio($bibid); |
80 |
my $timeneeded = gettimeofday - $starttime; |
81 |
print "$i in $timeneeded s\n" unless ($i % 50); |
82 |
foreach my $field ($record->field(995)) { |
83 |
$record->delete_field($field); |
84 |
} |
85 |
my $totdone=0; |
86 |
my $authid; |
87 |
# search the 606 field(s) |
88 |
foreach my $field ($record->field("606")) { |
89 |
foreach my $authentry ($field->subfield("a")) { |
90 |
# the hashentry variable contains all $x fields and the $a in a single string. Used to differenciate |
91 |
# $xsomething$aelse and $asomething else |
92 |
my $hashentry = $authentry; |
93 |
foreach my $x ($field->subfield('x')) { |
94 |
$hashentry.=" -- $x"; |
95 |
} |
96 |
# remove ��$e... |
97 |
# all the same for mysql, but NOT for perl hashes ! |
98 |
# without those lines, t� is not tot and pat� is not patee |
99 |
$hashentry =~ s/���e/g; |
100 |
$hashentry =~ s/��a/g; |
101 |
$hashentry =~ s/�i/g; |
102 |
$hashentry =~ s/�o/g; |
103 |
$hashentry =~ s/|/u/g; |
104 |
# uppercase all, in case of typing error. |
105 |
$hashentry = uc($hashentry); |
106 |
$totdone++; |
107 |
if ($alreadydone{$hashentry}) { |
108 |
$authid = $alreadydone{$hashentry}; |
109 |
print "."; |
110 |
} else { |
111 |
print "*"; |
112 |
#create authority. |
113 |
my $authorityRecord = MARC::Record->new(); |
114 |
my $newfield = MARC::Field->new(250,'','','a' => "".$authentry); |
115 |
foreach my $x ($field->subfield('x')) { |
116 |
$newfield->add_subfields('x' => $x); |
117 |
} |
118 |
foreach my $z ($field->subfield('z')) { |
119 |
$newfield->add_subfields('z' => $z); |
120 |
} |
121 |
$authorityRecord->insert_fields_ordered($newfield); |
122 |
$authid=AUTHaddauthority($dbh,$authorityRecord,'','NC'); |
123 |
$alreadydone{$hashentry} = $authid; |
124 |
# we have the authority number, now we update all biblios that use this authority... |
125 |
my @x = $field->subfield('x'); # depending on the number of $x in the subfield |
126 |
if ($#x eq -1) { # no $x |
127 |
$sthBIBLIOS->execute($authentry); |
128 |
while (my ($bibid,$tag,$tagorder,$subfieldorder) = $sthBIBLIOS->fetchrow) { |
129 |
# check that the field does not already have a $x (if it has, it will or has been managed by another authority |
130 |
my $inbiblio = GetMarcBiblio($bibid); |
131 |
my $isOK = 0; |
132 |
# loop in each 606 field |
133 |
foreach my $in606 ($inbiblio->field('606')) { |
134 |
my $inEntry = $in606->subfield('a'); |
135 |
# and rebuild the $x -- $x -- $a string (like for $hashentry, few lines before) |
136 |
foreach my $x ($in606->subfield('x')) { |
137 |
$inEntry.=" -- $x"; |
138 |
} |
139 |
$inEntry =~ s/���e/g; |
140 |
$inEntry =~ s/��a/g; |
141 |
$inEntry =~ s/�i/g; |
142 |
$inEntry =~ s/�o/g; |
143 |
$inEntry =~ s/|/u/g; |
144 |
$inEntry = uc($inEntry); |
145 |
# ok, it's confirmed that we must add the $9 subfield for this biblio, so... |
146 |
$isOK=1 if $inEntry eq $hashentry; |
147 |
} |
148 |
# ... add it ! |
149 |
C4::Biblio::MARCaddsubfield($dbh,$bibid,$tag,'',$tagorder,9,$subfieldorder,$authid) if $isOK; |
150 |
} |
151 |
} |
152 |
if ($#x eq 0) { # one $x |
153 |
$sthBIBLIOSx->execute($authentry,$x[0]); |
154 |
while (my ($bibid,$tag,$tagorder,$subfieldorder) = $sthBIBLIOSx->fetchrow) { |
155 |
my $inbiblio = GetMarcBiblio($bibid); |
156 |
my $isOK = 0; |
157 |
foreach my $in606 ($inbiblio->field('606')) { |
158 |
my $inEntry = $in606->subfield('a'); |
159 |
foreach my $x ($in606->subfield('x')) { |
160 |
$inEntry.=" -- $x"; |
161 |
} |
162 |
$inEntry =~ s/���e/g; |
163 |
$inEntry =~ s/��a/g; |
164 |
$inEntry =~ s/�i/g; |
165 |
$inEntry =~ s/�o/g; |
166 |
$inEntry =~ s/|/u/g; |
167 |
$inEntry = uc($inEntry); |
168 |
$isOK=1 if $inEntry eq $hashentry; |
169 |
} |
170 |
C4::Biblio::MARCaddsubfield($dbh,$bibid,$tag,'',$tagorder,9,$subfieldorder,$authid) if $isOK; |
171 |
} |
172 |
} |
173 |
if ($#x eq 1) { # two $x |
174 |
$sthBIBLIOSxx->execute($authentry,$x[0],$x[1]); |
175 |
while (my ($bibid,$tag,$tagorder,$subfieldorder) = $sthBIBLIOSxx->fetchrow) { |
176 |
my $inbiblio = GetMarcBiblio($bibid); |
177 |
my $isOK = 0; |
178 |
foreach my $in606 ($inbiblio->field('606')) { |
179 |
my $inEntry = $in606->subfield('a'); |
180 |
foreach my $x ($in606->subfield('x')) { |
181 |
$inEntry.=" -- $x"; |
182 |
} |
183 |
$inEntry =~ s/���e/g; |
184 |
$inEntry =~ s/��a/g; |
185 |
$inEntry =~ s/�i/g; |
186 |
$inEntry =~ s/�o/g; |
187 |
$inEntry =~ s/|/u/g; |
188 |
$inEntry = uc($inEntry); |
189 |
$isOK=1 if $inEntry eq $hashentry; |
190 |
} |
191 |
C4::Biblio::MARCaddsubfield($dbh,$bibid,$tag,'',$tagorder,9,$subfieldorder,$authid) if $isOK; |
192 |
} |
193 |
} |
194 |
if ($#x eq 2) { # 3 $x |
195 |
$sthBIBLIOSxxx->execute($authentry,$x[0],$x[1],$x[2]); |
196 |
while (my ($bibid,$tag,$tagorder,$subfieldorder) = $sthBIBLIOSxxx->fetchrow) { |
197 |
my $inbiblio = GetMarcBiblio($bibid); |
198 |
my $isOK = 0; |
199 |
foreach my $in606 ($inbiblio->field('606')) { |
200 |
my $inEntry = $in606->subfield('a'); |
201 |
foreach my $x ($in606->subfield('x')) { |
202 |
$inEntry.=" -- $x"; |
203 |
} |
204 |
$inEntry =~ s/���e/g; |
205 |
$inEntry =~ s/��a/g; |
206 |
$inEntry =~ s/�i/g; |
207 |
$inEntry =~ s/�o/g; |
208 |
$inEntry =~ s/|/u/g; |
209 |
$inEntry = uc($inEntry); |
210 |
$isOK=1 if $inEntry eq $hashentry; |
211 |
} |
212 |
C4::Biblio::MARCaddsubfield($dbh,$bibid,$tag,'',$tagorder,9,$subfieldorder,$authid) if $isOK; |
213 |
} |
214 |
} |
215 |
if ($#x eq 3) { # 3 $x |
216 |
$sthBIBLIOSxxxx->execute($authentry,$x[0],$x[1],$x[2],$x[3]); |
217 |
while (my ($bibid,$tag,$tagorder,$subfieldorder) = $sthBIBLIOSxxxx->fetchrow) { |
218 |
my $inbiblio = GetMarcBiblio($bibid); |
219 |
my $isOK = 0; |
220 |
foreach my $in606 ($inbiblio->field('606')) { |
221 |
my $inEntry = $in606->subfield('a'); |
222 |
foreach my $x ($in606->subfield('x')) { |
223 |
$inEntry.=" -- $x"; |
224 |
} |
225 |
$inEntry =~ s/���e/g; |
226 |
$inEntry =~ s/��a/g; |
227 |
$inEntry =~ s/�i/g; |
228 |
$inEntry =~ s/�o/g; |
229 |
$inEntry =~ s/|/u/g; |
230 |
$inEntry = uc($inEntry); |
231 |
$isOK=1 if $inEntry eq $hashentry; |
232 |
} |
233 |
C4::Biblio::MARCaddsubfield($dbh,$bibid,$tag,'',$tagorder,9,$subfieldorder,$authid) if $isOK; |
234 |
} |
235 |
} |
236 |
if ($#x >4) { |
237 |
# too many $x, not handled, warn the developer that tries to migrate |
238 |
print "warning there is ".$#x.'$x values'; |
239 |
} |
240 |
} |
241 |
} |
242 |
} |
243 |
$i++; |
244 |
} |
245 |
my $timeneeded = gettimeofday - $starttime; |
246 |
print "$i entries done in $timeneeded seconds (".($i/$timeneeded)." per second)\n"; |