Bug 21899: Update MARC21 frameworks to Update 27 (November 2018)
[koha.git] / installer / data / mysql / update22to30.pl
blobd38f080bcccc389b30e41419ac992b0536c2c538
1 #!/usr/bin/perl
4 # Database Updater
5 # This script checks for required updates to the database.
7 # Part of the Koha Library Software www.koha-community.org
8 # Licensed under the GPL.
10 # Bugs/ToDo:
11 # - Would also be a good idea to offer to do a backup at this time...
13 # NOTE: If you do something more than once in here, make it table driven.
14 use strict;
16 # CPAN modules
17 use DBI;
18 use Getopt::Long;
19 # Koha modules
20 use C4::Context;
22 use MARC::Record;
23 use MARC::File::XML ( BinaryEncoding => 'utf8' );
25 # FIXME - The user might be installing a new database, so can't rely
26 # on /etc/koha.conf anyway.
28 my $debug = 0;
30 my (
31 $sth, $sti,
32 $query,
33 %existingtables, # tables already in database
34 %types,
35 $table,
36 $column,
37 $type, $null, $key, $default, $extra,
38 $prefitem, # preference item in systempreferences table
41 my $silent;
42 GetOptions(
43 's' =>\$silent
45 my $dbh = C4::Context->dbh;
46 $|=1; # flushes output
48 my $DBversion = "3.00.00.000";
49 # if we are upgrading from Koha 2.2, then we need to run the complete & long updatedatabase
50 # Tables to add if they don't exist
51 my %requiretables = (
52 action_logs => "(
53 `timestamp` TIMESTAMP NOT NULL ,
54 `user` INT( 11 ) NOT NULL default '0' ,
55 `module` TEXT default '',
56 `action` TEXT default '' ,
57 `object` INT(11) NULL ,
58 `info` TEXT default '' ,
59 PRIMARY KEY ( `timestamp` , `user` )
60 )",
61 letter => "(
62 module varchar(20) NOT NULL default '',
63 code varchar(20) NOT NULL default '',
64 name varchar(100) NOT NULL default '',
65 title varchar(200) NOT NULL default '',
66 content text,
67 PRIMARY KEY (module,code)
68 )",
69 alert =>"(
70 alertid int(11) NOT NULL auto_increment,
71 borrowernumber int(11) NOT NULL default '0',
72 type varchar(10) NOT NULL default '',
73 externalid varchar(20) NOT NULL default '',
74 PRIMARY KEY (alertid),
75 KEY borrowernumber (borrowernumber),
76 KEY type (type,externalid)
77 )",
78 opac_news => "(
79 `idnew` int(10) unsigned NOT NULL auto_increment,
80 `title` varchar(250) NOT NULL default '',
81 `new` text NOT NULL,
82 `lang` varchar(4) NOT NULL default '',
83 `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
84 PRIMARY KEY (`idnew`)
85 )",
86 repeatable_holidays => "(
87 `id` int(11) NOT NULL auto_increment,
88 `branchcode` varchar(10) NOT NULL default '',
89 `weekday` smallint(6) default NULL,
90 `day` smallint(6) default NULL,
91 `month` smallint(6) default NULL,
92 `title` varchar(50) NOT NULL default '',
93 `description` text NOT NULL,
94 PRIMARY KEY (`id`)
95 )",
96 special_holidays => "(
97 `id` int(11) NOT NULL auto_increment,
98 `branchcode` varchar(10) NOT NULL default '',
99 `day` smallint(6) NOT NULL default '0',
100 `month` smallint(6) NOT NULL default '0',
101 `year` smallint(6) NOT NULL default '0',
102 `isexception` smallint(1) NOT NULL default '1',
103 `title` varchar(50) NOT NULL default '',
104 `description` text NOT NULL,
105 PRIMARY KEY (`id`)
107 overduerules =>"(`branchcode` varchar(10) NOT NULL default '',
108 `categorycode` varchar(2) NOT NULL default '',
109 `delay1` int(4) default '0',
110 `letter1` varchar(20) default NULL,
111 `debarred1` varchar(1) default '0',
112 `delay2` int(4) default '0',
113 `debarred2` varchar(1) default '0',
114 `letter2` varchar(20) default NULL,
115 `delay3` int(4) default '0',
116 `letter3` varchar(20) default NULL,
117 `debarred3` int(1) default '0',
118 PRIMARY KEY (`branchcode`,`categorycode`)
120 cities => "(`cityid` int auto_increment,
121 `city_name` varchar(100) NOT NULL default '',
122 `city_zipcode` varchar(20),
123 PRIMARY KEY (`cityid`)
125 roadtype => "(`roadtypeid` int auto_increment,
126 `road_type` varchar(100) NOT NULL default '',
127 PRIMARY KEY (`roadtypeid`)
130 labels => "(
131 labelid int(11) NOT NULL auto_increment,
132 batch_id varchar(10) NOT NULL default '1',
133 itemnumber varchar(100) NOT NULL default '',
134 timestamp timestamp(14) NOT NULL,
135 PRIMARY KEY (labelid)
138 labels_conf => "(
139 id int(4) NOT NULL auto_increment,
140 barcodetype char(100) default '',
141 title int(1) default '0',
142 subtitle int(1) default '0',
143 itemtype int(1) default '0',
144 barcode int(1) default '0',
145 dewey int(1) default '0',
146 class int(1) default '0',
147 subclass int(1) default '0',
148 itemcallnumber int(1) default '0',
149 author int(1) default '0',
150 issn int(1) default '0',
151 isbn int(1) default '0',
152 startlabel int(2) NOT NULL default '1',
153 printingtype char(32) default 'BAR',
154 layoutname char(20) NOT NULL default 'TEST',
155 guidebox int(1) default '0',
156 active tinyint(1) default '1',
157 fonttype char(10) collate utf8_unicode_ci default NULL,
158 ccode char(4) collate utf8_unicode_ci default NULL,
159 callnum_split int(1) default NULL,
160 text_justify char(1) collate utf8_unicode_ci default NULL,
161 PRIMARY KEY (id)
163 reviews => "(
164 reviewid integer NOT NULL auto_increment,
165 borrowernumber integer,
166 biblionumber integer,
167 review text,
168 approved tinyint,
169 datereviewed datetime,
170 PRIMARY KEY (reviewid)
172 subscriptionroutinglist=>"(
173 routingid integer NOT NULL auto_increment,
174 borrowernumber integer,
175 ranking integer,
176 subscriptionid integer,
177 PRIMARY KEY (routingid)
180 notifys => "(
181 notify_id int(11) NOT NULL default '0',
182 `borrowernumber` int(11) NOT NULL default '0',
183 `itemnumber` int(11) NOT NULL default '0',
184 `notify_date` date default NULL,
185 `notify_send_date` date default NULL,
186 `notify_level` int(1) NOT NULL default '0',
187 `method` varchar(20) NOT NULL default ''
190 charges => "(
191 `charge_id` varchar(5) NOT NULL default '',
192 `description` text NOT NULL,
193 `amount` decimal(28,6) NOT NULL default '0.000000',
194 `min` int(4) NOT NULL default '0',
195 `max` int(4) NOT NULL default '0',
196 `level` int(1) NOT NULL default '0',
197 PRIMARY KEY (`charge_id`)
199 tags => "(
200 `entry` varchar(255) NOT NULL default '',
201 `weight` bigint(20) NOT NULL default '0',
202 PRIMARY KEY (`entry`)
205 zebraqueue => "(
206 `id` int NOT NULL auto_increment,
207 `biblio_auth_number` int(11) NOT NULL default '0',
208 `operation` char(20) NOT NULL default '',
209 `server` char(20) NOT NULL default '',
210 PRIMARY KEY (`id`)
211 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1",
215 my %requirefields = (
216 subscription => { 'letter' => 'varchar(20) NULL', 'distributedto' => 'text NULL', 'firstacquidate'=>'date default NULL','irregularity'=>'TEXT NULL default \'\'','numberpattern'=>'TINYINT(3) NULL default 0', 'callnumber'=>'text NULL', 'hemisphere' =>'TINYINT(3) NULL default 0', 'issuesatonce'=>'TINYINT(3) NOT NULL default 1', 'branchcode' =>'varchar(10) NOT NULL default \'\'', 'manualhistory'=>'TINYINT(1) NOT NULL default 0','internalnotes'=>'LONGTEXT NULL default \'\''},
217 itemtypes => { 'imageurl' => 'varchar(200) NULL'},
218 aqbookfund => { 'branchcode' => 'varchar(4) NULL'},
219 aqbudget => { 'branchcode' => 'varchar(4) NULL'},
220 auth_header => { 'marc' => 'BLOB NOT NULL', 'linkid' => 'BIGINT(20) NULL'},
221 auth_subfield_structure =>{ 'hidden' => 'TINYINT(3) NOT NULL default 0', 'kohafield' => "VARCHAR(45) NULL default ''", 'linkid' => 'TINYINT(1) NOT NULL default 0', 'isurl' => 'TINYINT(1)', 'frameworkcode'=>'VARCHAR(8) NOT NULL'},
222 marc_breeding => { 'isbn' => 'varchar(13) NOT NULL'},
223 serial =>{ 'publisheddate' => 'date AFTER planneddate', 'claimdate' => 'date', 'itemnumber'=>'text NULL','routingnotes'=>'text NULL',},
224 statistics => { 'associatedborrower' => 'integer'},
225 z3950servers =>{ "name" =>"text", "description" => "text NOT NULL",
226 "position" =>"enum('primary','secondary','') NOT NULL default 'primary'", "icon" =>"text",
227 "type" =>"enum('zed','opensearch') NOT NULL default 'zed'",
229 issues =>{ 'issuedate'=>"date NULL default NULL", },
231 # tablename => { 'field' => 'fieldtype' },
234 # Enter here the table to delete.
235 my @TableToDelete = qw(
236 additionalauthors
237 bibliosubject
238 bibliosubtitle
239 bibliothesaurus
242 my %uselessfields = (
243 # tablename => "field1,field2",
244 borrowers => "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
245 deletedborrowers=> "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
246 items => "multivolumepart,multivolume,binding",
247 deleteditems => "multivolumepart,multivolume,binding",
249 # the other hash contains other actions that can't be done elsewhere. they are done
250 # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
252 # The tabledata hash contains data that should be in the tables.
253 # The uniquefieldrequired hash entry is used to determine which (if any) fields
254 # must not exist in the table for this row to be inserted. If the
255 # uniquefieldrequired entry is already in the table, the existing data is not
256 # modified, unless the forceupdate hash entry is also set. Fields in the
257 # anonymous "forceupdate" hash will be forced to be updated to the default
258 # values given in the %tabledata hash.
260 my %tabledata = (
261 # tablename => [
262 # { uniquefielrequired => 'fieldname', # the primary key in the table
263 # fieldname => fieldvalue,
264 # fieldname2 => fieldvalue2,
265 # },
266 # ],
267 systempreferences => [
269 uniquefieldrequired => 'variable',
270 variable => 'useDaysMode',
271 value => 'Calendar',
272 forceupdate => { 'explanation' => 1,
273 'type' => 1},
274 explanation => 'Choose the method for calculating due date: select Calendar to use the holidays module, and Days to ignore the holidays module',
275 type => 'Choice',
276 options => 'Calendar|Days|Datedue'
279 uniquefieldrequired => 'variable',
280 variable => 'DebugLevel',
281 value => '0',
282 forceupdate => { 'explanation' => 1,
283 'type' => 1},
284 explanation => 'Set the level of error info sent to the browser. 0=none, 1=some, 2=most',
285 type => 'Choice',
286 options => '0|1|2'
289 uniquefieldrequired => 'variable',
290 variable => 'BorrowersTitles',
291 value => 'Mr|Mrs|Miss|Ms',
292 forceupdate => { 'explanation' => 1,
293 'type' => 1},
294 explanation => 'List all Titles for borrowers',
295 type => 'free',
298 uniquefieldrequired => 'variable',
299 variable => 'BorrowerMandatoryField',
300 value => 'cardnumber|surname|address',
301 forceupdate => { 'explanation' => 1,
302 'type' => 1},
303 explanation => 'List all mandatory fields for borrowers',
304 type => 'free',
307 uniquefieldrequired => 'variable',
308 variable => 'borrowerRelationship',
309 value => 'father|mother,grand-mother',
310 forceupdate => { 'explanation' => 1,
311 'type' => 1},
312 explanation => 'The relationships between a guarantor & a guarantee (separated by | or ,)',
313 type => 'free',
316 uniquefieldrequired => 'variable',
317 variable => 'ReservesMaxPickUpDelay',
318 value => '10',
319 forceupdate => { 'explanation' => 1,
320 'type' => 1},
321 explanation => 'Maximum delay to pick up a reserved document',
322 type => 'free',
325 uniquefieldrequired => 'variable',
326 variable => 'TransfersMaxDaysWarning',
327 value => '3',
328 forceupdate => { 'explanation' => 1,
329 'type' => 1},
330 explanation => 'Max delay before considering the transfer has potentialy a problem',
331 type => 'free',
334 uniquefieldrequired => 'variable',
335 variable => 'memberofinstitution',
336 value => '0',
337 forceupdate => { 'explanation' => 1,
338 'type' => 1},
339 explanation => 'Are your patrons members of institutions',
340 type => 'YesNo',
343 uniquefieldrequired => 'variable',
344 variable => 'ReadingHistory',
345 value => '0',
346 forceupdate => { 'explanation' => 1,
347 'type' => 1},
348 explanation => 'Allow reading record info retrievable from issues and oldissues tables',
349 type => 'YesNo',
352 uniquefieldrequired => 'variable',
353 variable => 'IssuingInProcess',
354 value => '0',
355 forceupdate => { 'explanation' => 1,
356 'type' => 1},
357 explanation => 'Allow no debt alert if the patron is issuing item that accumulate debt',
358 type => 'YesNo',
361 uniquefieldrequired => 'variable',
362 variable => 'AutomaticItemReturn',
363 value => '1',
364 forceupdate => { 'explanation' => 1,
365 'type' => 1},
366 explanation => 'This Variable allow or not to return automaticly to his homebranch',
367 type => 'YesNo',
370 uniquefieldrequired => 'variable',
371 variable => 'reviewson',
372 value => '0',
373 forceupdate => { 'explanation' => 1,
374 'type' => 1},
375 explanation => 'Allows patrons to submit reviews from the opac',
376 type => 'YesNo',
379 uniquefieldrequired => 'variable',
380 variable => 'intranet_includes',
381 value => 'includes',
382 forceupdate => { 'explanation' => 1,
383 'type' => 1},
384 explanation => 'The includes directory you want for specific look of Koha (includes or includes_npl for example)',
385 type => 'Free',
388 uniquefieldrequired => 'variable',
389 variable => 'AutoLocation',
390 value => '0',
391 forceupdate => { 'explanation' => 1,
392 'type' => 1},
393 explanation => 'switch to activate or not Autolocation, if Yes, the Librarian can\'t change his location, it\'s defined by branchip',
394 type => 'YesNo',
397 uniquefieldrequired => 'variable',
398 variable => 'serialsadditems',
399 value => '0',
400 forceupdate => {
401 'explanation' => 1,
402 'type' => 1
404 explanation => 'If set, a new item will be automatically added when receiving an issue',
405 type => 'YesNo',
408 uniquefieldrequired => 'variable',
409 variable => 'expandedSearchOption',
410 value => '0',
411 forceupdate => {
412 'explanation' => 1,
413 'type' => 1
415 explanation => 'search among marc field',
416 type => 'YesNo',
419 uniquefieldrequired => 'variable',
420 variable => 'RequestOnOpac',
421 value => '1',
422 forceupdate => { 'explanation' => 1,
423 'type' => 1},
424 explanation => 'option to allow reserves on opac',
425 type => 'YesNo',
428 uniquefieldrequired => 'variable',
429 variable => 'OpacCloud',
430 value => '1',
431 forceupdate => { 'explanation' => 1,
432 'type' => 1},
433 explanation => 'Enable / Disable cloud link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
434 type => 'YesNo',
437 uniquefieldrequired => 'variable',
438 variable => 'OpacBrowser',
439 value => '1',
440 forceupdate => { 'explanation' => 1,
441 'type' => 1},
442 explanation => 'Enable/Disable browser link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
443 type => 'YesNo',
446 uniquefieldrequired => 'variable',
447 variable => 'OpacTopissue',
448 value => '0',
449 forceupdate => { 'explanation' => 1,
450 'type' => 1},
451 explanation => 'If ON, enables the \'most popular items\' link on OPAC. Warning, this is an EXPERIMENTAL feature, turning ON may overload your server',
452 type => 'YesNo',
455 uniquefieldrequired => 'variable',
456 variable => 'OpacAuthorities',
457 value => '1',
458 forceupdate => { 'explanation' => 1,
459 'type' => 1},
460 explanation => 'Enable / Disable the search authority link on OPAC',
461 type => 'YesNo',
464 uniquefieldrequired => 'variable',
465 variable => 'CataloguingLog',
466 value => '0',
467 forceupdate => {'explanation' => 1, 'type' => 1},
468 explanation => 'Active this if you want to log cataloguing action.',
469 type => 'YesNo',
472 uniquefieldrequired => 'variable',
473 variable => 'BorrowersLog',
474 value => '0',
475 forceupdate => {'explanation' => 1, 'type' => 1},
476 explanation => 'Active this if you want to log borrowers edition/creation/deletion...',
477 type => 'YesNo',
480 uniquefieldrequired => 'variable',
481 variable => 'SubscriptionLog',
482 value => '0',
483 forceupdate => {'explanation' => 1, 'type' => 1},
484 explanation => 'Active this if you want to log Subscription action',
485 type => 'YesNo',
488 uniquefieldrequired => 'variable',
489 variable => 'IssueLog',
490 value => '0',
491 forceupdate => {'explanation' => 1, 'type' => 1},
492 explanation => 'Active this if you want to log issue.',
493 type => 'YesNo',
496 uniquefieldrequired => 'variable',
497 variable => 'ReturnLog',
498 value => '0',
499 forceupdate => {'explanation' => 1, 'type' => 1},
500 explanation => 'Active this if you want to log the circulation return',
501 type => 'YesNo',
504 uniquefieldrequired => 'variable',
505 variable => 'Version',
506 value => '3.0',
507 forceupdate => {'explanation' => 1, 'type' => 1},
508 explanation => 'Koha Version',
509 type => 'Free',
512 uniquefieldrequired => 'variable',
513 variable => 'LetterLog',
514 value => '0',
515 forceupdate => {'explanation' => 1, 'type' => 1},
516 explanation => 'Active this if you want to log all the letter sent',
517 type => 'YesNo',
520 uniquefieldrequired => 'variable',
521 variable => 'FinesLog',
522 value => '0',
523 forceupdate => {'explanation' => 1, 'type' => 1},
524 explanation => 'Active this if you want to log fines',
525 type => 'YesNo',
528 uniquefieldrequired => 'variable',
529 variable => 'NoZebra',
530 value => '0',
531 forceupdate => {'explanation' => 1, 'type' => 1},
532 explanation => 'Active this if you want NOT to use zebra (large libraries should avoid this parameters)',
533 type => 'YesNo',
536 uniquefieldrequired => 'variable',
537 variable => 'NoZebraIndexes',
538 value => '0',
539 forceupdate => {'explanation' => 1, 'type' => 1},
540 explanation => "Enter a specific hash for NoZebra indexes. Enter : 'indexname' => '100a,245a,500*','index2' => '...'",
541 type => 'Free',
544 uniquefieldrequired => 'variable',
545 variable => 'uppercasesurnames',
546 value => '0',
547 forceupdate => {'explanation' => 1, 'type' => 1},
548 explanation => "Force Surnames to be uppercase",
549 type => 'YesNo',
552 userflags => [
554 uniquefieldrequired => 'bit',
555 bit => '14',
556 flag => 'editauthorities',
557 flagdesc => 'allow to edit authorities',
558 defaulton => '0',
561 uniquefieldrequired => 'bit',
562 bit => '15',
563 flag => 'serials',
564 flagdesc => 'allow to manage serials subscriptions',
565 defaulton => '0',
568 uniquefieldrequired => 'bit',
569 bit => '16',
570 flag => 'reports',
571 flagdesc => 'allow to access to the reports module',
572 defaulton => '0',
575 authorised_values => [
577 uniquefieldrequired => 'id',
578 category => 'SUGGEST',
579 authorised_value => 'Not enough budget',
580 lib => 'This book it too much expensive',
585 my %fielddefinitions = (
586 # fieldname => [
587 # { field => 'fieldname',
588 # type => 'fieldtype',
589 # null => '',
590 # key => '',
591 # default => ''
592 # },
593 # ],
594 aqbasket => [
596 field => 'booksellerid',
597 type => 'int(11)',
598 null => 'NOT NULL',
599 key => '',
600 default => '1',
601 extra => '',
604 field => 'booksellerinvoicenumber',
605 type => 'mediumtext',
606 null => 'NULL',
607 key => '',
608 default => '',
609 extra => '',
612 aqbookfund => [
614 field => 'bookfundid',
615 type => 'varchar(10)',
616 null => 'NOT NULL',
617 key => '',
618 default => "''",
619 extra => '',
622 field => 'branchcode',
623 type => 'varchar(10)',
624 null => 'NOT NULL',
625 key => '',
626 default => "''",
627 extra => '',
630 field => 'bookfundname',
631 type => 'mediumtext',
632 null => 'NULL',
633 key => '',
634 default => '',
635 extra => '',
636 after => 'bookfundid',
640 aqbooksellers => [
642 field => 'id',
643 type => 'int(11)',
644 null => 'NOT NULL',
645 key => 'PRI',
646 default => '',
647 extra => 'auto_increment',
650 field => 'currency',
651 type => 'varchar(3)',
652 null => 'NOT NULL',
653 key => '',
654 default => "''",
655 extra => '',
658 field => 'listprice',
659 type => 'varchar(10)',
660 null => 'NULL',
661 key => '',
662 default => '',
663 extra => '',
666 field => 'invoiceprice',
667 type => 'varchar(10)',
668 null => 'NULL',
669 key => '',
670 default => '',
671 extra => '',
674 field => 'invoicedisc',
675 type => 'float(6,4)',
676 null => 'NULL',
677 key => '',
678 default => 'NULL',
679 extra => '',
682 field => 'address1',
683 type => 'mediumtext',
684 null => 'NULL',
685 key => '',
686 default => '',
687 extra => '',
690 field => 'address2',
691 type => 'mediumtext',
692 null => 'NULL',
693 key => '',
694 default => '',
695 extra => '',
698 field => 'address3',
699 type => 'mediumtext',
700 null => 'NULL',
701 key => '',
702 default => '',
703 extra => '',
706 field => 'address4',
707 type => 'mediumtext',
708 null => 'NULL',
709 key => '',
710 default => '',
711 extra => '',
714 field => 'accountnumber',
715 type => 'mediumtext',
716 null => 'NULL',
717 key => '',
718 default => '',
719 extra => '',
722 field => 'othersupplier',
723 type => 'mediumtext',
724 null => 'NULL',
725 key => '',
726 default => '',
727 extra => '',
730 field => 'specialty',
731 type => 'mediumtext',
732 null => 'NULL',
733 key => '',
734 default => '',
735 extra => '',
738 field => 'booksellerfax',
739 type => 'mediumtext',
740 null => 'NULL',
741 key => '',
742 default => '',
743 extra => '',
746 field => 'notes',
747 type => 'mediumtext',
748 null => 'NULL',
749 key => '',
750 default => '',
751 extra => '',
754 field => 'bookselleremail',
755 type => 'mediumtext',
756 null => 'NULL',
757 key => '',
758 default => '',
759 extra => '',
762 field => 'booksellerurl',
763 type => 'mediumtext',
764 null => 'NULL',
765 key => '',
766 default => '',
767 extra => '',
770 field => 'contnotes',
771 type => 'mediumtext',
772 null => 'NULL',
773 key => '',
774 default => '',
775 extra => '',
778 field => 'postal',
779 type => 'mediumtext',
780 null => 'NULL',
781 key => '',
782 default => '',
783 extra => '',
787 aqbudget => [
789 field => 'bookfundid',
790 type => 'varchar(10)',
791 null => 'NOT NULL',
792 key => '',
793 default => "''",
794 exra => '',
797 field => 'branchcode',
798 type => 'varchar(10)',
799 null => 'NULL',
800 key => '',
801 default => '',
802 exra => '',
806 aqorderbreakdown => [
808 field => 'bookfundid',
809 type => 'varchar(10)',
810 null => 'NOT NULL',
811 key => '',
812 default => "''",
813 exra => '',
816 field => 'branchcode',
817 type => 'varchar(10)',
818 null => 'NULL',
819 key => '',
820 default => '',
821 exra => '',
825 aqorderdelivery => [
827 field => 'ordernumber',
828 type => 'date',
829 null => 'NULL',
830 key => '',
831 default => 'NULL',
832 exra => '',
835 field => 'deliverycomments',
836 type => 'mediumtext',
837 null => 'NULL',
838 key => '',
839 default => '',
840 exra => '',
844 aqorders => [
846 field => 'title',
847 type => 'mediumtext',
848 null => 'NULL',
849 key => '',
850 default => '',
851 exra => '',
854 field => 'currency',
855 type => 'varchar(3)',
856 null => 'NULL',
857 key => '',
858 default => 'NULL',
859 exra => '',
862 field => 'booksellerinvoicenumber',
863 type => 'mediumtext',
864 null => 'NULL',
865 key => '',
866 default => '',
867 extra => '',
870 field => 'notes',
871 type => 'mediumtext',
872 null => 'NULL',
873 key => '',
874 default => '',
875 extra => '',
878 field => 'supplierreference',
879 type => 'mediumtext',
880 null => 'NULL',
881 key => '',
882 default => '',
883 extra => '',
886 field => 'purchaseordernumber',
887 type => 'mediumtext',
888 null => 'NULL',
889 key => '',
890 default => '',
891 extra => '',
895 accountlines => [
897 field => 'notify_id',
898 type => 'int(11)',
899 null => 'NOT NULL',
900 key => '',
901 default => '0',
902 extra => '',
905 field => 'notify_level',
906 type => 'int(2)',
907 null => 'NOT NULL',
908 key => '',
909 default => '0',
910 extra => '',
913 field => 'accountno',
914 type => 'smallint(6)',
915 null => 'NOT NULL',
916 key => '',
917 default => '0',
918 extra => '',
921 field => 'description',
922 type => 'mediumtext',
923 null => 'NULL',
926 field => 'dispute',
927 type => 'mediumtext',
928 null => 'NULL',
933 auth_header => [
935 field => 'authtypecode',
936 type => 'varchar(10)',
937 null => 'NOT NULL',
938 key => '',
939 default => "''",
940 extra => '',
943 field => 'datecreated',
944 type => 'date',
945 null => 'NULL',
946 key => '',
947 default => "NULL",
948 extra => '',
951 field => 'origincode',
952 type => 'varchar(20)',
953 null => 'NULL',
954 key => '',
955 default => "NULL",
956 extra => '',
959 field => 'authtrees',
960 type => 'mediumtext',
961 null => 'NULL',
962 key => '',
963 default => "",
964 extra => '',
965 after => 'origincode',
969 auth_subfield_structure => [
971 field => 'authtypecode',
972 type => 'varchar(10)',
973 null => 'NOT NULL',
974 key => '',
975 default => "''",
976 extra => '',
979 field => 'tagfield',
980 type => 'varchar(3)',
981 null => 'NOT NULL',
982 key => '',
983 default => "''",
984 extra => '',
987 field => 'tagsubfield',
988 type => 'varchar(1)',
989 null => 'NOT NULL',
990 key => '',
991 default => "''",
992 extra => '',
995 field => 'liblibrarian',
996 type => 'varchar(255)',
997 null => 'NOT NULL',
998 key => '',
999 default => "''",
1000 extra => '',
1003 field => 'libopac',
1004 type => 'varchar(255)',
1005 null => 'NOT NULL',
1006 key => '',
1007 default => "''",
1008 extra => '',
1011 field => 'authorised_value',
1012 type => 'varchar(10)',
1013 null => 'NULL',
1014 key => '',
1015 default => "NULL",
1016 extra => '',
1019 field => 'value_builder',
1020 type => 'varchar(80)',
1021 null => 'NULL',
1022 key => '',
1023 default => "NULL",
1024 extra => '',
1027 field => 'seealso',
1028 type => 'varchar(255)',
1029 null => 'NULL',
1030 key => '',
1031 default => "NULL",
1032 extra => '',
1035 field => 'kohafield',
1036 type => 'varchar(45)',
1037 null => 'NULL',
1038 key => '',
1039 default => "''",
1040 extra => '',
1043 field => 'frameworkcode',
1044 type => 'varchar(8)',
1045 null => 'NOT NULL',
1046 key => '',
1047 default => "''",
1048 extra => '',
1052 auth_tag_structure => [
1054 field => 'authtypecode',
1055 type => 'varchar(10)',
1056 null => 'NOT NULL',
1057 key => '',
1058 default => "''",
1059 extra => '',
1062 field => 'tagfield',
1063 type => 'varchar(3)',
1064 null => 'NOT NULL',
1065 key => '',
1066 default => "''",
1067 extra => '',
1070 field => 'liblibrarian',
1071 type => 'varchar(255)',
1072 null => 'NOT NULL',
1073 key => '',
1074 default => "''",
1075 extra => '',
1078 field => 'libopac',
1079 type => 'varchar(255)',
1080 null => 'NOT NULL',
1081 key => '',
1082 default => "''",
1083 extra => '',
1086 field => 'authorised_value',
1087 type => 'varchar(10)',
1088 null => 'NULL',
1089 key => '',
1090 default => "NULL",
1091 extra => '',
1095 auth_types => [
1097 field => 'auth_tag_to_report',
1098 type => 'varchar(3)',
1099 null => 'NOT NULL',
1100 key => '',
1101 default => "''",
1102 extra => '',
1105 field => 'summary',
1106 type => 'mediumtext',
1107 null => 'NOT NULL',
1108 key => '',
1109 default => '',
1110 extra => '',
1114 authorised_values => [
1116 field => 'category',
1117 type => 'varchar(10)',
1118 null => 'NOT NULL',
1119 key => '',
1120 default => "''",
1121 extra => '',
1124 field => 'authorised_value',
1125 type => 'varchar(80)',
1126 null => 'NOT NULL',
1127 key => '',
1128 default => "''",
1129 extra => '',
1132 field => 'lib',
1133 type => 'varchar(80)',
1134 null => 'NULL',
1135 key => '',
1136 default => 'NULL',
1137 extra => '',
1141 biblio_framework => [
1143 field => 'frameworkcode',
1144 type => 'varchar(4)',
1145 null => 'NOT NULL',
1146 key => '',
1147 default => "''",
1148 extra => '',
1151 field => 'frameworktext',
1152 type => 'varchar(255)',
1153 null => 'NOT NULL',
1154 key => '',
1155 default => "''",
1156 extra => '',
1160 borrowers => [
1162 field => 'cardnumber',
1163 type => 'varchar(16)',
1164 null => 'NULL',
1165 key => '',
1166 default => 'NULL',
1167 extra => '',
1169 { field => 'surname',
1170 type => 'mediumtext',
1171 null => 'NOT NULL',
1173 { field => 'firstname',
1174 type => 'text',
1175 null => 'NULL',
1177 { field => 'title',
1178 type => 'mediumtext',
1179 null => 'NULL',
1181 { field => 'othernames',
1182 type => 'mediumtext',
1183 null => 'NULL',
1185 { field => 'initials',
1186 type => 'text',
1187 null => 'NULL',
1189 { field => 'B_email',
1190 type => 'text',
1191 null => 'NULL',
1192 after => 'B_zipcode',
1195 field => 'streetnumber', # street number (hidden if streettable table is empty)
1196 type => 'varchar(10)',
1197 null => 'NULL',
1198 after => 'initials',
1201 field => 'streettype', # street table, list builded from a system table
1202 type => 'varchar(50)',
1203 null => 'NULL',
1204 after => 'streetnumber',
1206 { field => 'phone',
1207 type => 'text',
1208 null => 'NULL',
1211 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1212 type => 'varchar(10)',
1213 null => 'NULL',
1214 after => 'fax',
1217 field => 'B_streettype', # street table, list builded from a system table
1218 type => 'varchar(50)',
1219 null => 'NULL',
1220 after => 'B_streetnumber',
1223 field => 'phonepro',
1224 type => 'text',
1225 null => 'NULL',
1226 after => 'fax',
1229 field => 'address2', # complement address
1230 type => 'text',
1231 null => 'NULL',
1232 after => 'address',
1235 field => 'emailpro',
1236 type => 'text',
1237 null => 'NULL',
1238 after => 'fax',
1241 field => 'contactfirstname', # contact's firstname
1242 type => 'text',
1243 null => 'NULL',
1244 after => 'contactname',
1247 field => 'contacttitle', # contact's title
1248 type => 'text',
1249 null => 'NULL',
1250 after => 'contactfirstname',
1253 field => 'branchcode',
1254 type => 'varchar(10)',
1255 null => 'NOT NULL',
1256 default => "''",
1257 extra => '',
1260 field => 'categorycode',
1261 type => 'varchar(10)',
1262 null => 'NOT NULL',
1263 default => "''",
1264 extra => '',
1267 field => 'address',
1268 type => 'mediumtext',
1269 null => 'NOT NULL',
1270 default => '',
1271 extra => '',
1274 field => 'email',
1275 type => 'mediumtext',
1276 null => 'NULL',
1277 default => '',
1278 extra => '',
1281 field => 'B_city',
1282 type => 'mediumtext',
1283 null => 'NULL',
1284 default => '',
1285 extra => '',
1288 field => 'city',
1289 type => 'mediumtext',
1290 null => 'NOT NULL',
1291 default => '',
1292 extra => '',
1295 field => 'fax',
1296 type => 'mediumtext',
1297 null => 'NULL',
1298 default => '',
1299 extra => '',
1302 field => 'B_phone',
1303 type => 'mediumtext',
1304 null => 'NULL',
1305 default => '',
1306 extra => '',
1309 field => 'contactname',
1310 type => 'mediumtext',
1311 null => 'NULL',
1312 default => '',
1313 extra => '',
1316 field => 'opacnote',
1317 type => 'mediumtext',
1318 null => 'NULL',
1319 default => '',
1320 extra => '',
1323 field => 'borrowernotes',
1324 type => 'mediumtext',
1325 null => 'NULL',
1326 default => '',
1327 extra => '',
1330 field => 'sex',
1331 type => 'varchar(1)',
1332 null => 'NULL',
1333 default => 'NULL',
1334 extra => '',
1338 biblioitems => [
1340 field => 'itemtype',
1341 type => 'varchar(10)',
1342 null => 'NOT NULL',
1343 key => '',
1344 default => '',
1345 extra => '',
1348 field => 'lcsort',
1349 type => 'varchar(25)',
1350 null => 'NULL',
1351 key => '',
1352 default => '',
1353 extra => '',
1356 field => 'ccode',
1357 type => 'varchar(4)',
1358 null => 'NULL',
1359 key => '',
1360 default => '',
1361 extra => '',
1364 field => 'dewey',
1365 type => 'varchar(30)',
1366 null => 'null',
1367 default => '',
1368 extra => '',
1371 field => 'publicationyear',
1372 type => 'text',
1373 null => 'null',
1374 default => '',
1375 extra => '',
1378 field => 'collectiontitle',
1379 type => 'mediumtext',
1380 null => 'null',
1381 default => '',
1382 extra => '',
1383 after => 'volumeddesc',
1386 field => 'collectionissn',
1387 type => 'text',
1388 null => 'null',
1389 default => '',
1390 extra => '',
1391 after => 'collectiontitle',
1394 field => 'collectionvolume',
1395 type => 'mediumtext',
1396 null => 'null',
1397 default => '',
1398 extra => '',
1399 after => 'collectionissn',
1402 field => 'editionstatement',
1403 type => 'text',
1404 null => 'null',
1405 default => '',
1406 extra => '',
1407 after => 'collectionvolume',
1410 field => 'editionresponsibility',
1411 type => 'text',
1412 null => 'null',
1413 default => '',
1414 extra => '',
1415 after => 'editionstatement',
1418 field => 'volume',
1419 type => 'mediumtext',
1420 null => 'NULL',
1421 default => '',
1422 extra => '',
1425 field => 'number',
1426 type => 'mediumtext',
1427 null => 'NULL',
1428 default => '',
1429 extra => '',
1432 field => 'notes',
1433 type => 'mediumtext',
1434 null => 'NULL',
1435 default => '',
1436 extra => '',
1440 biblio => [
1442 field => 'author',
1443 type => 'mediumtext',
1444 null => 'NULL',
1445 default => '',
1446 extra => '',
1449 field => 'title',
1450 type => 'mediumtext',
1451 null => 'NULL',
1452 default => '',
1453 extra => '',
1456 field => 'unititle',
1457 type => 'mediumtext',
1458 null => 'NULL',
1459 default => '',
1460 extra => '',
1463 field => 'seriestitle',
1464 type => 'mediumtext',
1465 null => 'NULL',
1466 default => '',
1467 extra => '',
1470 field => 'abstract',
1471 type => 'mediumtext',
1472 null => 'NULL',
1473 default => '',
1474 extra => '',
1477 field => 'notes',
1478 type => 'mediumtext',
1479 null => 'NULL',
1480 default => '',
1481 extra => '',
1484 field => 'frameworkcode',
1485 type => 'varchar(4)',
1486 null => 'NOT NULL',
1487 default => "''",
1488 extra => '',
1489 after => 'biblionumber',
1493 deletedbiblio => [
1495 field => 'author',
1496 type => 'mediumtext',
1497 null => 'NULL',
1498 default => '',
1499 extra => '',
1502 field => 'title',
1503 type => 'mediumtext',
1504 null => 'NULL',
1505 default => '',
1506 extra => '',
1509 field => 'unititle',
1510 type => 'mediumtext',
1511 null => 'NULL',
1512 default => '',
1513 extra => '',
1516 field => 'seriestitle',
1517 type => 'mediumtext',
1518 null => 'NULL',
1519 default => '',
1520 extra => '',
1523 field => 'abstract',
1524 type => 'mediumtext',
1525 null => 'NULL',
1526 default => '',
1527 extra => '',
1530 field => 'notes',
1531 type => 'mediumtext',
1532 null => 'NULL',
1533 default => '',
1534 extra => '',
1537 field => 'frameworkcode',
1538 type => 'varchar(4)',
1539 null => 'NOT NULL',
1540 default => "''",
1541 extra => '',
1542 after => 'biblionumber',
1545 deletedbiblioitems => [
1547 field => 'itemtype',
1548 type => 'varchar(10)',
1549 null => 'NOT NULL',
1550 default => '',
1551 extra => '',
1554 field => 'dewey',
1555 type => 'varchar(30)',
1556 null => 'null',
1557 default => '',
1558 extra => '',
1561 field => 'itemtype',
1562 type => 'varchar(10)',
1563 null => 'NULL',
1564 default => 'NULL',
1565 extra => '',
1568 field => 'volume',
1569 type => 'mediumtext',
1570 null => 'NULL',
1571 default => '',
1572 extra => '',
1575 field => 'notes',
1576 type => 'mediumtext',
1577 null => 'NULL',
1578 default => '',
1579 extra => '',
1582 field => 'number',
1583 type => 'mediumtext',
1584 null => 'NULL',
1585 default => '',
1586 extra => '',
1590 bookshelf => [
1592 field => 'shelfname',
1593 type => 'varchar(255)',
1594 null => 'NULL',
1595 default => 'NULL',
1596 extra => '',
1599 field => 'owner',
1600 type => 'varchar(80)',
1601 null => 'NULL',
1602 default => 'NULL',
1603 extra => '',
1606 field => 'category',
1607 type => 'varchar(1)',
1608 null => 'NULL',
1609 default => 'NULL',
1610 extra => '',
1614 branchcategories => [
1616 field => 'codedescription',
1617 type => 'mediumtext',
1618 null => 'NULL',
1619 default => '',
1620 extra => '',
1624 branches => [
1626 field => 'branchip',
1627 type => 'varchar(15)',
1628 null => 'NULL',
1629 key => '',
1630 default => '',
1631 extra => '',
1634 field => 'branchprinter',
1635 type => 'varchar(100)',
1636 null => 'NULL',
1637 key => '',
1638 default => '',
1639 extra => '',
1642 field => 'branchcode',
1643 type => 'varchar(10)',
1644 null => 'NOT NULL',
1645 default => "''",
1646 extra => '',
1649 field => 'branchname',
1650 type => 'mediumtext',
1651 null => 'NOT NULL',
1652 default => '',
1653 extra => '',
1656 field => 'branchaddress1',
1657 type => 'mediumtext',
1658 null => 'NULL',
1659 default => '',
1660 extra => '',
1663 field => 'branchaddress2',
1664 type => 'mediumtext',
1665 null => 'NULL',
1666 default => '',
1667 extra => '',
1670 field => 'branchaddress3',
1671 type => 'mediumtext',
1672 null => 'NULL',
1673 default => '',
1674 extra => '',
1677 field => 'branchphone',
1678 type => 'mediumtext',
1679 null => 'NULL',
1680 default => '',
1681 extra => '',
1684 field => 'branchfax',
1685 type => 'mediumtext',
1686 null => 'NULL',
1687 default => '',
1688 extra => '',
1691 field => 'branchemail',
1692 type => 'mediumtext',
1693 null => 'NULL',
1694 default => '',
1695 extra => '',
1699 branchrelations => [
1701 field => 'branchcode',
1702 type => 'VARCHAR(10)',
1703 null => 'NOT NULL',
1704 key => '',
1705 default => "''",
1706 extra => '',
1709 field => 'categorycode',
1710 type => 'VARCHAR(10)',
1711 null => 'NOT NULL',
1712 key => '',
1713 default => "''",
1714 extra => '',
1718 branchtransfers =>[
1720 field => 'frombranch',
1721 type => 'VARCHAR(10)',
1722 null => 'NOT NULL',
1723 key => '',
1724 default => "''",
1725 extra => '',
1728 field => 'tobranch',
1729 type => 'VARCHAR(10)',
1730 null => 'NOT NULL',
1731 key => '',
1732 default => "''",
1735 field => 'comments',
1736 type => 'mediumtext',
1737 null => 'NULL',
1738 key => '',
1739 default => '',
1743 categories => [
1745 field => 'category_type',
1746 type => 'varchar(1)',
1747 null => 'NOT NULL',
1748 key => '',
1749 default => 'A',
1750 extra => '',
1753 field => 'categorycode',
1754 type => 'varchar(10)',
1755 null => 'NOT NULL',
1756 key => 'PRI',
1757 default => "''",
1758 extra => '',
1761 field => 'description',
1762 type => 'mediumtext',
1763 null => 'NULL',
1764 key => '',
1765 default => '',
1766 extra => '',
1770 deletedborrowers => [
1772 field => 'branchcode',
1773 type => 'varchar(10)',
1774 null => 'NOT NULL',
1775 default => "''",
1776 extra => '',
1779 field => 'categorycode',
1780 type => 'varchar(2)',
1781 null => 'NULL',
1782 default => 'NULL',
1783 extra => '',
1786 field => 'B_phone',
1787 type => 'mediumtext',
1788 null => 'NULL',
1789 default => '',
1790 extra => '',
1793 field => 'borrowernotes',
1794 type => 'mediumtext',
1795 null => 'NULL',
1796 default => '',
1797 extra => '',
1800 field => 'contactname',
1801 type => 'mediumtext',
1802 null => 'NULL',
1803 default => '',
1804 extra => '',
1807 field => 'B_city',
1808 type => 'mediumtext',
1809 null => 'NULL',
1810 default => '',
1811 extra => '',
1814 field => 'B_zipcode',
1815 type => 'varchar(25)',
1816 null => 'NULL',
1817 default => 'NULL',
1818 extra => '',
1821 field => 'zipcode',
1822 type => 'varchar(25)',
1823 null => 'NULL',
1824 default => 'NULL',
1825 extra => '',
1826 after => 'city',
1829 field => 'email',
1830 type => 'mediumtext',
1831 null => 'NULL',
1832 default => '',
1833 extra => '',
1836 field => 'address',
1837 type => 'mediumtext',
1838 null => 'NOT NULL',
1839 default => '',
1840 extra => '',
1843 field => 'fax',
1844 type => 'mediumtext',
1845 null => 'NULL',
1846 default => '',
1847 extra => '',
1850 field => 'city',
1851 type => 'mediumtext',
1852 null => 'NOT NULL',
1853 default => '',
1854 extra => '',
1856 { field => 'surname',
1857 type => 'mediumtext',
1858 null => 'NOT NULL',
1860 { field => 'firstname',
1861 type => 'text',
1862 null => 'NULL',
1864 { field => 'initials',
1865 type => 'text',
1866 null => 'NULL',
1868 { field => 'title',
1869 type => 'mediumtext',
1870 null => 'NULL',
1872 { field => 'othernames',
1873 type => 'mediumtext',
1874 null => 'NULL',
1876 { field => 'B_email',
1877 type => 'text',
1878 null => 'NULL',
1879 after => 'B_zipcode',
1882 field => 'streetnumber', # street number (hidden if streettable table is empty)
1883 type => 'varchar(10)',
1884 null => 'NULL',
1885 default => 'NULL',
1886 after => 'initials',
1889 field => 'streettype', # street table, list builded from a system table
1890 type => 'varchar(50)',
1891 null => 'NULL',
1892 default => 'NULL',
1893 after => 'streetnumber',
1895 { field => 'phone',
1896 type => 'text',
1897 null => 'NULL',
1900 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1901 type => 'varchar(10)',
1902 null => 'NULL',
1903 after => 'fax',
1906 field => 'B_streettype', # street table, list builded from a system table
1907 type => 'varchar(50)',
1908 null => 'NULL',
1909 after => 'B_streetnumber',
1912 field => 'phonepro',
1913 type => 'text',
1914 null => 'NULL',
1915 after => 'fax',
1918 field => 'address2', # complement address
1919 type => 'text',
1920 null => 'NULL',
1921 after => 'address',
1924 field => 'emailpro',
1925 type => 'text',
1926 null => 'NULL',
1927 after => 'fax',
1930 field => 'contactfirstname', # contact's firstname
1931 type => 'text',
1932 null => 'NULL',
1933 after => 'contactname',
1936 field => 'contacttitle', # contact's title
1937 type => 'text',
1938 null => 'NULL',
1939 after => 'contactfirstname',
1942 field => 'sex',
1943 type => 'varchar(1)',
1944 null => 'NULL',
1945 default => 'NULL',
1946 extra => '',
1950 issues => [
1952 field => 'borrowernumber',
1953 type => 'int(11)',
1954 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1955 key => '',
1956 default => '',
1957 extra => '',
1960 field => 'itemnumber',
1961 type => 'int(11)',
1962 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1963 key => '',
1964 default => '',
1965 extra => '',
1968 field => 'branchcode',
1969 type => 'varchar(10)',
1970 null => 'NULL',
1971 key => '',
1972 default => '',
1973 extra => '',
1976 field => 'issuedate',
1977 type => 'date',
1978 null => 'NULL',
1979 key => '',
1980 default => '',
1981 extra => '',
1984 field => 'return',
1985 type => 'varchar(4)',
1986 null => 'NULL',
1987 key => '',
1988 default => 'NULL',
1989 extra => '',
1992 field => 'issuingbranch',
1993 type => 'varchar(18)',
1994 null => 'NULL',
1995 key => '',
1996 default => '',
1997 extra => '',
2000 issuingrules => [
2002 field => 'categorycode',
2003 type => 'varchar(10)',
2004 null => 'NOT NULL',
2005 default => "''",
2006 extra => '',
2009 field => 'branchcode',
2010 type => 'varchar(10)',
2011 null => 'NOT NULL',
2012 default => "''",
2013 extra => '',
2016 field => 'itemtype',
2017 type => 'varchar(10)',
2018 null => 'NOT NULL',
2019 default => "''",
2020 extra => '',
2024 items => [
2026 field => 'onloan',
2027 type => 'date',
2028 null => 'NULL',
2029 key => '',
2030 default => '',
2031 extra => '',
2034 field => 'cutterextra',
2035 type => 'varchar(45)',
2036 null => 'NULL',
2037 key => '',
2038 default => '',
2039 extra => '',
2042 field => 'homebranch',
2043 type => 'varchar(10)',
2044 null => 'NULL',
2045 key => '',
2046 default => '',
2047 extra => '',
2050 field => 'holdingbranch',
2051 type => 'varchar(10)',
2052 null => 'NULL',
2053 key => '',
2054 default => '',
2055 extra => '',
2058 field => 'itype',
2059 type => 'varchar(10)',
2060 null => 'NULL',
2061 key => '',
2062 default => '',
2063 extra => '',
2066 field => 'paidfor',
2067 type => 'mediumtext',
2068 null => 'NULL',
2069 key => '',
2070 default => '',
2071 extra => '',
2074 field => 'itemnotes',
2075 type => 'mediumtext',
2076 null => 'NULL',
2077 key => '',
2078 default => '',
2079 extra => '',
2083 deleteditems => [
2085 field => 'paidfor',
2086 type => 'mediumtext',
2087 null => 'NULL',
2088 key => '',
2089 default => '',
2090 extra => '',
2093 field => 'itemnotes',
2094 type => 'mediumtext',
2095 null => 'NULL',
2096 key => '',
2097 default => '',
2098 extra => '',
2102 itemtypes => [
2104 field => 'itemtype',
2105 type => 'varchar(10)',
2106 default => "''",
2107 null => 'NOT NULL',
2108 key => 'PRI',
2109 extra => 'UNIQUE',
2112 field => 'description',
2113 type => 'MEDIUMTEXT',
2114 null => 'NULL',
2115 key => '',
2116 extra => '',
2119 field => 'summary',
2120 type => 'TEXT',
2121 null => 'NULL',
2122 key => '',
2123 extra => '',
2126 marc_breeding => [
2128 field => 'marc',
2129 type => 'LONGBLOB',
2130 null => 'NULL',
2131 key => '',
2132 extra => '',
2135 marc_subfield_structure => [
2137 field => 'defaultvalue',
2138 type => 'TEXT',
2139 null => 'NULL',
2140 key => '',
2141 extra => '',
2144 field => 'authtypecode',
2145 type => 'varchar(20)',
2146 null => 'NULL',
2147 key => '',
2148 default => 'NULL',
2149 extra => '',
2152 field => 'tagfield',
2153 type => 'varchar(3)',
2154 null => 'NOT NULL',
2155 key => '',
2156 default => "''",
2157 extra => '',
2160 field => 'tagsubfield',
2161 type => 'varchar(1)',
2162 null => 'NOT NULL',
2163 key => '',
2164 default => "''",
2165 extra => '',
2168 field => 'authorised_value',
2169 type => 'varchar(20)',
2170 null => 'NULL',
2171 key => '',
2172 default => "NULL",
2173 extra => '',
2176 field => 'seealso',
2177 type => 'varchar(1100)',
2178 null => 'NULL',
2179 key => '',
2180 default => "NULL",
2181 extra => '',
2185 marc_tag_structure => [
2187 field => 'tagfield',
2188 type => 'varchar(3)',
2189 null => 'NOT NULL',
2190 key => '',
2191 default => "''",
2192 extra => '',
2195 field => 'liblibrarian',
2196 type => 'varchar(255)',
2197 null => 'NOT NULL',
2198 key => '',
2199 default => "''",
2200 extra => '',
2203 field => 'libopac',
2204 type => 'varchar(255)',
2205 null => 'NOT NULL',
2206 key => '',
2207 default => "''",
2208 extra => '',
2211 field => 'authorised_value',
2212 type => 'varchar(10)',
2213 null => 'NULL',
2214 key => '',
2215 default => "NULL",
2216 extra => '',
2219 field => 'frameworkcode',
2220 type => 'varchar(4)',
2221 null => 'NOT NULL',
2222 key => '',
2223 default => "''",
2224 extra => '',
2228 opac_news => [
2230 field => 'expirationdate',
2231 type => 'date',
2232 null => 'null',
2233 key => '',
2234 extra => '',
2237 field => 'number',
2238 type => 'int(11)',
2239 null => 'NULL',
2240 key => '',
2241 default => '',
2242 extra => '',
2246 printers => [
2248 field => 'printername',
2249 type => 'varchar(40)',
2250 null => 'NOT NULL',
2251 key => '',
2252 default => "''",
2253 extra => '',
2256 field => 'printqueue',
2257 type => 'varchar(20)',
2258 null => 'NULL',
2259 key => '',
2260 default => "NULL",
2261 extra => '',
2264 field => 'printtype',
2265 type => 'varchar(20)',
2266 null => 'NULL',
2267 key => '',
2268 default => "NULL",
2269 extra => '',
2273 reserveconstraints => [
2275 field => 'reservedate',
2276 type => 'date',
2277 null => 'NULL',
2278 key => '',
2279 default => 'NULL',
2280 extra => '',
2284 reserves => [
2286 field => 'waitingdate',
2287 type => 'date',
2288 null => 'NULL',
2289 key => '',
2290 default => '',
2291 extra => '',
2294 field => 'reservedate',
2295 type => 'date',
2296 null => 'NULL',
2297 key => '',
2298 default => '',
2299 extra => '',
2302 field => 'constrainttype',
2303 type => 'varchar(1)',
2304 null => 'NULL',
2305 key => '',
2306 default => 'NULL',
2307 extra => '',
2308 after => 'biblionumber',
2311 field => 'branchcode',
2312 type => 'varchar(10)',
2313 null => 'NULL',
2314 key => '',
2315 default => '',
2316 extra => '',
2319 field => 'reservenotes',
2320 type => 'mediumtext',
2321 null => 'NULL',
2322 key => '',
2323 default => '',
2324 extra => '',
2327 field => 'found',
2328 type => 'varchar(1)',
2329 null => 'NULL',
2330 key => '',
2331 default => '',
2332 extra => '',
2336 serial => [
2338 field => 'planneddate',
2339 type => 'DATE',
2340 null => 'NULL',
2341 key => '',
2342 default => 'NULL',
2343 extra => '',
2346 field => 'notes',
2347 type => 'TEXT',
2348 null => 'NULL',
2349 key => '',
2350 default => '',
2351 extra => '',
2352 after => 'planneddate',
2356 shelfcontents => [
2358 field => 'dateadded',
2359 type => 'timestamp',
2360 null => 'NULL',
2364 statistics => [
2366 field => 'branch',
2367 type => 'varchar(10)',
2368 null => 'NOT NULL',
2371 field => 'datetime',
2372 type => 'datetime',
2373 null => 'NULL',
2374 default => 'NULL',
2377 field => 'itemtype',
2378 type => 'varchar(10)',
2379 null => 'NULL',
2382 field => 'other',
2383 type => 'mediumtext',
2384 null => 'NULL',
2388 subscription => [
2390 field => 'startdate',
2391 type => 'date',
2392 null => 'NULL',
2393 key => '' ,
2394 default => 'NULL',
2395 extra => '',
2398 field => 'notes',
2399 type => 'mediumtext',
2400 null => 'NULL',
2401 key => '' ,
2402 default => '',
2403 extra => '',
2406 field => 'monthlength',
2407 type => 'int(11)',
2408 null => 'NULL',
2409 key => '' ,
2410 default => '0',
2411 extra => '',
2415 subscriptionhistory => [
2417 field => 'histstartdate',
2418 type => 'date',
2419 null => 'NULL',
2420 key => '' ,
2421 default => 'NULL',
2422 extra => '',
2425 field => 'enddate',
2426 type => 'date',
2427 null => 'NULL',
2428 key => '' ,
2429 default => 'NULL',
2430 extra => '',
2434 systempreferences => [
2436 field => 'options',
2437 type => 'mediumtext',
2438 null => 'NULL',
2439 key => '' ,
2440 default => '',
2441 extra => '',
2444 field => 'value',
2445 type => 'text',
2446 null => 'NULL',
2447 key => '',
2448 default => '',
2449 extra => '',
2452 field => 'explanation',
2453 type => 'text',
2454 null => 'NULL',
2455 key => '',
2456 default => '',
2457 extra => '',
2460 suggestions => [
2462 field => 'reason',
2463 type => 'text',
2464 null => 'NULL',
2465 key => '' ,
2466 default => '',
2467 extra => '',
2470 field => 'note',
2471 type => 'mediumtext',
2472 null => 'NULL',
2473 key => '' ,
2474 default => '',
2475 extra => '',
2478 userflags => [
2480 field => 'flag',
2481 type => 'varchar(30)',
2482 null => 'NULL',
2483 key => '' ,
2484 default => '',
2485 extra => '',
2488 field => 'flagdesc',
2489 type => 'varchar(255)',
2490 null => 'NULL',
2491 key => '' ,
2492 default => '',
2493 extra => '',
2496 z3950servers => [
2498 field => 'name',
2499 type => 'mediumtext',
2500 null => 'NULL',
2501 key => '' ,
2502 default => '',
2503 extra => '',
2508 my %indexes = (
2509 # table => [
2510 # { indexname => 'index detail'
2512 # ],
2513 accountoffsets => [
2514 { indexname => 'accountoffsets_ibfk_1',
2515 content => 'borrowernumber',
2518 aqbooksellers => [
2519 { indexname => 'PRIMARY',
2520 content => 'id',
2521 type => 'PRI',
2524 aqbasket => [
2525 { indexname => 'booksellerid',
2526 content => 'booksellerid',
2529 aqorders => [
2530 { indexname => 'basketno',
2531 content => 'basketno',
2534 aqorderbreakdown => [
2535 { indexname => 'ordernumber',
2536 content => 'ordernumber',
2538 { indexname => 'bookfundid',
2539 content => 'bookfundid',
2542 biblioitems => [
2543 { indexname => 'isbn',
2544 content => 'isbn',
2546 { indexname => 'publishercode',
2547 content => 'publishercode',
2550 borrowers => [
2552 indexname => 'borrowernumber',
2553 content => 'borrowernumber',
2554 type => 'PRI',
2555 force => 1,
2558 branches => [
2560 indexname => 'branchcode',
2561 content => 'branchcode',
2562 type => 'PRI',
2565 branchrelations => [
2567 indexname => 'PRIMARY',
2568 content => 'categorycode',
2569 type => 'PRI',
2572 branchrelations => [
2573 { indexname => 'PRIMARY',
2574 content => 'branchcode,categorycode',
2575 type => 'PRI',
2577 { indexname => 'branchcode',
2578 content => 'branchcode',
2580 { indexname => 'categorycode',
2581 content => 'categorycode',
2584 currency => [
2585 { indexname => 'PRIMARY',
2586 content => 'currency',
2587 type => 'PRI',
2590 categories => [
2592 indexname => 'categorycode',
2593 content => 'categorycode',
2596 issuingrules => [
2598 indexname => 'categorycode',
2599 content => 'categorycode',
2602 indexname => 'itemtype',
2603 content => 'itemtype',
2606 items => [
2607 { indexname => 'homebranch',
2608 content => 'homebranch',
2610 { indexname => 'holdingbranch',
2611 content => 'holdingbranch',
2614 itemtypes => [
2616 indexname => 'itemtype',
2617 content => 'itemtype',
2620 shelfcontents => [
2621 { indexname => 'shelfnumber',
2622 content => 'shelfnumber',
2624 { indexname => 'itemnumber',
2625 content => 'itemnumber',
2628 userflags => [
2629 { indexname => 'PRIMARY',
2630 content => 'bit',
2631 type => 'PRI',
2636 my %foreign_keys = (
2637 # table => [
2638 # { key => 'the key in table' (must be indexed)
2639 # foreigntable => 'the foreigntable name', # (the parent)
2640 # foreignkey => 'the foreign key column(s)' # (in the parent)
2641 # onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
2642 # onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
2644 # ],
2645 branchrelations => [
2646 { key => 'branchcode',
2647 foreigntable => 'branches',
2648 foreignkey => 'branchcode',
2649 onUpdate => 'CASCADE',
2650 onDelete => 'CASCADE',
2652 { key => 'categorycode',
2653 foreigntable => 'branchcategories',
2654 foreignkey => 'categorycode',
2655 onUpdate => 'CASCADE',
2656 onDelete => 'CASCADE',
2659 shelfcontents => [
2660 { key => 'shelfnumber',
2661 foreigntable => 'bookshelf',
2662 foreignkey => 'shelfnumber',
2663 onUpdate => 'CASCADE',
2664 onDelete => 'CASCADE',
2666 { key => 'itemnumber',
2667 foreigntable => 'items',
2668 foreignkey => 'itemnumber',
2669 onUpdate => 'CASCADE',
2670 onDelete => 'CASCADE',
2673 # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
2674 # easily deleted, but branches/itemtype not too easy to empty...
2675 biblioitems => [
2676 { key => 'biblionumber',
2677 foreigntable => 'biblio',
2678 foreignkey => 'biblionumber',
2679 onUpdate => 'CASCADE',
2680 onDelete => 'CASCADE',
2683 items => [
2684 { key => 'biblioitemnumber',
2685 foreigntable => 'biblioitems',
2686 foreignkey => 'biblioitemnumber',
2687 onUpdate => 'CASCADE',
2688 onDelete => 'CASCADE',
2690 { key => 'homebranch',
2691 foreigntable => 'branches',
2692 foreignkey => 'branchcode',
2693 onUpdate => 'CASCADE',
2694 onDelete => 'RESTRICT',
2696 { key => 'holdingbranch',
2697 foreigntable => 'branches',
2698 foreignkey => 'branchcode',
2699 onUpdate => 'CASCADE',
2700 onDelete => 'RESTRICT',
2703 aqbasket => [
2704 { key => 'booksellerid',
2705 foreigntable => 'aqbooksellers',
2706 foreignkey => 'id',
2707 onUpdate => 'CASCADE',
2708 onDelete => 'RESTRICT',
2711 aqorders => [
2712 { key => 'basketno',
2713 foreigntable => 'aqbasket',
2714 foreignkey => 'basketno',
2715 onUpdate => 'CASCADE',
2716 onDelete => 'CASCADE',
2718 { key => 'biblionumber',
2719 foreigntable => 'biblio',
2720 foreignkey => 'biblionumber',
2721 onUpdate => 'SET NULL',
2722 onDelete => 'SET NULL',
2725 aqbooksellers => [
2726 { key => 'listprice',
2727 foreigntable => 'currency',
2728 foreignkey => 'currency',
2729 onUpdate => 'CASCADE',
2730 onDelete => 'CASCADE',
2732 { key => 'invoiceprice',
2733 foreigntable => 'currency',
2734 foreignkey => 'currency',
2735 onUpdate => 'CASCADE',
2736 onDelete => 'CASCADE',
2739 aqorderbreakdown => [
2740 { key => 'ordernumber',
2741 foreigntable => 'aqorders',
2742 foreignkey => 'ordernumber',
2743 onUpdate => 'CASCADE',
2744 onDelete => 'CASCADE',
2746 { key => 'bookfundid',
2747 foreigntable => 'aqbookfund',
2748 foreignkey => 'bookfundid',
2749 onUpdate => 'CASCADE',
2750 onDelete => 'CASCADE',
2753 branchtransfers => [
2754 { key => 'frombranch',
2755 foreigntable => 'branches',
2756 foreignkey => 'branchcode',
2757 onUpdate => 'CASCADE',
2758 onDelete => 'CASCADE',
2760 { key => 'tobranch',
2761 foreigntable => 'branches',
2762 foreignkey => 'branchcode',
2763 onUpdate => 'CASCADE',
2764 onDelete => 'CASCADE',
2766 { key => 'itemnumber',
2767 foreigntable => 'items',
2768 foreignkey => 'itemnumber',
2769 onUpdate => 'CASCADE',
2770 onDelete => 'CASCADE',
2773 issues => [ # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
2774 # for stat purposes
2775 { key => 'borrowernumber',
2776 foreigntable => 'borrowers',
2777 foreignkey => 'borrowernumber',
2778 onUpdate => 'SET NULL',
2779 onDelete => 'SET NULL',
2781 { key => 'itemnumber',
2782 foreigntable => 'items',
2783 foreignkey => 'itemnumber',
2784 onUpdate => 'SET NULL',
2785 onDelete => 'SET NULL',
2788 reserves => [
2789 { key => 'borrowernumber',
2790 foreigntable => 'borrowers',
2791 foreignkey => 'borrowernumber',
2792 onUpdate => 'CASCADE',
2793 onDelete => 'CASCADE',
2795 { key => 'biblionumber',
2796 foreigntable => 'biblio',
2797 foreignkey => 'biblionumber',
2798 onUpdate => 'CASCADE',
2799 onDelete => 'CASCADE',
2801 { key => 'itemnumber',
2802 foreigntable => 'items',
2803 foreignkey => 'itemnumber',
2804 onUpdate => 'CASCADE',
2805 onDelete => 'CASCADE',
2807 { key => 'branchcode',
2808 foreigntable => 'branches',
2809 foreignkey => 'branchcode',
2810 onUpdate => 'CASCADE',
2811 onDelete => 'CASCADE',
2814 borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2815 # but prevent deleting a branch as soon as it has 1 borrower !
2816 { key => 'categorycode',
2817 foreigntable => 'categories',
2818 foreignkey => 'categorycode',
2819 onUpdate => 'RESTRICT',
2820 onDelete => 'RESTRICT',
2822 { key => 'branchcode',
2823 foreigntable => 'branches',
2824 foreignkey => 'branchcode',
2825 onUpdate => 'RESTRICT',
2826 onDelete => 'RESTRICT',
2829 accountlines => [
2830 { key => 'borrowernumber',
2831 foreigntable => 'borrowers',
2832 foreignkey => 'borrowernumber',
2833 onUpdate => 'CASCADE',
2834 onDelete => 'CASCADE',
2836 { key => 'itemnumber',
2837 foreigntable => 'items',
2838 foreignkey => 'itemnumber',
2839 onUpdate => 'SET NULL',
2840 onDelete => 'SET NULL',
2843 accountoffsets => [
2844 { key => 'borrowernumber',
2845 foreigntable => 'borrowers',
2846 foreignkey => 'borrowernumber',
2847 onUpdate => 'CASCADE',
2848 onDelete => 'CASCADE',
2851 auth_tag_structure => [
2852 { key => 'authtypecode',
2853 foreigntable => 'auth_types',
2854 foreignkey => 'authtypecode',
2855 onUpdate => 'CASCADE',
2856 onDelete => 'CASCADE',
2859 # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
2863 # column changes
2864 my %column_change = (
2865 # table
2866 borrowers => [
2868 from => 'emailaddress',
2869 to => 'email',
2870 after => 'city',
2873 from => 'streetaddress',
2874 to => 'address',
2875 after => 'initials',
2878 from => 'faxnumber',
2879 to => 'fax',
2880 after => 'phone',
2883 from => 'textmessaging',
2884 to => 'opacnote',
2885 after => 'userid',
2888 from => 'altnotes',
2889 to => 'contactnote',
2890 after => 'opacnote',
2893 from => 'physstreet',
2894 to => 'B_address',
2895 after => 'fax',
2898 from => 'streetcity',
2899 to => 'B_city',
2900 after => 'B_address',
2903 from => 'phoneday',
2904 to => 'mobile',
2905 after => 'phone',
2908 from => 'zipcode',
2909 to => 'zipcode',
2910 after => 'city',
2913 from => 'homezipcode',
2914 to => 'B_zipcode',
2915 after => 'B_city',
2918 from => 'altphone',
2919 to => 'B_phone',
2920 after => 'B_zipcode',
2923 from => 'expiry',
2924 to => 'dateexpiry',
2925 after => 'dateenrolled',
2928 from => 'guarantor',
2929 to => 'guarantorid',
2930 after => 'contactname',
2933 from => 'altrelationship',
2934 to => 'relationship',
2935 after => 'borrowernotes',
2939 deletedborrowers => [
2941 from => 'emailaddress',
2942 to => 'email',
2943 after => 'city',
2946 from => 'streetaddress',
2947 to => 'address',
2948 after => 'initials',
2951 from => 'faxnumber',
2952 to => 'fax',
2953 after => 'phone',
2956 from => 'textmessaging',
2957 to => 'opacnote',
2958 after => 'userid',
2961 from => 'altnotes',
2962 to => 'contactnote',
2963 after => 'opacnote',
2966 from => 'physstreet',
2967 to => 'B_address',
2968 after => 'fax',
2971 from => 'streetcity',
2972 to => 'B_city',
2973 after => 'B_address',
2976 from => 'phoneday',
2977 to => 'mobile',
2978 after => 'phone',
2981 from => 'zipcode',
2982 to => 'zipcode',
2983 after => 'city',
2986 from => 'homezipcode',
2987 to => 'B_zipcode',
2988 after => 'B_city',
2991 from => 'altphone',
2992 to => 'B_phone',
2993 after => 'B_zipcode',
2996 from => 'expiry',
2997 to => 'dateexpiry',
2998 after => 'dateenrolled',
3001 from => 'guarantor',
3002 to => 'guarantorid',
3003 after => 'contactname',
3006 from => 'altrelationship',
3007 to => 'relationship',
3008 after => 'borrowernotes',
3014 # MOVE all tables TO UTF-8 and innoDB
3015 $sth = $dbh->prepare("show table status");
3016 $sth->execute;
3017 while ( my $table = $sth->fetchrow_hashref ) {
3018 next if $table->{Name} eq 'marc_word';
3019 next if $table->{Name} eq 'marc_subfield_table';
3020 next if $table->{Name} eq 'auth_word';
3021 next if $table->{Name} eq 'auth_subfield_table';
3022 if ($table->{Engine} ne 'InnoDB') {
3023 print "moving $table->{Name} to InnoDB\n";
3024 $dbh->do("ALTER TABLE $table->{Name} ENGINE = innodb");
3026 unless ($table->{Collation} =~ /^utf8/) {
3027 print "moving $table->{Name} to utf8\n";
3028 $dbh->do("ALTER TABLE $table->{Name} CONVERT TO CHARACTER SET utf8");
3029 $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
3030 # 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 !
3031 } else {
3035 # list of columns that must exist for %column_change to be
3036 # processed without error, but which do not necessarily exist
3037 # in all 2.2 databases
3038 my %required_prereq_fields = (
3039 deletedborrowers => [
3040 [ 'textmessaging', 'mediumtext AFTER faxnumber' ],
3041 [ 'password', 'varchar(30) default NULL' ],
3042 [ 'flags', 'int(11) default NULL' ],
3043 [ 'userid', 'varchar(30) default NULL' ],
3044 [ 'homezipcode', 'varchar(25) default NULL' ],
3045 [ 'zipcode', 'varchar(25) default NULL' ],
3046 [ 'sort1', 'varchar(80) default NULL' ],
3047 [ 'sort2', 'varchar(80) default NULL' ],
3051 foreach $table ( keys %required_prereq_fields ) {
3052 print "Check table $table\n" if $debug and not $silent;
3053 $sth = $dbh->prepare("show columns from $table");
3054 $sth->execute();
3055 undef %types;
3056 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3058 $types{$column} = $type;
3059 } # while
3060 foreach my $entry ( @{ $required_prereq_fields{$table} } ) {
3061 ($column, $type) = @{ $entry };
3062 print " Check column $column [$type]\n" if $debug and not $silent;
3063 if ( !$types{$column} ) {
3065 # column doesn't exist
3066 print "Adding $column field to $table table...\n" unless $silent;
3067 $query = "alter table $table
3068 add column $column " . $type;
3069 print "Execute: $query\n" if $debug;
3070 my $sti = $dbh->prepare($query);
3071 $sti->execute;
3072 if ( $sti->err ) {
3073 print "**Error : $sti->errstr \n";
3074 $sti->finish;
3075 } # if error
3076 } # if column
3077 } # foreach column
3078 } # foreach table
3080 foreach my $table (keys %column_change) {
3081 $sth = $dbh->prepare("show columns from $table");
3082 $sth->execute();
3083 undef %types;
3084 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3086 $types{$column}->{type} ="$type";
3087 $types{$column}->{null} = "$null";
3088 $types{$column}->{key} = "$key";
3089 $types{$column}->{default} = "$default";
3090 $types{$column}->{extra} = "$extra";
3091 } # while
3092 my $tablerows = $column_change{$table};
3093 foreach my $row ( @$tablerows ) {
3094 if ($types{$row->{from}}->{type}) {
3095 print "altering $table $row->{from} to $row->{to}\n";
3096 # ALTER TABLE `borrowers` CHANGE `faxnumber` `fax` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
3097 # alter table `borrowers` change `faxnumber` `fax` type text null after phone
3098 my $sql =
3099 "alter table `$table` change `$row->{from}` `$row->{to}` $types{$row->{from}}->{type} ".
3100 ($types{$row->{from}}->{null} eq 'YES'?" NULL":" NOT NULL").
3101 ($types{$row->{from}}->{default}?" default ".$types{$row->{from}}->{default}:"").
3102 "$types{$row->{from}}->{extra} after $row->{after} ";
3103 # print "$sql";
3104 $dbh->do($sql);
3109 # Enter here the field you want to delete from DB.
3110 # FIXME :: there is a %uselessfield before which seems doing the same things.
3111 my %fieldtodelete = (
3112 # tablename => [fieldname1,fieldname2,...]
3114 ); # %fielddelete
3116 print "removing some unused fields...\n";
3117 foreach my $table ( keys %fieldtodelete ) {
3118 foreach my $field ( @{$fieldtodelete{$table}} ){
3119 print "removing ".$field." from ".$table;
3120 my $sth = $dbh->prepare("ALTER TABLE $table DROP $field");
3121 $sth->execute;
3122 if ( $sth->err ) {
3123 print "Error : $sth->errstr \n";
3128 # Enter here the line you want to remove from DB.
3129 my %linetodelete = (
3130 # table name => where clause.
3131 userflags => [ "bit = 8" ], # delete the 'reserveforself' flags
3133 ); # %linetodelete
3135 #-------------------
3136 # Initialize
3138 # Start checking
3140 # Get version of MySQL database engine.
3141 my $mysqlversion = `mysqld --version`;
3142 $mysqlversion =~ /Ver (\S*) /;
3143 $mysqlversion = $1;
3144 if ( $mysqlversion ge '3.23' ) {
3145 print "Could convert to MyISAM database tables...\n" unless $silent;
3148 #---------------------------------
3149 # Tables
3151 # Collect all tables into a list
3152 $sth = $dbh->prepare("show tables");
3153 $sth->execute;
3154 while ( my ($table) = $sth->fetchrow ) {
3155 $existingtables{$table} = 1;
3159 # Now add any missing tables
3160 foreach $table ( keys %requiretables ) {
3161 unless ( $existingtables{$table} ) {
3162 print "Adding $table table...\n" unless $silent;
3163 my $sth = $dbh->prepare("create table $table $requiretables{$table} ENGINE=InnoDB DEFAULT CHARSET=utf8");
3164 $sth->execute;
3165 if ( $sth->err ) {
3166 print "Error : $sth->errstr \n";
3167 $sth->finish;
3168 } # if error
3169 } # unless exists
3170 } # foreach
3172 #---------------------------------
3173 # Columns
3175 foreach $table ( keys %requirefields ) {
3176 print "Check table $table\n" if $debug and not $silent;
3177 $sth = $dbh->prepare("show columns from $table");
3178 $sth->execute();
3179 undef %types;
3180 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3182 $types{$column} = $type;
3183 } # while
3184 foreach $column ( keys %{ $requirefields{$table} } ) {
3185 print " Check column $column [$types{$column}]\n" if $debug and not $silent;
3186 if ( !$types{$column} ) {
3188 # column doesn't exist
3189 print "Adding $column field to $table table...\n" unless $silent;
3190 $query = "alter table $table
3191 add column $column " . $requirefields{$table}->{$column};
3192 print "Execute: $query\n" if $debug;
3193 my $sti = $dbh->prepare($query);
3194 $sti->execute;
3195 if ( $sti->err ) {
3196 print "**Error : $sti->errstr \n";
3197 $sti->finish;
3198 } # if error
3199 } # if column
3200 } # foreach column
3201 } # foreach table
3203 foreach $table ( sort keys %fielddefinitions ) {
3204 print "Check table $table\n" if $debug;
3205 $sth = $dbh->prepare("show columns from $table");
3206 $sth->execute();
3207 my $definitions;
3208 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3210 $definitions->{$column}->{type} = $type;
3211 $definitions->{$column}->{null} = $null;
3212 $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
3213 $definitions->{$column}->{key} = $key;
3214 $definitions->{$column}->{default} = $default;
3215 $definitions->{$column}->{extra} = $extra;
3216 } # while
3217 my $fieldrow = $fielddefinitions{$table};
3218 foreach my $row (@$fieldrow) {
3219 my $field = $row->{field};
3220 my $type = $row->{type};
3221 my $null = $row->{null};
3222 # $null = 'YES' if $row->{null} eq 'NULL';
3223 my $key = $row->{key};
3224 my $default = $row->{default};
3225 # $default="''" unless $default;
3226 my $extra = $row->{extra};
3227 my $def = $definitions->{$field};
3228 my $after = ($row->{after}?" after ".$row->{after}:"");
3230 unless ( $type eq $def->{type}
3231 && $null eq $def->{null}
3232 && $key eq $def->{key}
3233 && $default eq $def->{default}
3234 && $extra eq $def->{extra} )
3236 if ( $null eq '' ) {
3237 $null = 'NOT NULL';
3239 if ( $key eq 'PRI' ) {
3240 $key = 'PRIMARY KEY';
3242 unless ( $extra eq 'auto_increment' ) {
3243 $extra = '';
3246 # if it's a new column use "add", if it's an old one, use "change".
3247 my $action;
3248 if ($definitions->{$field}->{type}) {
3249 $action="change `$field`"
3250 } else {
3251 $action="add";
3253 # if it's a primary key, drop the previous pk, before altering the table
3254 print " alter or create $field in $table\n" unless $silent;
3255 my $query;
3256 if ($key ne 'PRIMARY KEY') {
3257 # warn "alter table $table $action $field $type $null $key $extra default $default $after";
3258 $query = "alter table $table $action `$field` $type $null $key $extra ".
3259 GetDefaultClause($default)." $after";
3260 } else {
3261 # warn "alter table $table drop primary key, $action $field $type $null $key $extra default $default $after";
3262 # something strange : for indexes UNIQUE, they are reported as primary key here.
3263 # but if you try to run with drop primary key, it fails.
3264 # thus, we run the query twice, one will fail, one will succeed.
3265 # strange...
3266 $query="alter table $table drop primary key, $action `$field` $type $null $key $extra ".
3267 GetDefaultClause($default)." $after";
3268 $query="alter table $table $action `$field` $type $null $key $extra ".
3269 GetDefaultClause($default)." $after";
3271 $dbh->do($query) or warn "Error while executing: $query";
3276 print "removing some unused data...\n";
3277 foreach my $table ( keys %linetodelete ) {
3278 foreach my $where ( @{$linetodelete{$table}} ){
3279 print "DELETE FROM ".$table." where ".$where;
3280 print "\n";
3281 my $sth = $dbh->prepare("DELETE FROM $table where $where");
3282 $sth->execute;
3283 if ( $sth->err ) {
3284 print "Error : $sth->errstr \n";
3289 # Populate tables with required data
3291 # synch table and deletedtable.
3292 foreach my $table (('borrowers','items','biblio','biblioitems')) {
3293 my %deletedborrowers;
3294 print "synch'ing $table and deleted$table\n";
3295 $sth = $dbh->prepare("show columns from deleted$table");
3296 $sth->execute;
3297 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
3298 $deletedborrowers{$column}=1;
3300 $sth = $dbh->prepare("show columns from $table");
3301 $sth->execute;
3302 my $previous;
3303 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
3304 unless ($deletedborrowers{$column}) {
3305 my $newcol="alter table deleted$table add $column $type";
3306 if ($null eq 'YES') {
3307 $newcol .= " NULL ";
3308 } else {
3309 $newcol .= " NOT NULL ";
3311 $newcol .= "default ".$dbh->quote($default) if $default;
3312 $newcol .= " after $previous" if $previous;
3313 $previous=$column;
3314 print "creating column $column\n";
3315 $dbh->do($newcol);
3320 # update publisheddate
3322 $sth = $dbh->prepare("select count(*) from serial where publisheddate is NULL");
3323 $sth->execute;
3324 my ($emptypublished) = $sth->fetchrow;
3325 if ($emptypublished) {
3326 print "Updating publisheddate\n";
3327 $dbh->do("update serial set publisheddate=planneddate where publisheddate is NULL");
3329 # Why are we setting publisheddate = planneddate ?? if we don't have the data, we don't know it.
3330 # now, let's get rid of 000-00-00's.
3332 $dbh->do("update serial set publisheddate=NULL where publisheddate = 0");
3333 $dbh->do("update subscription set firstacquidate=startdate where firstacquidate = 0");
3335 foreach my $table ( keys %tabledata ) {
3336 print "Checking for data required in table $table...\n" unless $silent;
3337 my $tablerows = $tabledata{$table};
3338 foreach my $row (@$tablerows) {
3339 my $uniquefieldrequired = $row->{uniquefieldrequired};
3340 my $uniquevalue = $row->{$uniquefieldrequired};
3341 my $forceupdate = $row->{forceupdate};
3342 my $sth =
3343 $dbh->prepare(
3344 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
3346 $sth->execute($uniquevalue);
3347 if ($sth->rows) {
3348 foreach my $field (keys %$forceupdate) {
3349 if ($forceupdate->{$field}) {
3350 my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
3351 $sth->execute($row->{$field}, $uniquevalue);
3354 } else {
3355 print "Adding row to $table: " unless $silent;
3356 my @values;
3357 my $fieldlist;
3358 my $placeholders;
3359 foreach my $field ( keys %$row ) {
3360 next if $field eq 'uniquefieldrequired';
3361 next if $field eq 'forceupdate';
3362 my $value = $row->{$field};
3363 push @values, $value;
3364 print " $field => $value" unless $silent;
3365 $fieldlist .= "$field,";
3366 $placeholders .= "?,";
3368 print "\n" unless $silent;
3369 $fieldlist =~ s/,$//;
3370 $placeholders =~ s/,$//;
3371 print "insert into $table ($fieldlist) values ($placeholders)";
3372 my $sth =
3373 $dbh->prepare(
3374 "insert into $table ($fieldlist) values ($placeholders)");
3375 $sth->execute(@values);
3381 # check indexes and create them when needed
3383 print "Checking for index required...\n" unless $silent;
3384 foreach my $table ( keys %indexes ) {
3386 # read all indexes from $table
3388 $sth = $dbh->prepare("show index from $table");
3389 $sth->execute;
3390 my %existingindexes;
3391 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
3392 $existingindexes{$key_name} = 1;
3394 # read indexes to check
3395 my $tablerows = $indexes{$table};
3396 foreach my $row (@$tablerows) {
3397 my $key_name=$row->{indexname};
3398 if ($existingindexes{$key_name} eq 1 and not $row->{force}) {
3399 # print "$key_name existing";
3400 } else {
3401 print "\tCreating index $key_name in $table\n";
3402 my $sql;
3403 if ($row->{indexname} eq 'PRIMARY' or $row->{type} eq 'PRI') {
3404 $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
3405 } else {
3406 $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
3408 $dbh->do($sql);
3409 print "Error $sql : $dbh->err \n" if $dbh->err;
3415 # check foreign keys and create them when needed
3417 print "Checking for foreign keys required...\n" unless $silent;
3418 foreach my $table ( sort keys %foreign_keys ) {
3420 # read all indexes from $table
3422 $sth = $dbh->prepare("show table status like '$table'");
3423 $sth->execute;
3424 my $stat = $sth->fetchrow_hashref;
3425 # read indexes to check
3426 my $tablerows = $foreign_keys{$table};
3427 foreach my $row (@$tablerows) {
3428 my $foreign_table=$row->{foreigntable};
3429 if ($stat->{'Comment'} =~/$foreign_table/) {
3430 # print "$foreign_table existing\n";
3431 } else {
3432 print "\tCreating foreign key $foreign_table in $table\n";
3433 # first, drop any orphan value in child table
3434 if ($row->{onDelete} ne "RESTRICT") {
3435 my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
3436 $dbh->do($sql);
3437 print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
3439 my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
3440 $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
3441 $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
3442 $dbh->do($sql);
3443 if ($dbh->err) {
3444 print "====================
3445 An error occurred during :
3446 \t$sql
3447 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).
3448 You can find those values with select
3449 \t$table.* from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})
3450 ====================\n
3456 # now drop useless tables
3457 foreach $table ( @TableToDelete ) {
3458 if ( $existingtables{$table} ) {
3459 print "Dropping unused table $table\n" if $debug and not $silent;
3460 $dbh->do("drop table $table");
3461 if ( $dbh->err ) {
3462 print "Error : $dbh->errstr \n";
3468 # SPECIFIC STUFF
3471 # create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
3474 # 1st, get how many biblio we will have to do...
3475 $sth = $dbh->prepare('select count(*) from marc_biblio');
3476 $sth->execute;
3477 my ($totaltodo) = $sth->fetchrow;
3479 $sth = $dbh->prepare("show columns from biblio");
3480 $sth->execute();
3481 my $definitions;
3482 my $bibliofwexist=0;
3483 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3484 $bibliofwexist=1 if $column eq 'frameworkcode';
3486 unless ($bibliofwexist) {
3487 print "moving biblioframework to biblio table\n";
3488 $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
3489 $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
3490 $sth->execute;
3491 my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
3492 my $totaldone=0;
3493 while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
3494 $sth_update->execute($frameworkcode,$biblionumber);
3495 $totaldone++;
3496 print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3498 print "\rdone\n";
3501 # at last, remove useless fields
3502 foreach $table ( keys %uselessfields ) {
3503 my @fields = split (/,/,$uselessfields{$table});
3504 my $fields;
3505 my $exists;
3506 foreach my $fieldtodrop (@fields) {
3507 $fieldtodrop =~ s/\t//g;
3508 $fieldtodrop =~ s/\n//g;
3509 $exists =0;
3510 $sth = $dbh->prepare("show columns from $table");
3511 $sth->execute;
3512 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3514 $exists =1 if ($column eq $fieldtodrop);
3516 if ($exists) {
3517 print "deleting $fieldtodrop field in $table...\n" unless $silent;
3518 my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
3519 $sth->execute;
3522 } # foreach
3525 # Changing aqbookfund's primary key
3527 $sth=$dbh->prepare("ALTER TABLE `aqbookfund` DROP PRIMARY KEY , ADD PRIMARY KEY ( `bookfundid` , `branchcode` ) ;");
3528 $sth->execute;
3529 $sth->finish;
3531 # drop extra key on borrowers.borrowernumber
3532 $dbh->do("ALTER TABLE borrowers DROP KEY borrowernumber");
3534 # update enrolmentperiod
3535 $dbh->do("UPDATE categories SET enrolmentperiod = enrolmentperiod * 12");
3537 print "upgrade to Koha 3.0 done\n";
3538 SetVersion ($DBversion);
3540 =head1 GetDefaultClause
3542 Generate a default clause (for an ALTER TABLE command)
3544 =cut
3546 sub GetDefaultClause {
3547 my $default = shift;
3549 return "" unless defined $default;
3550 return "" if $default eq '';
3551 return "default ''" if $default eq "''";
3552 return "default NULL" if $default eq "NULL";
3553 return "default " . $dbh->quote($default);
3556 =head1 TransformToNum
3558 Transform the Koha version from a 4 parts string
3559 to a number, with just 1.
3561 =cut
3563 sub TransformToNum {
3564 my $version = shift;
3565 # remove the 3 last . to have a Perl number
3566 $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
3567 return $version;
3570 =head1 SetVersion
3572 set the DBversion in the systempreferences
3574 =cut
3576 sub SetVersion {
3577 my $kohaversion = TransformToNum(shift);
3578 if (C4::Context->preference('Version')) {
3579 my $finish=$dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='Version'");
3580 $finish->execute($kohaversion);
3581 } else {
3582 my $finish=$dbh->prepare("INSERT into systempreferences (variable,value,explanation) values ('Version',?,'The Koha database version. WARNING: Do not change this value manually, it is maintained by the webinstaller')");
3583 $finish->execute($kohaversion);
3586 exit;
3588 # Revision 1.172 2007/07/19 10:21:22 hdl