Revert "Bug 30373: (follow-up) Fix license"
[koha.git] / installer / data / mysql / update22to30.pl
1 #!/usr/bin/perl
2
3
4 # Database Updater
5 # This script checks for required updates to the database.
6
7 # Part of the Koha Library Software www.koha-community.org
8 # Licensed under the GPL.
9
10 # Bugs/ToDo:
11 # - Would also be a good idea to offer to do a backup at this time...
12
13 # NOTE:  If you do something more than once in here, make it table driven.
14 use strict;
15
16 # CPAN modules
17 use Getopt::Long qw( GetOptions );
18 # Koha modules
19 use C4::Context;
20
21 use MARC::File::XML ( BinaryEncoding => 'utf8' );
22  
23 # FIXME - The user might be installing a new database, so can't rely
24 # on /etc/koha.conf anyway.
25
26 my $debug = 0;
27
28 my (
29     $sth, $sti,
30     $query,
31     %existingtables,    # tables already in database
32     %types,
33     $table,
34     $column,
35     $type, $null, $key, $default, $extra,
36 );
37
38 my $silent;
39 GetOptions(
40     's' =>\$silent
41     );
42 my $dbh = C4::Context->dbh;
43 $|=1; # flushes output
44
45 my $DBversion = "3.00.00.000";
46 # if we are upgrading from Koha 2.2, then we need to run the complete & long updatedatabase
47     # Tables to add if they don't exist
48     my %requiretables = (
49         action_logs     => "(
50                         `timestamp` TIMESTAMP NOT NULL ,
51                         `user` INT( 11 ) NOT NULL default '0' ,
52                         `module` TEXT default '',
53                         `action` TEXT default '' ,
54                         `object` INT(11) NULL ,
55                         `info` TEXT default '' ,
56                         PRIMARY KEY ( `timestamp` , `user` )
57                     )",
58         letter        => "(
59                         module varchar(20) NOT NULL default '',
60                         code varchar(20) NOT NULL default '',
61                         name varchar(100) NOT NULL default '',
62                         title varchar(200) NOT NULL default '',
63                         content text,
64                         PRIMARY KEY  (module,code)
65                     )",
66         alert        =>"(
67                         alertid int(11) NOT NULL auto_increment,
68                         borrowernumber int(11) NOT NULL default '0',
69                         type varchar(10) NOT NULL default '',
70                         externalid varchar(20) NOT NULL default '',
71                         PRIMARY KEY  (alertid),
72                         KEY borrowernumber (borrowernumber),
73                         KEY type (type,externalid)
74                     )",
75         opac_news => "(
76                     `idnew` int(10) unsigned NOT NULL auto_increment,
77                     `title` varchar(250) NOT NULL default '',
78                     `new` text NOT NULL,
79                     `lang` varchar(4) NOT NULL default '',
80                     `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
81                     PRIMARY KEY  (`idnew`)
82                     )",
83         repeatable_holidays => "(
84                     `id` int(11) NOT NULL auto_increment,
85                     `branchcode` varchar(10) NOT NULL default '',
86                     `weekday` smallint(6) default NULL,
87                     `day` smallint(6) default NULL,
88                     `month` smallint(6) default NULL,
89                     `title` varchar(50) NOT NULL default '',
90                     `description` text NOT NULL,
91                     PRIMARY KEY  (`id`)
92                     )",
93         special_holidays => "(
94                     `id` int(11) NOT NULL auto_increment,
95                     `branchcode` varchar(10) NOT NULL default '',
96                     `day` smallint(6) NOT NULL default '0',
97                     `month` smallint(6) NOT NULL default '0',
98                     `year` smallint(6) NOT NULL default '0',
99                     `isexception` smallint(1) NOT NULL default '1',
100                     `title` varchar(50) NOT NULL default '',
101                     `description` text NOT NULL,
102                     PRIMARY KEY  (`id`)
103                     )",
104         overduerules    =>"(`branchcode` varchar(10) NOT NULL default '',
105                         `categorycode` varchar(2) NOT NULL default '',
106                         `delay1` int(4) default '0',
107                         `letter1` varchar(20) default NULL,
108                         `debarred1` varchar(1) default '0',
109                         `delay2` int(4) default '0',
110                         `debarred2` varchar(1) default '0',
111                         `letter2` varchar(20) default NULL,
112                         `delay3` int(4) default '0',
113                         `letter3` varchar(20) default NULL,
114                         `debarred3` int(1) default '0',
115                         PRIMARY KEY  (`branchcode`,`categorycode`)
116                         )",
117         cities            => "(`cityid` int auto_increment,
118                             `city_name` varchar(100) NOT NULL default '',
119                             `city_zipcode` varchar(20),
120                             PRIMARY KEY (`cityid`)
121                         )",
122         roadtype            => "(`roadtypeid` int auto_increment,
123                             `road_type` varchar(100) NOT NULL default '',
124                             PRIMARY KEY (`roadtypeid`)
125                         )",
126     
127         labels                     => "(
128                     labelid int(11) NOT NULL auto_increment,
129                                 batch_id varchar(10) NOT NULL default '1',
130                                 itemnumber varchar(100) NOT NULL default '',
131                                 timestamp timestamp(14) NOT NULL,
132                                 PRIMARY KEY  (labelid)
133                                 )",
134     
135         labels_conf                => "(
136                     id int(4) NOT NULL auto_increment,
137                                 barcodetype char(100) default '',
138                                 title int(1) default '0',
139                                 subtitle int(1) default '0',
140                                 itemtype int(1) default '0',
141                                 barcode int(1) default '0',
142                                 dewey int(1) default '0',
143                                 class int(1) default '0',
144                                 subclass int(1) default '0',
145                                 itemcallnumber int(1) default '0',
146                                 author int(1) default '0',
147                                 issn int(1) default '0',
148                                 isbn int(1) default '0',
149                                 startlabel int(2) NOT NULL default '1',
150                                 printingtype char(32) default 'BAR',
151                                 layoutname char(20) NOT NULL default 'TEST',
152                                 guidebox int(1) default '0',
153                                 active tinyint(1) default '1',
154                                 fonttype char(10) collate utf8_unicode_ci default NULL,
155                                 ccode char(4) collate utf8_unicode_ci default NULL,
156                                 callnum_split int(1) default NULL,
157                                 text_justify char(1) collate utf8_unicode_ci default NULL,
158                                 PRIMARY KEY  (id)
159                                 )",
160         reviews                  => "(
161                                 reviewid integer NOT NULL auto_increment,
162                                 borrowernumber integer,
163                                 biblionumber integer,
164                                 review text,
165                                 approved tinyint,
166                                 datereviewed datetime,
167                                 PRIMARY KEY (reviewid)
168                                 )",
169         subscriptionroutinglist=>"(
170                                 routingid integer NOT NULL auto_increment,
171                                 borrowernumber integer,
172                                 ranking integer,
173                                 subscriptionid integer,
174                                 PRIMARY KEY (routingid)
175                                 )",
176     
177         notifys    => "(
178                 notify_id int(11) NOT NULL default '0',
179                     `borrowernumber` int(11) NOT NULL default '0',
180                 `itemnumber` int(11) NOT NULL default '0',
181                 `notify_date` date default NULL,
182                         `notify_send_date` date default NULL,
183                         `notify_level` int(1) NOT NULL default '0',
184                         `method` varchar(20) NOT NULL default ''
185                 )",
186     
187     charges    => "(
188                 `charge_id` varchar(5) NOT NULL default '',
189                     `description` text NOT NULL,
190                     `amount` decimal(28,6) NOT NULL default '0.000000',
191                             `min` int(4) NOT NULL default '0',
192                     `max` int(4) NOT NULL default '0',
193                             `level` int(1) NOT NULL default '0',
194                             PRIMARY KEY  (`charge_id`)
195                 )",
196         tags => "(
197             `entry` varchar(255) NOT NULL default '',
198             `weight` bigint(20) NOT NULL default '0',
199             PRIMARY KEY  (`entry`)
200         )
201         ",
202     zebraqueue    => "(
203                     `id` int NOT NULL auto_increment,
204                     `biblio_auth_number` int(11) NOT NULL default '0',
205                     `operation` char(20) NOT NULL default '',
206                     `server` char(20) NOT NULL default '',
207                     PRIMARY KEY  (`id`)
208                 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1",
209     
210     );
211     
212     my %requirefields = (
213         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 \'\''},
214         itemtypes => { 'imageurl' => 'varchar(200) NULL'},
215         aqbookfund => { 'branchcode' => 'varchar(4) NULL'},
216         aqbudget => { 'branchcode' => 'varchar(4) NULL'},
217         auth_header => { 'marc' => 'BLOB NOT NULL', 'linkid' => 'BIGINT(20) NULL'},
218         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'},
219         marc_breeding => { 'isbn' => 'varchar(13) NOT NULL'},
220         serial =>{ 'publisheddate' => 'date AFTER planneddate', 'claimdate' => 'date', 'itemnumber'=>'text NULL','routingnotes'=>'text NULL',},
221         statistics => { 'associatedborrower' => 'integer'},
222         z3950servers =>{  "name" =>"text",  "description" => "text NOT NULL",
223                         "position" =>"enum('primary','secondary','') NOT NULL default 'primary'",  "icon" =>"text",
224                         "type" =>"enum('zed','opensearch') NOT NULL default 'zed'",
225                         },
226         issues =>{ 'issuedate'=>"date NULL default NULL", },
227     
228     #    tablename        => { 'field' => 'fieldtype' },
229     );
230     
231     # Enter here the table to delete.
232     my @TableToDelete = qw(
233         additionalauthors
234         bibliosubject
235         bibliosubtitle
236         bibliothesaurus
237     );
238     
239     my %uselessfields = (
240     # tablename => "field1,field2",
241         borrowers => "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
242         deletedborrowers=> "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
243         items => "multivolumepart,multivolume,binding",
244         deleteditems => "multivolumepart,multivolume,binding",
245         );
246     # the other hash contains other actions that can't be done elsewhere. they are done
247     # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
248     
249     # The tabledata hash contains data that should be in the tables.
250     # The uniquefieldrequired hash entry is used to determine which (if any) fields
251     # must not exist in the table for this row to be inserted.  If the
252     # uniquefieldrequired entry is already in the table, the existing data is not
253     # modified, unless the forceupdate hash entry is also set.  Fields in the
254     # anonymous "forceupdate" hash will be forced to be updated to the default
255     # values given in the %tabledata hash.
256     
257     my %tabledata = (
258     # tablename => [
259     #    {    uniquefielrequired => 'fieldname', # the primary key in the table
260     #        fieldname => fieldvalue,
261     #        fieldname2 => fieldvalue2,
262     #    },
263     # ],
264         systempreferences => [
265             {
266                 uniquefieldrequired => 'variable',
267                 variable            => 'useDaysMode',
268                 value               => 'Calendar',
269                 forceupdate         => { 'explanation' => 1,
270                                         'type' => 1},
271                 explanation            => 'Choose the method for calculating due date: select Calendar to use the holidays module, and Days to ignore the holidays module',
272                 type        => 'Choice',
273                 options        => 'Calendar|Days|Datedue'
274             },
275             {
276                 uniquefieldrequired => 'variable',
277                 variable            => 'DebugLevel',
278                 value               => '0',
279                 forceupdate         => { 'explanation' => 1,
280                                         'type' => 1},
281                 explanation            => 'Set the level of error info sent to the browser. 0=none, 1=some, 2=most',
282                 type                => 'Choice',
283                 options             => '0|1|2'
284             },
285             {
286                 uniquefieldrequired => 'variable',
287                 variable            => 'BorrowersTitles',
288                 value               => 'Mr|Mrs|Miss|Ms',
289                 forceupdate         => { 'explanation' => 1,
290                                         'type' => 1},
291                 explanation         => 'List all Titles for borrowers',
292                 type                => 'free',
293             },
294             {
295                 uniquefieldrequired => 'variable',
296                 variable            => 'BorrowerMandatoryField',
297                 value               => 'cardnumber|surname|address',
298                 forceupdate         => { 'explanation' => 1,
299                                         'type' => 1},
300                 explanation         => 'List all mandatory fields for borrowers',
301                 type                => 'free',
302             },
303             {
304                 uniquefieldrequired => 'variable',
305                 variable            => 'borrowerRelationship',
306                 value               => 'father|mother,grand-mother',
307                 forceupdate         => { 'explanation' => 1,
308                                         'type' => 1},
309                 explanation         => 'The relationships between a guarantor & a guarantee (separated by | or ,)',
310                 type                => 'free',
311             },
312             {
313                 uniquefieldrequired => 'variable',
314                 variable            => 'ReservesMaxPickUpDelay',
315                 value               => '10',
316                 forceupdate         => { 'explanation' => 1,
317                                         'type' => 1},
318                 explanation         => 'Maximum delay to pick up a reserved document',
319                 type                => 'free',
320             },
321             {
322                 uniquefieldrequired => 'variable',
323                 variable            => 'TransfersMaxDaysWarning',
324                 value               => '3',
325                 forceupdate         => { 'explanation' => 1,
326                                         'type' => 1},
327                 explanation         => 'Max delay before considering the transfer has potentialy a problem',
328                 type                => 'free',
329             },
330             {
331                 uniquefieldrequired => 'variable',
332                 variable            => 'memberofinstitution',
333                 value               => '0',
334                 forceupdate         => { 'explanation' => 1,
335                                         'type' => 1},
336                 explanation         => 'Are your patrons members of institutions',
337                 type                => 'YesNo',
338             },
339         {
340                 uniquefieldrequired => 'variable',
341                 variable            => 'ReadingHistory',
342                 value               => '0',
343                 forceupdate         => { 'explanation' => 1,
344                                         'type' => 1},
345                 explanation         => 'Allow reading record info retrievable from issues and oldissues tables',
346                 type                => 'YesNo',
347             },
348         {
349                 uniquefieldrequired => 'variable',
350                 variable            => 'IssuingInProcess',
351                 value               => '0',
352                 forceupdate         => { 'explanation' => 1,
353                                         'type' => 1},
354                 explanation         => 'Allow no debt alert if the patron is issuing item that accumulate debt',
355                 type                => 'YesNo',
356             },
357         {
358                 uniquefieldrequired => 'variable',
359                 variable            => 'AutomaticItemReturn',
360                 value               => '1',
361                 forceupdate         => { 'explanation' => 1,
362                                         'type' => 1},
363                 explanation         => 'This Variable allow or not to return automaticly to his homebranch',
364                 type                => 'YesNo',
365             },
366         {
367                 uniquefieldrequired => 'variable',
368                 variable            => 'reviewson',
369                 value               => '0',
370                 forceupdate         => { 'explanation' => 1,
371                                         'type' => 1},
372                 explanation         => 'Allows patrons to submit reviews from the opac',
373                 type                => 'YesNo',
374             },
375         {
376                 uniquefieldrequired => 'variable',
377                 variable            => 'intranet_includes',
378                 value               => 'includes',
379                 forceupdate         => { 'explanation' => 1,
380                                         'type' => 1},
381                 explanation         => 'The includes directory you want for specific look of Koha (includes or includes_npl for example)',
382                 type                => 'Free',
383             },
384             {
385                 uniquefieldrequired => 'variable',
386                 variable            => 'AutoLocation',
387                 value               => '0',
388                 forceupdate         => { 'explanation' => 1,
389                                         'type' => 1},
390                 explanation         => 'switch to activate or not Autolocation, if Yes, the Librarian can\'t change his location, it\'s defined by branchip',
391                 type                => 'YesNo',
392             },
393             {
394                 uniquefieldrequired => 'variable',
395                 variable            => 'serialsadditems',
396                 value               => '0',
397                 forceupdate         => {
398                     'explanation' => 1,
399                     'type' => 1
400                 },
401                 explanation => 'If set, a new item will be automatically added when receiving an issue',
402                 type => 'YesNo',
403             },
404             {
405                 uniquefieldrequired => 'variable',
406                 variable            => 'expandedSearchOption',
407                 value               => '0',
408                 forceupdate         => {
409                     'explanation' => 1,
410                     'type' => 1
411                 },
412                 explanation => 'search among marc field',
413                 type => 'YesNo',
414             },
415         {
416                 uniquefieldrequired => 'variable',
417                 variable            => 'RequestOnOpac',
418                 value               => '1',
419                 forceupdate         => { 'explanation' => 1,
420                                         'type' => 1},
421                 explanation         => 'option to allow reserves on opac',
422                 type                => 'YesNo',
423             },
424         {
425                 uniquefieldrequired => 'variable',
426                 variable            => 'OpacCloud',
427                 value               => '1',
428                 forceupdate         => { 'explanation' => 1,
429                                         'type' => 1},
430                 explanation         => 'Enable / Disable cloud link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
431                 type                => 'YesNo',
432             },
433         {
434                 uniquefieldrequired => 'variable',
435                 variable            => 'OpacBrowser',
436                 value               => '1',
437                 forceupdate         => { 'explanation' => 1,
438                                         'type' => 1},
439                 explanation         => 'Enable/Disable browser link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
440                 type                => 'YesNo',
441             },
442         {
443                 uniquefieldrequired => 'variable',
444                 variable            => 'OpacTopissue',
445                 value               => '0',
446                 forceupdate         => { 'explanation' => 1,
447                                         'type' => 1},
448                 explanation         => 'If ON, enables the \'most popular items\' link on OPAC. Warning, this is an EXPERIMENTAL feature, turning ON may overload your server',
449                 type                => 'YesNo',
450             },
451         {
452                 uniquefieldrequired => 'variable',
453                 variable            => 'OpacAuthorities',
454                 value               => '1',
455                 forceupdate         => { 'explanation' => 1,
456                                         'type' => 1},
457                 explanation         => 'Enable / Disable the search authority link on OPAC',
458                 type                => 'YesNo',
459             },
460             {
461                 uniquefieldrequired => 'variable',
462                 variable            => 'CataloguingLog',
463                 value               => '0',
464                 forceupdate         => {'explanation' => 1, 'type' => 1},
465                 explanation         => 'Active this if you want to log cataloguing action.',
466                 type                => 'YesNo',
467             },
468             {
469                 uniquefieldrequired => 'variable',
470                 variable            => 'BorrowersLog',
471                 value               => '0',
472                 forceupdate         => {'explanation' => 1, 'type' => 1},
473                 explanation         => 'Active this if you want to log borrowers edition/creation/deletion...',
474                 type                => 'YesNo',
475             },
476             {
477                 uniquefieldrequired => 'variable',
478                 variable            => 'SubscriptionLog',
479                 value               => '0',
480                 forceupdate         => {'explanation' => 1, 'type' => 1},
481                 explanation         => 'Active this if you want to log Subscription action',
482                 type                => 'YesNo',
483             },
484             {
485                 uniquefieldrequired => 'variable',
486                 variable            => 'IssueLog',
487                 value               => '0',
488                 forceupdate         => {'explanation' => 1, 'type' => 1},
489                 explanation         => 'Active this if you want to log issue.',
490                 type                => 'YesNo',
491             },
492             {
493                 uniquefieldrequired => 'variable',
494                 variable            => 'ReturnLog',
495                 value               => '0',
496                 forceupdate         => {'explanation' => 1, 'type' => 1},
497                 explanation         => 'Active this if you want to log the circulation return',
498                 type                => 'YesNo',
499             },
500             {
501                 uniquefieldrequired => 'variable',
502                 variable            => 'Version',
503                 value               => '3.0',
504                 forceupdate         => {'explanation' => 1, 'type' => 1},
505                 explanation         => 'Koha Version',
506                 type                => 'Free',
507             },
508             {   
509                 uniquefieldrequired => 'variable',
510                 variable            => 'LetterLog',
511                 value               => '0',
512                 forceupdate         => {'explanation' => 1, 'type' => 1},
513                 explanation         => 'Active this if you want to log all the letter sent',
514                 type                => 'YesNo',
515             },
516             {
517                 uniquefieldrequired => 'variable',
518                 variable            => 'FinesLog',
519                 value               => '0',
520                 forceupdate         => {'explanation' => 1, 'type' => 1},
521                 explanation         => 'Active this if you want to log fines',
522                 type                => 'YesNo',
523             },
524             {
525                 uniquefieldrequired => 'variable',
526                 variable            => 'NoZebra',
527                 value               => '0',
528                 forceupdate         => {'explanation' => 1, 'type' => 1},
529                 explanation         => 'Active this if you want NOT to use zebra (large libraries should avoid this parameters)',
530                 type                => 'YesNo',
531             },
532             {
533                 uniquefieldrequired => 'variable',
534                 variable            => 'NoZebraIndexes',
535                 value               => '0',
536                 forceupdate         => {'explanation' => 1, 'type' => 1},
537                 explanation         => "Enter a specific hash for NoZebra indexes. Enter : 'indexname' => '100a,245a,500*','index2' => '...'",
538                 type                => 'Free',
539             },
540             {
541                 uniquefieldrequired => 'variable',
542                 variable            => 'uppercasesurnames',
543                 value               => '0',
544                 forceupdate         => {'explanation' => 1, 'type' => 1},
545                 explanation         => "Force Surnames to be uppercase",
546                 type                => 'YesNo',
547             },
548         ],
549         userflags => [
550             {
551                 uniquefieldrequired => 'bit',
552                 bit                 => '14',
553                 flag                => 'editauthorities',
554                 flagdesc            => 'allow to edit authorities',
555                 defaulton           => '0',
556             },
557             {
558                 uniquefieldrequired => 'bit',
559                 bit                 => '15',
560                 flag                 => 'serials',
561                 flagdesc            => 'allow to manage serials subscriptions',
562                 defaulton           => '0',
563             },
564             {
565                 uniquefieldrequired => 'bit',
566                 bit                 => '16',
567                 flag                 => 'reports',
568                 flagdesc            => 'allow to access to the reports module',
569                 defaulton           => '0',
570             },
571         ],
572         authorised_values => [
573             {
574                 uniquefieldrequired => 'id',
575                 category            => 'SUGGEST',
576                 authorised_value    => 'Not enough budget',
577                 lib                 => 'This book it too much expensive',
578             }
579         ],
580     );
581     
582     my %fielddefinitions = (
583     # fieldname => [
584     #    {          field => 'fieldname',
585     #             type    => 'fieldtype',
586     #             null    => '',
587     #             key     => '',
588     #             default => ''
589     #         },
590     #     ],
591         aqbasket =>  [
592             {
593                 field    => 'booksellerid',
594                 type    => 'int(11)',
595                 null    => 'NOT NULL',
596                 key        => '',
597                 default    => '1',
598                 extra    => '',
599             },
600             {
601                 field   => 'booksellerinvoicenumber',
602                 type    => 'mediumtext',
603                                 null    => 'NULL',
604                 key     => '',
605                 default => '',
606                 extra   => '',
607             },
608         ],
609                 aqbookfund => [
610                         {
611                                 field  => 'bookfundid',
612                                 type   => 'varchar(10)',
613                                 null   => 'NOT NULL',
614                                 key    => '',
615                                 default => "''",
616                                 extra  => '',
617                         },
618             {
619                 field   => 'branchcode',
620                 type    => 'varchar(10)',
621                                 null    => 'NOT NULL',
622                 key     => '',
623                 default => "''",
624                 extra   => '',
625             },
626             {
627                 field   => 'bookfundname',
628                 type    => 'mediumtext',
629                                 null    => 'NULL',
630                 key     => '',
631                 default => '',
632                 extra   => '',
633                 after   => 'bookfundid',
634             },
635                 ],
636   
637         aqbooksellers =>  [
638             {
639                 field    => 'id',
640                 type    => 'int(11)',
641                 null    => 'NOT NULL',
642                 key        => 'PRI',
643                 default    => '',
644                 extra    => 'auto_increment',
645             },
646             {
647                 field    => 'currency',
648                 type    => 'varchar(3)',
649                 null    => 'NOT NULL',
650                 key        => '',
651                 default    => "''",
652                 extra    => '',
653             },
654             {
655                 field    => 'listprice',
656                 type    => 'varchar(10)',
657                 null    => 'NULL',
658                 key        => '',
659                 default    => '',
660                 extra    => '',
661             },
662             {
663                 field    => 'invoiceprice',
664                 type    => 'varchar(10)',
665                 null    => 'NULL',
666                 key        => '',
667                 default    => '',
668                 extra    => '',
669             },
670                         {
671                                 field   => 'invoicedisc',
672                                 type    => 'float(6,4)',
673                                 null    => 'NULL',
674                                 key     => '',
675                                 default => 'NULL',
676                                 extra   => '',
677                         },
678                         {
679                                 field   => 'address1',
680                                 type    => 'mediumtext',
681                                 null    => 'NULL',
682                                 key     => '',
683                                 default => '',
684                                 extra   => '',
685                         },
686                         {
687                                 field   => 'address2',
688                                 type    => 'mediumtext',
689                                 null    => 'NULL',
690                                 key     => '',
691                                 default => '',
692                                 extra   => '',
693                         },
694                         {
695                                 field   => 'address3',
696                                 type    => 'mediumtext',
697                                 null    => 'NULL',
698                                 key     => '',
699                                 default => '',
700                                 extra   => '',
701                         },
702                         {
703                                 field   => 'address4',
704                                 type    => 'mediumtext',
705                                 null    => 'NULL',
706                                 key     => '',
707                                 default => '',
708                                 extra   => '',
709                         },
710                         {
711                                 field   => 'accountnumber',
712                                 type    => 'mediumtext',
713                                 null    => 'NULL',
714                                 key     => '',
715                                 default => '',
716                                 extra   => '',
717                         },
718                         {
719                                 field   => 'othersupplier',
720                                 type    => 'mediumtext',
721                                 null    => 'NULL',
722                                 key     => '',
723                                 default => '',
724                                 extra   => '',
725                         },
726                         {
727                                 field   => 'specialty',
728                                 type    => 'mediumtext',
729                                 null    => 'NULL',
730                                 key     => '',
731                                 default => '',
732                                 extra   => '',
733                         },
734                         {
735                                 field   => 'booksellerfax',
736                                 type    => 'mediumtext',
737                                 null    => 'NULL',
738                                 key     => '',
739                                 default => '',
740                                 extra   => '',
741                         },
742                         {
743                                 field   => 'notes',
744                                 type    => 'mediumtext',
745                                 null    => 'NULL',
746                                 key     => '',
747                                 default => '',
748                                 extra   => '',
749                         },
750                         {
751                                 field   => 'bookselleremail',
752                                 type    => 'mediumtext',
753                                 null    => 'NULL',
754                                 key     => '',
755                                 default => '',
756                                 extra   => '',
757                         },
758                         {
759                                 field   => 'booksellerurl',
760                                 type    => 'mediumtext',
761                                 null    => 'NULL',
762                                 key     => '',
763                                 default => '',
764                                 extra   => '',
765                         },
766                         {
767                                 field   => 'contnotes',
768                                 type    => 'mediumtext',
769                                 null    => 'NULL',
770                                 key     => '',
771                                 default => '',
772                                 extra   => '',
773                         },
774                         {
775                                 field   => 'postal',
776                                 type    => 'mediumtext',
777                                 null    => 'NULL',
778                                 key     => '',
779                                 default => '',
780                                 extra   => '',
781                         },
782         ],
783         
784                 aqbudget     =>  [
785                         {
786                                 field    => 'bookfundid',
787                                 type     => 'varchar(10)',
788                                 null     => 'NOT NULL',
789                                 key      => '',
790                                 default  => "''",
791                                 exra     => '',
792                          },
793                         {
794                                 field    => 'branchcode',
795                                 type     => 'varchar(10)',
796                                 null     => 'NULL',
797                                 key      => '',
798                                 default  => '',
799                                 exra     => '',
800                          },
801                 ],
802                 
803                 aqorderbreakdown     =>  [
804                         {
805                                 field    => 'bookfundid',
806                                 type     => 'varchar(10)',
807                                 null     => 'NOT NULL',
808                                 key      => '',
809                                 default  => "''",
810                                 exra     => '',
811                          },
812                         {
813                                 field    => 'branchcode',
814                                 type     => 'varchar(10)',
815                                 null     => 'NULL',
816                                 key      => '',
817                                 default  => '',
818                                 exra     => '',
819                          },
820                 ],
821
822                 aqorderdelivery => [
823                         {
824                                 field    => 'ordernumber',
825                                 type     => 'date',
826                                 null     => 'NULL',
827                                 key      => '',
828                                 default  => 'NULL',
829                                 exra     => '',
830                          },
831                         {
832                                 field    => 'deliverycomments',
833                                 type     => 'mediumtext',
834                                 null     => 'NULL',
835                                 key      => '',
836                                 default  => '',
837                                 exra     => '',
838                          },
839         ],
840
841         aqorders => [
842                         {
843                                 field    => 'title',
844                                 type     => 'mediumtext',
845                                 null     => 'NULL',
846                                 key      => '',
847                                 default  => '',
848                                 exra     => '',
849                          },
850                         {
851                                 field    => 'currency',
852                                 type     => 'varchar(3)',
853                                 null     => 'NULL',
854                                 key      => '',
855                                 default  => 'NULL',
856                                 exra     => '',
857                          },
858             {
859                 field   => 'booksellerinvoicenumber',
860                 type    => 'mediumtext',
861                                 null    => 'NULL',
862                 key     => '',
863                 default => '',
864                 extra   => '',
865             },
866             {
867                 field   => 'notes',
868                 type    => 'mediumtext',
869                                 null    => 'NULL',
870                 key     => '',
871                 default => '',
872                 extra   => '',
873             },
874             {
875                 field   => 'supplierreference',
876                 type    => 'mediumtext',
877                                 null    => 'NULL',
878                 key     => '',
879                 default => '',
880                 extra   => '',
881             },
882             {
883                 field   => 'purchaseordernumber',
884                 type    => 'mediumtext',
885                                 null    => 'NULL',
886                 key     => '',
887                 default => '',
888                 extra   => '',
889             },
890         ],
891
892         accountlines =>  [
893             {
894                 field    => 'notify_id',
895                 type    => 'int(11)',
896                 null    => 'NOT NULL',
897                 key        => '',
898                 default    => '0',
899                 extra    => '',
900             },
901             {
902                 field    => 'notify_level',
903                 type    => 'int(2)',
904                 null    => 'NOT NULL',
905                 key        => '',
906                 default    => '0',
907                 extra    => '',
908             },
909                         {
910                                 field   => 'accountno',
911                                 type    => 'smallint(6)',
912                                 null    => 'NOT NULL',
913                                 key     => '',
914                                 default => '0',
915                                 extra   => '',
916                         },
917                         {
918                                 field   => 'description',
919                                 type    => 'mediumtext',
920                                 null    => 'NULL',
921                         },
922                         {
923                                 field   => 'dispute',
924                                 type    => 'mediumtext',
925                                 null    => 'NULL',
926                     },
927         
928         ],
929        
930         auth_header => [
931             {
932                 field   => 'authtypecode',
933                 type    => 'varchar(10)',
934                                 null    => 'NOT NULL',
935                 key     => '',
936                 default => "''",
937                 extra   => '',
938             },
939             {
940                 field   => 'datecreated',
941                 type    => 'date',
942                                 null    => 'NULL',
943                 key     => '',
944                 default => "NULL",
945                 extra   => '',
946             },
947             {
948                 field   => 'origincode',
949                 type    => 'varchar(20)',
950                                 null    => 'NULL',
951                 key     => '',
952                 default => "NULL",
953                 extra   => '',
954             },
955             {
956                 field   => 'authtrees',
957                 type    => 'mediumtext',
958                                 null    => 'NULL',
959                 key     => '',
960                 default => "",
961                 extra   => '',
962                 after   => 'origincode',
963             },
964         ],
965  
966         auth_subfield_structure => [
967             {
968                 field   => 'authtypecode',
969                 type    => 'varchar(10)',
970                                 null    => 'NOT NULL',
971                 key     => '',
972                 default => "''",
973                 extra   => '',
974             },
975             {
976                 field   => 'tagfield',
977                 type    => 'varchar(3)',
978                                 null    => 'NOT NULL',
979                 key     => '',
980                 default => "''",
981                 extra   => '',
982             },
983             {
984                 field   => 'tagsubfield',
985                 type    => 'varchar(1)',
986                                 null    => 'NOT NULL',
987                 key     => '',
988                 default => "''",
989                 extra   => '',
990             },
991             {
992                 field   => 'liblibrarian',
993                 type    => 'varchar(255)',
994                                 null    => 'NOT NULL',
995                 key     => '',
996                 default => "''",
997                 extra   => '',
998             },
999             {
1000                 field   => 'libopac',
1001                 type    => 'varchar(255)',
1002                                 null    => 'NOT NULL',
1003                 key     => '',
1004                 default => "''",
1005                 extra   => '',
1006             },
1007             {
1008                 field   => 'authorised_value',
1009                 type    => 'varchar(10)',
1010                                 null    => 'NULL',
1011                 key     => '',
1012                 default => "NULL",
1013                 extra   => '',
1014             },
1015             {
1016                 field   => 'value_builder',
1017                 type    => 'varchar(80)',
1018                                 null    => 'NULL',
1019                 key     => '',
1020                 default => "NULL",
1021                 extra   => '',
1022             },
1023             {
1024                 field   => 'seealso',
1025                 type    => 'varchar(255)',
1026                                 null    => 'NULL',
1027                 key     => '',
1028                 default => "NULL",
1029                 extra   => '',
1030             },
1031             {
1032                 field   => 'kohafield',
1033                 type    => 'varchar(45)',
1034                                 null    => 'NULL',
1035                 key     => '',
1036                 default => "''",
1037                 extra   => '',
1038             },
1039             {
1040                 field   => 'frameworkcode',
1041                 type    => 'varchar(8)',
1042                                 null    => 'NOT NULL',
1043                 key     => '',
1044                 default => "''",
1045                 extra   => '',
1046             },
1047         ],
1048             
1049         auth_tag_structure => [
1050             {
1051                 field   => 'authtypecode',
1052                 type    => 'varchar(10)',
1053                                 null    => 'NOT NULL',
1054                 key     => '',
1055                 default => "''",
1056                 extra   => '',
1057             },
1058             {
1059                 field   => 'tagfield',
1060                 type    => 'varchar(3)',
1061                                 null    => 'NOT NULL',
1062                 key     => '',
1063                 default => "''",
1064                 extra   => '',
1065             },
1066             {
1067                 field   => 'liblibrarian',
1068                 type    => 'varchar(255)',
1069                                 null    => 'NOT NULL',
1070                 key     => '',
1071                 default => "''",
1072                 extra   => '',
1073             },
1074             {
1075                 field   => 'libopac',
1076                 type    => 'varchar(255)',
1077                                 null    => 'NOT NULL',
1078                 key     => '',
1079                 default => "''",
1080                 extra   => '',
1081             },
1082             {
1083                 field   => 'authorised_value',
1084                 type    => 'varchar(10)',
1085                                 null    => 'NULL',
1086                 key     => '',
1087                 default => "NULL",
1088                 extra   => '',
1089             },
1090         ],
1091
1092         auth_types => [
1093             {
1094                 field   => 'auth_tag_to_report',
1095                 type    => 'varchar(3)',
1096                                 null    => 'NOT NULL',
1097                 key     => '',
1098                 default => "''",
1099                 extra   => '',
1100             },
1101             {
1102                 field   => 'summary',
1103                 type    => 'mediumtext',
1104                                 null    => 'NOT NULL',
1105                 key     => '',
1106                 default => '',
1107                 extra   => '',
1108             },
1109         ],
1110
1111         authorised_values => [
1112             {
1113                 field   => 'category',
1114                 type    => 'varchar(10)',
1115                                 null    => 'NOT NULL',
1116                 key     => '',
1117                 default => "''",
1118                 extra   => '',
1119             },
1120             {
1121                 field   => 'authorised_value',
1122                 type    => 'varchar(80)',
1123                                 null    => 'NOT NULL',
1124                 key     => '',
1125                 default => "''",
1126                 extra   => '',
1127             },
1128             {
1129                 field   => 'lib',
1130                 type    => 'varchar(80)',
1131                                 null    => 'NULL',
1132                 key     => '',
1133                 default => 'NULL',
1134                 extra   => '',
1135             },
1136         ],
1137
1138         biblio_framework => [
1139             {
1140                 field   => 'frameworkcode',
1141                 type    => 'varchar(4)',
1142                                 null    => 'NOT NULL',
1143                 key     => '',
1144                 default => "''",
1145                 extra   => '',
1146             },
1147             {
1148                 field   => 'frameworktext',
1149                 type    => 'varchar(255)',
1150                                 null    => 'NOT NULL',
1151                 key     => '',
1152                 default => "''",
1153                 extra   => '',
1154             },
1155         ],
1156
1157         borrowers => [
1158             {
1159                 field   => 'cardnumber',
1160                 type    => 'varchar(16)',
1161                                 null    => 'NULL',
1162                 key     => '',
1163                 default => 'NULL',
1164                 extra   => '',
1165             },
1166             {    field => 'surname',
1167                 type => 'mediumtext',
1168                 null => 'NOT NULL',
1169             },
1170             {    field => 'firstname',
1171                 type => 'text',
1172                 null => 'NULL',
1173             },
1174             {    field => 'title',
1175                 type => 'mediumtext',
1176                 null => 'NULL',
1177             },
1178             {    field => 'othernames',
1179                 type => 'mediumtext',
1180                 null => 'NULL',
1181             },
1182             {    field => 'initials',
1183                 type => 'text',
1184                 null => 'NULL',
1185             },
1186             {    field => 'B_email',
1187                 type => 'text',
1188                 null => 'NULL',
1189                 after => 'B_zipcode',
1190             },
1191             {
1192                 field => 'streetnumber', # street number (hidden if streettable table is empty)
1193                 type => 'varchar(10)',
1194                 null => 'NULL',
1195                 after => 'initials',
1196             },
1197             {
1198                 field => 'streettype', # street table, list builded from a system table
1199                 type => 'varchar(50)',
1200                 null => 'NULL',
1201                 after => 'streetnumber',
1202             },
1203             {    field => 'phone',
1204                 type => 'text',
1205                 null => 'NULL',
1206             },
1207             {
1208                 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1209                 type => 'varchar(10)',
1210                 null => 'NULL',
1211                 after => 'fax',
1212             },
1213             {
1214                 field => 'B_streettype', # street table, list builded from a system table
1215                 type => 'varchar(50)',
1216                 null => 'NULL',
1217                 after => 'B_streetnumber',
1218             },
1219             {
1220                 field => 'phonepro',
1221                 type => 'text',
1222                 null => 'NULL',
1223                 after => 'fax',
1224             },
1225             {
1226                 field => 'address2', # complement address
1227                 type => 'text',
1228                 null => 'NULL',
1229                 after => 'address',
1230             },
1231             {
1232                 field => 'emailpro',
1233                 type => 'text',
1234                 null => 'NULL',
1235                 after => 'fax',
1236             },
1237             {
1238                 field => 'contactfirstname', # contact's firstname
1239                 type => 'text',
1240                 null => 'NULL',
1241                 after => 'contactname',
1242             },
1243             {
1244                 field => 'contacttitle', # contact's title
1245                 type => 'text',
1246                 null => 'NULL',
1247                 after => 'contactfirstname',
1248             },
1249             {
1250                 field => 'branchcode',
1251                 type  => 'varchar(10)',
1252                 null  => 'NOT NULL',
1253                 default    => "''",
1254                 extra => '',
1255             },
1256             {
1257                 field => 'categorycode',
1258                 type  => 'varchar(10)',
1259                 null  => 'NOT NULL',
1260                 default    => "''",
1261                 extra => '',
1262             },
1263             {
1264                 field => 'address',
1265                 type  => 'mediumtext',
1266                 null  => 'NOT NULL',
1267                 default    => '',
1268                 extra => '',
1269             },
1270             {
1271                 field => 'email',
1272                 type  => 'mediumtext',
1273                 null  => 'NULL',
1274                 default    => '',
1275                 extra => '',
1276             },
1277             {
1278                 field => 'B_city',
1279                 type  => 'mediumtext',
1280                 null  => 'NULL',
1281                 default    => '',
1282                 extra => '',
1283             },
1284             {
1285                 field => 'city',
1286                 type  => 'mediumtext',
1287                 null  => 'NOT NULL',
1288                 default    => '',
1289                 extra => '',
1290             },
1291             {
1292                 field => 'fax',
1293                 type  => 'mediumtext',
1294                 null  => 'NULL',
1295                 default    => '',
1296                 extra => '',
1297             },
1298             {
1299                 field => 'B_phone',
1300                 type  => 'mediumtext',
1301                 null  => 'NULL',
1302                 default    => '',
1303                 extra => '',
1304             },
1305             {
1306                 field => 'contactname',
1307                 type  => 'mediumtext',
1308                 null  => 'NULL',
1309                 default    => '',
1310                 extra => '',
1311             },
1312             {
1313                 field => 'opacnote',
1314                 type  => 'mediumtext',
1315                 null  => 'NULL',
1316                 default    => '',
1317                 extra => '',
1318             },
1319             {
1320                 field => 'borrowernotes',
1321                 type  => 'mediumtext',
1322                 null  => 'NULL',
1323                 default    => '',
1324                 extra => '',
1325             },
1326             {
1327                 field => 'sex',
1328                 type  => 'varchar(1)',
1329                 null  => 'NULL',
1330                 default    => 'NULL',
1331                 extra => '',
1332             },
1333         ],
1334         
1335         biblioitems =>  [
1336             {
1337                 field    => 'itemtype',
1338                 type    => 'varchar(10)',
1339                 null    => 'NOT NULL',
1340                 key        => '',
1341                 default    => '',
1342                 extra    => '',
1343             },
1344             {
1345                 field    => 'lcsort',
1346                 type    => 'varchar(25)',
1347                 null    => 'NULL',
1348                 key        => '',
1349                 default    => '',
1350                 extra    => '',
1351             },
1352             {
1353                 field    => 'ccode',
1354                 type    => 'varchar(4)',
1355                 null    => 'NULL',
1356                 key        => '',
1357                 default    => '',
1358                 extra    => '',
1359             },
1360             {
1361                 field   => 'dewey',
1362                 type    => 'varchar(30)',
1363                 null    => 'null',
1364                 default => '',
1365                 extra   => '',
1366             },
1367             {
1368                 field   => 'publicationyear',
1369                 type    => 'text',
1370                 null    => 'null',
1371                 default => '',
1372                 extra   => '',
1373             },
1374             {
1375                 field   => 'collectiontitle',
1376                 type    => 'mediumtext',
1377                 null    => 'null',
1378                 default => '',
1379                 extra   => '',
1380                 after   => 'volumeddesc',
1381             },
1382             {
1383                 field   => 'collectionissn',
1384                 type    => 'text',
1385                 null    => 'null',
1386                 default => '',
1387                 extra   => '',
1388                 after   => 'collectiontitle',
1389             },
1390             {
1391                 field   => 'collectionvolume',
1392                 type    => 'mediumtext',
1393                 null    => 'null',
1394                 default => '',
1395                 extra   => '',
1396                 after   => 'collectionissn',
1397             },
1398             {
1399                 field   => 'editionstatement',
1400                 type    => 'text',
1401                 null    => 'null',
1402                 default => '',
1403                 extra   => '',
1404                 after   => 'collectionvolume',
1405             },
1406             {
1407                 field   => 'editionresponsibility',
1408                 type    => 'text',
1409                 null    => 'null',
1410                 default => '',
1411                 extra   => '',
1412                 after   => 'editionstatement',
1413             },
1414             {
1415                 field   => 'volume',
1416                 type    => 'mediumtext',
1417                 null    => 'NULL',
1418                 default => '',
1419                 extra   => '',
1420             },
1421             {
1422                 field   => 'number',
1423                 type    => 'mediumtext',
1424                 null    => 'NULL',
1425                 default => '',
1426                 extra   => '',
1427             },
1428             {
1429                 field   => 'notes',
1430                 type    => 'mediumtext',
1431                 null    => 'NULL',
1432                 default => '',
1433                 extra   => '',
1434             },
1435         ],
1436                 
1437         biblio => [
1438             {
1439                 field   => 'author',
1440                 type    => 'mediumtext',
1441                 null    => 'NULL',
1442                 default => '',
1443                 extra   => '',
1444             },
1445             {
1446                 field   => 'title',
1447                 type    => 'mediumtext',
1448                 null    => 'NULL',
1449                 default => '',
1450                 extra   => '',
1451             },
1452             {
1453                 field   => 'unititle',
1454                 type    => 'mediumtext',
1455                 null    => 'NULL',
1456                 default => '',
1457                 extra   => '',
1458             },
1459             {
1460                 field   => 'seriestitle',
1461                 type    => 'mediumtext',
1462                 null    => 'NULL',
1463                 default => '',
1464                 extra   => '',
1465             },
1466             {
1467                 field   => 'abstract',
1468                 type    => 'mediumtext',
1469                 null    => 'NULL',
1470                 default => '',
1471                 extra   => '',
1472             },
1473             {
1474                 field   => 'notes',
1475                 type    => 'mediumtext',
1476                 null    => 'NULL',
1477                 default => '',
1478                 extra   => '',
1479             },
1480             {
1481                 field   => 'frameworkcode',
1482                 type    => 'varchar(4)',
1483                 null    => 'NOT NULL',
1484                 default => "''",
1485                 extra   => '',
1486                 after   => 'biblionumber',
1487             },
1488             ],
1489
1490         deletedbiblio => [
1491             {
1492                 field   => 'author',
1493                 type    => 'mediumtext',
1494                 null    => 'NULL',
1495                 default => '',
1496                 extra   => '',
1497             },
1498             {
1499                 field   => 'title',
1500                 type    => 'mediumtext',
1501                 null    => 'NULL',
1502                 default => '',
1503                 extra   => '',
1504             },
1505             {
1506                 field   => 'unititle',
1507                 type    => 'mediumtext',
1508                 null    => 'NULL',
1509                 default => '',
1510                 extra   => '',
1511             },
1512             {
1513                 field   => 'seriestitle',
1514                 type    => 'mediumtext',
1515                 null    => 'NULL',
1516                 default => '',
1517                 extra   => '',
1518             },
1519             {
1520                 field   => 'abstract',
1521                 type    => 'mediumtext',
1522                 null    => 'NULL',
1523                 default => '',
1524                 extra   => '',
1525             },
1526             {
1527                 field   => 'notes',
1528                 type    => 'mediumtext',
1529                 null    => 'NULL',
1530                 default => '',
1531                 extra   => '',
1532             },
1533             {
1534                 field   => 'frameworkcode',
1535                 type    => 'varchar(4)',
1536                 null    => 'NOT NULL',
1537                 default => "''",
1538                 extra   => '',
1539                 after   => 'biblionumber',
1540             },
1541             ],
1542         deletedbiblioitems => [
1543             {
1544                 field   => 'itemtype',
1545                 type    => 'varchar(10)',
1546                 null    => 'NOT NULL',
1547                 default => '',
1548                 extra   => '',
1549             },
1550             {
1551                 field   => 'dewey',
1552                 type    => 'varchar(30)',
1553                 null    => 'null',
1554                 default => '',
1555                 extra   => '',
1556             },
1557             {
1558                 field   => 'itemtype',
1559                 type    => 'varchar(10)',
1560                 null    => 'NULL',
1561                 default => 'NULL',
1562                 extra   => '',
1563             },
1564             {
1565                 field   => 'volume',
1566                 type    => 'mediumtext',
1567                 null    => 'NULL',
1568                 default => '',
1569                 extra   => '',
1570             },
1571             {
1572                 field   => 'notes',
1573                 type    => 'mediumtext',
1574                 null    => 'NULL',
1575                 default => '',
1576                 extra   => '',
1577             },
1578             {
1579                 field   => 'number',
1580                 type    => 'mediumtext',
1581                 null    => 'NULL',
1582                 default => '',
1583                 extra   => '',
1584             },
1585         ],
1586
1587         bookshelf => [
1588             {
1589                 field   => 'shelfname',
1590                 type    => 'varchar(255)',
1591                 null    => 'NULL',
1592                 default => 'NULL',
1593                 extra   => '',
1594             },
1595             {
1596                 field   => 'owner',
1597                 type    => 'varchar(80)',
1598                 null    => 'NULL',
1599                 default => 'NULL',
1600                 extra   => '',
1601             },
1602             {
1603                 field   => 'category',
1604                 type    => 'varchar(1)',
1605                 null    => 'NULL',
1606                 default => 'NULL',
1607                 extra   => '',
1608             },
1609         ],
1610
1611         branchcategories => [
1612             {
1613                 field   => 'codedescription',
1614                 type    => 'mediumtext',
1615                 null    => 'NULL',
1616                 default => '',
1617                 extra   => '',
1618             },
1619         ],
1620
1621         branches =>  [
1622             {
1623                 field    => 'branchip',
1624                 type    => 'varchar(15)',
1625                 null    => 'NULL',
1626                 key        => '',
1627                 default    => '',
1628                 extra    => '',
1629             },
1630             {
1631                 field    => 'branchprinter',
1632                 type    => 'varchar(100)',
1633                 null    => 'NULL',
1634                 key        => '',
1635                 default    => '',
1636                 extra    => '',
1637             },
1638             {
1639                 field   => 'branchcode',
1640                 type    => 'varchar(10)',
1641                 null    => 'NOT NULL',
1642                 default => "''",
1643                 extra   => '',
1644             },
1645             {
1646                 field   => 'branchname',
1647                 type    => 'mediumtext',
1648                 null    => 'NOT NULL',
1649                 default => '',
1650                 extra   => '',
1651             },
1652             {
1653                 field   => 'branchaddress1',
1654                 type    => 'mediumtext',
1655                 null    => 'NULL',
1656                 default => '',
1657                 extra   => '',
1658             },
1659             {
1660                 field   => 'branchaddress2',
1661                 type    => 'mediumtext',
1662                 null    => 'NULL',
1663                 default => '',
1664                 extra   => '',
1665             },
1666             {
1667                 field   => 'branchaddress3',
1668                 type    => 'mediumtext',
1669                 null    => 'NULL',
1670                 default => '',
1671                 extra   => '',
1672             },
1673             {
1674                 field   => 'branchphone',
1675                 type    => 'mediumtext',
1676                 null    => 'NULL',
1677                 default => '',
1678                 extra   => '',
1679             },
1680             {
1681                 field   => 'branchfax',
1682                 type    => 'mediumtext',
1683                 null    => 'NULL',
1684                 default => '',
1685                 extra   => '',
1686             },
1687             {
1688                 field   => 'branchemail',
1689                 type    => 'mediumtext',
1690                 null    => 'NULL',
1691                 default => '',
1692                 extra   => '',
1693             },
1694         ],
1695     
1696         branchrelations => [
1697             {
1698                 field   => 'branchcode',
1699                 type    => 'VARCHAR(10)',
1700                 null    => 'NOT NULL',
1701                 key     => '',
1702                 default => "''",
1703                 extra   => '',
1704             },
1705             {
1706                 field   => 'categorycode',
1707                 type    => 'VARCHAR(10)',
1708                 null    => 'NOT NULL',
1709                 key     => '',
1710                 default => "''",
1711                 extra   => '',
1712             }
1713         ],
1714
1715         branchtransfers =>[
1716             {
1717                 field   => 'frombranch',
1718                 type    => 'VARCHAR(10)',
1719                 null    => 'NOT NULL',
1720                 key     => '',
1721                 default => "''",
1722                 extra   => '',
1723             },
1724             {
1725                 field   => 'tobranch',
1726                 type    => 'VARCHAR(10)',
1727                 null    => 'NOT NULL',
1728                 key     => '',
1729                 default => "''",
1730             },
1731             {
1732                 field   => 'comments',
1733                 type    => 'mediumtext',
1734                 null    => 'NULL',
1735                 key     => '',
1736                 default => '',
1737             },
1738         ],
1739         
1740         categories =>  [
1741             {
1742                 field    => 'category_type',
1743                 type    => 'varchar(1)',
1744                 null    => 'NOT NULL',
1745                 key        => '',
1746                 default    => 'A',
1747                 extra    => '',
1748             },
1749             {
1750                 field   => 'categorycode',
1751                 type    => 'varchar(10)',
1752                 null    => 'NOT NULL',
1753                 key     => 'PRI',
1754                 default => "''",
1755                 extra   => '',
1756             },
1757             {
1758                 field   => 'description',
1759                 type    => 'mediumtext',
1760                 null    => 'NULL',
1761                 key     => '',
1762                 default => '',
1763                 extra   => '',
1764             },
1765         ],
1766         
1767         deletedborrowers => [
1768             {
1769                 field => 'branchcode',
1770                 type  => 'varchar(10)',
1771                 null  => 'NOT NULL',
1772                 default    => "''",
1773                 extra => '',
1774             },
1775             {
1776                 field => 'categorycode',
1777                 type  => 'varchar(2)',
1778                 null  => 'NULL',
1779                 default    => 'NULL',
1780                 extra => '',
1781             },
1782             {
1783                 field => 'B_phone',
1784                 type  => 'mediumtext',
1785                 null  => 'NULL',
1786                 default    => '',
1787                 extra => '',
1788             },
1789             {
1790                 field => 'borrowernotes',
1791                 type  => 'mediumtext',
1792                 null  => 'NULL',
1793                 default    => '',
1794                 extra => '',
1795             },
1796             {
1797                 field => 'contactname',
1798                 type  => 'mediumtext',
1799                 null  => 'NULL',
1800                 default    => '',
1801                 extra => '',
1802             },
1803             {
1804                 field => 'B_city',
1805                 type  => 'mediumtext',
1806                 null  => 'NULL',
1807                 default    => '',
1808                 extra => '',
1809             },
1810             {
1811                 field => 'B_zipcode',
1812                 type  => 'varchar(25)',
1813                 null  => 'NULL',
1814                 default    => 'NULL',
1815                 extra => '',
1816             },
1817             {
1818                 field => 'zipcode',
1819                 type  => 'varchar(25)',
1820                 null  => 'NULL',
1821                 default    => 'NULL',
1822                 extra => '',
1823                 after => 'city',
1824             },
1825             {
1826                 field => 'email',
1827                 type  => 'mediumtext',
1828                 null  => 'NULL',
1829                 default    => '',
1830                 extra => '',
1831             },
1832             {
1833                 field => 'address',
1834                 type  => 'mediumtext',
1835                 null  => 'NOT NULL',
1836                 default    => '',
1837                 extra => '',
1838             },
1839             {
1840                 field => 'fax',
1841                 type  => 'mediumtext',
1842                 null  => 'NULL',
1843                 default    => '',
1844                 extra => '',
1845             },
1846             {
1847                 field => 'city',
1848                 type  => 'mediumtext',
1849                 null  => 'NOT NULL',
1850                 default    => '',
1851                 extra => '',
1852             },
1853             {    field => 'surname',
1854                 type => 'mediumtext',
1855                 null => 'NOT NULL',
1856             },
1857             {    field => 'firstname',
1858                 type => 'text',
1859                 null => 'NULL',
1860             },
1861             {    field => 'initials',
1862                 type => 'text',
1863                 null => 'NULL',
1864             },
1865             {    field => 'title',
1866                 type => 'mediumtext',
1867                 null => 'NULL',
1868             },
1869             {    field => 'othernames',
1870                 type => 'mediumtext',
1871                 null => 'NULL',
1872             },
1873             {    field => 'B_email',
1874                 type => 'text',
1875                 null => 'NULL',
1876                 after => 'B_zipcode',
1877             },
1878             {
1879                 field => 'streetnumber', # street number (hidden if streettable table is empty)
1880                 type => 'varchar(10)',
1881                 null => 'NULL',
1882                 default => 'NULL',
1883                 after => 'initials',
1884             },
1885             {
1886                 field => 'streettype', # street table, list builded from a system table
1887                 type => 'varchar(50)',
1888                 null => 'NULL',
1889                 default => 'NULL',
1890                 after => 'streetnumber',
1891             },
1892             {    field => 'phone',
1893                 type => 'text',
1894                 null => 'NULL',
1895             },
1896             {
1897                 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1898                 type => 'varchar(10)',
1899                 null => 'NULL',
1900                 after => 'fax',
1901             },
1902             {
1903                 field => 'B_streettype', # street table, list builded from a system table
1904                 type => 'varchar(50)',
1905                 null => 'NULL',
1906                 after => 'B_streetnumber',
1907             },
1908             {
1909                 field => 'phonepro',
1910                 type => 'text',
1911                 null => 'NULL',
1912                 after => 'fax',
1913             },
1914             {
1915                 field => 'address2', # complement address
1916                 type => 'text',
1917                 null => 'NULL',
1918                 after => 'address',
1919             },
1920             {
1921                 field => 'emailpro',
1922                 type => 'text',
1923                 null => 'NULL',
1924                 after => 'fax',
1925             },
1926             {
1927                 field => 'contactfirstname', # contact's firstname
1928                 type => 'text',
1929                 null => 'NULL',
1930                 after => 'contactname',
1931             },
1932             {
1933                 field => 'contacttitle', # contact's title
1934                 type => 'text',
1935                 null => 'NULL',
1936                 after => 'contactfirstname',
1937             },
1938             {
1939                 field => 'sex',
1940                 type  => 'varchar(1)',
1941                 null  => 'NULL',
1942                 default    => 'NULL',
1943                 extra => '',
1944             },
1945         ],
1946         
1947         issues =>  [
1948             {
1949                 field    => 'borrowernumber',
1950                 type    => 'int(11)',
1951                 null    => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1952                 key        => '',
1953                 default    => '',
1954                 extra    => '',
1955             },
1956             {
1957                 field    => 'itemnumber',
1958                 type    => 'int(11)',
1959                 null    => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1960                 key        => '',
1961                 default    => '',
1962                 extra    => '',
1963             },
1964             {
1965                 field   => 'branchcode',
1966                 type    => 'varchar(10)',
1967                 null    => 'NULL',
1968                 key     => '',
1969                 default => '',
1970                 extra   => '',
1971             },
1972             {
1973                 field   => 'issuedate',
1974                 type    => 'date',
1975                 null    => 'NULL',
1976                 key     => '',
1977                 default => '',
1978                 extra   => '',
1979             },
1980             {
1981                 field   => 'return',
1982                 type    => 'varchar(4)',
1983                 null    => 'NULL',
1984                 key     => '',
1985                 default => 'NULL',
1986                 extra   => '',
1987             },
1988             {
1989                 field   => 'issuingbranch',
1990                 type    => 'varchar(18)',
1991                 null    => 'NULL',
1992                 key     => '',
1993                 default => '',
1994                 extra   => '',
1995             },
1996         ],
1997         issuingrules => [
1998             {
1999                 field   => 'categorycode',
2000                 type    => 'varchar(10)',
2001                 null    => 'NOT NULL',
2002                 default => "''",
2003                 extra   => '',
2004             },
2005             {
2006                 field   => 'branchcode',
2007                 type    => 'varchar(10)',
2008                 null    => 'NOT NULL',
2009                 default => "''",
2010                 extra   => '',
2011             },
2012             {
2013                 field   => 'itemtype',
2014                 type    => 'varchar(10)',
2015                 null    => 'NOT NULL',
2016                 default => "''",
2017                 extra   => '',
2018             },
2019         ],
2020
2021         items => [
2022             {
2023                 field    => 'onloan',
2024                 type    => 'date',
2025                 null    => 'NULL',
2026                 key        => '',
2027                 default    => '',
2028                 extra    => '',
2029             },
2030             {
2031                 field    => 'cutterextra',
2032                 type    => 'varchar(45)',
2033                 null    => 'NULL',
2034                 key        => '',
2035                 default    => '',
2036                 extra    => '',
2037             },
2038             {
2039                 field    => 'homebranch',
2040                 type    => 'varchar(10)',
2041                 null    => 'NULL',
2042                 key        => '',
2043                 default    => '',
2044                 extra    => '',
2045             },
2046             {
2047                 field    => 'holdingbranch',
2048                 type    => 'varchar(10)',
2049                 null    => 'NULL',
2050                 key        => '',
2051                 default    => '',
2052                 extra    => '',
2053             },
2054             {
2055                 field    => 'itype',
2056                 type    => 'varchar(10)',
2057                 null    => 'NULL',
2058                 key        => '',
2059                 default    => '',
2060                 extra    => '',
2061             },
2062             {
2063                 field    => 'paidfor',
2064                 type    => 'mediumtext',
2065                 null    => 'NULL',
2066                 key        => '',
2067                 default    => '',
2068                 extra    => '',
2069             },
2070             {
2071                 field    => 'itemnotes',
2072                 type    => 'mediumtext',
2073                 null    => 'NULL',
2074                 key        => '',
2075                 default    => '',
2076                 extra    => '',
2077             },
2078         ],
2079
2080         deleteditems => [
2081             {
2082                 field    => 'paidfor',
2083                 type    => 'mediumtext',
2084                 null    => 'NULL',
2085                 key        => '',
2086                 default    => '',
2087                 extra    => '',
2088             },
2089             {
2090                 field    => 'itemnotes',
2091                 type    => 'mediumtext',
2092                 null    => 'NULL',
2093                 key        => '',
2094                 default    => '',
2095                 extra    => '',
2096             },
2097         ],
2098
2099         itemtypes => [
2100             {
2101                 field  => 'itemtype',
2102                 type   => 'varchar(10)',
2103                 default    => "''",
2104                 null   => 'NOT NULL',
2105                 key    => 'PRI',
2106                 extra  => 'UNIQUE',
2107             },
2108             {
2109                 field  => 'description',
2110                 type   => 'MEDIUMTEXT',
2111                 null   => 'NULL',
2112                 key    => '',
2113                 extra  => '',
2114             },
2115             {
2116                 field  => 'summary',
2117                 type   => 'TEXT',
2118                 null   => 'NULL',
2119                 key    => '',
2120                 extra  => '',
2121             },
2122         ],
2123         marc_breeding => [
2124             {
2125                 field => 'marc',
2126                 type  => 'LONGBLOB',
2127                 null  => 'NULL',
2128                 key    => '',
2129                 extra  => '',
2130             }
2131         ],
2132         marc_subfield_structure => [
2133             {
2134                 field => 'defaultvalue',
2135                 type  => 'TEXT',
2136                 null  => 'NULL',
2137                 key    => '',
2138                 extra  => '',
2139             },
2140             {
2141                 field   => 'authtypecode',
2142                 type    => 'varchar(20)',
2143                                 null    => 'NULL',
2144                 key     => '',
2145                 default => 'NULL',
2146                 extra   => '',
2147             },
2148             {
2149                 field   => 'tagfield',
2150                 type    => 'varchar(3)',
2151                                 null    => 'NOT NULL',
2152                 key     => '',
2153                 default => "''",
2154                 extra   => '',
2155             },
2156             {
2157                 field   => 'tagsubfield',
2158                 type    => 'varchar(1)',
2159                                 null    => 'NOT NULL',
2160                 key     => '',
2161                 default => "''",
2162                 extra   => '',
2163             },
2164             {
2165                 field   => 'authorised_value',
2166                 type    => 'varchar(20)',
2167                                 null    => 'NULL',
2168                 key     => '',
2169                 default => "NULL",
2170                 extra   => '',
2171             },
2172             {
2173                 field   => 'seealso',
2174                 type    => 'varchar(1100)',
2175                                 null    => 'NULL',
2176                 key     => '',
2177                 default => "NULL",
2178                 extra   => '',
2179             },
2180         ],
2181             
2182         marc_tag_structure => [
2183             {
2184                 field   => 'tagfield',
2185                 type    => 'varchar(3)',
2186                                 null    => 'NOT NULL',
2187                 key     => '',
2188                 default => "''",
2189                 extra   => '',
2190             },
2191             {
2192                 field   => 'liblibrarian',
2193                 type    => 'varchar(255)',
2194                                 null    => 'NOT NULL',
2195                 key     => '',
2196                 default => "''",
2197                 extra   => '',
2198             },
2199             {
2200                 field   => 'libopac',
2201                 type    => 'varchar(255)',
2202                                 null    => 'NOT NULL',
2203                 key     => '',
2204                 default => "''",
2205                 extra   => '',
2206             },
2207             {
2208                 field   => 'authorised_value',
2209                 type    => 'varchar(10)',
2210                                 null    => 'NULL',
2211                 key     => '',
2212                 default => "NULL",
2213                 extra   => '',
2214             },
2215             {
2216                 field   => 'frameworkcode',
2217                 type    => 'varchar(4)',
2218                                 null    => 'NOT NULL',
2219                 key     => '',
2220                 default => "''",
2221                 extra   => '',
2222             },
2223         ],
2224
2225         opac_news => [
2226             {
2227                 field  => 'expirationdate',
2228                 type   => 'date',
2229                 null   => 'null',
2230                 key    => '',
2231                 extra  => '',
2232             },
2233             {
2234                 field   => 'number',
2235                 type    => 'int(11)',
2236                 null    => 'NULL',
2237                 key     => '',
2238                 default => '',
2239                 extra   => '',
2240             },
2241         ],
2242
2243         printers => [
2244             {
2245                 field   => 'printername',
2246                 type    => 'varchar(40)',
2247                                 null    => 'NOT NULL',
2248                 key     => '',
2249                 default => "''",
2250                 extra   => '',
2251             },
2252             {
2253                 field   => 'printqueue',
2254                 type    => 'varchar(20)',
2255                                 null    => 'NULL',
2256                 key     => '',
2257                 default => "NULL",
2258                 extra   => '',
2259             },
2260             {
2261                 field   => 'printtype',
2262                 type    => 'varchar(20)',
2263                                 null    => 'NULL',
2264                 key     => '',
2265                 default => "NULL",
2266                 extra   => '',
2267             },
2268         ],
2269
2270         reserveconstraints => [
2271             {
2272                 field    => 'reservedate',
2273                 type    => 'date',
2274                 null    => 'NULL',
2275                 key        => '',
2276                 default    => 'NULL',
2277                 extra    => '',
2278             },
2279         ],
2280
2281         reserves =>  [
2282             {
2283                 field    => 'waitingdate',
2284                 type    => 'date',
2285                 null    => 'NULL',
2286                 key        => '',
2287                 default    => '',
2288                 extra    => '',
2289             },
2290             {
2291                 field    => 'reservedate',
2292                 type    => 'date',
2293                 null    => 'NULL',
2294                 key        => '',
2295                 default    => '',
2296                 extra    => '',
2297             },
2298             {
2299                 field    => 'constrainttype',
2300                 type    => 'varchar(1)',
2301                 null    => 'NULL',
2302                 key        => '',
2303                 default    => 'NULL',
2304                 extra    => '',
2305                 after   => 'biblionumber',
2306             },
2307             {
2308                 field    => 'branchcode',
2309                 type    => 'varchar(10)',
2310                 null    => 'NULL',
2311                 key        => '',
2312                 default    => '',
2313                 extra    => '',
2314             },
2315             {
2316                 field    => 'reservenotes',
2317                 type    => 'mediumtext',
2318                 null    => 'NULL',
2319                 key        => '',
2320                 default    => '',
2321                 extra    => '',
2322             },
2323             {
2324                 field    => 'found',
2325                 type    => 'varchar(1)',
2326                 null    => 'NULL',
2327                 key        => '',
2328                 default    => '',
2329                 extra    => '',
2330             },
2331         ],
2332
2333         serial => [
2334             {
2335                 field   => 'planneddate',
2336                 type    => 'DATE',
2337                 null    => 'NULL',
2338                 key     => '',
2339                 default => 'NULL',
2340                 extra   => '',
2341             },
2342             {
2343                 field   => 'notes',
2344                 type    => 'TEXT',
2345                 null    => 'NULL',
2346                 key     => '',
2347                 default => '',
2348                 extra   => '',
2349                 after   => 'planneddate',
2350             },
2351         ],
2352
2353         shelfcontents => [
2354             {
2355                 field => 'dateadded',
2356                 type => 'timestamp',
2357                 null    => 'NULL',
2358             },
2359         ],
2360
2361         statistics => [
2362             {
2363                 field => 'branch',
2364                 type => 'varchar(10)',
2365                 null    => 'NOT NULL',
2366             },
2367             {
2368                 field => 'datetime',
2369                 type => 'datetime',
2370                 null    => 'NULL',
2371                 default => 'NULL',
2372             },
2373             {
2374                 field => 'itemtype',
2375                 type => 'varchar(10)',
2376                 null    => 'NULL',
2377             },
2378             {
2379                 field => 'other',
2380                 type => 'mediumtext',
2381                 null    => 'NULL',
2382             },
2383         ],
2384
2385         subscription => [
2386             {
2387                 field   => 'startdate',
2388                 type    => 'date',
2389                 null    => 'NULL',
2390                 key     => ''  ,
2391                 default => 'NULL',
2392                 extra   =>    '',
2393             },
2394             {
2395                 field   => 'notes',
2396                 type    => 'mediumtext',
2397                 null    => 'NULL',
2398                 key     => ''  ,
2399                 default => '',
2400                 extra   =>    '',
2401             },
2402             {
2403                 field   => 'monthlength',
2404                 type    => 'int(11)',
2405                 null    => 'NULL',
2406                 key     => ''  ,
2407                 default => '0',
2408                 extra   =>    '',
2409             },
2410         ],
2411
2412         subscriptionhistory => [
2413             {
2414                 field   => 'histstartdate',
2415                 type    => 'date',
2416                 null    => 'NULL',
2417                 key     => ''  ,
2418                 default => 'NULL',
2419                 extra   =>    '',
2420             },
2421             {
2422                 field   => 'enddate',
2423                 type    => 'date',
2424                 null    => 'NULL',
2425                 key     => ''  ,
2426                 default => 'NULL',
2427                 extra   =>    '',
2428             },
2429         ],
2430
2431         systempreferences =>  [
2432             {
2433                 field   => 'options',
2434                 type    => 'mediumtext',
2435                 null    => 'NULL',
2436                 key     => ''  ,
2437                 default => '',
2438                 extra   =>    '',
2439             },
2440             {
2441                 field    => 'value',
2442                 type    => 'text',
2443                 null    => 'NULL',
2444                 key        => '',
2445                 default    => '',
2446                 extra    => '',
2447             },
2448             {
2449                 field    => 'explanation',
2450                 type    => 'text',
2451                 null    => 'NULL',
2452                 key        => '',
2453                 default    => '',
2454                 extra    => '',
2455             },
2456         ],
2457         suggestions => [
2458             {
2459                 field   => 'reason',
2460                 type    => 'text',
2461                 null    => 'NULL',
2462                 key     => ''  ,
2463                 default => '',
2464                 extra   =>    '',
2465             },
2466             {
2467                 field   => 'note',
2468                 type    => 'mediumtext',
2469                 null    => 'NULL',
2470                 key     => ''  ,
2471                 default => '',
2472                 extra   =>    '',
2473             },
2474         ],
2475         userflags => [
2476             {
2477                 field   => 'flag',
2478                 type    => 'varchar(30)',
2479                 null    => 'NULL',
2480                 key     => ''  ,
2481                 default => '',
2482                 extra   =>    '',
2483             },
2484             {
2485                 field   => 'flagdesc',
2486                 type    => 'varchar(255)',
2487                 null    => 'NULL',
2488                 key     => ''  ,
2489                 default => '',
2490                 extra   =>    '',
2491             },
2492         ],
2493         z3950servers => [
2494             {
2495                 field   => 'name',
2496                 type    => 'mediumtext',
2497                 null    => 'NULL',
2498                 key     => ''  ,
2499                 default => '',
2500                 extra   =>    '',
2501             },
2502         ],
2503     );
2504     
2505     my %indexes = (
2506     #    table => [
2507     #         {    indexname => 'index detail'
2508     #         }
2509     #    ],
2510         accountoffsets => [
2511             {    indexname => 'accountoffsets_ibfk_1',
2512                 content => 'borrowernumber',
2513             },
2514         ],
2515         aqbooksellers => [
2516             {    indexname => 'PRIMARY',
2517                 content => 'id',
2518                 type => 'PRI',
2519             }
2520         ],
2521         aqbasket => [
2522             {    indexname => 'booksellerid',
2523                 content => 'booksellerid',
2524             },
2525         ],
2526         aqorders => [
2527             {    indexname => 'basketno',
2528                 content => 'basketno',
2529             },
2530         ],
2531         aqorderbreakdown => [
2532             {    indexname => 'ordernumber',
2533                 content => 'ordernumber',
2534             },
2535             {    indexname => 'bookfundid',
2536                 content => 'bookfundid',
2537             },
2538         ],
2539         biblioitems => [
2540             {    indexname => 'isbn',
2541                 content => 'isbn',
2542             },
2543             {    indexname => 'publishercode',
2544                 content => 'publishercode',
2545             },
2546         ],
2547         borrowers => [
2548             {
2549                 indexname => 'borrowernumber',
2550                 content   => 'borrowernumber',
2551                 type => 'PRI',
2552                 force => 1,
2553             }
2554         ],
2555         branches => [
2556             {
2557                 indexname => 'branchcode',
2558                 content   => 'branchcode',
2559                 type => 'PRI',
2560             }
2561         ],
2562         branchrelations => [
2563             {
2564                 indexname => 'PRIMARY',
2565                 content => 'categorycode',
2566                 type => 'PRI',
2567             }
2568         ],
2569         branchrelations => [
2570             {    indexname => 'PRIMARY',
2571                 content => 'branchcode,categorycode',
2572                 type => 'PRI',
2573             },
2574             {    indexname => 'branchcode',
2575                 content => 'branchcode',
2576             },
2577             {    indexname => 'categorycode',
2578                 content => 'categorycode',
2579             }
2580         ],
2581         currency => [
2582             {    indexname => 'PRIMARY',
2583                 content => 'currency',
2584                 type => 'PRI',
2585             }
2586         ],
2587         categories => [
2588             {
2589                 indexname => 'categorycode',
2590                 content   => 'categorycode',
2591             }
2592         ],
2593         issuingrules => [
2594             {
2595                 indexname => 'categorycode',
2596                 content   => 'categorycode',
2597             },
2598             {
2599                 indexname => 'itemtype',
2600                 content   => 'itemtype',
2601             },
2602         ],
2603         items => [
2604             {    indexname => 'homebranch',
2605                 content => 'homebranch',
2606             },
2607             {    indexname => 'holdingbranch',
2608                 content => 'holdingbranch',
2609             }
2610         ],
2611         itemtypes => [
2612             {
2613                 indexname => 'itemtype',
2614                 content   => 'itemtype',
2615             }
2616         ],
2617         shelfcontents => [
2618             {    indexname => 'shelfnumber',
2619                 content => 'shelfnumber',
2620             },
2621             {    indexname => 'itemnumber',
2622                 content => 'itemnumber',
2623             }
2624         ],
2625             userflags => [
2626                     {   indexname => 'PRIMARY',
2627                             content => 'bit',
2628                             type => 'PRI',
2629                     }
2630             ]
2631     );
2632     
2633     my %foreign_keys = (
2634     #    table => [
2635     #         {    key => 'the key in table' (must be indexed)
2636     #            foreigntable => 'the foreigntable name', # (the parent)
2637     #            foreignkey => 'the foreign key column(s)' # (in the parent)
2638     #            onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
2639     #            onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
2640     #         }
2641     #    ],
2642         branchrelations => [
2643             {    key => 'branchcode',
2644                 foreigntable => 'branches',
2645                 foreignkey => 'branchcode',
2646                 onUpdate => 'CASCADE',
2647                 onDelete => 'CASCADE',
2648             },
2649             {    key => 'categorycode',
2650                 foreigntable => 'branchcategories',
2651                 foreignkey => 'categorycode',
2652                 onUpdate => 'CASCADE',
2653                 onDelete => 'CASCADE',
2654             },
2655         ],
2656         shelfcontents => [
2657             {    key => 'shelfnumber',
2658                 foreigntable => 'bookshelf',
2659                 foreignkey => 'shelfnumber',
2660                 onUpdate => 'CASCADE',
2661                 onDelete => 'CASCADE',
2662             },
2663             {    key => 'itemnumber',
2664                 foreigntable => 'items',
2665                 foreignkey => 'itemnumber',
2666                 onUpdate => 'CASCADE',
2667                 onDelete => 'CASCADE',
2668             },
2669         ],
2670         # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
2671         # easily deleted, but branches/itemtype not too easy to empty...
2672         biblioitems => [
2673             {    key => 'biblionumber',
2674                 foreigntable => 'biblio',
2675                 foreignkey => 'biblionumber',
2676                 onUpdate => 'CASCADE',
2677                 onDelete => 'CASCADE',
2678             },
2679         ],
2680         items => [
2681             {    key => 'biblioitemnumber',
2682                 foreigntable => 'biblioitems',
2683                 foreignkey => 'biblioitemnumber',
2684                 onUpdate => 'CASCADE',
2685                 onDelete => 'CASCADE',
2686             },
2687             {    key => 'homebranch',
2688                 foreigntable => 'branches',
2689                 foreignkey => 'branchcode',
2690                 onUpdate => 'CASCADE',
2691                 onDelete => 'RESTRICT',
2692             },
2693             {    key => 'holdingbranch',
2694                 foreigntable => 'branches',
2695                 foreignkey => 'branchcode',
2696                 onUpdate => 'CASCADE',
2697                 onDelete => 'RESTRICT',
2698             },
2699         ],
2700         aqbasket => [
2701             {    key => 'booksellerid',
2702                 foreigntable => 'aqbooksellers',
2703                 foreignkey => 'id',
2704                 onUpdate => 'CASCADE',
2705                 onDelete => 'RESTRICT',
2706             },
2707         ],
2708         aqorders => [
2709             {    key => 'basketno',
2710                 foreigntable => 'aqbasket',
2711                 foreignkey => 'basketno',
2712                 onUpdate => 'CASCADE',
2713                 onDelete => 'CASCADE',
2714             },
2715             {    key => 'biblionumber',
2716                 foreigntable => 'biblio',
2717                 foreignkey => 'biblionumber',
2718                 onUpdate => 'SET NULL',
2719                 onDelete => 'SET NULL',
2720             },
2721         ],
2722         aqbooksellers => [
2723             {    key => 'listprice',
2724                 foreigntable => 'currency',
2725                 foreignkey => 'currency',
2726                 onUpdate => 'CASCADE',
2727                 onDelete => 'CASCADE',
2728             },
2729             {    key => 'invoiceprice',
2730                 foreigntable => 'currency',
2731                 foreignkey => 'currency',
2732                 onUpdate => 'CASCADE',
2733                 onDelete => 'CASCADE',
2734             },
2735         ],
2736         aqorderbreakdown => [
2737             {    key => 'ordernumber',
2738                 foreigntable => 'aqorders',
2739                 foreignkey => 'ordernumber',
2740                 onUpdate => 'CASCADE',
2741                 onDelete => 'CASCADE',
2742             },
2743             {    key => 'bookfundid',
2744                 foreigntable => 'aqbookfund',
2745                 foreignkey => 'bookfundid',
2746                 onUpdate => 'CASCADE',
2747                 onDelete => 'CASCADE',
2748             },
2749         ],
2750         branchtransfers => [
2751             {    key => 'frombranch',
2752                 foreigntable => 'branches',
2753                 foreignkey => 'branchcode',
2754                 onUpdate => 'CASCADE',
2755                 onDelete => 'CASCADE',
2756             },
2757             {    key => 'tobranch',
2758                 foreigntable => 'branches',
2759                 foreignkey => 'branchcode',
2760                 onUpdate => 'CASCADE',
2761                 onDelete => 'CASCADE',
2762             },
2763             {    key => 'itemnumber',
2764                 foreigntable => 'items',
2765                 foreignkey => 'itemnumber',
2766                 onUpdate => 'CASCADE',
2767                 onDelete => 'CASCADE',
2768             },
2769         ],
2770         issues => [    # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
2771         # for stat purposes
2772             {    key => 'borrowernumber',
2773                 foreigntable => 'borrowers',
2774                 foreignkey => 'borrowernumber',
2775                 onUpdate => 'SET NULL',
2776                 onDelete => 'SET NULL',
2777             },
2778             {    key => 'itemnumber',
2779                 foreigntable => 'items',
2780                 foreignkey => 'itemnumber',
2781                 onUpdate => 'SET NULL',
2782                 onDelete => 'SET NULL',
2783             },
2784         ],
2785         reserves => [
2786             {    key => 'borrowernumber',
2787                 foreigntable => 'borrowers',
2788                 foreignkey => 'borrowernumber',
2789                 onUpdate => 'CASCADE',
2790                 onDelete => 'CASCADE',
2791             },
2792             {    key => 'biblionumber',
2793                 foreigntable => 'biblio',
2794                 foreignkey => 'biblionumber',
2795                 onUpdate => 'CASCADE',
2796                 onDelete => 'CASCADE',
2797             },
2798             {    key => 'itemnumber',
2799                 foreigntable => 'items',
2800                 foreignkey => 'itemnumber',
2801                 onUpdate => 'CASCADE',
2802                 onDelete => 'CASCADE',
2803             },
2804             {    key => 'branchcode',
2805                 foreigntable => 'branches',
2806                 foreignkey => 'branchcode',
2807                 onUpdate => 'CASCADE',
2808                 onDelete => 'CASCADE',
2809             },
2810         ],
2811         borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2812         # but prevent deleting a branch as soon as it has 1 borrower !
2813             {    key => 'categorycode',
2814                 foreigntable => 'categories',
2815                 foreignkey => 'categorycode',
2816                 onUpdate => 'RESTRICT',
2817                 onDelete => 'RESTRICT',
2818             },
2819             {    key => 'branchcode',
2820                 foreigntable => 'branches',
2821                 foreignkey => 'branchcode',
2822                 onUpdate => 'RESTRICT',
2823                 onDelete => 'RESTRICT',
2824             },
2825         ],
2826         accountlines => [
2827             {    key => 'borrowernumber',
2828                 foreigntable => 'borrowers',
2829                 foreignkey => 'borrowernumber',
2830                 onUpdate => 'CASCADE',
2831                 onDelete => 'CASCADE',
2832             },
2833             {    key => 'itemnumber',
2834                 foreigntable => 'items',
2835                 foreignkey => 'itemnumber',
2836                 onUpdate => 'SET NULL',
2837                 onDelete => 'SET NULL',
2838             },
2839         ],
2840         accountoffsets => [
2841             {    key => 'borrowernumber',
2842                 foreigntable => 'borrowers',
2843                 foreignkey => 'borrowernumber',
2844                 onUpdate => 'CASCADE',
2845                 onDelete => 'CASCADE',
2846             },
2847         ],
2848         auth_tag_structure => [
2849             {    key => 'authtypecode',
2850                 foreigntable => 'auth_types',
2851                 foreignkey => 'authtypecode',
2852                 onUpdate => 'CASCADE',
2853                 onDelete => 'CASCADE',
2854             },
2855         ],
2856         # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
2857     );
2858     
2859     
2860     # column changes
2861     my %column_change = (
2862         # table
2863         borrowers => [
2864                     {
2865                         from => 'emailaddress',
2866                         to => 'email',
2867                         after => 'city',
2868                     },
2869                     {
2870                         from => 'streetaddress',
2871                         to => 'address',
2872                         after => 'initials',
2873                     },
2874                     {
2875                         from => 'faxnumber',
2876                         to => 'fax',
2877                         after => 'phone',
2878                     },
2879                     {
2880                         from => 'textmessaging',
2881                         to => 'opacnote',
2882                         after => 'userid',
2883                     },
2884                     {
2885                         from => 'altnotes',
2886                         to => 'contactnote',
2887                         after => 'opacnote',
2888                     },
2889                     {
2890                         from => 'physstreet',
2891                         to => 'B_address',
2892                         after => 'fax',
2893                     },
2894                     {
2895                         from => 'streetcity',
2896                         to => 'B_city',
2897                         after => 'B_address',
2898                     },
2899                     {
2900                         from => 'phoneday',
2901                         to => 'mobile',
2902                         after => 'phone',
2903                     },
2904                     {
2905                         from => 'zipcode',
2906                         to => 'zipcode',
2907                         after => 'city',
2908                     },
2909                     {
2910                         from => 'homezipcode',
2911                         to => 'B_zipcode',
2912                         after => 'B_city',
2913                     },
2914                     {
2915                         from => 'altphone',
2916                         to => 'B_phone',
2917                         after => 'B_zipcode',
2918                     },
2919                     {
2920                         from => 'expiry',
2921                         to => 'dateexpiry',
2922                         after => 'dateenrolled',
2923                     },
2924                     {
2925                         from => 'guarantor',
2926                         to => 'guarantorid',
2927                         after => 'contactname',
2928                     },
2929                     {
2930                         from => 'altrelationship',
2931                         to => 'relationship',
2932                         after => 'borrowernotes',
2933                     },
2934                 ],
2935     
2936         deletedborrowers => [
2937                     {
2938                         from => 'emailaddress',
2939                         to => 'email',
2940                         after => 'city',
2941                     },
2942                     {
2943                         from => 'streetaddress',
2944                         to => 'address',
2945                         after => 'initials',
2946                     },
2947                     {
2948                         from => 'faxnumber',
2949                         to => 'fax',
2950                         after => 'phone',
2951                     },
2952                     {
2953                         from => 'textmessaging',
2954                         to => 'opacnote',
2955                         after => 'userid',
2956                     },
2957                     {
2958                         from => 'altnotes',
2959                         to => 'contactnote',
2960                         after => 'opacnote',
2961                     },
2962                     {
2963                         from => 'physstreet',
2964                         to => 'B_address',
2965                         after => 'fax',
2966                     },
2967                     {
2968                         from => 'streetcity',
2969                         to => 'B_city',
2970                         after => 'B_address',
2971                     },
2972                     {
2973                         from => 'phoneday',
2974                         to => 'mobile',
2975                         after => 'phone',
2976                     },
2977                     {
2978                         from => 'zipcode',
2979                         to => 'zipcode',
2980                         after => 'city',
2981                     },
2982                     {
2983                         from => 'homezipcode',
2984                         to => 'B_zipcode',
2985                         after => 'B_city',
2986                     },
2987                     {
2988                         from => 'altphone',
2989                         to => 'B_phone',
2990                         after => 'B_zipcode',
2991                     },
2992                     {
2993                         from => 'expiry',
2994                         to => 'dateexpiry',
2995                         after => 'dateenrolled',
2996                     },
2997                     {
2998                         from => 'guarantor',
2999                         to => 'guarantorid',
3000                         after => 'contactname',
3001                     },
3002                     {
3003                         from => 'altrelationship',
3004                         to => 'relationship',
3005                         after => 'borrowernotes',
3006                     },
3007                 ],
3008             );
3009         
3010     
3011     # MOVE all tables TO UTF-8 and innoDB
3012     $sth = $dbh->prepare("show table status");
3013     $sth->execute;
3014     while ( my $table = $sth->fetchrow_hashref ) {
3015         next if $table->{Name} eq 'marc_word';
3016         next if $table->{Name} eq 'marc_subfield_table';
3017         next if $table->{Name} eq 'auth_word';
3018         next if $table->{Name} eq 'auth_subfield_table';
3019         if ($table->{Engine} ne 'InnoDB') {
3020             print "moving $table->{Name} to InnoDB\n";
3021             $dbh->do("ALTER TABLE $table->{Name} ENGINE = innodb");
3022         }
3023         unless ($table->{Collation} =~ /^utf8/) {
3024             print "moving $table->{Name} to utf8\n";
3025             $dbh->do("ALTER TABLE $table->{Name} CONVERT TO CHARACTER SET utf8");
3026             $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
3027             # 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 !
3028         } else {
3029         }
3030     }
3031    
3032     # list of columns that must exist for %column_change to be
3033     # processed without error, but which do not necessarily exist
3034     # in all 2.2 databases
3035     my %required_prereq_fields = (
3036         deletedborrowers => [ 
3037                                 [ 'textmessaging', 'mediumtext AFTER faxnumber' ],
3038                                 [ 'password',      'varchar(30) default NULL'   ],
3039                                 [ 'flags',         'int(11) default NULL'       ],
3040                                 [ 'userid',        'varchar(30) default NULL'   ],
3041                                 [ 'homezipcode',   'varchar(25) default NULL'   ],
3042                                 [ 'zipcode',       'varchar(25) default NULL'   ],
3043                                 [ 'sort1',         'varchar(80) default NULL'   ],
3044                                 [ 'sort2',         'varchar(80) default NULL'   ],
3045                              ],
3046     );
3047
3048     foreach my $table ( keys %required_prereq_fields ) {
3049         print "Check table $table\n" if $debug and not $silent;
3050         $sth = $dbh->prepare("show columns from $table");
3051         $sth->execute();
3052         undef %types;
3053         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3054         {
3055             $types{$column} = $type;
3056         }    # while
3057         foreach my $entry ( @{ $required_prereq_fields{$table} } ) {
3058             ($column, $type) = @{ $entry };
3059             print "  Check column $column  [$type]\n" if $debug and not $silent;
3060             if ( !$types{$column} ) {
3061     
3062                 # column doesn't exist
3063                 print "Adding $column field to $table table...\n" unless $silent;
3064                 $query = "alter table $table
3065                 add column $column " . $type;
3066                 print "Execute: $query\n" if $debug;
3067                 my $sti = $dbh->prepare($query);
3068                 $sti->execute;
3069                 if ( $sti->err ) {
3070                     print "**Error : $sti->errstr \n";
3071                     $sti->finish;
3072                 }    # if error
3073             }    # if column
3074         }    # foreach column
3075     }    # foreach table
3076     
3077     foreach my $table (keys %column_change) {
3078         $sth = $dbh->prepare("show columns from $table");
3079         $sth->execute();
3080         undef %types;
3081         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3082         {
3083             $types{$column}->{type} ="$type";
3084             $types{$column}->{null} = "$null";
3085             $types{$column}->{key} = "$key";
3086             $types{$column}->{default} = "$default";
3087             $types{$column}->{extra} = "$extra";
3088         }    # while
3089         my $tablerows = $column_change{$table};
3090         foreach my $row ( @$tablerows ) {
3091             if ($types{$row->{from}}->{type}) {
3092                 print "altering $table $row->{from} to $row->{to}\n";
3093                 # ALTER TABLE `borrowers` CHANGE `faxnumber` `fax` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
3094     #             alter table `borrowers` change `faxnumber` `fax` type text  null after phone
3095                 my $sql =
3096                     "alter table `$table` change `$row->{from}` `$row->{to}` $types{$row->{from}}->{type} ".
3097                     ($types{$row->{from}}->{null} eq 'YES'?" NULL":" NOT NULL").
3098                     ($types{$row->{from}}->{default}?" default ".$types{$row->{from}}->{default}:"").
3099                     "$types{$row->{from}}->{extra} after $row->{after} ";
3100     #             print "$sql";
3101                 $dbh->do($sql);
3102             }
3103         }
3104     }
3105     
3106     # Enter here the field you want to delete from DB.
3107     # FIXME :: there is a %uselessfield before which seems doing the same things.
3108     my %fieldtodelete = (
3109         # tablename => [fieldname1,fieldname2,...]
3110     
3111     ); # %fielddelete
3112     
3113     print "removing some unused fields...\n";
3114     foreach my $table ( keys %fieldtodelete ) {
3115         foreach my $field ( @{$fieldtodelete{$table}} ){
3116             print "removing ".$field." from ".$table;
3117             my $sth = $dbh->prepare("ALTER TABLE $table DROP $field");
3118             $sth->execute;
3119             if ( $sth->err ) {
3120                 print "Error : $sth->errstr \n";
3121             }
3122         }
3123     }
3124     
3125     # Enter here the line you want to remove from DB.
3126     my %linetodelete = (
3127         # table name => where clause.
3128         userflags => [ "bit = 8" ], # delete the 'reserveforself' flags
3129         
3130     ); # %linetodelete
3131     
3132     #-------------------
3133     # Initialize
3134     
3135     # Start checking
3136     
3137     # Get version of MySQL database engine.
3138     my $mysqlversion = `mysqld --version`;
3139     $mysqlversion =~ /Ver (\S*) /;
3140     $mysqlversion = $1;
3141     if ( $mysqlversion ge '3.23' ) {
3142         print "Could convert to MyISAM database tables...\n" unless $silent;
3143     }
3144     
3145     #---------------------------------
3146     # Tables
3147     
3148     # Collect all tables into a list
3149     $sth = $dbh->prepare("show tables");
3150     $sth->execute;
3151     while ( my ($table) = $sth->fetchrow ) {
3152         $existingtables{$table} = 1;
3153     }
3154     
3155     
3156     # Now add any missing tables
3157     foreach my $table ( keys %requiretables ) {
3158         unless ( $existingtables{$table} ) {
3159         print "Adding $table table...\n" unless $silent;
3160             my $sth = $dbh->prepare("create table $table $requiretables{$table} ENGINE=InnoDB DEFAULT CHARSET=utf8");
3161             $sth->execute;
3162             if ( $sth->err ) {
3163                 print "Error : $sth->errstr \n";
3164                 $sth->finish;
3165             }    # if error
3166         }    # unless exists
3167     }    # foreach
3168     
3169     #---------------------------------
3170     # Columns
3171     
3172     foreach my $table ( keys %requirefields ) {
3173         print "Check table $table\n" if $debug and not $silent;
3174         $sth = $dbh->prepare("show columns from $table");
3175         $sth->execute();
3176         undef %types;
3177         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3178         {
3179             $types{$column} = $type;
3180         }    # while
3181         foreach my $column ( keys %{ $requirefields{$table} } ) {
3182             print "  Check column $column  [$types{$column}]\n" if $debug and not $silent;
3183             if ( !$types{$column} ) {
3184     
3185                 # column doesn't exist
3186                 print "Adding $column field to $table table...\n" unless $silent;
3187                 $query = "alter table $table
3188                 add column $column " . $requirefields{$table}->{$column};
3189                 print "Execute: $query\n" if $debug;
3190                 my $sti = $dbh->prepare($query);
3191                 $sti->execute;
3192                 if ( $sti->err ) {
3193                     print "**Error : $sti->errstr \n";
3194                     $sti->finish;
3195                 }    # if error
3196             }    # if column
3197         }    # foreach column
3198     }    # foreach table
3199     
3200     foreach my $table ( sort keys %fielddefinitions ) {
3201         print "Check table $table\n" if $debug;
3202         $sth = $dbh->prepare("show columns from $table");
3203         $sth->execute();
3204         my $definitions;
3205         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3206         {
3207             $definitions->{$column}->{type}    = $type;
3208             $definitions->{$column}->{null}    = $null;
3209             $definitions->{$column}->{null}    = 'NULL' if $null eq 'YES';
3210             $definitions->{$column}->{key}     = $key;
3211             $definitions->{$column}->{default} = $default;
3212             $definitions->{$column}->{extra}   = $extra;
3213         }    # while
3214         my $fieldrow = $fielddefinitions{$table};
3215         foreach my $row (@$fieldrow) {
3216             my $field   = $row->{field};
3217             my $type    = $row->{type};
3218             my $null    = $row->{null};
3219     #         $null    = 'YES' if $row->{null} eq 'NULL';
3220             my $key     = $row->{key};
3221             my $default = $row->{default};
3222     #         $default="''" unless $default;
3223             my $extra   = $row->{extra};
3224             my $def     = $definitions->{$field};
3225             my $after    = ($row->{after}?" after ".$row->{after}:"");
3226     
3227             unless ( $type eq $def->{type}
3228                 && $null eq $def->{null}
3229                 && $key eq $def->{key}
3230                 && $default eq $def->{default}
3231                 && $extra eq $def->{extra} )
3232             {
3233                 if ( $null eq '' ) {
3234                     $null = 'NOT NULL';
3235                 }
3236                 if ( $key eq 'PRI' ) {
3237                     $key = 'PRIMARY KEY';
3238                 }
3239                 unless ( $extra eq 'auto_increment' ) {
3240                     $extra = '';
3241                 }
3242         
3243                 # if it's a new column use "add", if it's an old one, use "change".
3244                 my $action;
3245                 if ($definitions->{$field}->{type}) {
3246                     $action="change `$field`"
3247                 } else {
3248                     $action="add";
3249                 }
3250     # if it's a primary key, drop the previous pk, before altering the table
3251                 print "  alter or create $field in $table\n" unless $silent;
3252                 my $query;
3253                 if ($key ne 'PRIMARY KEY') {
3254     #                 warn "alter table $table $action $field $type $null $key $extra default $default $after";
3255                     $query = "alter table $table $action `$field` $type $null $key $extra ".
3256                              GetDefaultClause($default)." $after";
3257                 } else {
3258     #             warn "alter table $table drop primary key, $action $field $type $null $key $extra default $default $after";
3259                     # something strange : for indexes UNIQUE, they are reported as primary key here.
3260                     # but if you try to run with drop primary key, it fails.
3261                     # thus, we run the query twice, one will fail, one will succeed.
3262                     # strange...
3263                     $query="alter table $table drop primary key, $action `$field` $type $null $key $extra ".
3264                            GetDefaultClause($default)." $after";
3265                     $query="alter table $table $action `$field` $type $null $key $extra ".
3266                            GetDefaultClause($default)." $after";
3267                 }
3268                 $dbh->do($query) or warn "Error while executing: $query";
3269             }
3270         }
3271     }
3272     
3273     print "removing some unused data...\n";
3274     foreach my $table ( keys %linetodelete ) {
3275         foreach my $where ( @{$linetodelete{$table}} ){
3276             print "DELETE FROM ".$table." where ".$where;
3277             print "\n";
3278             my $sth = $dbh->prepare("DELETE FROM $table where $where");
3279             $sth->execute;
3280             if ( $sth->err ) {
3281                 print "Error : $sth->errstr \n";
3282             }
3283         }
3284     }
3285     
3286     # Populate tables with required data
3287     
3288     # synch table and deletedtable.
3289     foreach my $table (('borrowers','items','biblio','biblioitems')) {
3290         my %deletedborrowers;
3291         print "synch'ing $table and deleted$table\n";
3292         $sth = $dbh->prepare("show columns from deleted$table");
3293         $sth->execute;
3294         while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
3295             $deletedborrowers{$column}=1;
3296         }
3297         $sth = $dbh->prepare("show columns from $table");
3298         $sth->execute;
3299         my $previous;
3300         while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
3301             unless ($deletedborrowers{$column}) {
3302                 my $newcol="alter table deleted$table add $column $type";
3303                 if ($null eq 'YES') {
3304                     $newcol .= " NULL ";
3305                 } else {
3306                     $newcol .= " NOT NULL ";
3307                 }
3308                 $newcol .= "default ".$dbh->quote($default) if $default;
3309                 $newcol .= " after $previous" if $previous;
3310                 $previous=$column;
3311                 print "creating column $column\n";
3312                 $dbh->do($newcol);
3313             }
3314         }
3315     }
3316     #
3317     # update publisheddate 
3318     #
3319     $sth = $dbh->prepare("select count(*) from serial where publisheddate is NULL");
3320     $sth->execute;
3321     my ($emptypublished) = $sth->fetchrow;
3322     if ($emptypublished) {
3323         print "Updating publisheddate\n";
3324         $dbh->do("update serial set publisheddate=planneddate where publisheddate is NULL");
3325     }
3326     # Why are we setting publisheddate = planneddate ?? if we don't have the data, we don't know it.
3327     # now, let's get rid of 000-00-00's.
3328
3329         $dbh->do("update serial set publisheddate=NULL where publisheddate = 0");
3330         $dbh->do("update subscription set firstacquidate=startdate where firstacquidate = 0");
3331     
3332     foreach my $table ( keys %tabledata ) {
3333         print "Checking for data required in table $table...\n" unless $silent;
3334         my $tablerows = $tabledata{$table};
3335         foreach my $row (@$tablerows) {
3336             my $uniquefieldrequired = $row->{uniquefieldrequired};
3337             my $uniquevalue         = $row->{$uniquefieldrequired};
3338             my $forceupdate         = $row->{forceupdate};
3339             my $sth                 =
3340             $dbh->prepare(
3341     "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
3342             );
3343             $sth->execute($uniquevalue);
3344             if ($sth->rows) {
3345                 foreach my $field (keys %$forceupdate) {
3346                     if ($forceupdate->{$field}) {
3347                         my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
3348                         $sth->execute($row->{$field}, $uniquevalue);
3349                     }
3350                 }
3351             } else {
3352                 print "Adding row to $table: " unless $silent;
3353                 my @values;
3354                 my $fieldlist;
3355                 my $placeholders;
3356                 foreach my $field ( keys %$row ) {
3357                     next if $field eq 'uniquefieldrequired';
3358                     next if $field eq 'forceupdate';
3359                     my $value = $row->{$field};
3360                     push @values, $value;
3361                     print "  $field => $value" unless $silent;
3362                     $fieldlist .= "$field,";
3363                     $placeholders .= "?,";
3364                 }
3365                 print "\n" unless $silent;
3366                 $fieldlist    =~ s/,$//;
3367                 $placeholders =~ s/,$//;
3368                 print "insert into $table ($fieldlist) values ($placeholders)";
3369                 my $sth =
3370                 $dbh->prepare(
3371                     "insert into $table ($fieldlist) values ($placeholders)");
3372                 $sth->execute(@values);
3373             }
3374         }
3375     }
3376     
3377     #
3378     # check indexes and create them when needed
3379     #
3380     print "Checking for index required...\n" unless $silent;
3381     foreach my $table ( keys %indexes ) {
3382         #
3383         # read all indexes from $table
3384         #
3385         $sth = $dbh->prepare("show index from $table");
3386         $sth->execute;
3387         my %existingindexes;
3388         while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
3389             $existingindexes{$key_name} = 1;
3390         }
3391         # read indexes to check
3392         my $tablerows = $indexes{$table};
3393         foreach my $row (@$tablerows) {
3394             my $key_name=$row->{indexname};
3395             if ($existingindexes{$key_name} eq 1 and not $row->{force}) {
3396     #             print "$key_name existing";
3397             } else {
3398                 print "\tCreating index $key_name in $table\n";
3399                 my $sql;
3400                 if ($row->{indexname} eq 'PRIMARY' or $row->{type} eq 'PRI') {
3401                     $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
3402                 } else {
3403                     $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
3404                 }
3405                 $dbh->do($sql);
3406                 print "Error $sql : $dbh->err \n" if $dbh->err;
3407             }
3408         }
3409     }
3410     
3411     #
3412     # check foreign keys and create them when needed
3413     #
3414     print "Checking for foreign keys required...\n" unless $silent;
3415     foreach my $table ( sort keys %foreign_keys ) {
3416         #
3417         # read all indexes from $table
3418         #
3419         $sth = $dbh->prepare("show table status like '$table'");
3420         $sth->execute;
3421         my $stat = $sth->fetchrow_hashref;
3422         # read indexes to check
3423         my $tablerows = $foreign_keys{$table};
3424         foreach my $row (@$tablerows) {
3425             my $foreign_table=$row->{foreigntable};
3426             if ($stat->{'Comment'} =~/$foreign_table/) {
3427     #             print "$foreign_table existing\n";
3428             } else {
3429                 print "\tCreating foreign key $foreign_table in $table\n";
3430                 # first, drop any orphan value in child table
3431                 if ($row->{onDelete} ne "RESTRICT") {
3432                     my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
3433                     $dbh->do($sql);
3434                     print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
3435                 }
3436                 my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
3437                 $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
3438                 $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
3439                 $dbh->do($sql);
3440                 if ($dbh->err) {
3441                     print "====================
3442     An error occurred during :
3443     \t$sql
3444     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).
3445     You can find those values with select
3446     \t$table.* from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})
3447     ====================\n
3448     ";
3449                 }
3450             }
3451         }
3452     }
3453     # now drop useless tables
3454     foreach my $table ( @TableToDelete ) {
3455         if ( $existingtables{$table} ) {
3456             print "Dropping unused table $table\n" if $debug and not $silent;
3457             $dbh->do("drop table $table");
3458             if ( $dbh->err ) {
3459                 print "Error : $dbh->errstr \n";
3460             }
3461         }
3462     }
3463     
3464     #
3465     # SPECIFIC STUFF
3466     #
3467     #
3468     # create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
3469     #
3470     
3471     # 1st, get how many biblio we will have to do...
3472     $sth = $dbh->prepare('select count(*) from marc_biblio');
3473     $sth->execute;
3474     my ($totaltodo) = $sth->fetchrow;
3475     
3476     $sth = $dbh->prepare("show columns from biblio");
3477     $sth->execute();
3478     my $definitions;
3479     my $bibliofwexist=0;
3480     while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3481         $bibliofwexist=1 if $column eq 'frameworkcode';
3482     }
3483     unless ($bibliofwexist) {
3484         print "moving biblioframework to biblio table\n";
3485         $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
3486         $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
3487         $sth->execute;
3488         my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
3489         my $totaldone=0;
3490         while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
3491             $sth_update->execute($frameworkcode,$biblionumber);
3492             $totaldone++;
3493             print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3494         }
3495         print "\rdone\n";
3496     }
3497     
3498     # at last, remove useless fields
3499     foreach my $table ( keys %uselessfields ) {
3500         my @fields = split (/,/,$uselessfields{$table});
3501         my $exists;
3502         foreach my $fieldtodrop (@fields) {
3503             $fieldtodrop =~ s/\t//g;
3504             $fieldtodrop =~ s/\n//g;
3505             $exists =0;
3506             $sth = $dbh->prepare("show columns from $table");
3507             $sth->execute;
3508             while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
3509             {
3510                 $exists =1 if ($column eq $fieldtodrop);
3511             }
3512             if ($exists) {
3513                 print "deleting $fieldtodrop field in $table...\n" unless $silent;
3514                 my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
3515                 $sth->execute;
3516             }
3517         }
3518     }    # foreach
3519     
3520     #
3521     # Changing aqbookfund's primary key 
3522     #
3523     $sth=$dbh->prepare("ALTER TABLE `aqbookfund` DROP PRIMARY KEY , ADD PRIMARY KEY ( `bookfundid` , `branchcode` ) ;");
3524     $sth->execute;
3525     $sth->finish;
3526    
3527     # drop extra key on borrowers.borrowernumber
3528     $dbh->do("ALTER TABLE borrowers DROP KEY borrowernumber"); 
3529     
3530     # update enrolmentperiod
3531     $dbh->do("UPDATE categories SET enrolmentperiod = enrolmentperiod * 12");
3532     
3533     print "upgrade to Koha 3.0 done\n";
3534     SetVersion ($DBversion);
3535
3536 =head1 GetDefaultClause
3537
3538 Generate a default clause (for an ALTER TABLE command)
3539
3540 =cut
3541
3542 sub GetDefaultClause {
3543     my $default = shift;
3544
3545     return "" unless defined $default;
3546     return "" if $default eq '';    
3547     return "default ''" if $default eq "''";
3548     return "default NULL" if $default eq "NULL";
3549     return "default " . $dbh->quote($default);
3550 }
3551
3552 =head1 TransformToNum
3553
3554 Transform the Koha version from a 4 parts string
3555 to a number, with just 1.
3556
3557 =cut
3558
3559 sub TransformToNum {
3560     my $version = shift;
3561     # remove the 3 last . to have a Perl number
3562     $version =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
3563     return $version;
3564 }
3565
3566 =head1 SetVersion
3567
3568 set the DBversion in the systempreferences
3569
3570 =cut
3571
3572 sub SetVersion {
3573     my $kohaversion = TransformToNum(shift);
3574     if (C4::Context->preference('Version')) {
3575       my $finish=$dbh->prepare("UPDATE systempreferences SET value=? WHERE variable='Version'");
3576       $finish->execute($kohaversion);
3577     } else {
3578       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')");
3579       $finish->execute($kohaversion);
3580     }
3581 }
3582 exit;
3583
3584 # Revision 1.172  2007/07/19 10:21:22  hdl