6 # This script checks for required updates to the database.
8 # Part of the Koha Library Software www.koha.org
9 # Licensed under the GPL.
12 # - Would also be a good idea to offer to do a backup at this time...
14 # NOTE: If you do something more than once in here, make it table driven.
24 # FIXME - The user might be installing a new database, so can't rely
25 # on /etc/koha.conf anyway.
32 %existingtables, # tables already in database
36 $type, $null, $key, $default, $extra,
37 $prefitem, # preference item in systempreferences table
44 my $dbh = C4::Context->dbh;
45 print "connected to your DB. Checking & modifying it\n" unless $silent;
50 # Tables to add if they don't exist
52 shelfcontents => "( shelfnumber int not null,
53 itemnumber int not null,
55 bookshelf => "( shelfnumber int auto_increment primary key,
56 shelfname char(255))",
57 z3950queue => "( id int auto_increment primary key,
66 identifier char(30))",
67 z3950results => "( id int auto_increment primary key,
77 branchrelations => "( branchcode varchar(4),
78 categorycode varchar(4))",
79 websites => "( websitenumber int(11) NOT NULL auto_increment,
80 biblionumber int(11) NOT NULL default '0',
84 PRIMARY KEY (websitenumber) )",
85 marcrecorddone => "( isbn char(40),
88 controlnumber char(40))",
89 uploadedmarc => "( id int(11) NOT NULL auto_increment PRIMARY KEY,
91 hidden smallint(6) default NULL,
92 name varchar(255) default NULL)",
93 ethnicity => "( code varchar(10) NOT NULL default '',
94 name varchar(255) default NULL,
95 PRIMARY KEY (code) )",
96 sessions => "( sessionID varchar(255) NOT NULL default '',
97 userid varchar(255) default NULL,
98 ip varchar(16) default NULL,
100 PRIMARY KEY (sessionID) )",
101 sessionqueries => "( sessionID varchar(255) NOT NULL default '',
102 userid char(100) NOT NULL default '',
103 ip char(18) NOT NULL default '',
104 url text NOT NULL default '' )",
105 bibliothesaurus => "( id bigint(20) NOT NULL auto_increment,
106 freelib char(255) NOT NULL default '',
107 stdlib char(255) NOT NULL default '',
108 category char(10) NOT NULL default '',
109 level tinyint(4) NOT NULL default '1',
110 hierarchy char(80) NOT NULL default '',
111 father char(80) NOT NULL default '',
113 KEY freelib (freelib),
115 KEY category (category),
116 KEY hierarchy (hierarchy)
119 bibid bigint(20) unsigned NOT NULL auto_increment,
120 biblionumber int(11) NOT NULL default '0',
121 datecreated date NOT NULL default '0000-00-00',
122 datemodified date default NULL,
123 origincode char(20) default NULL,
125 KEY origincode (origincode),
126 KEY biblionumber (biblionumber)
128 marc_blob_subfield => "(
129 blobidlink bigint(20) NOT NULL auto_increment,
130 subfieldvalue longtext NOT NULL,
131 PRIMARY KEY (blobidlink)
133 marc_subfield_structure => "(
134 tagfield char(3) NOT NULL default '',
135 tagsubfield char(1) NOT NULL default '',
136 liblibrarian char(255) NOT NULL default '',
137 libopac char(255) NOT NULL default '',
138 repeatable tinyint(4) NOT NULL default '0',
139 mandatory tinyint(4) NOT NULL default '0',
140 kohafield char(40) default NULL,
141 tab tinyint(1) default NULL,
142 authorised_value char(10) default NULL,
143 thesaurus_category char(10) default NULL,
144 value_builder char(80) default NULL,
145 PRIMARY KEY (tagfield,tagsubfield),
146 KEY kohafield (kohafield),
149 marc_subfield_table => "(
150 subfieldid bigint(20) unsigned NOT NULL auto_increment,
151 bibid bigint(20) unsigned NOT NULL default '0',
152 tag char(3) NOT NULL default '',
153 tagorder tinyint(4) NOT NULL default '1',
154 tag_indicator char(2) NOT NULL default '',
155 subfieldcode char(1) NOT NULL default '',
156 subfieldorder tinyint(4) NOT NULL default '1',
157 subfieldvalue varchar(255) default NULL,
158 valuebloblink bigint(20) default NULL,
159 PRIMARY KEY (subfieldid),
162 KEY tag_indicator (tag_indicator),
163 KEY subfieldorder (subfieldorder),
164 KEY subfieldcode (subfieldcode),
165 KEY subfieldvalue (subfieldvalue),
166 KEY tagorder (tagorder)
168 marc_tag_structure => "(
169 tagfield char(3) NOT NULL default '',
170 liblibrarian char(255) NOT NULL default '',
171 libopac char(255) NOT NULL default '',
172 repeatable tinyint(4) NOT NULL default '0',
173 mandatory tinyint(4) NOT NULL default '0',
174 authorised_value char(10) default NULL,
175 PRIMARY KEY (tagfield)
178 bibid bigint(20) NOT NULL default '0',
179 tag char(3) NOT NULL default '',
180 tagorder tinyint(4) NOT NULL default '1',
181 subfieldid char(1) NOT NULL default '',
182 subfieldorder tinyint(4) NOT NULL default '1',
183 word varchar(255) NOT NULL default '',
184 sndx_word varchar(255) NOT NULL default '',
187 KEY tagorder (tagorder),
188 KEY subfieldid (subfieldid),
189 KEY subfieldorder (subfieldorder),
191 KEY sndx_word (sndx_word)
193 marc_breeding => "( id bigint(20) NOT NULL auto_increment,
194 file varchar(80) NOT NULL default '',
195 isbn varchar(10) NOT NULL default '',
196 title varchar(128) default NULL,
197 author varchar(80) default NULL,
199 encoding varchar(40) default NULL,
204 authorised_values => "(id int(11) NOT NULL auto_increment,
205 category char(10) NOT NULL default '',
206 authorised_value char(80) NOT NULL default '',
211 userflags => "( bit int(11) NOT NULL default '0',
212 flag char(30), flagdesc char(255),
216 authtypecode char(10) not NULL,
217 authtypetext char(255) not NULL,
218 auth_tag_to_report char(3) not NULL,
219 summary text not NULL,
220 PRIMARY KEY (authtypecode)
222 biblio_framework => "(
223 frameworkcode char(4) not NULL,
224 frameworktext char(255) not NULL,
225 PRIMARY KEY (frameworkcode)
227 auth_subfield_structure => "(
228 authtypecode char(10) NOT NULL default '',
229 tagfield char(3) NOT NULL default '',
230 tagsubfield char(1) NOT NULL default '',
231 liblibrarian char(255) NOT NULL default '',
232 libopac char(255) NOT NULL default '',
233 repeatable tinyint(4) NOT NULL default '0',
234 mandatory tinyint(4) NOT NULL default '0',
235 tab tinyint(1) default NULL,
236 authorised_value char(10) default NULL,
237 value_builder char(80) default NULL,
238 seealso char(255) default NULL,
239 PRIMARY KEY (authtypecode,tagfield,tagsubfield),
240 KEY tab (authtypecode,tab)
242 auth_tag_structure => "(
243 authtypecode char(10) NOT NULL default '',
244 tagfield char(3) NOT NULL default '',
245 liblibrarian char(255) NOT NULL default '',
246 libopac char(255) NOT NULL default '',
247 repeatable tinyint(4) NOT NULL default '0',
248 mandatory tinyint(4) NOT NULL default '0',
249 authorised_value char(10) default NULL,
250 PRIMARY KEY (authtypecode,tagfield)
253 authid bigint(20) unsigned NOT NULL auto_increment,
254 authtypecode char(10) NOT NULL default '',
255 datecreated date NOT NULL default '0000-00-00',
256 datemodified date default NULL,
257 origincode char(20) default NULL,
258 PRIMARY KEY (authid),
259 KEY origincode (origincode),
261 auth_subfield_table => "(
262 subfieldid bigint(20) unsigned NOT NULL auto_increment,
263 authid bigint(20) unsigned NOT NULL default '0',
264 tag char(3) NOT NULL default '',
265 tagorder tinyint(4) NOT NULL default '1',
266 tag_indicator char(2) NOT NULL default '',
267 subfieldcode char(1) NOT NULL default '',
268 subfieldorder tinyint(4) NOT NULL default '1',
269 subfieldvalue varchar(255) default NULL,
270 PRIMARY KEY (subfieldid),
273 KEY subfieldcode (subfieldcode),
274 KEY subfieldvalue (subfieldvalue)
277 authid bigint(20) NOT NULL default '0',
278 tagsubfield char(4) NOT NULL default '',
279 tagorder tinyint(4) NOT NULL default '1',
280 subfieldorder tinyint(4) NOT NULL default '1',
281 word varchar(255) NOT NULL default '',
282 sndx_word varchar(255) NOT NULL default '',
284 KEY marc_search (tagsubfield,word),
286 KEY sndx_word (sndx_word)
289 suggestionnumber int(8) NOT NULL auto_increment,
290 suggestedby int(11) NOT NULL default '0',
291 managedby int(11) default NULL,
292 status varchar(10) NOT NULL default '',
294 author varchar(80) default NULL,
295 title varchar(80) default NULL,
296 copyrightdate smallint(6) default NULL,
297 publishercode varchar(255) default NULL,
298 date timestamp(8) NOT NULL,
299 mailoverseeing smallint(1) default 0,
300 PRIMARY KEY (suggestionnumber),
301 KEY suggestedby (suggestedby),
302 KEY managedby (managedby)
306 my %requirefields = (
307 biblio => { 'abstract' => 'text' },
308 deletedbiblio => { 'abstract' => 'text', 'marc' => 'blob' },
309 deleteditems => { 'marc' => 'blob', 'paidfor' => 'text' },
311 'lccn' => 'char(25)',
312 'url' => 'varchar(255)',
315 deletedbiblioitems => {
316 'lccn' => 'char(25)',
317 'url' => 'varchar(255)',
320 branchtransfers => { 'datearrived' => 'datetime' },
321 statistics => { 'borrowernumber' => 'int(11)' },
323 'invoicedisc' => 'float(6,4)',
324 'nocalc' => 'int(11)'
327 'userid' => 'char(30)',
328 'password' => 'char(30)',
329 'flags' => 'int(11)',
330 'textmessaging' => 'varchar(30)',
331 'zipcode' => 'varchar(25)',
332 'homezipcode' => 'varchar(25)',
333 'sort1' => 'char(80)',
334 'sort2' => 'char(80)',
336 aqorders => { 'budgetdate' => 'date',
337 'sort1' => 'char(80)',
338 'sort2' => 'char(80)', },
339 aqbudget => {'aqbudgetid' => 'tinyint(4) auto_increment primary key'},
340 items => {'paidfor' => 'text'},
342 #added so that reference items are not available for reserves...
343 itemtypes => { 'notforloan' => 'smallint(6)' },
344 systempreferences => { 'explanation' => 'char(80)',
345 'type' => 'char(20)',
346 'options' => 'text' },
347 z3950servers => { 'syntax' => 'char(80)' },
348 marc_tag_structure =>{
349 'frameworkcode' => 'char(4) not NULL default \'\''},
350 marc_subfield_structure =>{'seealso' => 'char(255)',
351 'frameworkcode' => 'char(4) not NULL default \'\'',
352 'hidden' => 'tinyint(1)',
353 'isurl' => 'tinyint(1)',
355 bookshelf => {'owner' => 'char(80)',
356 'category' => 'char(1)',
358 marc_biblio => { 'frameworkcode' => 'char(4) not NULL default \'\'' },
361 my %dropable_table = (
362 classification => 'classification',
363 multipart => 'multipart',
364 multivolume => 'multivolume',
365 newitems => 'newitems',
366 procedures => 'procedures',
367 publisher => 'publisher',
368 searchstats => 'searchstats',
369 serialissues => 'serialissues',
372 # the other hash contains other actions that can't be done elsewhere. they are done
373 # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
375 # The tabledata hash contains data that should be in the tables.
376 # The uniquefieldrequired hash entry is used to determine which (if any) fields
377 # must not exist in the table for this row to be inserted. If the
378 # uniquefieldrequired entry is already in the table, the existing data is not
379 # modified, unless the forceupdate hash entry is also set. Fields in the
380 # anonymous "forceupdate" hash will be forced to be updated to the default
381 # values given in the %tabledata hash.
386 uniquefieldrequired => 'bit',
388 flag => 'superlibrarian',
389 flagdesc => 'Access to all librarian functions',
393 uniquefieldrequired => 'bit',
396 flagdesc => 'Circulate books',
400 uniquefieldrequired => 'bit',
403 flagdesc => 'View Catalogue (Librarian Interface)',
407 uniquefieldrequired => 'bit',
409 flag => 'parameters',
410 flagdesc => 'Set Koha system paramters',
414 uniquefieldrequired => 'bit',
417 flagdesc => 'Add or modify borrowers',
421 uniquefieldrequired => 'bit',
423 flag => 'permissions',
424 flagdesc => 'Set user permissions',
428 uniquefieldrequired => 'bit',
430 flag => 'reserveforothers',
431 flagdesc => 'Reserve books for patrons',
435 uniquefieldrequired => 'bit',
438 flagdesc => 'Borrow books',
442 uniquefieldrequired => 'bit',
444 flag => 'reserveforself',
445 flagdesc => 'Reserve books for self',
449 uniquefieldrequired => 'bit',
451 flag => 'editcatalogue',
452 flagdesc => 'Edit Catalogue (Modify bibliographic/holdings data)',
456 uniquefieldrequired => 'bit',
458 flag => 'updatecharges',
459 flagdesc => 'Update borrower charges',
463 systempreferences => [
465 uniquefieldrequired => 'variable',
466 forceupdate => { 'explanation' => 1,
468 variable => 'LibraryName',
469 value => '<i><b>Koha<br/>Free Software ILS<br/><br/></b>Koha : a gift, a contribution<br/> in Maori</i>',
470 explanation => 'Library name as shown on main opac page',
475 uniquefieldrequired => 'variable',
476 forceupdate => { 'explanation' => 1,
478 variable => 'autoMemberNum',
480 explanation => 'Member number is auto-calculated',
485 uniquefieldrequired => 'variable',
486 forceupdate => { 'explanation' => 1,
489 variable => 'acquisitions',
492 'Normal, budget-based acquisitions, or Simple bibliographic-data acquisitions',
494 options => 'simple|normal'
497 uniquefieldrequired => 'variable',
498 forceupdate => { 'explanation' => 1,
501 variable => 'dateformat',
504 'date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy/mm/dd)',
506 options => 'metric|us|iso'
509 uniquefieldrequired => 'variable',
510 variable => 'template',
511 forceupdate => { 'explanation' => 1,
514 explanation => 'Preference order for intranet interface templates',
518 uniquefieldrequired => 'variable',
519 variable => 'autoBarcode',
520 forceupdate => { 'explanation' => 1,
523 explanation => 'Barcode is auto-calculated',
527 uniquefieldrequired => 'variable',
528 variable => 'insecure',
529 forceupdate => { 'explanation' => 1,
533 'If YES, no auth at all is needed. Be careful if you set this to yes!',
537 uniquefieldrequired => 'variable',
538 variable => 'authoritysep',
539 forceupdate => { 'explanation' => 1,
544 'the separator used in authority/thesaurus. Usually --',
549 uniquefieldrequired => 'variable',
550 variable => 'opaclanguages',
551 forceupdate => { 'explanation' => 1,
554 explanation => 'Set the preferred order for translations. The top language will be tried first.',
558 uniquefieldrequired => 'variable',
559 variable => 'opacthemes',
560 forceupdate => { 'explanation' => 1,
563 explanation => 'Set the preferred order for themes. The top theme will be tried first.',
567 uniquefieldrequired => 'variable',
568 variable => 'timeout',
569 forceupdate => { 'explanation' => 1,
572 explanation => 'Inactivity timeout for cookies authentication (in seconds)',
576 uniquefieldrequired => 'variable',
578 forceupdate => { 'explanation' => 1,
581 explanation => 'Turn on MARC support',
585 uniquefieldrequired => 'variable',
586 variable => 'marcflavour',
587 forceupdate => { 'explanation' => 1,
592 'your MARC flavor (MARC21 or UNIMARC) used for character encoding',
594 options => 'MARC21|UNIMARC'
597 uniquefieldrequired => 'variable',
598 variable => 'checkdigit',
600 forceupdate => { 'explanation' => 1,
603 explanation => 'Validity checks on membership number: none or "Katipo" style checks',
605 options => 'none|katipo'
608 uniquefieldrequired => 'variable',
609 variable => 'maxoutstanding',
610 forceupdate => { 'explanation' => 1,
614 'maximum amount withstanding to be able make reserves ',
618 uniquefieldrequired => 'variable',
619 variable => 'maxreserves',
620 forceupdate => { 'explanation' => 1,
624 'maximum number of reserves a member can make',
629 uniquefieldrequired => 'variable',
630 variable => 'noissuescharge',
631 forceupdate => { 'explanation' => 1,
635 'maximum amount withstanding to be able to check out an item',
640 uniquefieldrequired => 'variable',
641 variable => 'KohaAdminEmailAddress',
642 forceupdate => { 'explanation' => 1,
644 value => 'your.mail@here',
645 explanation => 'the email address where borrowers modifs are sent',
649 uniquefieldrequired => 'variable',
651 forceupdate => { 'explanation' => 1,
654 explanation => 'the gist rate. NOT in %, but in numeric form (0.12 for 12%)',
658 uniquefieldrequired => 'variable',
659 variable => 'ldapserver',
660 forceupdate => { 'explanation' => 1,
663 explanation => 'your ldap server',
667 uniquefieldrequired => 'variable',
668 variable => 'ldapinfos',
669 forceupdate => { 'explanation' => 1,
672 explanation => 'ldap info. The ldap will be used in dn : uid=xxx, <ldapinfos>',
676 uniquefieldrequired => 'variable',
677 variable => 'printcirculationslips',
678 forceupdate => { 'explanation' => 1,
681 explanation => 'if set to 1, print circulation slips. If set to 0, don\'t',
685 uniquefieldrequired => 'variable',
686 variable => 'suggestion',
687 forceupdate => { 'explanation' => 1,
690 explanation => 'if set to 1, suggestions are activated in OPAC',
694 uniquefieldrequired => 'variable',
696 forceupdate => { 'explanation' => 1,
698 value => 'Fill with appropriate value...',
699 explanation => 'ISBD',
703 uniquefieldrequired => 'variable',
704 variable => 'virtualshelves',
705 forceupdate => { 'explanation' => 1,
708 explanation => 'Set virtual shelves management ON or OFF',
715 my %fielddefinitions = (
718 field => 'printername',
727 field => 'bookfundid',
736 field => 'aqbudgetid',
737 type => 'tinyint(4)',
741 extra => 'auto_increment'
751 extra => 'auto_increment'
756 field => 'z3950random',
757 type => 'varchar(40)',
765 type => 'varchar(40)',
779 # Get version of MySQL database engine.
780 my $mysqlversion = `mysqld --version`;
781 $mysqlversion =~ /Ver (\S*) /;
783 if ( $mysqlversion ge '3.23' ) {
784 print "Could convert to MyISAM database tables...\n" unless $silent;
787 #---------------------------------
790 # Collect all tables into a list
791 $sth = $dbh->prepare("show tables");
793 while ( my ($table) = $sth->fetchrow ) {
794 $existingtables{$table} = 1;
798 # Now add any missing tables
799 foreach $table ( keys %requiretables ) {
800 unless ( $existingtables{$table} ) {
801 print "Adding $table table...\n" unless $silent;
802 my $sth = $dbh->prepare("create table $table $requiretables{$table}");
805 print "Error : $sth->errstr \n";
811 # now drop useless tables
812 foreach $table ( keys %dropable_table ) {
813 if ( $existingtables{$table} ) {
814 print "Dropping unused table $table\n" if $debug and not $silent;
815 $dbh->do("drop table $table");
817 print "Error : $dbh->errstr \n";
821 unless ( $existingtables{'z3950servers'} ) {
822 #MJR: added syntax entries to close bug 624
823 print "Adding z3950servers table...\n" unless $silent;
824 my $sti = $dbh->prepare( "create table z3950servers (
837 $sti = $dbh->prepare( "insert into z3950servers
838 values ('z3950.loc.gov',
842 'Library of Congress',
847 unless ( $existingtables{'issuingrules'} ) {
848 $dbh->do("alter table categoryitem rename issuingrules");
849 $dbh->do("ALTER TABLE issuingrules ADD maxissueqty int(4) default NULL");
850 $dbh->do("ALTER TABLE issuingrules ADD issuelength int(4) default NULL");
851 $dbh->do("ALTER TABLE issuingrules ADD branchcode varchar(4) NOT NULL default ''");
852 print "renaming categoryitem\n" unless $silent;
856 #---------------------------------
859 foreach $table ( keys %requirefields ) {
860 print "Check table $table\n" if $debug and not $silent;
861 $sth = $dbh->prepare("show columns from $table");
864 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
866 $types{$column} = $type;
868 foreach $column ( keys %{ $requirefields{$table} } ) {
869 print " Check column $column [$types{$column}]\n" if $debug and not $silent;
870 if ( !$types{$column} ) {
872 # column doesn't exist
873 print "Adding $column field to $table table...\n" unless $silent;
874 $query = "alter table $table
875 add column $column " . $requirefields{$table}->{$column};
876 print "Execute: $query\n" if $debug;
877 my $sti = $dbh->prepare($query);
880 print "**Error : $sti->errstr \n";
887 foreach $table ( keys %fielddefinitions ) {
888 print "Check table $table\n" if $debug;
889 $sth = $dbh->prepare("show columns from $table");
892 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
894 $definitions->{$column}->{type} = $type;
895 $definitions->{$column}->{null} = $null;
896 $definitions->{$column}->{key} = $key;
897 $definitions->{$column}->{default} = $default;
898 $definitions->{$column}->{extra} = $extra;
900 my $fieldrow = $fielddefinitions{$table};
901 foreach my $row (@$fieldrow) {
902 my $field = $row->{field};
903 my $type = $row->{type};
904 my $null = $row->{null};
905 my $key = $row->{key};
906 my $default = $row->{default};
907 $default="''" unless $default;
908 my $extra = $row->{extra};
909 my $def = $definitions->{$field};
910 unless ( $type eq $def->{type}
911 && $null eq $def->{null}
912 && $key eq $def->{key}
913 && $default eq $def->{default}
914 && $extra eq $def->{extra} )
920 if ( $key eq 'PRI' ) {
921 $key = 'PRIMARY KEY';
923 unless ( $extra eq 'auto_increment' ) {
926 # if it's a new column use "add", if it's an old one, use "change".
928 if ($definitions->{$field}->{type}) {
929 $action="change $field"
933 # if it's a primary key, drop the previous pk, before altering the table
935 if ($key ne 'PRIMARY KEY') {
936 $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ?");
938 $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ?");
940 $sth->execute($default);
941 print " Alter $field in $table\n" unless $silent;
946 # Get list of columns from borrowers table
949 $sth = $dbh->prepare("show columns from borrowers");
951 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
953 $itemtypes{$column} = $type;
954 $nullenabled{$column} = $null;
957 unless ( $itemtypes{'cardnumber'} eq 'varchar(20)' ) {
958 $itemtypes{'cardnumber'} =~ /varchar\((\d+)\)/;
960 if ( $oldlength < 16 ) {
961 print "Setting maximum cardnumber length to 16 (was $oldlength) and marking unique.\n" unless $silent;
964 "alter table borrowers change cardnumber cardnumber varchar(16)");
969 "alter table borrowers drop index cardnumber");
974 "alter table borrowers add unique(cardnumber)");
980 # Get list of columns from items table
981 $sth = $dbh->prepare("show columns from items");
983 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
985 $itemtypes{$column} = $type;
986 $nullenabled{$column} = $null;
989 unless ( $itemtypes{'barcode'} eq 'varchar(20)' ) {
990 $itemtypes{'barcode'} =~ /varchar\((\d+)\)/;
992 if ( $oldlength < 20 ) {
993 print "Setting maximum barcode length to 20 (was $oldlength).\n" unless $silent;
996 "alter table items change barcode barcode varchar(20)");
1001 # dropping unique barcode index & setting barcode to null allowed.
1003 $sth = $dbh->prepare("show index from items");
1005 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1007 if ($key_name eq 'barcode' && $non_unique eq 0) {
1008 print "dropping BARCODE index to enable empty barcodes\n" unless $silent;
1009 $dbh->do("ALTER TABLE `items` DROP INDEX `barcode`");
1012 $dbh->do("ALTER TABLE `items` CHANGE `barcode` `barcode` VARCHAR( 20 )") unless ($nullenabled{barcode} eq 'YES');
1015 # creating fulltext index in bibliothesaurus if needed
1017 $sth = $dbh->prepare("show index from bibliothesaurus");
1020 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1022 if ($key_name eq 'category_2') {
1026 print "Creating fulltext index on bibliothesaurus\n" unless $exists or $silent;
1027 $dbh->do('create fulltext index category_2 on bibliothesaurus (category,freelib)') unless $exists;
1030 # creating index in z3950results if needed
1032 $sth = $dbh->prepare("show index from z3950results");
1035 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1037 if ($key_name eq 'query_server') {
1041 print "Creating index on z3950results\n" unless $exists or $silent;
1042 $dbh->do('create unique index query_server on z3950results (queryid,server)') unless $exists;
1044 # changing z3950daemon field to NULL in marc_breeding
1045 $dbh->do("ALTER TABLE `marc_breeding` CHANGE `z3950random` `z3950random` VARCHAR( 40 )");
1047 # making borrowernumber an auto_increment field
1048 $dbh->do("ALTER TABLE `borrowers` CHANGE `borrowernumber` `borrowernumber` INTEGER auto_increment");
1050 # changing indexes in marc_*_structure to use frameworkcode
1051 $dbh->do('alter table marc_subfield_structure drop index tab');
1052 $dbh->do('create index tab on marc_subfield_structure (frameworkcode,tab)');
1053 $dbh->do('alter table marc_subfield_structure drop index kohafield');
1054 $dbh->do('create index kohafield on marc_subfield_structure (frameworkcode,kohafield)');
1057 # extending the timestamp in branchtransfers...
1058 my %branchtransfers;
1060 $sth = $dbh->prepare("show columns from branchtransfers");
1062 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1064 $branchtransfers{$column} = $type;
1067 unless ( $branchtransfers{'datesent'} eq 'datetime' ) {
1068 print "Setting type of datesent in branchtransfers to datetime.\n" unless $silent;
1071 "alter table branchtransfers change datesent datesent datetime");
1075 unless ( $branchtransfers{'datearrived'} eq 'datetime' ) {
1076 print "Setting type of datearrived in branchtransfers to datetime.\n" unless $silent;
1079 "alter table branchtransfers change datearrived datearrived datetime");
1083 # changing the branchcategories table around...
1084 my %branchcategories;
1086 $sth = $dbh->prepare("show columns from branchcategories");
1088 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1090 $branchcategories{$column} = $type;
1093 unless ( $branchcategories{'categorycode'} eq 'varchar(4)' ) {
1095 "Setting type of categorycode in branchcategories to varchar(4),\n and making the primary key.\n" unless $silent;
1098 "alter table branchcategories change categorycode categorycode varchar(4) not null"
1103 "alter table branchcategories add primary key (categorycode)");
1107 unless ( $branchcategories{'categoryname'} eq 'text' ) {
1108 print "Changing branchcode in branchcategories to categoryname text.\n" unless $silent;
1111 "alter table branchcategories change branchcode categoryname text");
1115 unless ( $branchcategories{'codedescription'} eq 'text' ) {
1117 "Replacing branchholding in branchcategories with codedescription text.\n" unless $silent;
1120 "alter table branchcategories change branchholding codedescription text"
1125 # changing the items table around...
1128 $sth = $dbh->prepare("show columns from items");
1130 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1132 $items{$column} = $type;
1135 if ($items{'bulk'} eq "varchar(30)") {
1136 print " Setting callnumber in items table\n" unless $silent;
1138 $dbh->prepare("ALTER TABLE `items` CHANGE `bulk` `itemcallnumber` VARCHAR( 30 ) DEFAULT NULL");
1140 $sti = $dbh->prepare("update marc_subfield_structure set kohafield=\"items.itemcallnumber\" where kohafield=\"items.bulk\"");
1144 # changing the marc_subfield_structure table around...
1145 my %marc_subfield_structure;
1147 $sth = $dbh->prepare("show columns from marc_subfield_structure");
1149 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1151 $marc_subfield_structure{$column} = $type;
1154 if ($marc_subfield_structure{thesaurus_category}) {
1155 print " changing thesaurus_category in marc_subfield_structure table\n" unless $silent;
1157 $dbh->prepare("ALTER TABLE marc_subfield_structure CHANGE `thesaurus_category` `authtypecode` VARCHAR(10 ) DEFAULT NULL");
1162 # creating index in issuingrules if needed
1164 $sth = $dbh->prepare("show index from issuingrules");
1167 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1169 if ($key_name eq 'PRIMARY') {
1173 print "Creating index on issuing rules\n" unless $exists or $silent;
1174 $dbh->do('ALTER TABLE issuingrules ADD PRIMARY KEY ( branchcode, categorycode, itemtype )') unless $exists;
1176 $dbh->do('ALTER TABLE marc_tag_structure drop primary key');
1177 $dbh->do('ALTER TABLE marc_tag_structure ADD PRIMARY KEY ( frameworkcode, tagfield )');
1179 $dbh->do('ALTER TABLE marc_subfield_structure drop primary key');
1180 $dbh->do('ALTER TABLE marc_subfield_structure ADD PRIMARY KEY ( frameworkcode, tagfield, tagsubfield )');
1182 # Get list of columns from marc_word table
1185 $sth = $dbh->prepare("show columns from marc_word");
1187 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1189 $marc_word{$column} = $type;
1190 $nullenabled{$column} = $null;
1192 if ($marc_word{subfieldid}) {
1193 #create field tagsubfield, copy tag+subfieldid, then drop tag and subfieldid
1194 print "Modifying marc_word (concat on tag and subfield for better perfs)\n" unless $silent;
1195 $dbh->do("ALTER TABLE `marc_word` ADD `tagsubfield` CHAR( 4 ) NOT NULL AFTER `bibid`");
1196 $dbh->do("update marc_word set tagsubfield=concat(tag,subfieldid)");
1197 $dbh->do("alter table marc_word drop tag");
1198 $dbh->do("alter table marc_word drop subfieldid");
1199 $dbh->do("create index Search_Marc on marc_word (tagsubfield,word)");
1201 # Populate tables with required data
1203 foreach my $table ( keys %tabledata ) {
1204 print "Checking for data required in table $table...\n" unless $silent;
1205 my $tablerows = $tabledata{$table};
1206 foreach my $row (@$tablerows) {
1207 my $uniquefieldrequired = $row->{uniquefieldrequired};
1208 my $uniquevalue = $row->{$uniquefieldrequired};
1209 my $forceupdate = $row->{forceupdate};
1212 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
1214 $sth->execute($uniquevalue);
1216 foreach my $field (keys %$forceupdate) {
1217 if ($forceupdate->{$field}) {
1218 my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
1219 $sth->execute($row->{$field}, $uniquevalue);
1223 print "Adding row to $table: " unless $silent;
1227 foreach my $field ( keys %$row ) {
1228 next if $field eq 'uniquefieldrequired';
1229 next if $field eq 'forceupdate';
1230 my $value = $row->{$field};
1231 push @values, $value;
1232 print " $field => $value" unless $silent;
1233 $fieldlist .= "$field,";
1234 $placeholders .= "?,";
1236 print "\n" unless $silent;
1237 $fieldlist =~ s/,$//;
1238 $placeholders =~ s/,$//;
1241 "insert into $table ($fieldlist) values ($placeholders)");
1242 $sth->execute(@values);
1252 # Revision 1.90 2004/07/06 08:24:18 tipaul
1253 # adding 2 free fields that can be used for sorting purposes
1255 # Revision 1.89 2004/07/02 15:55:08 tipaul
1256 # Adding 2 new fields, called "sort1" and "sort2"
1257 # They can be used for sorting & statistics reasons by the library.
1259 # Revision 1.88 2004/06/26 23:34:26 rangi
1262 # Revision 1.87 2004/06/23 13:03:09 tipaul
1263 # fixes in DB structure
1265 # Revision 1.86 2004/06/22 11:30:57 tipaul
1266 # adding -s (silent) flag, to have a silent install.
1267 # only updater will be verbose
1269 # Revision 1.85 2004/06/17 15:19:44 tipaul
1270 # missing Marc_Search index on marc_word
1272 # Revision 1.84 2004/06/17 08:25:21 tipaul
1273 # DB modifs : merging tag & subfield in marc_word table
1275 # Revision 1.83 2004/06/10 08:32:02 tipaul
1276 # MARC authority management (continued)
1278 # Revision 1.82 2004/06/03 12:46:58 tipaul
1279 # * frameworks and itemtypes are independant
1281 # WARNING : will work only if applied to a 2.0 base. some modifs have been done since last commit that will NOT be applied if you run updatedatabase again.
1283 # Revision 1.81 2004/05/28 09:56:21 tipaul
1286 # Revision 1.80 2004/05/28 08:32:00 tipaul
1288 # * MARC authority file
1289 # * seealso & hidden in MARC biblio structure.
1291 # Revision 1.79 2004/05/18 09:50:07 tipaul
1292 # *** empty log message ***
1294 # Revision 1.78 2004/05/10 09:29:33 tipaul
1295 # css is now the default theme for OPAC.
1296 # It will be the theme used for improvements and new things in OPAC.
1298 # Revision 1.77 2004/05/06 14:56:51 tipaul
1299 # adding table issuingrules (previously called categoryitem
1301 # Revision 1.76 2004/05/03 09:32:25 tipaul
1302 # adding printcirculationsplit parameter (already existed, but was not in systempref by defaul)
1304 # Revision 1.75 2004/04/14 19:49:00 tipaul
1305 # seealso field set to 255 chars
1307 # Revision 1.74 2004/03/11 16:10:16 tipaul
1308 # *** empty log message ***
1310 # Revision 1.73 2004/03/06 20:26:13 tipaul
1311 # adding seealso feature in MARC searches