10 # This script checks for required updates to the database.
12 # Part of the Koha Library Software www.koha.org
13 # Licensed under the GPL.
16 # - Would also be a good idea to offer to do a backup at this time...
18 # NOTE: If you do something more than once in here, make it table driven.
29 use MARC::File::XML ( BinaryEncoding => 'utf8' );
31 # FIXME - The user might be installing a new database, so can't rely
32 # on /etc/koha.conf anyway.
39 %existingtables, # tables already in database
43 $type, $null, $key, $default, $extra,
44 $prefitem, # preference item in systempreferences table
48 GetOptions( 's' => \$silent );
49 my $dbh = C4::Context->dbh;
50 print "connected to your DB. Checking & modifying it\n" unless $silent;
51 $|=1; # flushes output
56 # Tables to add if they don't exist
58 categorytable => "(categorycode char(5) NOT NULL default '',
59 description text default '',
60 itemtypecodes text default '',
61 PRIMARY KEY (categorycode)
63 subcategorytable => "(subcategorycode char(5) NOT NULL default '',
64 description text default '',
65 itemtypecodes text default '',
66 PRIMARY KEY (subcategorycode)
68 mediatypetable => "(mediatypecode char(5) NOT NULL default '',
69 description text default '',
70 itemtypecodes text default '',
71 PRIMARY KEY (mediatypecode)
74 `timestamp` TIMESTAMP NOT NULL ,
75 `user` INT( 11 ) NOT NULL ,
76 `module` TEXT default '',
77 `action` TEXT default '' ,
78 `object` INT(11) default '' ,
79 `info` TEXT default '' ,
80 PRIMARY KEY ( `timestamp` , `user` )
83 module varchar(20) NOT NULL default '',
84 code varchar(20) NOT NULL default '',
85 name varchar(100) NOT NULL default '',
86 title varchar(200) NOT NULL default '',
88 PRIMARY KEY (module,code)
91 alertid int(11) NOT NULL auto_increment,
92 borrowernumber int(11) NOT NULL default '0',
93 type varchar(10) NOT NULL default '',
94 externalid varchar(20) NOT NULL default '',
95 PRIMARY KEY (alertid),
96 KEY borrowernumber (borrowernumber),
97 KEY type (type,externalid)
100 `idnew` int(10) unsigned NOT NULL auto_increment,
101 `title` varchar(250) NOT NULL default '',
103 `lang` varchar(4) NOT NULL default '',
104 `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
105 PRIMARY KEY (`idnew`)
107 repeatable_holidays => "(
108 `id` int(11) NOT NULL auto_increment,
109 `branchcode` varchar(4) NOT NULL default '',
110 `weekday` smallint(6) default NULL,
111 `day` smallint(6) default NULL,
112 `month` smallint(6) default NULL,
113 `title` varchar(50) NOT NULL default '',
114 `description` text NOT NULL,
117 special_holidays => "(
118 `id` int(11) NOT NULL auto_increment,
119 `branchcode` varchar(4) NOT NULL default '',
120 `day` smallint(6) NOT NULL default '0',
121 `month` smallint(6) NOT NULL default '0',
122 `year` smallint(6) NOT NULL default '0',
123 `isexception` smallint(1) NOT NULL default '1',
124 `title` varchar(50) NOT NULL default '',
125 `description` text NOT NULL,
128 overduerules =>"(`branchcode` varchar(255) NOT NULL default '',
129 `categorycode` char(2) NOT NULL default '',
130 `delay1` int(4) default '0',
131 `letter1` varchar(20) default NULL,
132 `debarred1` char(1) default '0',
133 `delay2` int(4) default '0',
134 `debarred2` char(1) default '0',
135 `letter2` varchar(20) default NULL,
136 `delay3` int(4) default '0',
137 `letter3` varchar(20) default NULL,
138 `debarred3` int(1) default '0',
139 PRIMARY KEY (`branchcode`,`categorycode`)
141 cities => "(`cityid` int auto_increment,
142 `city_name` char(100) NOT NULL,
143 `city_zipcode` char(20),
144 PRIMARY KEY (`cityid`)
146 <<<<<<< updatedatabase
147 roadtype => "(`roadtypeid` int auto_increment,
148 `road_type` char(100) NOT NULL,
149 PRIMARY KEY (`roadtypeid`)
152 bibid bigint(20) NOT NULL default '0',
153 tag char(3) NOT NULL default '',
154 tagorder tinyint(4) NOT NULL default '1',
155 subfieldid char(1) NOT NULL default '',
156 subfieldorder tinyint(4) NOT NULL default '1',
157 word varchar(255) NOT NULL default '',
158 sndx_word varchar(255) NOT NULL default '',
161 KEY tagorder (tagorder),
162 KEY subfieldid (subfieldid),
163 KEY subfieldorder (subfieldorder),
165 KEY sndx_word (sndx_word)
167 marc_breeding => "( id bigint(20) NOT NULL auto_increment,
168 file varchar(80) NOT NULL default '',
169 isbn varchar(10) NOT NULL default '',
170 title varchar(128) default NULL,
171 author varchar(80) default NULL,
173 encoding varchar(40) default NULL,
178 authorised_values => "(id int(11) NOT NULL auto_increment,
179 category char(10) NOT NULL default '',
180 authorised_value char(80) NOT NULL default '',
185 userflags => "( bit int(11) NOT NULL default '0',
186 flag char(30), flagdesc char(255),
190 authtypecode char(10) not NULL,
191 authtypetext char(255) not NULL,
192 auth_tag_to_report char(3) not NULL,
193 summary text not NULL,
194 PRIMARY KEY (authtypecode)
196 biblio_framework => "(
197 frameworkcode char(4) not NULL,
198 frameworktext char(255) not NULL,
199 PRIMARY KEY (frameworkcode)
201 auth_subfield_structure => "(
202 authtypecode char(10) NOT NULL default '',
203 tagfield char(3) NOT NULL default '',
204 tagsubfield char(1) NOT NULL default '',
205 liblibrarian char(255) NOT NULL default '',
206 libopac char(255) NOT NULL default '',
207 repeatable tinyint(4) NOT NULL default '0',
208 mandatory tinyint(4) NOT NULL default '0',
209 tab tinyint(1) default NULL,
210 authorised_value char(10) default NULL,
211 value_builder char(80) default NULL,
212 seealso char(255) default NULL,
213 PRIMARY KEY (authtypecode,tagfield,tagsubfield),
214 KEY tab (authtypecode,tab)
217 <<<<<<< updatedatabase
220 labelid int(11) NOT NULL auto_increment,
221 itemnumber varchar(100) NOT NULL default '',
222 timestamp timestamp(14) NOT NULL,
223 PRIMARY KEY (labelid)
227 id int(4) NOT NULL auto_increment,
228 barcodetype char(100) default '',
229 title tinyint(1) default '0',
230 isbn tinyint(1) default '0',
231 itemtype tinyint(1) default '0',
232 barcode tinyint(1) default '0',
233 dewey tinyint(1) default '0',
234 class tinyint(1) default '0',
235 author tinyint(1) default '0',
236 papertype char(100) default '',
237 startrow int(2) default NULL,
241 reviewid integer NOT NULL auto_increment,
242 borrowernumber integer,
243 biblionumber integer,
246 datereviewed datetime,
247 PRIMARY KEY (reviewid)
249 borrowers_to_borrowers => "(
255 auth_tag_structure => "(
256 authtypecode char(10) NOT NULL default '',
257 tagfield char(3) NOT NULL default '',
258 liblibrarian char(255) NOT NULL default '',
259 libopac char(255) NOT NULL default '',
260 repeatable tinyint(4) NOT NULL default '0',
261 mandatory tinyint(4) NOT NULL default '0',
262 authorised_value char(10) default NULL,
263 PRIMARY KEY (authtypecode,tagfield)
266 authid bigint(20) unsigned NOT NULL auto_increment,
267 authtypecode char(10) NOT NULL default '',
268 datecreated date NOT NULL default '0000-00-00',
269 datemodified date default NULL,
270 origincode char(20) default NULL,
271 PRIMARY KEY (authid),
272 KEY origincode (origincode)
274 auth_subfield_table => "(
275 subfieldid bigint(20) unsigned NOT NULL auto_increment,
276 authid bigint(20) unsigned NOT NULL default '0',
277 tag char(3) NOT NULL default '',
278 tagorder tinyint(4) NOT NULL default '1',
279 tag_indicator char(2) NOT NULL default '',
280 subfieldcode char(1) NOT NULL default '',
281 subfieldorder tinyint(4) NOT NULL default '1',
282 subfieldvalue varchar(255) default NULL,
283 PRIMARY KEY (subfieldid),
286 KEY subfieldcode (subfieldcode),
287 KEY subfieldvalue (subfieldvalue)
290 authid bigint(20) NOT NULL default '0',
291 tagsubfield char(4) NOT NULL default '',
292 tagorder tinyint(4) NOT NULL default '1',
293 subfieldorder tinyint(4) NOT NULL default '1',
294 word varchar(255) NOT NULL default '',
295 sndx_word varchar(255) NOT NULL default '',
297 KEY marc_search (tagsubfield,word),
299 KEY sndx_word (sndx_word)
302 suggestionid int(8) NOT NULL auto_increment,
303 suggestedby int(11) NOT NULL default '0',
304 managedby int(11) default NULL ,
305 STATUS varchar(10) NOT NULL default '',
307 author varchar(80) default NULL ,
308 title varchar(80) default NULL ,
309 copyrightdate smallint(6) default NULL ,
310 publishercode varchar(255) default NULL ,
311 date timestamp(8) NOT NULL ,
312 volumedesc varchar(255) default NULL ,
313 publicationyear smallint(6) default '0',
314 place varchar(255) default NULL ,
315 isbn varchar(10) default NULL ,
316 mailoverseeing smallint(1) default '0',
317 biblionumber int(11) default NULL ,
318 PRIMARY KEY (suggestionid) ,
319 KEY suggestedby(suggestedby) ,
320 KEY managedby(managedby)
322 aqbasket => "(basketno int(11) NOT NULL auto_increment,
325 booksellerid varchar(10),
326 authorisedby varchar(10),
327 booksellerinvoicenumber text,
328 PRIMARY KEY (basketno)
330 serial => "(serialid int(11) NOT NULL auto_increment,
331 biblionumber varchar(100) NOT NULL default '',
332 subscriptionid varchar(100) NOT NULL default '',
333 serialseq varchar(100) NOT NULL default '',
334 status tinyint(4) NOT NULL default '0',
335 planneddate date NOT NULL default '0000-00-00',
336 publishedddate date NOT NULL default '0000-00-00',
337 PRIMARY KEY (serialid)
339 subscription => "(biblionumber int(11) NOT NULL default '0',
340 subscriptionid int(11) NOT NULL auto_increment,
341 librarian varchar(100) default '',
342 startdate date default '0000-00-00',
343 aqbooksellerid int(11) default '0',
344 cost int(11) default '0',
345 aqbudgetid int(11) default '0',
346 weeklength tinyint(4) default '0',
347 monthlength tinyint(4) default '0',
348 numberlength tinyint(4) default '0',
349 periodicity tinyint(4) default '0',
350 dow varchar(100) default '',
351 numberingmethod varchar(100) default '',
353 status varchar(100) NOT NULL default '',
354 add1 int(11) default 0,
355 every1 int(11) default 0,
356 whenmorethan1 int(11) default 0,
359 add2 int(11) default 0,
360 every2 int(11) default 0,
361 whenmorethan2 int(11) default 0,
364 add3 int(11) default 0,
365 every3 int(11) default 0,
366 innerloop1 int(11) default 0,
367 innerloop2 int(11) default 0,
368 innerloop3 int(11) default 0,
369 whenmorethan3 int(11) default 0,
372 PRIMARY KEY (subscriptionid)
374 subscriptionhistory => "(biblionumber int(11) NOT NULL default '0',
375 subscriptionid int(11) NOT NULL default '0',
376 histstartdate date NOT NULL default '0000-00-00',
377 enddate date default '0000-00-00',
378 missinglist longtext NOT NULL,
379 recievedlist longtext NOT NULL,
380 opacnote varchar(150) NOT NULL default '',
381 librariannote varchar(150) NOT NULL default '',
382 PRIMARY KEY (subscriptionid),
383 KEY biblionumber (biblionumber)
385 labels => "(labelid int(11) NOT NULL auto_increment,
386 itemnumber varchar(100) NOT NULL default '',
387 timestamp timestamp(14) NOT NULL,
388 PRIMARY KEY (labelid)
390 labels_conf => "(id int(4) NOT NULL auto_increment,
391 barcodetype char(100) default '',
392 title tinyint(1) default '0',
393 isbn tinyint(1) default '0',
394 itemtype tinyint(1) default '0',
395 barcode tinyint(1) default '0',
396 dewey tinyint(1) default '0',
397 class tinyint(1) default '0',
398 author tinyint(1) default '0',
399 papertype char(100) default '',
400 startrow int(2) default NULL,
406 my %requirefields = (
407 <<<<<<< updatedatabase
408 subscription => { 'letter' => 'char(20) NULL', 'distributedto' => 'text NULL'},
409 itemtypes => { 'imageurl' => 'char(200) NULL'},
410 aqbookfund => { 'branchcode' => 'varchar(4) NULL'},
411 aqbudget => { 'branchcode' => 'varchar(4) NULL'},
412 auth_header => { 'marc' => 'BLOB NOT NULL', 'linkid' => 'BIGINT(20) NULL'},
413 auth_subfield_structure =>{ 'hidden' => 'TINYINT(3) NOT NULL UNSIGNED ZEROFILL', 'kohafield' => 'VARCHAR(45) NOT NULL', 'linkid' => 'TINYINT(1) NOT NULL UNSIGNED', 'isurl' => 'TINYINT(1) UNSIGNED'},
414 statistics => { 'associatedborrower' => 'integer'},
415 # tablename => { 'field' => 'fieldtype' },
417 biblio => { 'abstract' => 'text' },
418 deletedbiblio => { 'abstract' => 'text', 'marc' => 'blob' },
420 { 'marc' => 'blob', 'paidfor' => 'text', 'location' => 'varchar(80)' },
422 'lccn' => 'char(25)',
423 'url' => 'varchar(255)',
426 deletedbiblioitems => {
427 'lccn' => 'char(25)',
428 'url' => 'varchar(255)',
431 branchtransfers => { 'datearrived' => 'datetime' },
432 statistics => { 'borrowernumber' => 'int(11)' },
434 'invoicedisc' => 'float(6,4)',
435 'nocalc' => 'int(11)'
438 'userid' => 'char(30)',
439 'password' => 'char(30)',
440 'flags' => 'int(11)',
441 'textmessaging' => 'varchar(30)',
442 'zipcode' => 'varchar(25)',
443 'homezipcode' => 'varchar(25)',
444 'sort1' => 'char(80)',
445 'sort2' => 'char(80)',
448 'budgetdate' => 'date',
449 'sort1' => 'char(80)',
450 'sort2' => 'char(80)',
453 'aqbudgetid' => 'tinyint(4) auto_increment primary key',
454 'branchcode' => 'varchar(4)',
456 aqbookfund => { 'branchcode' => 'varchar(4)', },
457 items => { 'paidfor' => 'text', 'location' => 'char(80)' },
459 #added so that reference items are not available for reserves...
460 itemtypes => { 'notforloan' => 'smallint(6)' },
461 systempreferences => {
462 'explanation' => 'char(80)',
463 'type' => 'char(20)',
466 z3950servers => { 'syntax' => 'char(80)' },
467 marc_tag_structure =>
468 { 'frameworkcode' => 'char(4) not NULL default \'\'' },
469 marc_subfield_structure => {
470 'seealso' => 'char(255)',
471 'frameworkcode' => 'char(4) not NULL default \'\'',
472 'hidden' => 'tinyint(1)',
473 'isurl' => 'tinyint(1)',
474 'link' => 'char(80)',
477 'owner' => 'char(80)',
478 'category' => 'char(1)',
480 marc_biblio => { 'frameworkcode' => 'char(4) not NULL default \'\'' },
484 my %dropable_table = (
485 sessionqueries => 'sessionqueries',
486 marcrecorddone => 'marcrecorddone',
488 itemsprices => 'itemsprices',
489 biblioanalysis => 'biblioanalysis',
491 # tablename => 'tablename',
494 my %uselessfields = (
495 <<<<<<< updatedatabase
496 # tablename => "field1,field2",
497 borrowers => "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
498 deletedborrowers=> "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
501 aqorders => "requisitionedby,authorisedby,booksellerid,
502 deliverydays,followupdays,
503 numberfollowupsallowed,numberfollowupssent,
504 dateprinted,sourced,quantityreceiveddamaged,
505 subscriptionfrom,subscriptionto
510 # the other hash contains other actions that can't be done elsewhere. they are done
511 # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
513 # The tabledata hash contains data that should be in the tables.
514 # The uniquefieldrequired hash entry is used to determine which (if any) fields
515 # must not exist in the table for this row to be inserted. If the
516 # uniquefieldrequired entry is already in the table, the existing data is not
517 # modified, unless the forceupdate hash entry is also set. Fields in the
518 # anonymous "forceupdate" hash will be forced to be updated to the default
519 # values given in the %tabledata hash.
522 <<<<<<< updatedatabase
524 # { uniquefielrequired => 'fieldname', # the primary key in the table
525 # fieldname => fieldvalue,
526 # fieldname2 => fieldvalue2,
532 uniquefieldrequired => 'bit',
534 flag => 'superlibrarian',
535 flagdesc => 'Access to all librarian functions',
539 uniquefieldrequired => 'bit',
542 flagdesc => 'Circulate books',
546 uniquefieldrequired => 'bit',
549 flagdesc => 'View Catalogue (Librarian Interface)',
553 uniquefieldrequired => 'bit',
555 flag => 'parameters',
556 flagdesc => 'Set Koha system paramters',
560 uniquefieldrequired => 'bit',
563 flagdesc => 'Add or modify borrowers',
567 uniquefieldrequired => 'bit',
569 flag => 'permissions',
570 flagdesc => 'Set user permissions',
574 uniquefieldrequired => 'bit',
576 flag => 'reserveforothers',
577 flagdesc => 'Reserve books for patrons',
581 uniquefieldrequired => 'bit',
584 flagdesc => 'Borrow books',
588 uniquefieldrequired => 'bit',
590 flag => 'reserveforself',
591 flagdesc => 'Reserve books for self',
595 uniquefieldrequired => 'bit',
597 flag => 'editcatalogue',
598 flagdesc => 'Edit Catalogue (Modify bibliographic/holdings data)',
602 uniquefieldrequired => 'bit',
604 flag => 'updatecharges',
605 flagdesc => 'Update borrower charges',
609 uniquefieldrequired => 'bit',
611 flag => 'acquisition',
612 flagdesc => 'Acquisition and/or suggestion management',
616 uniquefieldrequired => 'bit',
618 flag => 'management',
619 flagdesc => 'Set library management parameters',
623 uniquefieldrequired => 'bit',
626 flagdesc => 'Use tools (export, import, barcodes)',
631 systempreferences => [
633 uniquefieldrequired => 'variable',
634 <<<<<<< updatedatabase
635 variable => 'Activate_Log',
637 forceupdate => { 'explanation' => 1,
639 explanation => 'Turn Log Actions on DB On an Off',
646 variable => 'LibraryName',
648 '<i><b>Koha<br/>Free Software ILS<br/><br/></b>Koha : a gift, a contribution<br/> in Maori</i>',
649 explanation => 'Library name as shown on main opac page',
655 uniquefieldrequired => 'variable',
656 <<<<<<< updatedatabase
657 variable => 'IndependantBranches',
659 forceupdate => { 'explanation' => 1,
661 explanation => 'Turn Branch independancy management On an Off',
668 variable => 'autoMemberNum',
670 explanation => 'Member number is auto-calculated',
676 uniquefieldrequired => 'variable',
677 <<<<<<< updatedatabase
678 variable => 'ReturnBeforeExpiry',
680 forceupdate => { 'explanation' => 1,
682 explanation => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
690 variable => 'acquisitions',
693 'Normal, budget-based acquisitions, or Simple bibliographic-data acquisitions',
695 options => 'simple|normal'
698 uniquefieldrequired => 'variable',
704 variable => 'dateformat',
707 'date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy/mm/dd)',
709 options => 'metric|us|iso'
712 uniquefieldrequired => 'variable',
713 variable => 'template',
719 explanation => 'Preference order for intranet interface templates',
723 uniquefieldrequired => 'variable',
724 variable => 'autoBarcode',
730 explanation => 'Barcode is auto-calculated',
734 uniquefieldrequired => 'variable',
735 variable => 'insecure',
742 'If YES, no auth at all is needed. Be careful if you set this to yes!',
746 uniquefieldrequired => 'variable',
747 variable => 'authoritysep',
755 'the separator used in authority/thesaurus. Usually --',
760 uniquefieldrequired => 'variable',
761 variable => 'opaclanguages',
768 'Set the preferred order for translations. The top language will be tried first.',
772 uniquefieldrequired => 'variable',
773 variable => 'opacthemes',
780 'Set the preferred order for themes. The top theme will be tried first.',
784 uniquefieldrequired => 'variable',
785 variable => 'timeout',
792 'Inactivity timeout for cookies authentication (in seconds)',
796 uniquefieldrequired => 'variable',
803 explanation => 'Turn on MARC support',
807 uniquefieldrequired => 'variable',
808 variable => 'sortbynonfiling',
814 explanation => 'Sort search results by MARC nonfiling characters',
818 uniquefieldrequired => 'variable',
819 variable => 'marcflavour',
827 'your MARC flavor (MARC21 or UNIMARC) used for character encoding',
829 options => 'MARC21|UNIMARC'
832 uniquefieldrequired => 'variable',
833 variable => 'checkdigit',
841 'Validity checks on membership number: none or "Katipo" style checks',
843 options => 'none|katipo'
846 uniquefieldrequired => 'variable',
847 variable => 'maxoutstanding',
854 'maximum amount withstanding to be able make reserves ',
858 uniquefieldrequired => 'variable',
859 variable => 'maxreserves',
865 explanation => 'maximum number of reserves a member can make',
870 uniquefieldrequired => 'variable',
871 variable => 'noissuescharge',
878 'maximum amount withstanding to be able to check out an item',
883 uniquefieldrequired => 'variable',
884 variable => 'KohaAdminEmailAddress',
889 value => 'your.mail@here',
890 explanation => 'the email address where borrowers modifs are sent',
894 uniquefieldrequired => 'variable',
902 'the gist rate. NOT in %, but in numeric form (0.12 for 12%)',
906 uniquefieldrequired => 'variable',
907 variable => 'printcirculationslips',
914 'if set to 1, print circulation slips. If set to 0, don\'t',
918 uniquefieldrequired => 'variable',
919 variable => 'suggestion',
925 explanation => 'if set to 1, suggestions are activated in OPAC',
929 uniquefieldrequired => 'variable',
935 value => 'Fill with appropriate value...',
936 explanation => 'ISBD',
940 uniquefieldrequired => 'variable',
941 variable => 'virtualshelves',
947 explanation => 'Set virtual shelves management ON or OFF',
951 uniquefieldrequired => 'variable',
952 variable => 'itemcallnumber',
959 'The MARC field/subfield that is used to calculate the itemcallnumber (in UNIMARC : 676a for Dewey, 680a for Loc)',
963 uniquefieldrequired => 'variable',
964 variable => 'BiblioDefaultView',
972 'Define the default view of a biblio. Can be either normal, marc or isbd',
974 options => 'normal|marc|isbd'
978 uniquefieldrequired => 'variable',
979 variable => 'LabelMARCView',
986 explanation => 'Define how a MARC record will display',
988 options => 'standard|economical'
993 uniquefieldrequired => 'variable',
994 variable => 'opacstylesheet',
1001 'Enter a complete URL to use an alternate layout stylesheet in OPAC',
1005 uniquefieldrequired => 'variable',
1006 variable => 'opaccolorstylesheet',
1013 'Enter the name of the color stylesheet to use in the OPAC',
1017 uniquefieldrequired => 'variable',
1018 variable => 'opaclayoutstylesheet',
1025 'Enter the name of the layout stylesheet to use in the OPAC',
1030 uniquefieldrequired => 'variable',
1031 variable => 'opacreadinghistory',
1038 'Turn on/off display of Patron Reading History in OPAC',
1042 uniquefieldrequired => 'variable',
1043 variable => 'opaclanguagesdisplay',
1050 'Turn on/off display of Change Language feature on OPAC',
1054 uniquefieldrequired => 'variable',
1055 variable => 'patronimages',
1062 'Turn on/off display of patron images in Intranet and specify a file extension for images',
1066 uniquefieldrequired => 'variable',
1067 variable => 'intranetstylesheet',
1074 'Enter a complete URL to use an alternate layout stylesheet in Intranet',
1078 uniquefieldrequired => 'variable',
1079 variable => 'intranetcolorstylesheet',
1086 'Enter the name of the color stylesheet to use in Intranet',
1090 uniquefieldrequired => 'variable',
1091 variable => 'opacsmallimage',
1098 'Enter a complete URL to an image, will be on top/left instead of the Koha logo',
1102 uniquefieldrequired => 'variable',
1103 variable => 'opaclargeimage',
1110 'Enter a complete URL to an image, will be on the main page, instead of the Koha logo',
1114 uniquefieldrequired => 'variable',
1115 variable => 'delimiter',
1121 explanation => 'separator for reports exported to spreadsheet',
1125 uniquefieldrequired => 'variable',
1127 value => 'OPENOFFICE.ORG',
1134 'Define the default application for report exportations into files',
1136 options => 'EXCEL|OPENOFFICE.ORG'
1139 uniquefieldrequired => 'variable',
1140 variable => 'Delimiter',
1148 'Define the default separator character for report exportations into files',
1150 options => ';|tabulation|,|/|\|#'
1153 uniquefieldrequired => 'variable',
1154 variable => 'SubscriptionHistory',
1162 'Define the information level for serials history in OPAC',
1164 options => 'simplified|full'
1167 uniquefieldrequired => 'variable',
1168 variable => 'hidelostitems',
1174 explanation => 'show or hide "lost" items in OPAC.',
1178 uniquefieldrequired => 'variable',
1179 variable => 'IndependantBranches',
1185 explanation => 'Turn Branch independency management On and Off',
1189 uniquefieldrequired => 'variable',
1190 variable => 'ReturnBeforeExpiry',
1197 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
1201 uniquefieldrequired => 'variable',
1202 variable => 'Disable_Dictionary',
1208 explanation => 'Disables Dictionary buttons if set to yes',
1212 uniquefieldrequired => 'variable',
1213 variable => 'hide_marc',
1220 'hide marc specific datas like subfield code & indicators to library',
1224 uniquefieldrequired => 'variable',
1225 variable => 'NotifyBorrowerDeparture',
1232 'Delay before expiry where a notice is sent when issuing',
1236 uniquefieldrequired => 'variable',
1237 variable => 'OpacPasswordChange',
1244 'Enable/Disable password change in OPAC (disable it when using LDAP auth)',
1248 uniquefieldrequired => 'variable',
1249 variable => 'OpacNav',
1256 'Use HTML tabs to add navigational links to the left-hand navigational bar in OPAC',
1261 uniquefieldrequired => 'variable',
1262 variable => 'IntranetNav',
1269 'Use HTML tabs to add navigational links to the left-hand navigational bar in Intranet',
1275 uniquefieldrequired => 'variable',
1276 variable => 'AnonSuggestions',
1284 'Set to anonymous borrowernumber to enable Anonymous suggestions',
1288 uniquefieldrequired => 'variable',
1289 variable => 'MARCOrgCode',
1297 'Your MARC Organization Code - http://www.loc.gov/marc/organizations/orgshome.html',
1301 uniquefieldrequired => 'variable',
1302 variable => 'AmazonContent',
1310 'Turn On Amazon Content - You MUST set AmazonDevKey and AmazonAssocTag if enabled',
1314 uniquefieldrequired => 'variable',
1315 variable => 'AmazonDevKey',
1323 'see: aws-portal.amazon.com/gp/aws/developer/registration/index.html',
1327 uniquefieldrequired => 'variable',
1328 variable => 'AmazonAssocTag',
1336 'see: associates.amazon.com/gp/flex/associates/apply-login.html',
1340 uniquefieldrequired => 'variable',
1346 variable => 'TemplateEncoding',
1347 value => 'iso-8859-1',
1348 explanation => 'Specify the encoding to use in Templates',
1350 options => 'iso-8859-1|utf-8'
1354 uniquefieldrequired => 'variable',
1355 variable => 'opaccredits',
1363 'Put any HTML Credits at the bottom of the OPAC page',
1369 uniquefieldrequired => 'variable',
1370 variable => 'opacheader',
1372 forceupdate => { 'explanation' => 1,
1374 explanation => 'Enter HTML to be included as a custom header in the OPAC',
1380 uniquefieldrequired => 'variable',
1381 variable => 'IntranetBiblioDefaultView',
1383 forceupdate => { 'explanation' => 1,
1385 explanation => 'Define the default view of a biblio in the intranet. Can be either normal, marc, or ISBD',
1387 options => 'normal|marc|isbd'
1391 uniquefieldrequired => 'variable',
1392 variable => 'opacbookbag',
1394 forceupdate => { 'explanation' => 1,
1396 explanation => 'Enable or disable display of biblio basket (book bag)',
1401 uniquefieldrequired => 'variable',
1402 variable => 'opacuserlogin',
1404 forceupdate => { 'explanation' => 1,
1406 explanation => 'Enable or disable display of user login features',
1411 uniquefieldrequired => 'variable',
1412 variable => 'serialsadditems',
1420 'If set, a new item will be automatically added when receiving an issue',
1424 uniquefieldrequired => 'variable',
1425 variable => 'advancedMARCeditor',
1433 "If set, the MARC editor won't show you tag/subfields description",
1437 uniquefieldrequired => 'variable',
1438 variable => 'z3950NormalizeAuthor',
1446 "If set, Personnal Authorities will replace authors in biblio.author",
1450 uniquefieldrequired => 'variable',
1451 variable => 'z3950AuthorAuthFields',
1452 value => '701,702,700',
1459 "contains the MARC biblio tags of person authorities to fill biblio.author with when importing biblio",
1463 uniquefieldrequired => 'variable',
1464 variable => 'useDaysMode',
1465 value => 'Calendar',
1466 forceupdate => { 'explanation' => 1,
1468 explanation => 'How to calculate return dates : Calendar means holidays will be controled, Days means the return date don\'t depend on holidays',
1470 options => 'Calendar|Days'
1473 uniquefieldrequired => 'variable',
1474 variable => 'borrowerMandatoryField',
1475 value => 'zipcode|surname',
1476 forceupdate => { 'explanation' => 1,
1478 explanation => 'List all mandatory fields for borrowers',
1482 <<<<<<< updatedatabase
1483 uniquefieldrequired => 'variable',
1484 variable => 'borrowerRelationship',
1485 value => 'father|mother,grand-mother',
1486 forceupdate => { 'explanation' => 1,
1488 explanation => 'The relationships between a guarantor & a guarantee (separated by | or ,)',
1491 field => 'aqbudgetid',
1492 type => 'tinyint(4)',
1496 extra => 'auto_increment'
1500 uniquefieldrequired => 'variable',
1501 variable => 'ReservesMaxPickUpDelay',
1503 forceupdate => { 'explanation' => 1,
1505 explanation => 'Maximum delay to pick up a reserved document',
1508 <<<<<<< updatedatabase
1514 uniquefieldrequired => 'variable',
1515 variable => 'TransfersMaxDaysWarning',
1517 forceupdate => { 'explanation' => 1,
1519 explanation => 'Max delay before considering the transfer has potentialy a problem',
1523 uniquefieldrequired => 'variable',
1524 variable => 'memberofinstitution',
1526 forceupdate => { 'explanation' => 1,
1528 explanation => 'Are your patrons members of institutions',
1532 uniquefieldrequired => 'variable',
1533 variable => 'ReadingHistory',
1535 forceupdate => { 'explanation' => 1,
1537 explanation => 'Allow reading record info retrievable from issues and oldissues tables',
1541 uniquefieldrequired => 'variable',
1542 variable => 'IssuingInProcess',
1544 forceupdate => { 'explanation' => 1,
1546 explanation => 'Allow no debt alert if the patron is issuing item that accumulate debt',
1550 uniquefieldrequired => 'variable',
1551 variable => 'AutomaticItemReturn',
1553 forceupdate => { 'explanation' => 1,
1555 explanation => 'This Variable allow or not to return automaticly to his homebranch',
1559 uniquefieldrequired => 'variable',
1560 variable => 'reviewson',
1562 forceupdate => { 'explanation' => 1,
1564 explanation => 'Allows patrons to submit reviews from the opac',
1568 <<<<<<< updatedatabase
1572 my %fielddefinitions = (
1574 # { field => 'fieldname',
1575 # type => 'fieldtype',
1594 <<<<<<< updatedatabase
1597 field => 'booksellerid',
1607 field => 'listprice',
1608 type => 'varchar(10)',
1615 field => 'invoiceprice',
1616 type => 'varchar(10)',
1625 field => 'borrowernumber',
1627 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1633 field => 'itemnumber',
1635 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1642 { field => 'firstname',
1646 { field => 'initials',
1650 { field => 'B_email',
1653 after => 'B_zipcode',
1656 field => 'streetnumber', # street number (hidden if streettable table is empty)
1659 after => 'initials',
1662 field => 'streettype', # street table, list builded from a system table
1665 after => 'streetnumber',
1672 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1678 field => 'B_streettype', # street table, list builded from a system table
1681 after => 'B_streetnumber',
1684 field => 'phonepro',
1690 field => 'address2', # complement address
1696 field => 'emailpro',
1702 field => 'contactfirstname', # contact's firstname
1705 after => 'contactname',
1708 field => 'contacttitle', # contact's title
1711 after => 'contactfirstname',
1715 deletedborrowers => [
1716 { field => 'firstname',
1720 { field => 'initials',
1724 { field => 'B_email',
1727 after => 'B_zipcode',
1730 field => 'streetnumber', # street number (hidden if streettable table is empty)
1733 after => 'initials',
1736 field => 'streettype', # street table, list builded from a system table
1739 after => 'streetnumber',
1746 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1752 field => 'B_streettype', # street table, list builded from a system table
1755 after => 'B_streetnumber',
1758 field => 'phonepro',
1764 field => 'address2', # complement address
1770 field => 'emailpro',
1776 field => 'contactfirstname', # contact's firstname
1779 after => 'contactname',
1782 field => 'contacttitle', # contact's title
1785 after => 'contactfirstname',
1791 field => 'branchip',
1792 type => 'varchar(15)',
1799 field => 'branchprinter',
1800 type => 'varchar(100)',
1809 field => 'category_type',
1819 field => 'waitingdate',
1831 # { indexname => 'index detail'
1835 { indexname => 'shelfnumber',
1836 content => 'shelfnumber',
1838 { indexname => 'itemnumber',
1839 content => 'itemnumber',
1843 { indexname => 'biblionumber',
1844 content => 'biblionumber',
1848 { indexname => 'homebranch',
1849 content => 'homebranch',
1851 { indexname => 'holdingbranch',
1852 content => 'holdingbranch',
1856 { indexname => 'PRIMARY',
1862 { indexname => 'booksellerid',
1863 content => 'booksellerid',
1867 { indexname => 'basketno',
1868 content => 'basketno',
1871 aqorderbreakdown => [
1872 { indexname => 'ordernumber',
1873 content => 'ordernumber',
1875 { indexname => 'bookfundid',
1876 content => 'bookfundid',
1880 { indexname => 'PRIMARY',
1881 content => 'currency',
1889 type => 'varchar(30)',
1899 my %foreign_keys = (
1901 # { key => 'the key in table' (must be indexed)
1902 # foreigntable => 'the foreigntable name', # (the parent)
1903 # foreignkey => 'the foreign key column(s)' # (in the parent)
1904 # onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
1905 # onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
1909 { key => 'shelfnumber',
1910 foreigntable => 'bookshelf',
1911 foreignkey => 'shelfnumber',
1912 onUpdate => 'CASCADE',
1913 onDelete => 'CASCADE',
1915 { key => 'itemnumber',
1916 foreigntable => 'items',
1917 foreignkey => 'itemnumber',
1918 onUpdate => 'CASCADE',
1919 onDelete => 'CASCADE',
1922 # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
1923 # easily deleted, but branches/itemtype not too easy to empty...
1925 { key => 'biblionumber',
1926 foreigntable => 'biblio',
1927 foreignkey => 'biblionumber',
1928 onUpdate => 'CASCADE',
1929 onDelete => 'CASCADE',
1931 { key => 'itemtype',
1932 foreigntable => 'itemtypes',
1933 foreignkey => 'itemtype',
1934 onUpdate => 'CASCADE',
1935 onDelete => 'RESTRICT',
1939 { key => 'biblioitemnumber',
1940 foreigntable => 'biblioitems',
1941 foreignkey => 'biblioitemnumber',
1942 onUpdate => 'CASCADE',
1943 onDelete => 'CASCADE',
1945 { key => 'homebranch',
1946 foreigntable => 'branches',
1947 foreignkey => 'branchcode',
1948 onUpdate => 'CASCADE',
1949 onDelete => 'RESTRICT',
1951 { key => 'holdingbranch',
1952 foreigntable => 'branches',
1953 foreignkey => 'branchcode',
1954 onUpdate => 'CASCADE',
1955 onDelete => 'RESTRICT',
1958 additionalauthors => [
1959 { key => 'biblionumber',
1960 foreigntable => 'biblio',
1961 foreignkey => 'biblionumber',
1962 onUpdate => 'CASCADE',
1963 onDelete => 'CASCADE',
1967 { key => 'biblionumber',
1968 foreigntable => 'biblio',
1969 foreignkey => 'biblionumber',
1970 onUpdate => 'CASCADE',
1971 onDelete => 'CASCADE',
1975 { key => 'booksellerid',
1976 foreigntable => 'aqbooksellers',
1978 onUpdate => 'CASCADE',
1979 onDelete => 'RESTRICT',
1983 { key => 'basketno',
1984 foreigntable => 'aqbasket',
1985 foreignkey => 'basketno',
1986 onUpdate => 'CASCADE',
1987 onDelete => 'CASCADE',
1989 { key => 'biblionumber',
1990 foreigntable => 'biblio',
1991 foreignkey => 'biblionumber',
1992 onUpdate => 'SET NULL',
1993 onDelete => 'SET NULL',
1997 { key => 'listprice',
1998 foreigntable => 'currency',
1999 foreignkey => 'currency',
2000 onUpdate => 'CASCADE',
2001 onDelete => 'CASCADE',
2003 { key => 'invoiceprice',
2004 foreigntable => 'currency',
2005 foreignkey => 'currency',
2006 onUpdate => 'CASCADE',
2007 onDelete => 'CASCADE',
2010 aqorderbreakdown => [
2011 { key => 'ordernumber',
2012 foreigntable => 'aqorders',
2013 foreignkey => 'ordernumber',
2014 onUpdate => 'CASCADE',
2015 onDelete => 'CASCADE',
2017 { key => 'bookfundid',
2018 foreigntable => 'aqbookfund',
2019 foreignkey => 'bookfundid',
2020 onUpdate => 'CASCADE',
2021 onDelete => 'CASCADE',
2024 branchtransfers => [
2025 { key => 'frombranch',
2026 foreigntable => 'branches',
2027 foreignkey => 'branchcode',
2028 onUpdate => 'CASCADE',
2029 onDelete => 'CASCADE',
2031 { key => 'tobranch',
2032 foreigntable => 'branches',
2033 foreignkey => 'branchcode',
2034 onUpdate => 'CASCADE',
2035 onDelete => 'CASCADE',
2037 { key => 'itemnumber',
2038 foreigntable => 'items',
2039 foreignkey => 'itemnumber',
2040 onUpdate => 'CASCADE',
2041 onDelete => 'CASCADE',
2045 { key => 'categorycode',
2046 foreigntable => 'categories',
2047 foreignkey => 'categorycode',
2048 onUpdate => 'CASCADE',
2049 onDelete => 'CASCADE',
2051 { key => 'itemtype',
2052 foreigntable => 'itemtypes',
2053 foreignkey => 'itemtype',
2054 onUpdate => 'CASCADE',
2055 onDelete => 'CASCADE',
2058 issues => [ # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
2060 { key => 'borrowernumber',
2061 foreigntable => 'borrowers',
2062 foreignkey => 'borrowernumber',
2063 onUpdate => 'SET NULL',
2064 onDelete => 'SET NULL',
2066 { key => 'itemnumber',
2067 foreigntable => 'items',
2068 foreignkey => 'itemnumber',
2069 onUpdate => 'SET NULL',
2070 onDelete => 'SET NULL',
2074 { key => 'borrowernumber',
2075 foreigntable => 'borrowers',
2076 foreignkey => 'borrowernumber',
2077 onUpdate => 'CASCADE',
2078 onDelete => 'CASCADE',
2080 { key => 'biblionumber',
2081 foreigntable => 'biblio',
2082 foreignkey => 'biblionumber',
2083 onUpdate => 'CASCADE',
2084 onDelete => 'CASCADE',
2086 { key => 'itemnumber',
2087 foreigntable => 'items',
2088 foreignkey => 'itemnumber',
2089 onUpdate => 'CASCADE',
2090 onDelete => 'CASCADE',
2092 { key => 'branchcode',
2093 foreigntable => 'branches',
2094 foreignkey => 'branchcode',
2095 onUpdate => 'CASCADE',
2096 onDelete => 'CASCADE',
2099 borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2100 # but prevent deleting a branch as soon as it has 1 borrower !
2101 { key => 'categorycode',
2102 foreigntable => 'categories',
2103 foreignkey => 'categorycode',
2104 onUpdate => 'RESTRICT',
2105 onDelete => 'RESTRICT',
2107 { key => 'branchcode',
2108 foreigntable => 'branches',
2109 foreignkey => 'branchcode',
2110 onUpdate => 'RESTRICT',
2111 onDelete => 'RESTRICT',
2114 deletedborrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2115 # but prevent deleting a branch as soon as it has 1 borrower !
2116 { key => 'categorycode',
2117 foreigntable => 'categories',
2118 foreignkey => 'categorycode',
2119 onUpdate => 'RESTRICT',
2120 onDelete => 'RESTRICT',
2122 { key => 'branchcode',
2123 foreigntable => 'branches',
2124 foreignkey => 'branchcode',
2125 onUpdate => 'RESTRICT',
2126 onDelete => 'RESTRICT',
2130 { key => 'borrowernumber',
2131 foreigntable => 'borrowers',
2132 foreignkey => 'borrowernumber',
2133 onUpdate => 'CASCADE',
2134 onDelete => 'CASCADE',
2136 { key => 'itemnumber',
2137 foreigntable => 'items',
2138 foreignkey => 'itemnumber',
2139 onUpdate => 'SET NULL',
2140 onDelete => 'SET NULL',
2143 auth_tag_structure => [
2144 { key => 'authtypecode',
2145 foreigntable => 'auth_types',
2146 foreignkey => 'authtypecode',
2147 onUpdate => 'CASCADE',
2148 onDelete => 'CASCADE',
2151 # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
2156 my %column_change = (
2160 from => 'emailaddress',
2165 from => 'streetaddress',
2167 after => 'initials',
2170 from => 'faxnumber',
2175 from => 'textmessaging',
2181 to => 'contactnote',
2182 after => 'opacnote',
2185 from => 'physstreet',
2190 from => 'streetcity',
2192 after => 'B_address',
2205 from => 'homezipcode',
2212 after => 'B_zipcode',
2217 after => 'dateenrolled',
2220 from => 'guarantor',
2221 to => 'guarantorid',
2222 after => 'contactname',
2225 from => 'textmessaging',
2231 to => 'contactnotes',
2232 after => 'opacnotes',
2235 from => 'altrelationship',
2236 to => 'relationship',
2237 after => 'borrowernotes',
2241 deletedborrowers => [
2243 from => 'emailaddress',
2248 from => 'streetaddress',
2250 after => 'initials',
2253 from => 'faxnumber',
2258 from => 'textmessaging',
2264 to => 'contactnote',
2265 after => 'opacnote',
2268 from => 'physstreet',
2273 from => 'streetcity',
2275 after => 'B_address',
2288 from => 'homezipcode',
2295 after => 'B_zipcode',
2300 after => 'dateenrolled',
2303 from => 'guarantor',
2304 to => 'guarantorid',
2305 after => 'contactname',
2308 from => 'textmessaging',
2314 to => 'contactnotes',
2315 after => 'opacnotes',
2318 from => 'altrelationship',
2319 to => 'relationship',
2320 after => 'borrowernotes',
2326 foreach my $table (keys %column_change) {
2327 $sth = $dbh->prepare("show columns from $table");
2330 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2332 $types{$column}->{type} ="$type";
2333 $types{$column}->{null} = "$null";
2334 $types{$column}->{key} = "$key";
2335 $types{$column}->{default} = "$default";
2336 $types{$column}->{extra} = "$extra";
2338 my $tablerows = $column_change{$table};
2339 foreach my $row ( @$tablerows ) {
2340 if ($types{$row->{from}}->{type}) {
2341 print "altering $table $row->{from} to $row->{to}\n";
2342 # ALTER TABLE `borrowers` CHANGE `faxnumber` `fax` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
2343 # alter table `borrowers` change `faxnumber` `fax` type text null after phone
2345 "alter table `$table` change `$row->{from}` `$row->{to}` $types{$row->{from}}->{type} ".
2346 ($types{$row->{from}}->{null} eq 'YES'?" NULL":" NOT NULL").
2347 ($types{$row->{from}}->{default}?" default ".$types{$row->{from}}->{default}:"").
2348 "$types{$row->{from}}->{extra} after $row->{after} ";
2355 #-------------------
2360 # Get version of MySQL database engine.
2361 my $mysqlversion = `mysqld --version`;
2362 $mysqlversion =~ /Ver (\S*) /;
2364 if ( $mysqlversion ge '3.23' ) {
2365 print "Could convert to MyISAM database tables...\n" unless $silent;
2368 #---------------------------------
2371 # Collect all tables into a list
2372 $sth = $dbh->prepare("show tables");
2374 while ( my ($table) = $sth->fetchrow ) {
2375 $existingtables{$table} = 1;
2378 # Now add any missing tables
2379 foreach $table ( keys %requiretables ) {
2380 unless ( $existingtables{$table} ) {
2381 print "Adding $table table...\n" unless $silent;
2382 my $sth = $dbh->prepare("create table $table $requiretables{$table}");
2385 print "Error : $sth->errstr \n";
2391 # now drop useless tables
2392 foreach $table ( keys %dropable_table ) {
2393 if ( $existingtables{$table} ) {
2394 print "Dropping unused table $table\n" if $debug and not $silent;
2395 $dbh->do("drop table $table");
2397 print "Error : $dbh->errstr \n";
2401 <<<<<<< updatedatabase
2404 unless ( $existingtables{'z3950servers'} ) {
2406 #MJR: added syntax entries to close bug 624
2407 print "Adding z3950servers table...\n" unless $silent;
2408 my $sti = $dbh->prepare(
2409 "create table z3950servers (
2422 $sti = $dbh->prepare(
2423 "insert into z3950servers
2424 values ('z3950.loc.gov',
2428 'Library of Congress',
2433 unless ( $existingtables{'issuingrules'} ) {
2434 $dbh->do("alter table categoryitem rename issuingrules");
2435 $dbh->do("ALTER TABLE issuingrules ADD maxissueqty int(4) default NULL");
2436 $dbh->do("ALTER TABLE issuingrules ADD issuelength int(4) default NULL");
2438 "ALTER TABLE issuingrules ADD branchcode varchar(4) NOT NULL default ''"
2440 print "renaming categoryitem\n" unless $silent;
2444 #---------------------------------
2447 foreach $table ( keys %requirefields ) {
2448 print "Check table $table\n" if $debug and not $silent;
2449 $sth = $dbh->prepare("show columns from $table");
2452 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2454 $types{$column} = $type;
2456 foreach $column ( keys %{ $requirefields{$table} } ) {
2457 print " Check column $column [$types{$column}]\n"
2458 if $debug and not $silent;
2459 if ( !$types{$column} ) {
2461 # column doesn't exist
2462 print "Adding $column field to $table table...\n" unless $silent;
2463 $query = "alter table $table
2464 add column $column " . $requirefields{$table}->{$column};
2465 print "Execute: $query\n" if $debug;
2466 my $sti = $dbh->prepare($query);
2469 print "**Error : $sti->errstr \n";
2476 foreach $table ( keys %fielddefinitions ) {
2477 <<<<<<< updatedatabase
2478 print "Check table $table\n" if $debug;
2479 $sth = $dbh->prepare("show columns from $table");
2482 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2484 $definitions->{$column}->{type} = $type;
2485 $definitions->{$column}->{null} = $null;
2486 $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
2487 $definitions->{$column}->{key} = $key;
2488 $definitions->{$column}->{default} = $default;
2489 $definitions->{$column}->{extra} = $extra;
2491 my $fieldrow = $fielddefinitions{$table};
2492 foreach my $row (@$fieldrow) {
2493 my $field = $row->{field};
2494 my $type = $row->{type};
2495 my $null = $row->{null};
2496 # $null = 'YES' if $row->{null} eq 'NULL';
2497 my $key = $row->{key};
2498 my $default = $row->{default};
2499 my $null = $row->{null};
2500 # $default="''" unless $default;
2501 my $extra = $row->{extra};
2502 my $def = $definitions->{$field};
2503 my $after = ($row->{after}?" after ".$row->{after}:"");
2505 unless ( $type eq $def->{type}
2506 && $null eq $def->{null}
2507 && $key eq $def->{key}
2508 && $extra eq $def->{extra} )
2510 if ( $null eq '' ) {
2513 if ( $key eq 'PRI' ) {
2514 $key = 'PRIMARY KEY';
2516 unless ( $extra eq 'auto_increment' ) {
2520 # if it's a new column use "add", if it's an old one, use "change".
2522 if ($definitions->{$field}->{type}) {
2523 $action="change $field"
2527 # if it's a primary key, drop the previous pk, before altering the table
2529 if ($key ne 'PRIMARY KEY') {
2530 $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ? $after");
2532 $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ? $after");
2534 $sth->execute($default);
2535 print " alter or create $field in $table\n" unless $silent;
2539 print "Check table $table\n" if $debug;
2540 $sth = $dbh->prepare("show columns from $table");
2543 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2545 $definitions->{$column}->{type} = $type;
2546 $definitions->{$column}->{null} = $null;
2547 $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
2548 $definitions->{$column}->{key} = $key;
2549 $definitions->{$column}->{default} = $default;
2550 $definitions->{$column}->{extra} = $extra;
2552 my $fieldrow = $fielddefinitions{$table};
2553 foreach my $row (@$fieldrow) {
2554 my $field = $row->{field};
2555 my $type = $row->{type};
2556 my $key = $row->{key};
2557 my $default = $row->{default};
2558 my $null = $row->{null};
2560 # $default="''" unless $default;
2561 my $extra = $row->{extra};
2562 my $def = $definitions->{$field};
2564 unless ( $type eq $def->{type}
2565 && $null eq $def->{null}
2566 && $key eq $def->{key}
2567 && $extra eq $def->{extra} )
2569 if ( $null eq '' ) {
2572 if ( $key eq 'PRI' ) {
2573 $key = 'PRIMARY KEY';
2575 unless ( $extra eq 'auto_increment' ) {
2579 # if it's a new column use "add", if it's an old one, use "change".
2581 if ( $definitions->{$field}->{type} ) {
2582 $action = "change $field";
2588 # if it's a primary key, drop the previous pk, before altering the table
2590 if ( $key ne 'PRIMARY KEY' ) {
2593 "alter table $table $action $field $type $null $key $extra default ?"
2599 "alter table $table drop primary key, $action $field $type $null $key $extra default ?"
2602 $sth->execute($default);
2603 print " Alter $field in $table\n" unless $silent;
2609 <<<<<<< updatedatabase
2611 # Get list of columns from borrowers table
2614 $sth = $dbh->prepare("show columns from borrowers");
2616 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2618 $itemtypes{$column} = $type;
2619 $nullenabled{$column} = $null;
2622 unless ( $itemtypes{'cardnumber'} eq 'varchar(20)' ) {
2623 $itemtypes{'cardnumber'} =~ /varchar\((\d+)\)/;
2625 if ( $oldlength < 16 ) {
2627 "Setting maximum cardnumber length to 16 (was $oldlength) and marking unique.\n"
2631 "alter table borrowers change cardnumber cardnumber varchar(16)");
2634 $sti = $dbh->prepare("alter table borrowers drop index cardnumber");
2637 $sti = $dbh->prepare("alter table borrowers add unique(cardnumber)");
2644 # Get list of columns from items table
2645 $sth = $dbh->prepare("show columns from items");
2647 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2649 $itemtypes{$column} = $type;
2650 $nullenabled{$column} = $null;
2653 unless ( $itemtypes{'barcode'} eq 'varchar(20)' ) {
2654 $itemtypes{'barcode'} =~ /varchar\((\d+)\)/;
2656 if ( $oldlength < 20 ) {
2657 print "Setting maximum barcode length to 20 (was $oldlength).\n"
2660 $dbh->prepare("alter table items change barcode barcode varchar(20)");
2666 # dropping unique barcode index & setting barcode to null allowed.
2668 $sth = $dbh->prepare("show index from items");
2672 $table, $non_unique, $key_name, $Seq_in_index,
2673 $Column_name, $Collation, $cardinality, $sub_part,
2679 if ( $key_name eq 'barcode' && $non_unique eq 0 ) {
2680 print "dropping BARCODE index to enable empty barcodes\n"
2682 $dbh->do("ALTER TABLE `items` DROP INDEX `barcode`");
2685 $dbh->do("ALTER TABLE `items` CHANGE `barcode` `barcode` VARCHAR( 20 )")
2686 unless ( $nullenabled{barcode} eq 'YES' );
2689 # creating fulltext index in bibliothesaurus if needed
2691 $sth = $dbh->prepare("show index from bibliothesaurus");
2696 $table, $non_unique, $key_name, $Seq_in_index,
2697 $Column_name, $Collation, $cardinality, $sub_part,
2703 if ( $key_name eq 'category_2' ) {
2707 print "Creating fulltext index on bibliothesaurus\n" unless $exists or $silent;
2709 'create fulltext index category_2 on bibliothesaurus (category,freelib)')
2713 # creating index in z3950results if needed
2715 $sth = $dbh->prepare("show index from z3950results");
2720 $table, $non_unique, $key_name, $Seq_in_index,
2721 $Column_name, $Collation, $cardinality, $sub_part,
2727 if ( $key_name eq 'query_server' ) {
2731 print "Creating index on z3950results\n" unless $exists or $silent;
2732 $dbh->do('create unique index query_server on z3950results (queryid,server)')
2735 # changing z3950daemon field to NULL in marc_breeding
2737 "ALTER TABLE `marc_breeding` CHANGE `z3950random` `z3950random` VARCHAR( 40 )"
2740 # making borrowernumber an auto_increment field
2742 "ALTER TABLE `borrowers` CHANGE `borrowernumber` `borrowernumber` INTEGER auto_increment"
2745 # changing indexes in marc_*_structure to use frameworkcode
2746 $dbh->do('alter table marc_subfield_structure drop index tab');
2747 $dbh->do('create index tab on marc_subfield_structure (frameworkcode,tab)');
2748 $dbh->do('alter table marc_subfield_structure drop index kohafield');
2750 'create index kohafield on marc_subfield_structure (frameworkcode,kohafield)'
2753 # extending the timestamp in branchtransfers...
2754 my %branchtransfers;
2756 $sth = $dbh->prepare("show columns from branchtransfers");
2758 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2760 $branchtransfers{$column} = $type;
2763 unless ( $branchtransfers{'datesent'} eq 'datetime' ) {
2764 print "Setting type of datesent in branchtransfers to datetime.\n"
2768 "alter table branchtransfers change datesent datesent datetime");
2772 unless ( $branchtransfers{'datearrived'} eq 'datetime' ) {
2773 print "Setting type of datearrived in branchtransfers to datetime.\n"
2777 "alter table branchtransfers change datearrived datearrived datetime");
2781 # changing the branchcategories table around...
2782 my %branchcategories;
2784 $sth = $dbh->prepare("show columns from branchcategories");
2786 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2788 $branchcategories{$column} = $type;
2791 unless ( $branchcategories{'categorycode'} eq 'varchar(4)' ) {
2793 "Setting type of categorycode in branchcategories to varchar(4),\n and making the primary key.\n"
2797 "alter table branchcategories change categorycode categorycode varchar(4) not null"
2802 "alter table branchcategories add primary key (categorycode)");
2806 unless ( $branchcategories{'categoryname'} eq 'text' ) {
2807 print "Changing branchcode in branchcategories to categoryname text.\n"
2811 "alter table branchcategories change branchcode categoryname text");
2815 unless ( $branchcategories{'codedescription'} eq 'text' ) {
2817 "Replacing branchholding in branchcategories with codedescription text.\n"
2821 "alter table branchcategories change branchholding codedescription text"
2826 # changing the items table around...
2829 $sth = $dbh->prepare("show columns from items");
2831 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2833 $items{$column} = $type;
2836 if ( $items{'bulk'} eq "varchar(30)" ) {
2837 print " Setting callnumber in items table\n" unless $silent;
2840 "ALTER TABLE `items` CHANGE `bulk` `itemcallnumber` VARCHAR( 30 ) DEFAULT NULL"
2845 "update marc_subfield_structure set kohafield=\"items.itemcallnumber\" where kohafield=\"items.bulk\""
2850 # changing the marc_subfield_structure table around...
2851 my %marc_subfield_structure;
2853 $sth = $dbh->prepare("show columns from marc_subfield_structure");
2855 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2857 $marc_subfield_structure{$column} = $type;
2860 if ( $marc_subfield_structure{thesaurus_category} ) {
2861 print " changing thesaurus_category in marc_subfield_structure table\n"
2865 "ALTER TABLE marc_subfield_structure CHANGE `thesaurus_category` `authtypecode` VARCHAR(10 ) DEFAULT NULL"
2871 # creating index in issuingrules if needed
2873 $sth = $dbh->prepare("show index from issuingrules");
2878 $table, $non_unique, $key_name, $Seq_in_index,
2879 $Column_name, $Collation, $cardinality, $sub_part,
2885 if ( $key_name eq 'PRIMARY' ) {
2889 print "Creating index on issuing rules\n" unless $exists or $silent;
2891 'ALTER TABLE issuingrules ADD PRIMARY KEY ( branchcode, categorycode, itemtype )'
2895 $dbh->do('ALTER TABLE marc_tag_structure drop primary key');
2897 'ALTER TABLE marc_tag_structure ADD PRIMARY KEY ( frameworkcode, tagfield )'
2900 $dbh->do('ALTER TABLE marc_subfield_structure drop primary key');
2902 'ALTER TABLE marc_subfield_structure ADD PRIMARY KEY ( frameworkcode, tagfield, tagsubfield )'
2906 "alter table marc_subfield_table change tagorder tagorder int not null default '1'"
2909 # Get list of columns from marc_word table
2912 $sth = $dbh->prepare("show columns from marc_word");
2914 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2916 $marc_word{$column} = $type;
2917 $nullenabled{$column} = $null;
2919 if ( $marc_word{subfieldid} ) {
2921 #create field tagsubfield, copy tag+subfieldid, then drop tag and subfieldid
2922 print "Modifying marc_word (concat on tag and subfield for better perfs)\n"
2925 "ALTER TABLE `marc_word` ADD `tagsubfield` CHAR( 4 ) NOT NULL AFTER `bibid`"
2927 $dbh->do("update marc_word set tagsubfield=concat(tag,subfieldid)");
2928 $dbh->do("alter table marc_word drop tag");
2929 $dbh->do("alter table marc_word drop subfieldid");
2930 $dbh->do("create index Search_Marc on marc_word (tagsubfield,word)");
2934 # Populate tables with required data
2936 # synch table and deletedtable.
2937 foreach my $table ( ( 'borrowers', 'items', 'biblio', 'biblioitems' ) ) {
2938 my %deletedborrowers;
2939 print "synch'ing $table\n";
2940 $sth = $dbh->prepare("show columns from deleted$table");
2942 while ( my ( $column, $type, $null, $key, $default, $extra ) =
2945 $deletedborrowers{$column} = 1;
2947 $sth = $dbh->prepare("show columns from $table");
2950 while ( my ( $column, $type, $null, $key, $default, $extra ) =
2953 unless ( $deletedborrowers{$column} ) {
2954 my $newcol = "alter table deleted$table add $column $type";
2955 if ( $null eq 'YES' ) {
2956 $newcol .= " NULL ";
2959 $newcol .= " NOT NULL ";
2961 $newcol .= "default $default" if $default;
2962 $newcol .= " after $previous" if $previous;
2963 $previous = $column;
2964 print "creating column $column\n";
2970 <<<<<<< updatedatabase
2972 # fill aqbasket if it's empty and aqorder is not
2973 # => it means it has just been created & must be filled
2974 $sth = $dbh->prepare("select count(*) from aqbasket");
2976 if ( $sth->fetchrow == 0 ) {
2977 $sth = $dbh->prepare("select count(*) from aqorders");
2979 if ( $sth->fetchrow > 0 ) {
2980 print "Populating new table aqbasket\n";
2982 "IMPORTANT NOTE: error message \"Duplicate entry 'X' for key 1\" may appear. it should not be a real trouble\n";
2985 "select distinct basketno,booksellerid,authorisedby,entrydate,booksellerinvoicenumber from aqorders"
2988 my ( $basketno, $booksellerid, $authorisedby, $entrydate,
2989 $booksellerinvoicenumber );
2992 "insert into aqbasket (basketno,creationdate,booksellerid,authorisedby,booksellerinvoicenumber) values (?,?,?,?,?)"
2996 $basketno, $booksellerid,
2997 $authorisedby, $entrydate,
2998 $booksellerinvoicenumber
3004 "$basketno,$entrydate,$booksellerid,$authorisedby,$booksellerinvoicenumber\n";
3005 $sth2->execute( $basketno, $entrydate, $booksellerid, $authorisedby,
3006 $booksellerinvoicenumber );
3011 foreach my $table ( keys %tabledata ) {
3012 print "Checking for data required in table $table...\n" unless $silent;
3013 my $tablerows = $tabledata{$table};
3014 foreach my $row (@$tablerows) {
3015 my $uniquefieldrequired = $row->{uniquefieldrequired};
3016 my $uniquevalue = $row->{$uniquefieldrequired};
3017 my $forceupdate = $row->{forceupdate};
3020 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
3022 $sth->execute($uniquevalue);
3023 <<<<<<< updatedatabase
3025 foreach my $field (keys %$forceupdate) {
3026 if ($forceupdate->{$field}) {
3027 my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
3028 $sth->execute($row->{$field}, $uniquevalue);
3032 print "Adding row to $table: " unless $silent;
3036 foreach my $field ( keys %$row ) {
3037 next if $field eq 'uniquefieldrequired';
3038 next if $field eq 'forceupdate';
3039 my $value = $row->{$field};
3040 push @values, $value;
3041 print " $field => $value" unless $silent;
3042 $fieldlist .= "$field,";
3043 $placeholders .= "?,";
3045 print "\n" unless $silent;
3046 $fieldlist =~ s/,$//;
3047 $placeholders =~ s/,$//;
3050 "insert into $table ($fieldlist) values ($placeholders)");
3051 $sth->execute(@values);
3057 # check indexes and create them when needed
3059 print "Checking for index required...\n" unless $silent;
3060 foreach my $table ( keys %indexes ) {
3062 # read all indexes from $table
3064 $sth = $dbh->prepare("show index from $table");
3066 my %existingindexes;
3067 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
3068 $existingindexes{$key_name} = 1;
3070 # read indexes to check
3071 my $tablerows = $indexes{$table};
3072 foreach my $row (@$tablerows) {
3073 my $key_name=$row->{indexname};
3074 if ($existingindexes{$key_name} eq 1) {
3075 # print "$key_name existing";
3077 print "\tCreating index $key_name in $table\n";
3079 if ($row->{indexname} eq 'PRIMARY') {
3080 $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
3082 $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
3085 print "Error $sql : $dbh->err \n" if $dbh->err;
3091 # check foreign keys and create them when needed
3093 print "Checking for foreign keys required...\n" unless $silent;
3094 foreach my $table ( keys %foreign_keys ) {
3096 # read all indexes from $table
3098 $sth = $dbh->prepare("show table status like '$table'");
3100 my $stat = $sth->fetchrow_hashref;
3101 # read indexes to check
3102 my $tablerows = $foreign_keys{$table};
3103 foreach my $row (@$tablerows) {
3104 my $foreign_table=$row->{foreigntable};
3105 if ($stat->{'Comment'} =~/$foreign_table/) {
3106 # print "$foreign_table existing\n";
3108 print "\tCreating foreign key $foreign_table in $table\n";
3109 # first, drop any orphan value in child table
3110 if ($row->{onDelete} ne "RESTRICT") {
3111 my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
3113 print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
3115 my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
3116 $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
3117 $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
3120 print "====================
3121 An error occured during :
3123 It probably means there is something wrong in your DB : a row ($table.$row->{key}) refers to a value in $row->{foreigntable}.$row->{foreignkey} that does not exist. solve the problem and run updater again (or just the previous SQL statement).
3124 You can find those values with select
3125 \t$table.* from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})
3126 ====================\n
3137 # create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
3140 # 1st, get how many biblio we will have to do...
3141 $sth = $dbh->prepare('select count(*) from marc_biblio');
3143 my ($totaltodo) = $sth->fetchrow;
3145 $sth = $dbh->prepare("show columns from biblio");
3148 my $bibliofwexist=0;
3149 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3150 $bibliofwexist=1 if $column eq 'frameworkcode';
3152 unless ($bibliofwexist) {
3153 print "moving biblioframework to biblio table\n";
3154 $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
3155 $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
3157 my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
3159 while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
3160 $sth_update->execute($frameworkcode,$biblionumber);
3162 print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3168 # moving MARC data from marc_subfield_table to biblioitems.marc
3170 $sth = $dbh->prepare("show columns from biblioitems");
3174 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3175 $marcdone=1 if ($type eq 'blob' && $column eq 'marc') ;
3177 unless ($marcdone) {
3178 print "moving MARC record to biblioitems table\n";
3179 # changing marc field type
3180 $dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` BLOB NULL DEFAULT NULL ');
3181 # adding marc xml, just for convenience
3182 $dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ');
3183 # moving data from marc_subfield_value to biblio
3184 $sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
3186 my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
3188 while (my ($bibid,$biblionumber) = $sth->fetchrow) {
3189 my $record = MARCgetbiblio($dbh,$bibid);
3190 #Force UTF-8 in record leader
3191 $record->encoding('UTF-8');
3192 print $record->as_formatted if ($biblionumber==3902);
3193 $sth_update->execute($record->as_usmarc(),$record->as_xml_record(),$biblionumber);
3195 print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3200 foreach my $field ( keys %$forceupdate ) {
3201 if ( $forceupdate->{$field} ) {
3204 "update systempreferences set $field=? where $uniquefieldrequired=?"
3206 $sth->execute( $row->{$field}, $uniquevalue );
3211 print "Adding row to $table: " unless $silent;
3215 foreach my $field ( keys %$row ) {
3216 next if $field eq 'uniquefieldrequired';
3217 next if $field eq 'forceupdate';
3218 my $value = $row->{$field};
3219 push @values, $value;
3220 print " $field => $value" unless $silent;
3221 $fieldlist .= "$field,";
3222 $placeholders .= "?,";
3224 print "\n" unless $silent;
3225 $fieldlist =~ s/,$//;
3226 $placeholders =~ s/,$//;
3229 "insert into $table ($fieldlist) values ($placeholders)");
3230 $sth->execute(@values);
3237 # at last, remove useless fields
3238 foreach $table ( keys %uselessfields ) {
3239 my @fields = split /,/, $uselessfields{$table};
3242 foreach my $fieldtodrop (@fields) {
3243 $fieldtodrop =~ s/\t//g;
3244 $fieldtodrop =~ s/\n//g;
3246 $sth = $dbh->prepare("show columns from $table");
3248 while ( my ( $column, $type, $null, $key, $default, $extra ) =
3251 $exists = 1 if ( $column eq $fieldtodrop );
3254 print "deleting $fieldtodrop field in $table...\n" unless $silent;
3255 my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
3261 <<<<<<< updatedatabase
3263 # MOVE all tables TO UTF-8 and innoDB
3264 $sth = $dbh->prepare("show table status");
3266 while ( my $table = $sth->fetchrow_hashref ) {
3267 # if ($table->{Engine} ne 'InnoDB') {
3268 # $dbh->do("ALTER TABLE $table->{Name} TYPE = innodb");
3269 # print "moving $table->{Name} to InnoDB\n";
3271 unless ($table->{Collation} =~ /^utf8/) {
3272 $dbh->do("ALTER TABLE $table->{Name} CONVERT TO CHARACTER SET utf8");
3273 $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
3274 # FIXME : maybe a ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 would be better, def char set seems to work fine. If any problem encountered, let's try with convert !
3275 print "moving $table->{Name} to utf8\n";
3285 # those 2 subs are a copy of Biblio.pm, version 2.2.4
3286 # they are useful only once, for moving from 2.2 to 3.0
3287 # the MARCgetbiblio & MARCgetitem subs in Biblio.pm
3288 # are still here, but uses other tables
3289 # (the ones that are filled by updatedatabase !)
3294 # Returns MARC::Record of the biblio passed in parameter.
3295 my ( $dbh, $bibid ) = @_;
3296 my $record = MARC::Record->new();
3301 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
3302 from marc_subfield_table
3303 where bibid=? order by tag,tagorder,subfieldorder
3308 "select subfieldvalue from marc_blob_subfield where blobidlink=?");
3309 $sth->execute($bibid);
3310 my $prevtagorder = 1;
3311 my $prevtag = 'XXX';
3313 my $field; # for >=10 tags
3314 my $prevvalue; # for <10 tags
3315 while ( my $row = $sth->fetchrow_hashref ) {
3317 if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
3318 $sth2->execute( $row->{'valuebloblink'} );
3319 my $row2 = $sth2->fetchrow_hashref;
3321 $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
3323 if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
3324 $previndicator .= " ";
3325 if ( $prevtag < 10 ) {
3326 if ($prevtag ne '000') {
3327 $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX"; # ignore the 1st loop
3329 $record->leader(sprintf("%24s",$prevvalue));
3333 $record->add_fields($field) unless $prevtag eq "XXX";
3336 $prevtagorder = $row->{tagorder};
3337 $prevtag = $row->{tag};
3338 $previndicator = $row->{tag_indicator};
3339 if ( $row->{tag} < 10 ) {
3340 $prevvalue = $row->{subfieldvalue};
3343 $field = MARC::Field->new(
3344 ( sprintf "%03s", $prevtag ),
3345 substr( $row->{tag_indicator} . ' ', 0, 1 ),
3346 substr( $row->{tag_indicator} . ' ', 1, 1 ),
3347 $row->{'subfieldcode'},
3348 $row->{'subfieldvalue'}
3353 if ( $row->{tag} < 10 ) {
3354 $record->add_fields( ( sprintf "%03s", $row->{tag} ),
3355 $row->{'subfieldvalue'} );
3358 $field->add_subfields( $row->{'subfieldcode'},
3359 $row->{'subfieldvalue'} );
3361 $prevtag = $row->{tag};
3362 $previndicator = $row->{tag_indicator};
3366 # the last has not been included inside the loop... do it now !
3367 if ( $prevtag ne "XXX" )
3368 { # check that we have found something. Otherwise, prevtag is still XXX and we
3369 # must return an empty record, not make MARC::Record fail beca