adding 2 free fields that can be used for sorting purposes
[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                                 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 '',
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                                 mailoverseeing smallint(1) default 0,
300                                 PRIMARY KEY  (suggestionnumber),
301                                 KEY suggestedby (suggestedby),
302                                 KEY managedby (managedby)
303                         )",
304 );
305
306 my %requirefields = (
307     biblio        => { 'abstract' => 'text' },
308     deletedbiblio => { 'abstract' => 'text', 'marc' => 'blob' },
309     deleteditems => { 'marc' => 'blob', 'paidfor' => 'text' },
310     biblioitems   => {
311         'lccn' => 'char(25)',
312         'url'  => 'varchar(255)',
313         'marc' => 'text'
314     },
315     deletedbiblioitems => {
316         'lccn' => 'char(25)',
317         'url'  => 'varchar(255)',
318         'marc' => 'text'
319     },
320     branchtransfers => { 'datearrived'    => 'datetime' },
321     statistics      => { 'borrowernumber' => 'int(11)' },
322     aqbooksellers   => {
323         'invoicedisc' => 'float(6,4)',
324         'nocalc'      => 'int(11)'
325     },
326     borrowers => {
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)',
335     },
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'},
341
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)',
354                                                         },
355     bookshelf => {'owner' => 'char(80)',
356                                         'category' => 'char(1)',
357                                 },
358     marc_biblio        => { 'frameworkcode' => 'char(4) not NULL default \'\'' },
359 );
360
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',
370 );
371
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)
374
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.
382
383 my %tabledata = (
384     userflags => [
385         {
386             uniquefieldrequired => 'bit',
387             bit                 => 0,
388             flag                => 'superlibrarian',
389             flagdesc            => 'Access to all librarian functions',
390             defaulton           => 0
391         },
392         {
393             uniquefieldrequired => 'bit',
394             bit                 => 1,
395             flag                => 'circulate',
396             flagdesc            => 'Circulate books',
397             defaulton           => 0
398         },
399         {
400             uniquefieldrequired => 'bit',
401             bit                 => 2,
402             flag                => 'catalogue',
403             flagdesc            => 'View Catalogue (Librarian Interface)',
404             defaulton           => 0
405         },
406         {
407             uniquefieldrequired => 'bit',
408             bit                 => 3,
409             flag                => 'parameters',
410             flagdesc            => 'Set Koha system paramters',
411             defaulton           => 0
412         },
413         {
414             uniquefieldrequired => 'bit',
415             bit                 => 4,
416             flag                => 'borrowers',
417             flagdesc            => 'Add or modify borrowers',
418             defaulton           => 0
419         },
420         {
421             uniquefieldrequired => 'bit',
422             bit                 => 5,
423             flag                => 'permissions',
424             flagdesc            => 'Set user permissions',
425             defaulton           => 0
426         },
427         {
428             uniquefieldrequired => 'bit',
429             bit                 => 6,
430             flag                => 'reserveforothers',
431             flagdesc            => 'Reserve books for patrons',
432             defaulton           => 0
433         },
434         {
435             uniquefieldrequired => 'bit',
436             bit                 => 7,
437             flag                => 'borrow',
438             flagdesc            => 'Borrow books',
439             defaulton           => 1
440         },
441         {
442             uniquefieldrequired => 'bit',
443             bit                 => 8,
444             flag                => 'reserveforself',
445             flagdesc            => 'Reserve books for self',
446             defaulton           => 0
447         },
448         {
449             uniquefieldrequired => 'bit',
450             bit                 => 9,
451             flag                => 'editcatalogue',
452             flagdesc  => 'Edit Catalogue (Modify bibliographic/holdings data)',
453             defaulton => 0
454         },
455         {
456             uniquefieldrequired => 'bit',
457             bit                 => 10,
458             flag                => 'updatecharges',
459             flagdesc            => 'Update borrower charges',
460             defaulton           => 0
461         },
462     ],
463     systempreferences => [
464         {
465             uniquefieldrequired => 'variable',
466             forceupdate         => { 'explanation' => 1,
467                                      'type' => 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',
471             type                => ''
472
473         },
474         {
475             uniquefieldrequired => 'variable',
476             forceupdate         => { 'explanation' => 1,
477                                      'type' => 1 },
478             variable            => 'autoMemberNum',
479             value               => '1',
480             explanation         => 'Member number is auto-calculated',
481             type                => 'YesNo'
482
483         },
484         {
485             uniquefieldrequired => 'variable',
486             forceupdate         => { 'explanation' => 1,
487                                      'type' => 1,
488                                      'options' => 1 },
489             variable            => 'acquisitions',
490             value               => 'normal',
491             explanation         =>
492 'Normal, budget-based acquisitions, or Simple bibliographic-data acquisitions',
493             type                => 'Choice',
494             options             => 'simple|normal'
495         },
496         {
497             uniquefieldrequired => 'variable',
498             forceupdate         => { 'explanation' => 1,
499                                      'type' => 1,
500                                      'options' => 1 },
501             variable            => 'dateformat',
502             value               => 'metric',
503             explanation         =>
504             'date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy/mm/dd)',
505             type                => 'Choice',
506             options             => 'metric|us|iso'
507         },
508         {
509             uniquefieldrequired => 'variable',
510             variable            => 'template',
511             forceupdate         => { 'explanation' => 1,
512                                      'type' => 1 },
513             value               => 'default',
514             explanation         => 'Preference order for intranet interface templates',
515             type                => 'Themes'
516         },
517         {
518             uniquefieldrequired => 'variable',
519             variable            => 'autoBarcode',
520             forceupdate         => { 'explanation' => 1,
521                                      'type' => 1 },
522             value               => 'yes',
523             explanation         => 'Barcode is auto-calculated',
524             type                => 'YesNo'
525         },
526         {
527             uniquefieldrequired => 'variable',
528             variable            => 'insecure',
529             forceupdate         => { 'explanation' => 1,
530                                      'type' => 1 },
531             value               => 'no',
532             explanation         =>
533 'If YES, no auth at all is needed. Be careful if you set this to yes!',
534             type                => 'YesNo'
535         },
536         {
537             uniquefieldrequired => 'variable',
538             variable            => 'authoritysep',
539             forceupdate         => { 'explanation' => 1,
540                                      'type' => 1,
541                                      'options' => 1 },
542             value               => '--',
543             explanation         =>
544             'the separator used in authority/thesaurus. Usually --',
545             type                => 'free',
546             options             => '10'
547         },
548         {
549             uniquefieldrequired => 'variable',
550             variable            => 'opaclanguages',
551             forceupdate         => { 'explanation' => 1,
552                                      'type' => 1 },
553             value               => 'en',
554             explanation         => 'Set the preferred order for translations.  The top language will be tried first.',
555             type                => 'Languages'
556         },
557         {
558             uniquefieldrequired => 'variable',
559             variable            => 'opacthemes',
560             forceupdate         => { 'explanation' => 1,
561                                      'type' => 1 },
562             value               => 'css',
563             explanation         => 'Set the preferred order for themes.  The top theme will be tried first.',
564             type                => 'Themes'
565         },
566         {
567             uniquefieldrequired => 'variable',
568             variable            => 'timeout',
569             forceupdate         => { 'explanation' => 1,
570                                      'type' => 1 },
571             value               => '1200',
572             explanation         => 'Inactivity timeout for cookies authentication (in seconds)',
573             type                => 'Integer'
574         },
575         {
576             uniquefieldrequired => 'variable',
577             variable            => 'marc',
578             forceupdate         => { 'explanation' => 1,
579                                      'type' => 1 },
580             value               => 'yes',
581             explanation         => 'Turn on MARC support',
582             type                => 'YesNo'
583         },
584         {
585             uniquefieldrequired => 'variable',
586             variable            => 'marcflavour',
587             forceupdate         => { 'explanation' => 1,
588                                      'type' => 1,
589                                      'options' => 1},
590             value               => 'MARC21',
591             explanation         =>
592             'your MARC flavor (MARC21 or UNIMARC) used for character encoding',
593             type                => 'Choice',
594             options             => 'MARC21|UNIMARC'
595         },
596         {
597             uniquefieldrequired => 'variable',
598             variable            => 'checkdigit',
599             value               => 'none',
600             forceupdate         => { 'explanation' => 1,
601                                      'type' => 1,
602                                      'options' => 1},
603             explanation         => 'Validity checks on membership number: none or "Katipo" style checks',
604             type                => 'Choice',
605             options             => 'none|katipo'
606         },
607         {
608             uniquefieldrequired => 'variable',
609             variable            => 'maxoutstanding',
610             forceupdate         => { 'explanation' => 1,
611                                      'type' => 1 },
612             value               => '5',
613             explanation         =>
614             'maximum amount withstanding to be able make reserves ',
615             type                => 'Integer'
616         },
617         {
618             uniquefieldrequired => 'variable',
619             variable            => 'maxreserves',
620             forceupdate         => { 'explanation' => 1,
621                                      'type' => 1 },
622             value               => '5',
623             explanation         =>
624             'maximum number of reserves a member can make',
625             type                => 'Integer'
626
627         },
628         {
629             uniquefieldrequired => 'variable',
630             variable            => 'noissuescharge',
631             forceupdate         => { 'explanation' => 1,
632                                      'type' => 1 },
633             value               => '5',
634             explanation         =>
635             'maximum amount withstanding to be able to check out an item',
636             type                => 'Integer'
637
638         },
639         {
640             uniquefieldrequired => 'variable',
641             variable            => 'KohaAdminEmailAddress',
642             forceupdate         => { 'explanation' => 1,
643                                      'type' => 1 },
644             value               => 'your.mail@here',
645             explanation => 'the email address where borrowers modifs are sent',
646             type                => 'free'
647         },
648         {
649             uniquefieldrequired => 'variable',
650             variable            => 'gist',
651             forceupdate         => { 'explanation' => 1,
652                                      'type' => 1 },
653             value               => '0.125',
654             explanation => 'the gist rate. NOT in %, but in numeric form (0.12 for 12%)',
655             type                => 'free'
656         },
657         {
658             uniquefieldrequired => 'variable',
659             variable            => 'ldapserver',
660             forceupdate         => { 'explanation' => 1,
661                                      'type' => 1 },
662             value               => '',
663             explanation => 'your ldap server',
664             type                => 'free'
665         },
666         {
667             uniquefieldrequired => 'variable',
668             variable            => 'ldapinfos',
669             forceupdate         => { 'explanation' => 1,
670                                      'type' => 1 },
671             value               => '',
672             explanation => 'ldap info. The ldap will be used in dn : uid=xxx, <ldapinfos>',
673             type                => 'free'
674         },
675         {
676             uniquefieldrequired => 'variable',
677             variable            => 'printcirculationslips',
678             forceupdate         => { 'explanation' => 1,
679                                      'type' => 1 },
680             value               => '0',
681             explanation => 'if set to 1, print circulation slips. If set to 0, don\'t',
682             type                => 'free'
683         },
684         {
685             uniquefieldrequired => 'variable',
686             variable            => 'suggestion',
687             forceupdate         => { 'explanation' => 1,
688                                      'type' => 1 },
689             value               => '0',
690             explanation => 'if set to 1, suggestions are activated in OPAC',
691             type                => 'free'
692         },
693         {
694             uniquefieldrequired => 'variable',
695             variable            => 'ISBD',
696             forceupdate         => { 'explanation' => 1,
697                                      'type' => 1 },
698             value               => 'Fill with appropriate value...',
699             explanation => 'ISBD',
700             type                => 'free'
701         },
702         {
703             uniquefieldrequired => 'variable',
704             variable            => 'virtualshelves',
705             forceupdate         => { 'explanation' => 1,
706                                      'type' => 1 },
707             value               => '0',
708             explanation => 'Set virtual shelves management ON or OFF',
709             type                => 'YesNo'
710         },
711     ],
712
713 );
714
715 my %fielddefinitions = (
716     printers => [
717         {
718             field   => 'printername',
719             type    => 'char(40)',
720             null    => '',
721             key     => 'PRI',
722             default => ''
723         },
724     ],
725     aqbookfund => [
726         {
727             field   => 'bookfundid',
728             type    => 'char(5)',
729             null    => '',
730             key     => 'PRI',
731             default => ''
732         },
733     ],
734     aqbudget => [
735         {
736             field   => 'aqbudgetid',
737             type    => 'tinyint(4)',
738             null    => '',
739             key     => 'PRI',
740                   default =>'',
741             extra => 'auto_increment'
742         },
743     ],
744     z3950servers => [
745         {
746             field   => 'id',
747             type    => 'int',
748             null    => '',
749             key     => 'PRI',
750             default => '',
751             extra   => 'auto_increment'
752         },
753     ],
754         marc_breeding => [
755         {
756             field   => 'z3950random',
757             type    => 'varchar(40)',
758             null    => 'NULL',
759             key     => '',
760             default => '',
761             extra   => ''
762         },
763         {
764             field   => 'encoding',
765             type    => 'varchar(40)',
766             null    => '',
767             key     => '',
768             default => '',
769             extra   => ''
770         },
771     ],
772 );
773
774 #-------------------
775 # Initialize
776
777 # Start checking
778
779 # Get version of MySQL database engine.
780 my $mysqlversion = `mysqld --version`;
781 $mysqlversion =~ /Ver (\S*) /;
782 $mysqlversion = $1;
783 if ( $mysqlversion ge '3.23' ) {
784     print "Could convert to MyISAM database tables...\n" unless $silent;
785 }
786
787 #---------------------------------
788 # Tables
789
790 # Collect all tables into a list
791 $sth = $dbh->prepare("show tables");
792 $sth->execute;
793 while ( my ($table) = $sth->fetchrow ) {
794     $existingtables{$table} = 1;
795 }
796
797
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}");
803         $sth->execute;
804         if ( $sth->err ) {
805             print "Error : $sth->errstr \n";
806             $sth->finish;
807         }    # if error
808     }    # unless exists
809 }    # foreach
810
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");
816                 if ( $dbh->err ) {
817                         print "Error : $dbh->errstr \n";
818                 }
819         }
820 }
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 (
825                                                                                 host char(255),
826                                                                                 port int,
827                                                                                 db char(255),
828                                                                                 userid char(255),
829                                                                                 password char(255),
830                                                                                 name text,
831                                                                                 id int,
832                                                                                 checked smallint,
833                                                                                 rank int,
834                                                                                 syntax char(80))"
835     );
836     $sti->execute;
837     $sti = $dbh->prepare( "insert into z3950servers
838                                                                 values ('z3950.loc.gov',
839                                                                 7090,
840                                                                 'voyager',
841                                                                 '', '',
842                                                                 'Library of Congress',
843                                                                 1, 1, 1, 'USMARC')"
844     );
845     $sti->execute;
846 }
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;
853 }
854
855
856 #---------------------------------
857 # Columns
858
859 foreach $table ( keys %requirefields ) {
860     print "Check table $table\n" if $debug and not $silent;
861     $sth = $dbh->prepare("show columns from $table");
862     $sth->execute();
863     undef %types;
864     while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
865     {
866         $types{$column} = $type;
867     }    # while
868     foreach $column ( keys %{ $requirefields{$table} } ) {
869         print "  Check column $column  [$types{$column}]\n" if $debug and not $silent;
870         if ( !$types{$column} ) {
871
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);
878             $sti->execute;
879             if ( $sti->err ) {
880                 print "**Error : $sti->errstr \n";
881                 $sti->finish;
882             }    # if error
883         }    # if column
884     }    # foreach column
885 }    # foreach table
886
887 foreach $table ( keys %fielddefinitions ) {
888         print "Check table $table\n" if $debug;
889         $sth = $dbh->prepare("show columns from $table");
890         $sth->execute();
891         my $definitions;
892         while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
893         {
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;
899         }    # while
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} )
915                 {
916
917                         if ( $null eq '' ) {
918                                 $null = 'NOT NULL';
919                         }
920                         if ( $key eq 'PRI' ) {
921                                 $key = 'PRIMARY KEY';
922                         }
923                         unless ( $extra eq 'auto_increment' ) {
924                                 $extra = '';
925                         }
926                         # if it's a new column use "add", if it's an old one, use "change".
927                         my $action;
928                         if ($definitions->{$field}->{type}) {
929                                 $action="change $field"
930                         } else {
931                                 $action="add";
932                         }
933 # if it's a primary key, drop the previous pk, before altering the table
934                         my $sth;
935                         if ($key ne 'PRIMARY KEY') {
936                                 $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ?");
937                         } else {
938                                 $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ?");
939                         }
940                         $sth->execute($default);
941                         print "  Alter $field in $table\n" unless $silent;
942                 }
943         }
944 }
945
946 # Get list of columns from borrowers table
947 my %itemtypes;
948 my %nullenabled;
949 $sth = $dbh->prepare("show columns from borrowers");
950 $sth->execute;
951 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
952 {
953     $itemtypes{$column} = $type;
954     $nullenabled{$column} = $null;
955 }
956
957 unless ( $itemtypes{'cardnumber'} eq 'varchar(20)' ) {
958     $itemtypes{'cardnumber'} =~ /varchar\((\d+)\)/;
959     my $oldlength = $1;
960     if ( $oldlength < 16 ) {
961         print "Setting maximum cardnumber length to 16 (was $oldlength) and marking unique.\n" unless $silent;
962         my $sti =
963           $dbh->prepare(
964             "alter table borrowers change cardnumber cardnumber varchar(16)");
965         $sti->execute;
966         $sti->finish;
967         $sti =
968           $dbh->prepare(
969             "alter table borrowers drop index cardnumber");
970         $sti->execute;
971         $sti->finish;
972         $sti =
973           $dbh->prepare(
974             "alter table borrowers add unique(cardnumber)");
975         $sti->execute;
976         $sti->finish;
977     }
978 }
979 #
980 # Get list of columns from items table
981 $sth = $dbh->prepare("show columns from items");
982 $sth->execute;
983 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
984 {
985     $itemtypes{$column} = $type;
986     $nullenabled{$column} = $null;
987 }
988
989 unless ( $itemtypes{'barcode'} eq 'varchar(20)' ) {
990     $itemtypes{'barcode'} =~ /varchar\((\d+)\)/;
991     my $oldlength = $1;
992     if ( $oldlength < 20 ) {
993         print "Setting maximum barcode length to 20 (was $oldlength).\n" unless $silent;
994         my $sti =
995           $dbh->prepare(
996             "alter table items change barcode barcode varchar(20)");
997         $sti->execute;
998     }
999 }
1000 #
1001 # dropping unique barcode index & setting barcode to null allowed.
1002 #
1003 $sth = $dbh->prepare("show index from items");
1004 $sth->execute;
1005 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1006 {
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`");
1010         }
1011 }
1012 $dbh->do("ALTER TABLE `items` CHANGE `barcode` `barcode` VARCHAR( 20 )") unless ($nullenabled{barcode} eq 'YES');
1013
1014 #
1015 # creating fulltext index in bibliothesaurus if needed
1016 #
1017 $sth = $dbh->prepare("show index from bibliothesaurus");
1018 $sth->execute;
1019 my $exists=0;
1020 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1021 {
1022         if ($key_name eq 'category_2') {
1023                 $exists=1;
1024         }
1025 }
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;
1028
1029 #
1030 # creating  index in z3950results if needed
1031 #
1032 $sth = $dbh->prepare("show index from z3950results");
1033 $sth->execute;
1034 my $exists=0;
1035 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1036 {
1037         if ($key_name eq 'query_server') {
1038                 $exists=1;
1039         }
1040 }
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;
1043
1044 # changing z3950daemon field to NULL in marc_breeding
1045 $dbh->do("ALTER TABLE `marc_breeding` CHANGE `z3950random` `z3950random` VARCHAR( 40 )");
1046
1047 # making borrowernumber an auto_increment field
1048 $dbh->do("ALTER TABLE `borrowers` CHANGE `borrowernumber` `borrowernumber` INTEGER auto_increment");
1049
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)');
1055
1056
1057 # extending the timestamp in branchtransfers...
1058 my %branchtransfers;
1059
1060 $sth = $dbh->prepare("show columns from branchtransfers");
1061 $sth->execute;
1062 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1063 {
1064     $branchtransfers{$column} = $type;
1065 }
1066
1067 unless ( $branchtransfers{'datesent'} eq 'datetime' ) {
1068     print "Setting type of datesent in branchtransfers to datetime.\n" unless $silent;
1069     my $sti =
1070       $dbh->prepare(
1071         "alter table branchtransfers change datesent datesent datetime");
1072     $sti->execute;
1073 }
1074
1075 unless ( $branchtransfers{'datearrived'} eq 'datetime' ) {
1076     print "Setting type of datearrived in branchtransfers to datetime.\n" unless $silent;
1077     my $sti =
1078       $dbh->prepare(
1079         "alter table branchtransfers change datearrived datearrived datetime");
1080     $sti->execute;
1081 }
1082
1083 # changing the branchcategories table around...
1084 my %branchcategories;
1085
1086 $sth = $dbh->prepare("show columns from branchcategories");
1087 $sth->execute;
1088 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1089 {
1090     $branchcategories{$column} = $type;
1091 }
1092
1093 unless ( $branchcategories{'categorycode'} eq 'varchar(4)' ) {
1094     print
1095 "Setting type of categorycode in branchcategories to varchar(4),\n and making the primary key.\n" unless $silent;
1096     my $sti =
1097       $dbh->prepare(
1098 "alter table branchcategories change categorycode categorycode varchar(4) not null"
1099     );
1100     $sti->execute;
1101     $sti =
1102       $dbh->prepare(
1103         "alter table branchcategories add primary key (categorycode)");
1104     $sti->execute;
1105 }
1106
1107 unless ( $branchcategories{'categoryname'} eq 'text' ) {
1108     print "Changing branchcode in branchcategories to categoryname text.\n" unless $silent;
1109     my $sth =
1110       $dbh->prepare(
1111         "alter table branchcategories change branchcode categoryname text");
1112     $sth->execute;
1113 }
1114
1115 unless ( $branchcategories{'codedescription'} eq 'text' ) {
1116     print
1117 "Replacing branchholding in branchcategories with codedescription text.\n" unless $silent;
1118     my $sth =
1119       $dbh->prepare(
1120         "alter table branchcategories change branchholding codedescription text"
1121     );
1122     $sth->execute;
1123 }
1124
1125 # changing the items table around...
1126 my %items;
1127
1128 $sth = $dbh->prepare("show columns from items");
1129 $sth->execute;
1130 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1131 {
1132     $items{$column} = $type;
1133 }
1134
1135 if ($items{'bulk'} eq "varchar(30)") {
1136     print "  Setting callnumber in items table\n" unless $silent;
1137     my $sti =
1138       $dbh->prepare("ALTER TABLE `items` CHANGE `bulk` `itemcallnumber` VARCHAR( 30 ) DEFAULT NULL");
1139     $sti->execute;
1140     $sti = $dbh->prepare("update marc_subfield_structure set kohafield=\"items.itemcallnumber\" where kohafield=\"items.bulk\"");
1141     $sti->execute;
1142 }
1143
1144 # changing the marc_subfield_structure table around...
1145 my %marc_subfield_structure;
1146
1147 $sth = $dbh->prepare("show columns from marc_subfield_structure");
1148 $sth->execute;
1149 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1150 {
1151     $marc_subfield_structure{$column} = $type;
1152 }
1153
1154 if ($marc_subfield_structure{thesaurus_category}) {
1155     print "  changing thesaurus_category in marc_subfield_structure table\n" unless $silent;
1156     my $sti =
1157       $dbh->prepare("ALTER TABLE marc_subfield_structure CHANGE `thesaurus_category` `authtypecode` VARCHAR(10 ) DEFAULT NULL");
1158     $sti->execute;
1159 }
1160
1161 #
1162 # creating  index in issuingrules if needed
1163 #
1164 $sth = $dbh->prepare("show index from issuingrules");
1165 $sth->execute;
1166 my $exists=0;
1167 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow )
1168 {
1169         if ($key_name eq 'PRIMARY') {
1170                 $exists=1;
1171         }
1172 }
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;
1175
1176 $dbh->do('ALTER TABLE marc_tag_structure drop primary key');
1177 $dbh->do('ALTER TABLE marc_tag_structure ADD PRIMARY KEY ( frameworkcode, tagfield )');
1178
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 )');
1181
1182 # Get list of columns from marc_word table
1183 my %marc_word;
1184 my %nullenabled;
1185 $sth = $dbh->prepare("show columns from marc_word");
1186 $sth->execute;
1187 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
1188 {
1189     $marc_word{$column} = $type;
1190     $nullenabled{$column} = $null;
1191 }
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)");
1200 }
1201 # Populate tables with required data
1202
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};
1210         my $sth                 =
1211           $dbh->prepare(
1212 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
1213         );
1214         $sth->execute($uniquevalue);
1215         if ($sth->rows) {
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);
1220                 }
1221             }
1222         } else {
1223             print "Adding row to $table: " unless $silent;
1224             my @values;
1225             my $fieldlist;
1226             my $placeholders;
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 .= "?,";
1235             }
1236             print "\n" unless $silent;
1237             $fieldlist    =~ s/,$//;
1238             $placeholders =~ s/,$//;
1239             my $sth =
1240               $dbh->prepare(
1241                 "insert into $table ($fieldlist) values ($placeholders)");
1242             $sth->execute(@values);
1243         }
1244     }
1245 }
1246
1247 $sth->finish;
1248
1249 exit;
1250
1251 # $Log$
1252 # Revision 1.90  2004/07/06 08:24:18  tipaul
1253 # adding 2 free fields that can be used for sorting purposes
1254 #
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.
1258 #
1259 # Revision 1.88  2004/06/26 23:34:26  rangi
1260 # Fixing typo
1261 #
1262 # Revision 1.87  2004/06/23 13:03:09  tipaul
1263 # fixes in DB structure
1264 #
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
1268 #
1269 # Revision 1.85  2004/06/17 15:19:44  tipaul
1270 # missing Marc_Search index on marc_word
1271 #
1272 # Revision 1.84  2004/06/17 08:25:21  tipaul
1273 # DB modifs : merging tag & subfield in marc_word table
1274 #
1275 # Revision 1.83  2004/06/10 08:32:02  tipaul
1276 # MARC authority management (continued)
1277 #
1278 # Revision 1.82  2004/06/03 12:46:58  tipaul
1279 # * frameworks and itemtypes are independant
1280 #
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.
1282 #
1283 # Revision 1.81  2004/05/28 09:56:21  tipaul
1284 # bugfix
1285 #
1286 # Revision 1.80  2004/05/28 08:32:00  tipaul
1287 # adding :
1288 # * MARC authority file
1289 # * seealso & hidden in MARC biblio structure.
1290 #
1291 # Revision 1.79  2004/05/18 09:50:07  tipaul
1292 # *** empty log message ***
1293 #
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.
1297 #
1298 # Revision 1.77  2004/05/06 14:56:51  tipaul
1299 # adding table issuingrules (previously called categoryitem
1300 #
1301 # Revision 1.76  2004/05/03 09:32:25  tipaul
1302 # adding printcirculationsplit parameter (already existed, but was not in systempref by defaul)
1303 #
1304 # Revision 1.75  2004/04/14 19:49:00  tipaul
1305 # seealso field set to 255 chars
1306 #
1307 # Revision 1.74  2004/03/11 16:10:16  tipaul
1308 # *** empty log message ***
1309 #
1310 # Revision 1.73  2004/03/06 20:26:13  tipaul
1311 # adding seealso feature in MARC searches
1312 #