Acquisition & Suggestion :
[koha.git] / updater / updatedatabase
1 #!/usr/bin/perl
2
3 # $Id$
4
5 # Database Updater
6 # This script checks for required updates to the database.
7
8 # Part of the Koha Library Software www.koha.org
9 # Licensed under the GPL.
10
11 # Bugs/ToDo:
12 # - Would also be a good idea to offer to do a backup at this time...
13
14 # NOTE:  If you do something more than once in here, make it table driven.
15
16 use strict;
17
18 # CPAN modules
19 use DBI;
20 use Getopt::Long;
21 # Koha modules
22 use C4::Context;
23
24 # FIXME - The user might be installing a new database, so can't rely
25 # on /etc/koha.conf anyway.
26
27 my $debug = 0;
28
29 my (
30     $sth, $sti,
31     $query,
32     %existingtables,    # tables already in database
33     %types,
34     $table,
35     $column,
36     $type, $null, $key, $default, $extra,
37     $prefitem,          # preference item in systempreferences table
38 );
39
40 my $silent;
41 GetOptions(
42         's' =>\$silent
43         );
44 my $dbh = C4::Context->dbh;
45 print "connected to your DB. Checking & modifying it\n" unless $silent;
46
47 #-------------------
48 # Defines
49
50 # Tables to add if they don't exist
51 my %requiretables = (
52     shelfcontents => "( shelfnumber int not null,
53                                                         itemnumber int not null,
54                                                         flags int)",
55     bookshelf => "( shelfnumber int auto_increment primary key,
56                                                 shelfname char(255))",
57     z3950queue => "( id int auto_increment primary key,
58                                                 term text,
59                                                 type char(10),
60                                                 startdate int,
61                                                 enddate int,
62                                                 done smallint,
63                                                 results longblob,
64                                                 numrecords int,
65                                                 servers text,
66                                                 identifier char(30))",
67     z3950results => "( id int auto_increment primary key,
68                                                 queryid int,
69                                                 server char(255),
70                                                 startdate int,
71                                                 enddate int,
72                                                 results longblob,
73                                                 numrecords int,
74                                                 numdownloaded int,
75                                                 highestseen int,
76                                                 active smallint)",
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',
81                                                 title text,
82                                                 description text,
83                                                 url varchar(255),
84                                                 PRIMARY KEY (websitenumber) )",
85     marcrecorddone => "( isbn char(40),
86                                                                 issn char(40),
87                                                                 lccn char(40),
88                                                                 controlnumber char(40))",
89     uploadedmarc => "( id int(11) NOT NULL auto_increment PRIMARY KEY,
90                                                         marc longblob,
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,
99                                                 lasttime int,
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 '',
112                                                         PRIMARY KEY  (id),
113                                                         KEY freelib (freelib),
114                                                         KEY stdlib (stdlib),
115                                                         KEY category (category),
116                                                         KEY hierarchy (hierarchy)
117                                                         )",
118     marc_biblio => "(
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,
124                                                 PRIMARY KEY  (bibid),
125                                                 KEY origincode (origincode),
126                                                 KEY biblionumber (biblionumber)
127                                                 ) ",
128     marc_blob_subfield => "(
129                                         blobidlink bigint(20) NOT NULL auto_increment,
130                                         subfieldvalue longtext NOT NULL,
131                                         PRIMARY KEY  (blobidlink)
132                                         ) ",
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),
147                                                 KEY tab (tab)
148                                                 )",
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),
160                                                 KEY bibid (bibid),
161                                                 KEY tag (tag),
162                                                 KEY tag_indicator (tag_indicator),
163                                                 KEY subfieldorder (subfieldorder),
164                                                 KEY subfieldcode (subfieldcode),
165                                                 KEY subfieldvalue (subfieldvalue),
166                                                 KEY tagorder (tagorder)
167                                         )",
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)
176                                         )",
177     marc_word => "(
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 '',
185                                 KEY bibid (bibid),
186                                 KEY tag (tag),
187                                 KEY tagorder (tagorder),
188                                 KEY subfieldid (subfieldid),
189                                 KEY subfieldorder (subfieldorder),
190                                 KEY word (word),
191                                 KEY sndx_word (sndx_word)
192                         )",
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,
198                                 marc text NOT NULL,
199                                 encoding varchar(40) default NULL,
200                                 PRIMARY KEY  (id),
201                                 KEY title (title),
202                                 KEY isbn (isbn)
203                         )",
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 '',
207                                 lib char(80) NULL,
208                                 PRIMARY KEY  (id),
209                                 KEY name (category)
210                         )",
211     userflags => "( bit int(11) NOT NULL default '0',
212                                 flag char(30), flagdesc char(255),
213                                 defaulton int(11)
214                         )",
215         auth_types => "(
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)
221                         )",
222         biblio_framework => "(
223                                         frameworkcode char(4) not NULL,
224                                         frameworktext char(255) not NULL,
225                                         PRIMARY KEY (frameworkcode)
226                         )",
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)
241                                         )",
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)
251                                         )",
252     auth_header => "(
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),
260                                                 ) ",
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),
271                                                 KEY authid (authid),
272                                                 KEY tag (tag),
273                                                 KEY subfieldcode (subfieldcode),
274                                                 KEY subfieldvalue (subfieldvalue)
275                                         )",
276     auth_word => "(
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 '',
283                                 KEY authid (authid),
284                                 KEY marc_search (tagsubfield,word),
285                                 KEY word (word),
286                                 KEY sndx_word (sndx_word)
287                         )",
288         suggestions => "(
289                                 suggestionid 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 '',
293                                 note text,
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                                 volumedesc char(255) default NULL,
300                                 publicationyear smallint(6) default NULL,
301                                 place char(255) default NULL,
302                                 isbn char(10) default NULL,
303                                 mailoverseeing smallint(1) default 0,
304                                 PRIMARY KEY  (suggestionnumber),
305                                 KEY suggestedby (suggestedby),
306                                 KEY managedby (managedby)
307                         )",
308         aqbasket => "(basketno int(11) NOT NULL auto_increment,
309                                 creationdate date,
310                                 closedate date,
311                                 booksellerid varchar(10),
312                                 authorisedby varchar(10),
313                                 booksellerinvoicenumber text,
314                                 PRIMARY KEY (basketno)
315                                 )",
316 );
317
318 my %requirefields = (
319     biblio        => { 'abstract' => 'text' },
320     deletedbiblio => { 'abstract' => 'text', 'marc' => 'blob' },
321     deleteditems => { 'marc' => 'blob', 'paidfor' => 'text' },
322     biblioitems   => {
323         'lccn' => 'char(25)',
324         'url'  => 'varchar(255)',
325         'marc' => 'text'
326     },
327     deletedbiblioitems => {
328         'lccn' => 'char(25)',
329         'url'  => 'varchar(255)',
330         'marc' => 'text'
331     },
332     branchtransfers => { 'datearrived'    => 'datetime' },
333     statistics      => { 'borrowernumber' => 'int(11)' },
334     aqbooksellers   => {
335         'invoicedisc' => 'float(6,4)',
336         'nocalc'      => 'int(11)'
337     },
338     borrowers => {
339                 'userid'        => 'char(30)',
340                 'password'      => 'char(30)',
341                 'flags'         => 'int(11)',
342                 'textmessaging' => 'varchar(30)',
343                 'zipcode' => 'varchar(25)',
344                 'homezipcode' => 'varchar(25)',
345                 'sort1' => 'char(80)',
346                 'sort2' => 'char(80)',
347     },
348     aqorders => { 'budgetdate' => 'date',
349                                 'sort1' => 'char(80)',
350                                 'sort2' => 'char(80)', },
351     aqbudget => {'aqbudgetid' => 'tinyint(4) auto_increment primary key'},
352     items => {'paidfor' => 'text'},
353
354     #added so that reference items are not available for reserves...
355     itemtypes         => { 'notforloan'  => 'smallint(6)' },
356     systempreferences => { 'explanation' => 'char(80)',
357                            'type' => 'char(20)',
358                            'options' => 'text' },
359     z3950servers      => { 'syntax'      => 'char(80)' },
360         marc_tag_structure =>{
361                                                         'frameworkcode' => 'char(4) not NULL default \'\''},
362     marc_subfield_structure =>{'seealso'  => 'char(255)',
363                                                         'frameworkcode' => 'char(4) not NULL default \'\'',
364                                                         'hidden' => 'tinyint(1)',
365                                                         'isurl' => 'tinyint(1)',
366                                                         },
367     bookshelf => {'owner' => 'char(80)',
368                                         'category' => 'char(1)',
369                                 },
370     marc_biblio        => { 'frameworkcode' => 'char(4) not NULL default \'\'' },
371 );
372
373 my %dropable_table = (
374     classification => 'classification',
375     multipart      => 'multipart',
376     multivolume    => 'multivolume',
377     newitems       => 'newitems',
378     procedures     => 'procedures',
379     publisher      => 'publisher',
380     searchstats    => 'searchstats',
381     serialissues   => 'serialissues',
382 );
383
384 my %uselessfields = (
385         aqorders => "requisitionedby,authorisedby,booksellerid,
386                         deliverydays,followupdays,
387                         numberfollowupsallowed,numberfollowupssent,
388                         dateprinted,sourced,quantityreceiveddamaged,
389                         subscriptionfrom,subscriptionto
390                         "
391         );
392 # the other hash contains other actions that can't be done elsewhere. they are done
393 # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
394
395 # The tabledata hash contains data that should be in the tables.
396 # The uniquefieldrequired hash entry is used to determine which (if any) fields
397 # must not exist in the table for this row to be inserted.  If the
398 # uniquefieldrequired entry is already in the table, the existing data is not
399 # modified, unless the forceupdate hash entry is also set.  Fields in the
400 # anonymous "forceupdate" hash will be forced to be updated to the default
401 # values given in the %tabledata hash.
402
403 my %tabledata = (
404     userflags => [
405         {
406             uniquefieldrequired => 'bit',
407             bit                 => 0,
408             flag                => 'superlibrarian',
409             flagdesc            => 'Access to all librarian functions',
410             defaulton           => 0
411         },
412         {
413             uniquefieldrequired => 'bit',
414             bit                 => 1,
415             flag                => 'circulate',
416             flagdesc            => 'Circulate books',
417             defaulton           => 0
418         },
419         {
420             uniquefieldrequired => 'bit',
421             bit                 => 2,
422             flag                => 'catalogue',
423             flagdesc            => 'View Catalogue (Librarian Interface)',
424             defaulton           => 0
425         },
426         {
427             uniquefieldrequired => 'bit',
428             bit                 => 3,
429             flag                => 'parameters',
430             flagdesc            => 'Set Koha system paramters',
431             defaulton           => 0
432         },
433         {
434             uniquefieldrequired => 'bit',
435             bit                 => 4,
436             flag                => 'borrowers',
437             flagdesc            => 'Add or modify borrowers',
438             defaulton           => 0
439         },
440         {
441             uniquefieldrequired => 'bit',
442             bit                 => 5,
443             flag                => 'permissions',
444             flagdesc            => 'Set user permissions',
445             defaulton           => 0
446         },
447         {
448             uniquefieldrequired => 'bit',
449             bit                 => 6,
450             flag                => 'reserveforothers',
451             flagdesc            => 'Reserve books for patrons',
452             defaulton           => 0
453         },
454         {
455             uniquefieldrequired => 'bit',
456             bit                 => 7,
457             flag                => 'borrow',
458             flagdesc            => 'Borrow books',
459             defaulton           => 1
460         },
461         {
462             uniquefieldrequired => 'bit',
463             bit                 => 8,
464             flag                => 'reserveforself',
465             flagdesc            => 'Reserve books for self',
466             defaulton           => 0
467         },
468         {
469             uniquefieldrequired => 'bit',
470             bit                 => 9,
471             flag                => 'editcatalogue',
472             flagdesc  => 'Edit Catalogue (Modify bibliographic/holdings data)',
473             defaulton => 0
474         },
475         {
476             uniquefieldrequired => 'bit',
477             bit                 => 10,
478             flag                => 'updatecharges',
479             flagdesc            => 'Update borrower charges',
480             defaulton           => 0
481         },
482     ],
483     systempreferences => [
484         {
485             uniquefieldrequired => 'variable',
486             forceupdate         => { 'explanation' => 1,
487                                      'type' => 1 },
488             variable            => 'LibraryName',
489             value               => '<i><b>Koha<br/>Free Software ILS<br/><br/></b>Koha : a gift, a contribution<br/> in Maori</i>',
490             explanation         => 'Library name as shown on main opac page',
491             type                => ''
492
493         },
494         {
495             uniquefieldrequired => 'variable',
496             forceupdate         => { 'explanation' => 1,
497                                      'type' => 1 },
498             variable            => 'autoMemberNum',
499             value               => '1',
500             explanation         => 'Member number is auto-calculated',
501             type                => 'YesNo'
502
503         },
504         {
505             uniquefieldrequired => 'variable',
506             forceupdate         => { 'explanation' => 1,
507                                      'type' => 1,
508                                      'options' => 1 },
509             variable            => 'acquisitions',
510             value               => 'normal',
511             explanation         =>
512 'Normal, budget-based acquisitions, or Simple bibliographic-data acquisitions',
513             type                => 'Choice',
514             options             => 'simple|normal'
515         },
516         {
517             uniquefieldrequired => 'variable',
518             forceupdate         => { 'explanation' => 1,
519                                      'type' => 1,
520                                      'options' => 1 },
521             variable            => 'dateformat',
522             value               => 'metric',
523             explanation         =>
524             'date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy/mm/dd)',
525             type                => 'Choice',
526             options             => 'metric|us|iso'
527         },
528         {
529             uniquefieldrequired => 'variable',
530             variable            => 'template',
531             forceupdate         => { 'explanation' => 1,
532                                      'type' => 1 },
533             value               => 'default',
534             explanation         => 'Preference order for intranet interface templates',
535             type                => 'Themes'
536         },
537         {
538             uniquefieldrequired => 'variable',
539             variable            => 'autoBarcode',
540             forceupdate         => { 'explanation' => 1,
541                                      'type' => 1 },
542             value               => 'yes',
543             explanation         => 'Barcode is auto-calculated',
544             type                => 'YesNo'
545         },
546         {
547             uniquefieldrequired => 'variable',
548             variable            => 'insecure',
549             forceupdate         => { 'explanation' => 1,
550                                      'type' => 1 },
551             value               => 'no',
552             explanation         =>
553 'If YES, no auth at all is needed. Be careful if you set this to yes!',
554             type                => 'YesNo'
555         },
556         {
557             uniquefieldrequired => 'variable',
558             variable            => 'authoritysep',
559             forceupdate         => { 'explanation' => 1,
560                                      'type' => 1,
561                                      'options' => 1 },
562             value               => '--',
563             explanation         =>
564             'the separator used in authority/thesaurus. Usually --',
565             type                => 'free',
566             options             => '10'
567         },
568         {
569             uniquefieldrequired => 'variable',
570             variable            => 'opaclanguages',
571             forceupdate         => { 'explanation' => 1,
572                                      'type' => 1 },
573             value               => 'en',
574             explanation         => 'Set the preferred order for translations.  The top language will be tried first.',
575             type                => 'Languages'
576         },
577         {
578             uniquefieldrequired => 'variable',
579             variable            => 'opacthemes',
580             forceupdate         => { 'explanation' => 1,
581                                      'type' => 1 },
582             value               => 'css',
583             explanation         => 'Set the preferred order for themes.  The top theme will be tried first.',
584             type                => 'Themes'
585         },
586         {
587             uniquefieldrequired => 'variable',
588             variable            => 'timeout',
589             forceupdate         => { 'explanation' => 1,
590                                      'type' => 1 },
591             value               => '1200',
592             explanation         => 'Inactivity timeout for cookies authentication (in seconds)',
593             type                => 'Integer'
594         },
595         {
596             uniquefieldrequired => 'variable',
597             variable            => 'marc',
598             forceupdate         => { 'explanation' => 1,
599                                      'type' => 1 },
600             value               => 'yes',
601             explanation         => 'Turn on MARC support',
602             type                => 'YesNo'
603         },
604         {
605             uniquefieldrequired => 'variable',
606             variable            => 'marcflavour',
607             forceupdate         => { 'explanation' => 1,
608                                      'type' => 1,
609                                      'options' => 1},
610             value               => 'MARC21',
611             explanation         =>
612             'your MARC flavor (MARC21 or UNIMARC) used for character encoding',
613             type                => 'Choice',
614             options             => 'MARC21|UNIMARC'
615         },
616         {
617             uniquefieldrequired => 'variable',
618             variable            => 'checkdigit',
619             value               => 'none',
620             forceupdate         => { 'explanation' => 1,
621                                      'type' => 1,
622                                      'options' => 1},
623             explanation         => 'Validity checks on membership number: none or "Katipo" style checks',
624             type                => 'Choice',
625             options             => 'none|katipo'
626         },
627         {
628             uniquefieldrequired => 'variable',
629             variable            => 'maxoutstanding',
630             forceupdate         => { 'explanation' => 1,
631                                      'type' => 1 },
632             value               => '5',
633             explanation         =>
634             'maximum amount withstanding to be able make reserves ',
635             type                => 'Integer'
636         },
637         {
638             uniquefieldrequired => 'variable',
639             variable            => 'maxreserves',
640             forceupdate         => { 'explanation' => 1,
641                                      'type' => 1 },
642             value               => '5',
643             explanation         =>
644             'maximum number of reserves a member can make',
645             type                => 'Integer'
646
647         },
648         {
649             uniquefieldrequired => 'variable',
650             variable            => 'noissuescharge',
651             forceupdate         => { 'explanation' => 1,
652                                      'type' => 1 },
653             value               => '5',
654             explanation         =>
655             'maximum amount withstanding to be able to check out an item',
656             type                => 'Integer'
657
658         },
659         {
660             uniquefieldrequired => 'variable',
661             variable            => 'KohaAdminEmailAddress',
662             forceupdate         => { 'explanation' => 1,
663                                      'type' => 1 },
664             value               => 'your.mail@here',
665             explanation => 'the email address where borrowers modifs are sent',
666             type                => 'free'
667         },
668         {
669             uniquefieldrequired => 'variable',
670             variable            => 'gist',
671             forceupdate         => { 'explanation' => 1,
672                                      'type' => 1 },
673             value               => '0.125',
674             explanation => 'the gist rate. NOT in %, but in numeric form (0.12 for 12%)',
675             type                => 'free'
676         },
677         {
678             uniquefieldrequired => 'variable',
679             variable            => 'ldapserver',
680             forceupdate         => { 'explanation' => 1,
681                                      'type' => 1 },
682             value               => '',
683             explanation => 'your ldap server',
684             type                => 'free'
685         },
686         {
687             uniquefieldrequired => 'variable',
688             variable            => 'ldapinfos',
689             forceupdate         => { 'explanation' => 1,
690                                      'type' => 1 },
691             value               => '',
692             explanation => 'ldap info. The ldap will be used in dn : uid=xxx, <ldapinfos>',
693             type                => 'free'
694         },
695         {
696             uniquefieldrequired => 'variable',
697             variable            => 'printcirculationslips',
698             forceupdate         => { 'explanation' => 1,
699                                      'type' => 1 },
700             value               => '0',
701             explanation => 'if set to 1, print circulation slips. If set to 0, don\'t',
702             type                => 'free'
703         },
704         {
705             uniquefieldrequired => 'variable',
706             variable            => 'suggestion',
707             forceupdate         => { 'explanation' => 1,
708                                      'type' => 1 },
709             value               => '0',
710             explanation => 'if set to 1, suggestions are activated in OPAC',
711             type                => 'free'
712         },
713         {
714             uniquefieldrequired => 'variable',
715             variable            => 'ISBD',
716             forceupdate         => { 'explanation' => 1,
717                                      'type' => 1 },
718             value               => 'Fill with appropriate value...',
719             explanation => 'ISBD',
720             type                => 'free'
721         },
722         {
723             uniquefieldrequired => 'variable',
724             variable            => 'virtualshelves',
725             forceupdate         => { 'explanation' => 1,
726                                      'type' => 1 },
727             value               => '0',
728             explanation => 'Set virtual shelves management ON or OFF',
729             type                => 'YesNo'
730         },
731     ],
732
733 );
734
735 my %fielddefinitions = (
736     printers => [
737         {
738             field   => 'printername',
739             type    => 'char(40)',
740             null    => '',
741             key     => 'PRI',
742             default => ''
743         },
744     ],
745     aqbookfund => [
746         {
747             field   => 'bookfundid',
748             type    => 'char(5)',
749             null    => '',
750             key     => 'PRI',
751             default => ''
752         },
753     ],
754     aqbudget => [
755         {
756             field   => 'aqbudgetid',
757             type    => 'tinyint(4)',
758             null    => '',
759             key     => 'PRI',
760                   default =>'',
761             extra => 'auto_increment'
762         },
763     ],
764     z3950servers => [
765         {
766             field   => 'id',
767             type    => 'int',
768             null    => '',
769             key     => 'PRI',
770             default => '',
771             extra   => 'auto_increment'
772         },
773     ],
774         marc_breeding => [
775         {
776             field   => 'z3950random',
777             type    => 'varchar(40)',
778             null    => 'NULL',
779             key     => '',
780             default => '',
781             extra   => ''
782         },
783         {
784             field   => 'encoding',
785             type    => 'varchar(40)',
786             null    => '',
787             key     => '',
788             default => '',
789             extra   => ''
790         },
791     ],
792 );
793
794 #-------------------
795 # Initialize
796
797 # Start checking
798
799 # Get version of MySQL database engine.
800 my $mysqlversion = `mysqld --version`;
801 $mysqlversion =~ /Ver (\S*) /;
802 $mysqlversion = $1;
803 if ( $mysqlversion ge '3.23' ) {
804     print "Could convert to MyISAM database tables...\n" unless $silent;
805 }
806
807 #---------------------------------
808 # Tables
809
810 # Collect all tables into a list
811 $sth = $dbh->prepare("show tables");
812 $sth->execute;
813 while ( my ($table) = $sth->fetchrow ) {
814     $existingtables{$table} = 1;
815 }
816
817
818 # Now add any missing tables
819 foreach $table ( keys %requiretables ) {
820     unless ( $existingtables{$table} ) {
821         print "Adding $table table...\n" unless $silent;
822         my $sth = $dbh->prepare("create table $table $requiretables{$table}");
823         $sth->execute;
824         if ( $sth->err ) {
825             print "Error : $sth->errstr \n";
826             $sth->finish;
827         }    # if error
828     }    # unless exists
829 }    # foreach
830
831 # now drop useless tables
832 foreach $table ( keys %dropable_table ) {
833         if ( $existingtables{$table} ) {
834                 print "Dropping unused table $table\n" if $debug and not $silent;
835                 $dbh->do("drop table $table");
836                 if ( $dbh->err ) {
837                         print "Error : $dbh->errstr \n";
838                 }
839         }
840 }
841 unless ( $existingtables{'z3950servers'} ) {
842         #MJR: added syntax entries to close bug 624
843     print "Adding z3950servers table...\n" unless $silent;
844     my $sti = $dbh->prepare( "create table z3950servers (
845                                                                                 host char(255),
846                                                                                 port int,
847                                                                                 db char(255),
848                                                                                 userid char(255),
849                                                                                 password char(255),
850                                                                                 name text,
851                                                                                 id int,
852                                                                                 checked smallint,
853                                                                                 rank int,
854                                                                                 syntax char(80))"
855     );
856     $sti->execute;
857     $sti = $dbh->prepare( "insert into z3950servers
858                                                                 values ('z3950.loc.gov',
859                                                                 7090,
860                                                                 'voyager',
861                                                                 '', '',
862                                                                 'Library of Congress',
863                                                                 1, 1, 1, 'USMARC')"
864     );
865     $sti->execute;
866 }
867 unless ( $existingtables{'issuingrules'} ) {
868         $dbh->do("alter table categoryitem rename issuingrules");
869         $dbh->do("ALTER TABLE issuingrules ADD maxissueqty int(4) default NULL");
870         $dbh->do("ALTER TABLE issuingrules ADD issuelength int(4) default NULL");
871         $dbh->do("ALTER TABLE issuingrules ADD branchcode varchar(4) NOT NULL default ''");
872         print "renaming categoryitem\n" unless $silent;
873 }
874
875
876 #---------------------------------
877 # Columns
878
879 foreach $table ( keys %requirefields ) {
880     print "Check table $table\n" if $debug and not $silent;
881     $sth = $dbh->prepare("show columns from $table");
882     $sth->execute();
883     undef %types;
884     while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
885     {
886         $types{$column} = $type;
887     }    # while
888     foreach $column ( keys %{ $requirefields{$table} } ) {
889         print "  Check column $column  [$types{$column}]\n" if $debug and not $silent;
890         if ( !$types{$column} ) {
891
892             # column doesn't exist
893             print "Adding $column field to $table table...\n" unless $silent;
894             $query = "alter table $table
895                         add column $column " . $requirefields{$table}->{$column};
896             print "Execute: $query\n" if $debug;
897             my $sti = $dbh->prepare($query);
898             $sti->execute;
899             if ( $sti->err ) {
900                 print "**Error : $sti->errstr \n";
901                 $sti->finish;
902             }    # if error
903         }    # if column
904     }    # foreach column
905 }    # foreach table
906
907 foreach $table ( keys %fielddefinitions ) {
908         print "Check table $table\n" if $debug;
909         $sth = $dbh->prepare("show columns from $table");
910         $sth->execute();
911         my $definitions;
912         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
913         {
914                 $definitions->{$column}->{type}    = $type;
915                 $definitions->{$column}->{null}    = $null;
916                 $definitions->{$column}->{key}     = $key;
917                 $definitions->{$column}->{default} = $default;
918                 $definitions->{$column}->{extra}   = $extra;
919         }    # while
920         my $fieldrow = $fielddefinitions{$table};
921         foreach my $row (@$fieldrow) {
922                 my $field   = $row->{field};
923                 my $type    = $row->{type};
924                 my $null    = $row->{null};
925                 my $key     = $row->{key};
926                 my $default = $row->{default};
927                 $default="''" unless $default;
928                 my $extra   = $row->{extra};
929                 my $def     = $definitions->{$field};
930                 unless ( $type eq $def->{type}
931                         && $null eq $def->{null}
932                         && $key eq $def->{key}
933                         && $default eq $def->{default}
934                         && $extra eq $def->{extra} )
935                 {
936
937                         if ( $null eq '' ) {
938                                 $null = 'NOT NULL';
939                         }
940                         if ( $key eq 'PRI' ) {
941                                 $key = 'PRIMARY KEY';
942                         }
943                         unless ( $extra eq 'auto_increment' ) {
944                                 $extra = '';
945                         }
946                         # if it's a new column use "add", if it's an old one, use "change".
947                         my $action;
948                         if ($definitions->{$field}->{type}) {
949                                 $action="change $field"
950                         } else {
951                                 $action="add";
952                         }
953 # if it's a primary key, drop the previous pk, before altering the table
954                         my $sth;
955                         if ($key ne 'PRIMARY KEY') {
956                                 $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ?");
957                         } else {
958                                 $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ?");
959                         }
960                         $sth->execute($default);
961                         print "  Alter $field in $table\n" unless $silent;
962                 }
963         }
964 }
965
966 # Get list of columns from borrowers table
967 my %itemtypes;
968 my %nullenabled;
969 $sth = $dbh->prepare("show columns from borrowers");
970 $sth->execute;
971 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
972 {
973     $itemtypes{$column} = $type;
974     $nullenabled{$column} = $null;
975 }
976
977 unless ( $itemtypes{'cardnumber'} eq 'varchar(20)' ) {
978     $itemtypes{'cardnumber'} =~ /varchar\((\d+)\)/;
979     my $oldlength = $1;
980     if ( $oldlength < 16 ) {
981         print "Setting maximum cardnumber length to 16 (was $oldlength) and marking unique.\n" unless $silent;
982         my $sti =
983           $dbh->prepare(
984             "alter table borrowers change cardnumber cardnumber varchar(16)");
985         $sti->execute;
986         $sti->finish;
987         $sti =
988           $dbh->prepare(
989             "alter table borrowers drop index cardnumber");
990         $sti->execute;
991         $sti->finish;
992         $sti =
993           $dbh->prepare(
994             "alter table borrowers add unique(cardnumber)");
995         $sti->execute;
996         $sti->finish;
997     }
998 }
999 #
1000 # Get list of columns from items table
1001 $sth = $dbh->prepare("show columns from items");
1002 $sth->execute;
1003 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1004 {
1005     $itemtypes{$column} = $type;
1006     $nullenabled{$column} = $null;
1007 }
1008
1009 unless ( $itemtypes{'barcode'} eq 'varchar(20)' ) {
1010     $itemtypes{'barcode'} =~ /varchar\((\d+)\)/;
1011     my $oldlength = $1;
1012     if ( $oldlength < 20 ) {
1013         print "Setting maximum barcode length to 20 (was $oldlength).\n" unless $silent;
1014         my $sti =
1015           $dbh->prepare(
1016             "alter table items change barcode barcode varchar(20)");
1017         $sti->execute;
1018     }
1019 }
1020 #
1021 # dropping unique barcode index & setting barcode to null allowed.
1022 #
1023 $sth = $dbh->prepare("show index from items");
1024 $sth->execute;
1025 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1026 {
1027         if ($key_name eq 'barcode' && $non_unique eq 0) {
1028                 print "dropping BARCODE index to enable empty barcodes\n" unless $silent;
1029                 $dbh->do("ALTER TABLE `items` DROP INDEX `barcode`");
1030         }
1031 }
1032 $dbh->do("ALTER TABLE `items` CHANGE `barcode` `barcode` VARCHAR( 20 )") unless ($nullenabled{barcode} eq 'YES');
1033
1034 #
1035 # creating fulltext index in bibliothesaurus if needed
1036 #
1037 $sth = $dbh->prepare("show index from bibliothesaurus");
1038 $sth->execute;
1039 my $exists=0;
1040 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1041 {
1042         if ($key_name eq 'category_2') {
1043                 $exists=1;
1044         }
1045 }
1046 print "Creating fulltext index on bibliothesaurus\n" unless $exists or $silent;
1047 $dbh->do('create fulltext index category_2 on bibliothesaurus (category,freelib)') unless $exists;
1048
1049 #
1050 # creating  index in z3950results if needed
1051 #
1052 $sth = $dbh->prepare("show index from z3950results");
1053 $sth->execute;
1054 my $exists=0;
1055 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1056 {
1057         if ($key_name eq 'query_server') {
1058                 $exists=1;
1059         }
1060 }
1061 print "Creating  index on z3950results\n" unless $exists or $silent;
1062 $dbh->do('create unique index query_server on z3950results (queryid,server)') unless $exists;
1063
1064 # changing z3950daemon field to NULL in marc_breeding
1065 $dbh->do("ALTER TABLE `marc_breeding` CHANGE `z3950random` `z3950random` VARCHAR( 40 )");
1066
1067 # making borrowernumber an auto_increment field
1068 $dbh->do("ALTER TABLE `borrowers` CHANGE `borrowernumber` `borrowernumber` INTEGER auto_increment");
1069
1070 # changing indexes in marc_*_structure to use frameworkcode
1071 $dbh->do('alter table marc_subfield_structure drop index tab');
1072 $dbh->do('create index tab on marc_subfield_structure (frameworkcode,tab)');
1073 $dbh->do('alter table marc_subfield_structure drop index kohafield');
1074 $dbh->do('create index kohafield on marc_subfield_structure (frameworkcode,kohafield)');
1075
1076
1077 # extending the timestamp in branchtransfers...
1078 my %branchtransfers;
1079
1080 $sth = $dbh->prepare("show columns from branchtransfers");
1081 $sth->execute;
1082 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1083 {
1084     $branchtransfers{$column} = $type;
1085 }
1086
1087 unless ( $branchtransfers{'datesent'} eq 'datetime' ) {
1088     print "Setting type of datesent in branchtransfers to datetime.\n" unless $silent;
1089     my $sti =
1090       $dbh->prepare(
1091         "alter table branchtransfers change datesent datesent datetime");
1092     $sti->execute;
1093 }
1094
1095 unless ( $branchtransfers{'datearrived'} eq 'datetime' ) {
1096     print "Setting type of datearrived in branchtransfers to datetime.\n" unless $silent;
1097     my $sti =
1098       $dbh->prepare(
1099         "alter table branchtransfers change datearrived datearrived datetime");
1100     $sti->execute;
1101 }
1102
1103 # changing the branchcategories table around...
1104 my %branchcategories;
1105
1106 $sth = $dbh->prepare("show columns from branchcategories");
1107 $sth->execute;
1108 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1109 {
1110     $branchcategories{$column} = $type;
1111 }
1112
1113 unless ( $branchcategories{'categorycode'} eq 'varchar(4)' ) {
1114     print
1115 "Setting type of categorycode in branchcategories to varchar(4),\n and making the primary key.\n" unless $silent;
1116     my $sti =
1117       $dbh->prepare(
1118 "alter table branchcategories change categorycode categorycode varchar(4) not null"
1119     );
1120     $sti->execute;
1121     $sti =
1122       $dbh->prepare(
1123         "alter table branchcategories add primary key (categorycode)");
1124     $sti->execute;
1125 }
1126
1127 unless ( $branchcategories{'categoryname'} eq 'text' ) {
1128     print "Changing branchcode in branchcategories to categoryname text.\n" unless $silent;
1129     my $sth =
1130       $dbh->prepare(
1131         "alter table branchcategories change branchcode categoryname text");
1132     $sth->execute;
1133 }
1134
1135 unless ( $branchcategories{'codedescription'} eq 'text' ) {
1136     print
1137 "Replacing branchholding in branchcategories with codedescription text.\n" unless $silent;
1138     my $sth =
1139       $dbh->prepare(
1140         "alter table branchcategories change branchholding codedescription text"
1141     );
1142     $sth->execute;
1143 }
1144
1145 # changing the items table around...
1146 my %items;
1147
1148 $sth = $dbh->prepare("show columns from items");
1149 $sth->execute;
1150 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1151 {
1152     $items{$column} = $type;
1153 }
1154
1155 if ($items{'bulk'} eq "varchar(30)") {
1156     print "  Setting callnumber in items table\n" unless $silent;
1157     my $sti =
1158       $dbh->prepare("ALTER TABLE `items` CHANGE `bulk` `itemcallnumber` VARCHAR( 30 ) DEFAULT NULL");
1159     $sti->execute;
1160     $sti = $dbh->prepare("update marc_subfield_structure set kohafield=\"items.itemcallnumber\" where kohafield=\"items.bulk\"");
1161     $sti->execute;
1162 }
1163
1164 # changing the marc_subfield_structure table around...
1165 my %marc_subfield_structure;
1166
1167 $sth = $dbh->prepare("show columns from marc_subfield_structure");
1168 $sth->execute;
1169 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1170 {
1171     $marc_subfield_structure{$column} = $type;
1172 }
1173
1174 if ($marc_subfield_structure{thesaurus_category}) {
1175     print "  changing thesaurus_category in marc_subfield_structure table\n" unless $silent;
1176     my $sti =
1177       $dbh->prepare("ALTER TABLE marc_subfield_structure CHANGE `thesaurus_category` `authtypecode` VARCHAR(10 ) DEFAULT NULL");
1178     $sti->execute;
1179 }
1180
1181 #
1182 # creating  index in issuingrules if needed
1183 #
1184 $sth = $dbh->prepare("show index from issuingrules");
1185 $sth->execute;
1186 my $exists=0;
1187 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1188 {
1189         if ($key_name eq 'PRIMARY') {
1190                 $exists=1;
1191         }
1192 }
1193 print "Creating  index on issuing rules\n" unless $exists or $silent;
1194 $dbh->do('ALTER TABLE issuingrules ADD PRIMARY KEY ( branchcode, categorycode, itemtype )') unless $exists;
1195
1196 $dbh->do('ALTER TABLE marc_tag_structure drop primary key');
1197 $dbh->do('ALTER TABLE marc_tag_structure ADD PRIMARY KEY ( frameworkcode, tagfield )');
1198
1199 $dbh->do('ALTER TABLE marc_subfield_structure drop primary key');
1200 $dbh->do('ALTER TABLE marc_subfield_structure ADD PRIMARY KEY ( frameworkcode, tagfield, tagsubfield )');
1201
1202 # Get list of columns from marc_word table
1203 my %marc_word;
1204 my %nullenabled;
1205 $sth = $dbh->prepare("show columns from marc_word");
1206 $sth->execute;
1207 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1208 {
1209     $marc_word{$column} = $type;
1210     $nullenabled{$column} = $null;
1211 }
1212 if ($marc_word{subfieldid}) {
1213         #create field tagsubfield, copy tag+subfieldid, then drop tag and subfieldid
1214         print "Modifying marc_word (concat on tag and subfield for better perfs)\n" unless $silent;
1215         $dbh->do("ALTER TABLE `marc_word` ADD `tagsubfield` CHAR( 4 ) NOT NULL AFTER `bibid`");
1216         $dbh->do("update marc_word set tagsubfield=concat(tag,subfieldid)");
1217         $dbh->do("alter table marc_word drop tag");
1218         $dbh->do("alter table marc_word drop subfieldid");
1219         $dbh->do("create index Search_Marc on marc_word (tagsubfield,word)");
1220 }
1221 # Populate tables with required data
1222
1223 # fill aqbasket if it's empty and aqorder is not
1224 # => it means it has just been created & must be filled
1225 $sth = $dbh->prepare("select count(*) from aqbasket");
1226 $sth->execute;
1227 if ($sth->fetchrow == 0) {
1228         $sth = $dbh->prepare("select count(*) from aqorders");
1229         $sth->execute;
1230         if ($sth->fetchrow >0) {
1231                 print "Populating new table aqbasket\n";
1232                 print "IMPORTANT NOTE: error message \"Duplicate entry 'X' for key 1\" may appear. it should not be a real trouble\n";
1233                 $sth=$dbh->prepare("select distinct basketno,booksellerid,authorisedby,entrydate,booksellerinvoicenumber from aqorders");
1234                 $sth->execute;
1235                 my ($basketno,$booksellerid,$authorisedby,$entrydate,$booksellerinvoicenumber);
1236                 my $sth2 = $dbh->prepare("insert into aqbasket (basketno,creationdate,booksellerid,authorisedby,booksellerinvoicenumber) values (?,?,?,?,?)");
1237                 while (($basketno,$booksellerid,$authorisedby,$entrydate,$booksellerinvoicenumber) = $sth->fetchrow) {
1238                         print "$basketno,$entrydate,$booksellerid,$authorisedby,$booksellerinvoicenumber\n";
1239                         $sth2->execute($basketno,$entrydate,$booksellerid,$authorisedby,$booksellerinvoicenumber);
1240                 }
1241         }
1242 }
1243 foreach my $table ( keys %tabledata ) {
1244     print "Checking for data required in table $table...\n" unless $silent;
1245     my $tablerows = $tabledata{$table};
1246     foreach my $row (@$tablerows) {
1247         my $uniquefieldrequired = $row->{uniquefieldrequired};
1248         my $uniquevalue         = $row->{$uniquefieldrequired};
1249         my $forceupdate         = $row->{forceupdate};
1250         my $sth                 =
1251           $dbh->prepare(
1252 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
1253         );
1254         $sth->execute($uniquevalue);
1255         if ($sth->rows) {
1256             foreach my $field (keys %$forceupdate) {
1257                 if ($forceupdate->{$field}) {
1258                     my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
1259                     $sth->execute($row->{$field}, $uniquevalue);
1260                 }
1261             }
1262         } else {
1263             print "Adding row to $table: " unless $silent;
1264             my @values;
1265             my $fieldlist;
1266             my $placeholders;
1267             foreach my $field ( keys %$row ) {
1268                 next if $field eq 'uniquefieldrequired';
1269                 next if $field eq 'forceupdate';
1270                 my $value = $row->{$field};
1271                 push @values, $value;
1272                 print "  $field => $value" unless $silent;
1273                 $fieldlist .= "$field,";
1274                 $placeholders .= "?,";
1275             }
1276             print "\n" unless $silent;
1277             $fieldlist    =~ s/,$//;
1278             $placeholders =~ s/,$//;
1279             my $sth =
1280               $dbh->prepare(
1281                 "insert into $table ($fieldlist) values ($placeholders)");
1282             $sth->execute(@values);
1283         }
1284     }
1285 }
1286
1287 # at last, remove useless fields
1288 foreach $table ( keys %uselessfields ) {
1289         my @fields = split /,/,$uselessfields{$table};
1290         foreach my $fieldtodrop (@fields) {
1291                 $fieldtodrop =~ s/\t//g;
1292                 $fieldtodrop =~ s/\n//g;
1293                 print "deleting $fieldtodrop field in $table...\n" unless $silent;
1294                 my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
1295                 $sth->execute;
1296                 if ( $sth->err ) {
1297                         print "Error : $sth->errstr \n";
1298                         $sth->finish;
1299                 }    # if error
1300         }
1301 }    # foreach
1302
1303
1304 $sth->finish;
1305
1306 exit;
1307
1308 # $Log$
1309 # Revision 1.91  2004/07/15 09:52:28  tipaul
1310 # Acquisition & Suggestion :
1311 # * acquisition rewritte : create a aqbasket table to deal with "bookseller order header".
1312 # * add "close basket" feature : a closed basket can't be modified
1313 # * suggestion feature : manage suggestions in acquisition (after suggestion filled in OPAC)
1314 #
1315 # Revision 1.90  2004/07/06 08:24:18  tipaul
1316 # adding 2 free fields that can be used for sorting purposes
1317 #
1318 # Revision 1.89  2004/07/02 15:55:08  tipaul
1319 # Adding 2 new fields, called "sort1" and "sort2"
1320 # They can be used for sorting & statistics reasons by the library.
1321 #
1322 # Revision 1.88  2004/06/26 23:34:26  rangi
1323 # Fixing typo
1324 #
1325 # Revision 1.87  2004/06/23 13:03:09  tipaul
1326 # fixes in DB structure
1327 #
1328 # Revision 1.86  2004/06/22 11:30:57  tipaul
1329 # adding -s (silent) flag, to have a silent install.
1330 # only updater will be verbose
1331 #
1332 # Revision 1.85  2004/06/17 15:19:44  tipaul
1333 # missing Marc_Search index on marc_word
1334 #
1335 # Revision 1.84  2004/06/17 08:25:21  tipaul
1336 # DB modifs : merging tag & subfield in marc_word table
1337 #
1338 # Revision 1.83  2004/06/10 08:32:02  tipaul
1339 # MARC authority management (continued)
1340 #
1341 # Revision 1.82  2004/06/03 12:46:58  tipaul
1342 # * frameworks and itemtypes are independant
1343 #
1344 # 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.
1345 #
1346 # Revision 1.81  2004/05/28 09:56:21  tipaul
1347 # bugfix
1348 #
1349 # Revision 1.80  2004/05/28 08:32:00  tipaul
1350 # adding :
1351 # * MARC authority file
1352 # * seealso & hidden in MARC biblio structure.
1353 #
1354 # Revision 1.79  2004/05/18 09:50:07  tipaul
1355 # *** empty log message ***
1356 #
1357 # Revision 1.78  2004/05/10 09:29:33  tipaul
1358 # css is now the default theme for OPAC.
1359 # It will be the theme used for improvements and new things in OPAC.
1360 #
1361 # Revision 1.77  2004/05/06 14:56:51  tipaul
1362 # adding table issuingrules (previously called categoryitem
1363 #
1364 # Revision 1.76  2004/05/03 09:32:25  tipaul
1365 # adding printcirculationsplit parameter (already existed, but was not in systempref by defaul)
1366 #
1367 # Revision 1.75  2004/04/14 19:49:00  tipaul
1368 # seealso field set to 255 chars
1369 #
1370 # Revision 1.74  2004/03/11 16:10:16  tipaul
1371 # *** empty log message ***
1372 #
1373 # Revision 1.73  2004/03/06 20:26:13  tipaul
1374 # adding seealso feature in MARC searches
1375 #