10 # This script checks for required updates to the database.
12 # Part of the Koha Library Software www.koha.org
13 # Licensed under the GPL.
16 # - Would also be a good idea to offer to do a backup at this time...
18 # NOTE: If you do something more than once in here, make it table driven.
29 use MARC::File::XML ( BinaryEncoding => 'utf8' );
31 # FIXME - The user might be installing a new database, so can't rely
32 # on /etc/koha.conf anyway.
39 %existingtables, # tables already in database
43 $type, $null, $key, $default, $extra,
44 $prefitem, # preference item in systempreferences table
48 GetOptions( 's' => \$silent );
49 my $dbh = C4::Context->dbh;
50 print "connected to your DB. Checking & modifying it\n" unless $silent;
51 $|=1; # flushes output
56 # Tables to add if they don't exist
58 categorytable => "(categorycode char(5) NOT NULL default '',
59 description text default '',
60 itemtypecodes text default '',
61 PRIMARY KEY (categorycode)
63 subcategorytable => "(subcategorycode char(5) NOT NULL default '',
64 description text default '',
65 itemtypecodes text default '',
66 PRIMARY KEY (subcategorycode)
68 mediatypetable => "(mediatypecode char(5) NOT NULL default '',
69 description text default '',
70 itemtypecodes text default '',
71 PRIMARY KEY (mediatypecode)
74 `timestamp` TIMESTAMP NOT NULL ,
75 `user` INT( 11 ) NOT NULL ,
76 `module` TEXT default '',
77 `action` TEXT default '' ,
78 `object` INT(11) default '' ,
79 `info` TEXT default '' ,
80 PRIMARY KEY ( `timestamp` , `user` )
83 module varchar(20) NOT NULL default '',
84 code varchar(20) NOT NULL default '',
85 name varchar(100) NOT NULL default '',
86 title varchar(200) NOT NULL default '',
88 PRIMARY KEY (module,code)
91 alertid int(11) NOT NULL auto_increment,
92 borrowernumber int(11) NOT NULL default '0',
93 type varchar(10) NOT NULL default '',
94 externalid varchar(20) NOT NULL default '',
95 PRIMARY KEY (alertid),
96 KEY borrowernumber (borrowernumber),
97 KEY type (type,externalid)
100 `idnew` int(10) unsigned NOT NULL auto_increment,
101 `title` varchar(250) NOT NULL default '',
103 `lang` varchar(4) NOT NULL default '',
104 `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
105 PRIMARY KEY (`idnew`)
107 repeatable_holidays => "(
108 `id` int(11) NOT NULL auto_increment,
109 `branchcode` varchar(4) NOT NULL default '',
110 `weekday` smallint(6) default NULL,
111 `day` smallint(6) default NULL,
112 `month` smallint(6) default NULL,
113 `title` varchar(50) NOT NULL default '',
114 `description` text NOT NULL,
117 special_holidays => "(
118 `id` int(11) NOT NULL auto_increment,
119 `branchcode` varchar(4) NOT NULL default '',
120 `day` smallint(6) NOT NULL default '0',
121 `month` smallint(6) NOT NULL default '0',
122 `year` smallint(6) NOT NULL default '0',
123 `isexception` smallint(1) NOT NULL default '1',
124 `title` varchar(50) NOT NULL default '',
125 `description` text NOT NULL,
128 overduerules =>"(`branchcode` varchar(255) NOT NULL default '',
129 `categorycode` char(2) NOT NULL default '',
130 `delay1` int(4) default '0',
131 `letter1` varchar(20) default NULL,
132 `debarred1` char(1) default '0',
133 `delay2` int(4) default '0',
134 `debarred2` char(1) default '0',
135 `letter2` varchar(20) default NULL,
136 `delay3` int(4) default '0',
137 `letter3` varchar(20) default NULL,
138 `debarred3` int(1) default '0',
139 PRIMARY KEY (`branchcode`,`categorycode`)
141 cities => "(`cityid` int auto_increment,
142 `city_name` char(100) NOT NULL,
143 `city_zipcode` char(20),
144 PRIMARY KEY (`cityid`)
146 <<<<<<< updatedatabase
147 roadtype => "(`roadtypeid` int auto_increment,
148 `road_type` char(100) NOT NULL,
149 PRIMARY KEY (`roadtypeid`)
152 bibid bigint(20) NOT NULL default '0',
153 tag char(3) NOT NULL default '',
154 tagorder tinyint(4) NOT NULL default '1',
155 subfieldid char(1) NOT NULL default '',
156 subfieldorder tinyint(4) NOT NULL default '1',
157 word varchar(255) NOT NULL default '',
158 sndx_word varchar(255) NOT NULL default '',
161 KEY tagorder (tagorder),
162 KEY subfieldid (subfieldid),
163 KEY subfieldorder (subfieldorder),
165 KEY sndx_word (sndx_word)
167 marc_breeding => "( id bigint(20) NOT NULL auto_increment,
168 file varchar(80) NOT NULL default '',
169 isbn varchar(10) NOT NULL default '',
170 title varchar(128) default NULL,
171 author varchar(80) default NULL,
173 encoding varchar(40) default NULL,
178 authorised_values => "(id int(11) NOT NULL auto_increment,
179 category char(10) NOT NULL default '',
180 authorised_value char(80) NOT NULL default '',
185 userflags => "( bit int(11) NOT NULL default '0',
186 flag char(30), flagdesc char(255),
190 authtypecode char(10) not NULL,
191 authtypetext char(255) not NULL,
192 auth_tag_to_report char(3) not NULL,
193 summary text not NULL,
194 PRIMARY KEY (authtypecode)
196 biblio_framework => "(
197 frameworkcode char(4) not NULL,
198 frameworktext char(255) not NULL,
199 PRIMARY KEY (frameworkcode)
201 auth_subfield_structure => "(
202 authtypecode char(10) NOT NULL default '',
203 tagfield char(3) NOT NULL default '',
204 tagsubfield char(1) NOT NULL default '',
205 liblibrarian char(255) NOT NULL default '',
206 libopac char(255) NOT NULL default '',
207 repeatable tinyint(4) NOT NULL default '0',
208 mandatory tinyint(4) NOT NULL default '0',
209 tab tinyint(1) default NULL,
210 authorised_value char(10) default NULL,
211 value_builder char(80) default NULL,
212 seealso char(255) default NULL,
213 PRIMARY KEY (authtypecode,tagfield,tagsubfield),
214 KEY tab (authtypecode,tab)
217 <<<<<<< updatedatabase
220 labelid int(11) NOT NULL auto_increment,
221 itemnumber varchar(100) NOT NULL default '',
222 timestamp timestamp(14) NOT NULL,
223 PRIMARY KEY (labelid)
227 id int(4) NOT NULL auto_increment,
228 barcodetype char(100) default '',
229 title tinyint(1) default '0',
230 isbn tinyint(1) default '0',
231 itemtype tinyint(1) default '0',
232 barcode tinyint(1) default '0',
233 dewey tinyint(1) default '0',
234 class tinyint(1) default '0',
235 author tinyint(1) default '0',
236 papertype char(100) default '',
237 startrow int(2) default NULL,
241 reviewid integer NOT NULL auto_increment,
242 borrowernumber integer,
243 biblionumber integer,
246 datereviewed datetime,
247 PRIMARY KEY (reviewid)
249 borrowers_to_borrowers => "(
255 auth_tag_structure => "(
256 authtypecode char(10) NOT NULL default '',
257 tagfield char(3) NOT NULL default '',
258 liblibrarian char(255) NOT NULL default '',
259 libopac char(255) NOT NULL default '',
260 repeatable tinyint(4) NOT NULL default '0',
261 mandatory tinyint(4) NOT NULL default '0',
262 authorised_value char(10) default NULL,
263 PRIMARY KEY (authtypecode,tagfield)
266 authid bigint(20) unsigned NOT NULL auto_increment,
267 authtypecode char(10) NOT NULL default '',
268 datecreated date NOT NULL default '0000-00-00',
269 datemodified date default NULL,
270 origincode char(20) default NULL,
271 PRIMARY KEY (authid),
272 KEY origincode (origincode)
274 auth_subfield_table => "(
275 subfieldid bigint(20) unsigned NOT NULL auto_increment,
276 authid bigint(20) unsigned NOT NULL default '0',
277 tag char(3) NOT NULL default '',
278 tagorder tinyint(4) NOT NULL default '1',
279 tag_indicator char(2) NOT NULL default '',
280 subfieldcode char(1) NOT NULL default '',
281 subfieldorder tinyint(4) NOT NULL default '1',
282 subfieldvalue varchar(255) default NULL,
283 PRIMARY KEY (subfieldid),
286 KEY subfieldcode (subfieldcode),
287 KEY subfieldvalue (subfieldvalue)
290 authid bigint(20) NOT NULL default '0',
291 tagsubfield char(4) NOT NULL default '',
292 tagorder tinyint(4) NOT NULL default '1',
293 subfieldorder tinyint(4) NOT NULL default '1',
294 word varchar(255) NOT NULL default '',
295 sndx_word varchar(255) NOT NULL default '',
297 KEY marc_search (tagsubfield,word),
299 KEY sndx_word (sndx_word)
302 suggestionid int(8) NOT NULL auto_increment,
303 suggestedby int(11) NOT NULL default '0',
304 managedby int(11) default NULL ,
305 STATUS varchar(10) NOT NULL default '',
307 author varchar(80) default NULL ,
308 title varchar(80) default NULL ,
309 copyrightdate smallint(6) default NULL ,
310 publishercode varchar(255) default NULL ,
311 date timestamp(8) NOT NULL ,
312 volumedesc varchar(255) default NULL ,
313 publicationyear smallint(6) default '0',
314 place varchar(255) default NULL ,
315 isbn varchar(10) default NULL ,
316 mailoverseeing smallint(1) default '0',
317 biblionumber int(11) default NULL ,
318 PRIMARY KEY (suggestionid) ,
319 KEY suggestedby(suggestedby) ,
320 KEY managedby(managedby)
322 aqbasket => "(basketno int(11) NOT NULL auto_increment,
325 booksellerid varchar(10),
326 authorisedby varchar(10),
327 booksellerinvoicenumber text,
328 PRIMARY KEY (basketno)
330 serial => "(serialid int(11) NOT NULL auto_increment,
331 biblionumber varchar(100) NOT NULL default '',
332 subscriptionid varchar(100) NOT NULL default '',
333 serialseq varchar(100) NOT NULL default '',
334 status tinyint(4) NOT NULL default '0',
335 planneddate date NOT NULL default '0000-00-00',
336 publishedddate date NOT NULL default '0000-00-00',
337 PRIMARY KEY (serialid)
339 subscription => "(biblionumber int(11) NOT NULL default '0',
340 subscriptionid int(11) NOT NULL auto_increment,
341 librarian varchar(100) default '',
342 startdate date default '0000-00-00',
343 aqbooksellerid int(11) default '0',
344 cost int(11) default '0',
345 aqbudgetid int(11) default '0',
346 weeklength tinyint(4) default '0',
347 monthlength tinyint(4) default '0',
348 numberlength tinyint(4) default '0',
349 periodicity tinyint(4) default '0',
350 dow varchar(100) default '',
351 numberingmethod varchar(100) default '',
353 status varchar(100) NOT NULL default '',
354 add1 int(11) default 0,
355 every1 int(11) default 0,
356 whenmorethan1 int(11) default 0,
359 add2 int(11) default 0,
360 every2 int(11) default 0,
361 whenmorethan2 int(11) default 0,
364 add3 int(11) default 0,
365 every3 int(11) default 0,
366 innerloop1 int(11) default 0,
367 innerloop2 int(11) default 0,
368 innerloop3 int(11) default 0,
369 whenmorethan3 int(11) default 0,
372 PRIMARY KEY (subscriptionid)
374 subscriptionhistory => "(biblionumber int(11) NOT NULL default '0',
375 subscriptionid int(11) NOT NULL default '0',
376 histstartdate date NOT NULL default '0000-00-00',
377 enddate date default '0000-00-00',
378 missinglist longtext NOT NULL,
379 recievedlist longtext NOT NULL,
380 opacnote varchar(150) NOT NULL default '',
381 librariannote varchar(150) NOT NULL default '',
382 PRIMARY KEY (subscriptionid),
383 KEY biblionumber (biblionumber)
385 labels => "(labelid int(11) NOT NULL auto_increment,
386 itemnumber varchar(100) NOT NULL default '',
387 timestamp timestamp(14) NOT NULL,
388 PRIMARY KEY (labelid)
390 labels_conf => "(id int(4) NOT NULL auto_increment,
391 barcodetype char(100) default '',
392 title tinyint(1) default '0',
393 isbn tinyint(1) default '0',
394 itemtype tinyint(1) default '0',
395 barcode tinyint(1) default '0',
396 dewey tinyint(1) default '0',
397 class tinyint(1) default '0',
398 author tinyint(1) default '0',
399 papertype char(100) default '',
400 startrow int(2) default NULL,
406 my %requirefields = (
407 <<<<<<< updatedatabase
408 subscription => { 'letter' => 'char(20) NULL', 'distributedto' => 'text NULL'},
409 itemtypes => { 'imageurl' => 'char(200) NULL'},
410 aqbookfund => { 'branchcode' => 'varchar(4) NULL'},
411 aqbudget => { 'branchcode' => 'varchar(4) NULL'},
412 auth_header => { 'marc' => 'BLOB NOT NULL', 'linkid' => 'BIGINT(20) NULL'},
413 auth_subfield_structure =>{ 'hidden' => 'TINYINT(3) NOT NULL UNSIGNED ZEROFILL', 'kohafield' => 'VARCHAR(45) NOT NULL', 'linkid' => 'TINYINT(1) NOT NULL UNSIGNED', 'isurl' => 'TINYINT(1) UNSIGNED'},
414 statistics => { 'associatedborrower' => 'integer'},
415 # tablename => { 'field' => 'fieldtype' },
417 biblio => { 'abstract' => 'text' },
418 deletedbiblio => { 'abstract' => 'text', 'marc' => 'blob' },
420 { 'marc' => 'blob', 'paidfor' => 'text', 'location' => 'varchar(80)' },
422 'lccn' => 'char(25)',
423 'url' => 'varchar(255)',
426 deletedbiblioitems => {
427 'lccn' => 'char(25)',
428 'url' => 'varchar(255)',
431 branchtransfers => { 'datearrived' => 'datetime' },
432 statistics => { 'borrowernumber' => 'int(11)' },
434 'invoicedisc' => 'float(6,4)',
435 'nocalc' => 'int(11)'
438 'userid' => 'char(30)',
439 'password' => 'char(30)',
440 'flags' => 'int(11)',
441 'textmessaging' => 'varchar(30)',
442 'zipcode' => 'varchar(25)',
443 'homezipcode' => 'varchar(25)',
444 'sort1' => 'char(80)',
445 'sort2' => 'char(80)',
448 'budgetdate' => 'date',
449 'sort1' => 'char(80)',
450 'sort2' => 'char(80)',
453 'aqbudgetid' => 'tinyint(4) auto_increment primary key',
454 'branchcode' => 'varchar(4)',
456 aqbookfund => { 'branchcode' => 'varchar(4)', },
457 items => { 'paidfor' => 'text', 'location' => 'char(80)' },
459 #added so that reference items are not available for reserves...
460 itemtypes => { 'notforloan' => 'smallint(6)' },
461 systempreferences => {
462 'explanation' => 'char(80)',
463 'type' => 'char(20)',
466 z3950servers => { 'syntax' => 'char(80)' },
467 marc_tag_structure =>
468 { 'frameworkcode' => 'char(4) not NULL default \'\'' },
469 marc_subfield_structure => {
470 'seealso' => 'char(255)',
471 'frameworkcode' => 'char(4) not NULL default \'\'',
472 'hidden' => 'tinyint(1)',
473 'isurl' => 'tinyint(1)',
474 'link' => 'char(80)',
477 'owner' => 'char(80)',
478 'category' => 'char(1)',
480 marc_biblio => { 'frameworkcode' => 'char(4) not NULL default \'\'' },
484 my %dropable_table = (
485 sessionqueries => 'sessionqueries',
486 marcrecorddone => 'marcrecorddone',
488 itemsprices => 'itemsprices',
489 biblioanalysis => 'biblioanalysis',
491 # tablename => 'tablename',
494 my %uselessfields = (
495 <<<<<<< updatedatabase
496 # tablename => "field1,field2",
497 borrowers => "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
498 deletedborrowers=> "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
501 aqorders => "requisitionedby,authorisedby,booksellerid,
502 deliverydays,followupdays,
503 numberfollowupsallowed,numberfollowupssent,
504 dateprinted,sourced,quantityreceiveddamaged,
505 subscriptionfrom,subscriptionto
510 # the other hash contains other actions that can't be done elsewhere. they are done
511 # either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
513 # The tabledata hash contains data that should be in the tables.
514 # The uniquefieldrequired hash entry is used to determine which (if any) fields
515 # must not exist in the table for this row to be inserted. If the
516 # uniquefieldrequired entry is already in the table, the existing data is not
517 # modified, unless the forceupdate hash entry is also set. Fields in the
518 # anonymous "forceupdate" hash will be forced to be updated to the default
519 # values given in the %tabledata hash.
522 <<<<<<< updatedatabase
524 # { uniquefielrequired => 'fieldname', # the primary key in the table
525 # fieldname => fieldvalue,
526 # fieldname2 => fieldvalue2,
532 uniquefieldrequired => 'bit',
534 flag => 'superlibrarian',
535 flagdesc => 'Access to all librarian functions',
539 uniquefieldrequired => 'bit',
542 flagdesc => 'Circulate books',
546 uniquefieldrequired => 'bit',
549 flagdesc => 'View Catalogue (Librarian Interface)',
553 uniquefieldrequired => 'bit',
555 flag => 'parameters',
556 flagdesc => 'Set Koha system paramters',
560 uniquefieldrequired => 'bit',
563 flagdesc => 'Add or modify borrowers',
567 uniquefieldrequired => 'bit',
569 flag => 'permissions',
570 flagdesc => 'Set user permissions',
574 uniquefieldrequired => 'bit',
576 flag => 'reserveforothers',
577 flagdesc => 'Reserve books for patrons',
581 uniquefieldrequired => 'bit',
584 flagdesc => 'Borrow books',
588 uniquefieldrequired => 'bit',
590 flag => 'reserveforself',
591 flagdesc => 'Reserve books for self',
595 uniquefieldrequired => 'bit',
597 flag => 'editcatalogue',
598 flagdesc => 'Edit Catalogue (Modify bibliographic/holdings data)',
602 uniquefieldrequired => 'bit',
604 flag => 'updatecharges',
605 flagdesc => 'Update borrower charges',
609 uniquefieldrequired => 'bit',
611 flag => 'acquisition',
612 flagdesc => 'Acquisition and/or suggestion management',
616 uniquefieldrequired => 'bit',
618 flag => 'management',
619 flagdesc => 'Set library management parameters',
623 uniquefieldrequired => 'bit',
626 flagdesc => 'Use tools (export, import, barcodes)',
631 systempreferences => [
633 uniquefieldrequired => 'variable',
634 <<<<<<< updatedatabase
635 variable => 'Activate_Log',
637 forceupdate => { 'explanation' => 1,
639 explanation => 'Turn Log Actions on DB On an Off',
646 variable => 'LibraryName',
648 '<i><b>Koha<br/>Free Software ILS<br/><br/></b>Koha : a gift, a contribution<br/> in Maori</i>',
649 explanation => 'Library name as shown on main opac page',
655 uniquefieldrequired => 'variable',
656 <<<<<<< updatedatabase
657 variable => 'IndependantBranches',
659 forceupdate => { 'explanation' => 1,
661 explanation => 'Turn Branch independancy management On an Off',
668 variable => 'autoMemberNum',
670 explanation => 'Member number is auto-calculated',
676 uniquefieldrequired => 'variable',
677 <<<<<<< updatedatabase
678 variable => 'ReturnBeforeExpiry',
680 forceupdate => { 'explanation' => 1,
682 explanation => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
690 variable => 'acquisitions',
693 'Normal, budget-based acquisitions, or Simple bibliographic-data acquisitions',
695 options => 'simple|normal'
698 uniquefieldrequired => 'variable',
704 variable => 'dateformat',
707 'date format (us mm/dd/yyyy, metric dd/mm/yyy, ISO yyyy/mm/dd)',
709 options => 'metric|us|iso'
712 uniquefieldrequired => 'variable',
713 variable => 'template',
719 explanation => 'Preference order for intranet interface templates',
723 uniquefieldrequired => 'variable',
724 variable => 'autoBarcode',
730 explanation => 'Barcode is auto-calculated',
734 uniquefieldrequired => 'variable',
735 variable => 'insecure',
742 'If YES, no auth at all is needed. Be careful if you set this to yes!',
746 uniquefieldrequired => 'variable',
747 variable => 'authoritysep',
755 'the separator used in authority/thesaurus. Usually --',
760 uniquefieldrequired => 'variable',
761 variable => 'opaclanguages',
768 'Set the preferred order for translations. The top language will be tried first.',
772 uniquefieldrequired => 'variable',
773 variable => 'opacthemes',
780 'Set the preferred order for themes. The top theme will be tried first.',
784 uniquefieldrequired => 'variable',
785 variable => 'timeout',
792 'Inactivity timeout for cookies authentication (in seconds)',
796 uniquefieldrequired => 'variable',
803 explanation => 'Turn on MARC support',
807 uniquefieldrequired => 'variable',
808 variable => 'sortbynonfiling',
814 explanation => 'Sort search results by MARC nonfiling characters',
818 uniquefieldrequired => 'variable',
819 variable => 'marcflavour',
827 'your MARC flavor (MARC21 or UNIMARC) used for character encoding',
829 options => 'MARC21|UNIMARC'
832 uniquefieldrequired => 'variable',
833 variable => 'checkdigit',
841 'Validity checks on membership number: none or "Katipo" style checks',
843 options => 'none|katipo'
846 uniquefieldrequired => 'variable',
847 variable => 'maxoutstanding',
854 'maximum amount withstanding to be able make reserves ',
858 uniquefieldrequired => 'variable',
859 variable => 'maxreserves',
865 explanation => 'maximum number of reserves a member can make',
870 uniquefieldrequired => 'variable',
871 variable => 'noissuescharge',
878 'maximum amount withstanding to be able to check out an item',
883 uniquefieldrequired => 'variable',
884 variable => 'KohaAdminEmailAddress',
889 value => 'your.mail@here',
890 explanation => 'the email address where borrowers modifs are sent',
894 uniquefieldrequired => 'variable',
902 'the gist rate. NOT in %, but in numeric form (0.12 for 12%)',
906 uniquefieldrequired => 'variable',
907 variable => 'printcirculationslips',
914 'if set to 1, print circulation slips. If set to 0, don\'t',
918 uniquefieldrequired => 'variable',
919 variable => 'suggestion',
925 explanation => 'if set to 1, suggestions are activated in OPAC',
929 uniquefieldrequired => 'variable',
935 value => 'Fill with appropriate value...',
936 explanation => 'ISBD',
940 uniquefieldrequired => 'variable',
941 variable => 'virtualshelves',
947 explanation => 'Set virtual shelves management ON or OFF',
951 uniquefieldrequired => 'variable',
952 variable => 'itemcallnumber',
959 'The MARC field/subfield that is used to calculate the itemcallnumber (in UNIMARC : 676a for Dewey, 680a for Loc)',
963 uniquefieldrequired => 'variable',
964 variable => 'BiblioDefaultView',
972 'Define the default view of a biblio. Can be either normal, marc or isbd',
974 options => 'normal|marc|isbd'
978 uniquefieldrequired => 'variable',
979 variable => 'LabelMARCView',
986 explanation => 'Define how a MARC record will display',
988 options => 'standard|economical'
993 uniquefieldrequired => 'variable',
994 variable => 'opacstylesheet',
1001 'Enter a complete URL to use an alternate layout stylesheet in OPAC',
1005 uniquefieldrequired => 'variable',
1006 variable => 'opaccolorstylesheet',
1013 'Enter the name of the color stylesheet to use in the OPAC',
1017 uniquefieldrequired => 'variable',
1018 variable => 'opaclayoutstylesheet',
1025 'Enter the name of the layout stylesheet to use in the OPAC',
1030 uniquefieldrequired => 'variable',
1031 variable => 'opacreadinghistory',
1038 'Turn on/off display of Patron Reading History in OPAC',
1042 uniquefieldrequired => 'variable',
1043 variable => 'opaclanguagesdisplay',
1050 'Turn on/off display of Change Language feature on OPAC',
1054 uniquefieldrequired => 'variable',
1055 variable => 'patronimages',
1062 'Turn on/off display of patron images in Intranet and specify a file extension for images',
1066 uniquefieldrequired => 'variable',
1067 variable => 'intranetstylesheet',
1074 'Enter a complete URL to use an alternate layout stylesheet in Intranet',
1078 uniquefieldrequired => 'variable',
1079 variable => 'intranetcolorstylesheet',
1086 'Enter the name of the color stylesheet to use in Intranet',
1090 uniquefieldrequired => 'variable',
1091 variable => 'opacsmallimage',
1098 'Enter a complete URL to an image, will be on top/left instead of the Koha logo',
1102 uniquefieldrequired => 'variable',
1103 variable => 'opaclargeimage',
1110 'Enter a complete URL to an image, will be on the main page, instead of the Koha logo',
1114 uniquefieldrequired => 'variable',
1115 variable => 'delimiter',
1121 explanation => 'separator for reports exported to spreadsheet',
1125 uniquefieldrequired => 'variable',
1127 value => 'OPENOFFICE.ORG',
1134 'Define the default application for report exportations into files',
1136 options => 'EXCEL|OPENOFFICE.ORG'
1139 uniquefieldrequired => 'variable',
1140 variable => 'Delimiter',
1148 'Define the default separator character for report exportations into files',
1150 options => ';|tabulation|,|/|\|#'
1153 uniquefieldrequired => 'variable',
1154 variable => 'SubscriptionHistory',
1162 'Define the information level for serials history in OPAC',
1164 options => 'simplified|full'
1167 uniquefieldrequired => 'variable',
1168 variable => 'hidelostitems',
1174 explanation => 'show or hide "lost" items in OPAC.',
1178 uniquefieldrequired => 'variable',
1179 variable => 'IndependantBranches',
1185 explanation => 'Turn Branch independency management On and Off',
1189 uniquefieldrequired => 'variable',
1190 variable => 'ReturnBeforeExpiry',
1197 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
1201 uniquefieldrequired => 'variable',
1202 variable => 'Disable_Dictionary',
1208 explanation => 'Disables Dictionary buttons if set to yes',
1212 uniquefieldrequired => 'variable',
1213 variable => 'hide_marc',
1220 'hide marc specific datas like subfield code & indicators to library',
1224 uniquefieldrequired => 'variable',
1225 variable => 'NotifyBorrowerDeparture',
1232 'Delay before expiry where a notice is sent when issuing',
1236 uniquefieldrequired => 'variable',
1237 variable => 'OpacPasswordChange',
1244 'Enable/Disable password change in OPAC (disable it when using LDAP auth)',
1248 uniquefieldrequired => 'variable',
1249 variable => 'OpacNav',
1256 'Use HTML tabs to add navigational links to the left-hand navigational bar in OPAC',
1261 uniquefieldrequired => 'variable',
1262 variable => 'IntranetNav',
1269 'Use HTML tabs to add navigational links to the left-hand navigational bar in Intranet',
1275 uniquefieldrequired => 'variable',
1276 variable => 'AnonSuggestions',
1284 'Set to anonymous borrowernumber to enable Anonymous suggestions',
1288 uniquefieldrequired => 'variable',
1289 variable => 'MARCOrgCode',
1297 'Your MARC Organization Code - http://www.loc.gov/marc/organizations/orgshome.html',
1301 uniquefieldrequired => 'variable',
1302 variable => 'AmazonContent',
1310 'Turn On Amazon Content - You MUST set AmazonDevKey and AmazonAssocTag if enabled',
1314 uniquefieldrequired => 'variable',
1315 variable => 'AmazonDevKey',
1323 'see: aws-portal.amazon.com/gp/aws/developer/registration/index.html',
1327 uniquefieldrequired => 'variable',
1328 variable => 'AmazonAssocTag',
1336 'see: associates.amazon.com/gp/flex/associates/apply-login.html',
1340 uniquefieldrequired => 'variable',
1346 variable => 'TemplateEncoding',
1347 value => 'iso-8859-1',
1348 explanation => 'Specify the encoding to use in Templates',
1350 options => 'iso-8859-1|utf-8'
1354 uniquefieldrequired => 'variable',
1355 variable => 'opaccredits',
1363 'Put any HTML Credits at the bottom of the OPAC page',
1369 uniquefieldrequired => 'variable',
1370 variable => 'opacheader',
1372 forceupdate => { 'explanation' => 1,
1374 explanation => 'Enter HTML to be included as a custom header in the OPAC',
1380 uniquefieldrequired => 'variable',
1381 variable => 'IntranetBiblioDefaultView',
1383 forceupdate => { 'explanation' => 1,
1385 explanation => 'Define the default view of a biblio in the intranet. Can be either normal, marc, or ISBD',
1387 options => 'normal|marc|isbd'
1391 uniquefieldrequired => 'variable',
1392 variable => 'opacbookbag',
1394 forceupdate => { 'explanation' => 1,
1396 explanation => 'Enable or disable display of biblio basket (book bag)',
1401 uniquefieldrequired => 'variable',
1402 variable => 'opacuserlogin',
1404 forceupdate => { 'explanation' => 1,
1406 explanation => 'Enable or disable display of user login features',
1411 uniquefieldrequired => 'variable',
1412 variable => 'serialsadditems',
1420 'If set, a new item will be automatically added when receiving an issue',
1424 uniquefieldrequired => 'variable',
1425 variable => 'advancedMARCeditor',
1433 "If set, the MARC editor won't show you tag/subfields description",
1437 uniquefieldrequired => 'variable',
1438 variable => 'z3950NormalizeAuthor',
1446 "If set, Personnal Authorities will replace authors in biblio.author",
1450 uniquefieldrequired => 'variable',
1451 variable => 'z3950AuthorAuthFields',
1452 value => '701,702,700',
1459 "contains the MARC biblio tags of person authorities to fill biblio.author with when importing biblio",
1463 uniquefieldrequired => 'variable',
1464 variable => 'useDaysMode',
1465 value => 'Calendar',
1466 forceupdate => { 'explanation' => 1,
1468 explanation => 'How to calculate return dates : Calendar means holidays will be controled, Days means the return date don\'t depend on holidays',
1470 options => 'Calendar|Days'
1473 uniquefieldrequired => 'variable',
1474 variable => 'borrowerMandatoryField',
1475 value => 'zipcode|surname',
1476 forceupdate => { 'explanation' => 1,
1478 explanation => 'List all mandatory fields for borrowers',
1482 <<<<<<< updatedatabase
1483 uniquefieldrequired => 'variable',
1484 variable => 'borrowerRelationship',
1485 value => 'father|mother,grand-mother',
1486 forceupdate => { 'explanation' => 1,
1488 explanation => 'The relationships between a guarantor & a guarantee (separated by | or ,)',
1491 field => 'aqbudgetid',
1492 type => 'tinyint(4)',
1496 extra => 'auto_increment'
1500 uniquefieldrequired => 'variable',
1501 variable => 'ReservesMaxPickUpDelay',
1503 forceupdate => { 'explanation' => 1,
1505 explanation => 'Maximum delay to pick up a reserved document',
1508 <<<<<<< updatedatabase
1514 uniquefieldrequired => 'variable',
1515 variable => 'TransfersMaxDaysWarning',
1517 forceupdate => { 'explanation' => 1,
1519 explanation => 'Max delay before considering the transfer has potentialy a problem',
1523 uniquefieldrequired => 'variable',
1524 variable => 'memberofinstitution',
1526 forceupdate => { 'explanation' => 1,
1528 explanation => 'Are your patrons members of institutions',
1532 uniquefieldrequired => 'variable',
1533 variable => 'ReadingHistory',
1535 forceupdate => { 'explanation' => 1,
1537 explanation => 'Allow reading record info retrievable from issues and oldissues tables',
1541 uniquefieldrequired => 'variable',
1542 variable => 'IssuingInProcess',
1544 forceupdate => { 'explanation' => 1,
1546 explanation => 'Allow no debt alert if the patron is issuing item that accumulate debt',
1550 uniquefieldrequired => 'variable',
1551 variable => 'AutomaticItemReturn',
1553 forceupdate => { 'explanation' => 1,
1555 explanation => 'This Variable allow or not to return automaticly to his homebranch',
1559 uniquefieldrequired => 'variable',
1560 variable => 'reviewson',
1562 forceupdate => { 'explanation' => 1,
1564 explanation => 'Allows patrons to submit reviews from the opac',
1568 <<<<<<< updatedatabase
1572 my %fielddefinitions = (
1574 # { field => 'fieldname',
1575 # type => 'fieldtype',
1594 <<<<<<< updatedatabase
1597 field => 'booksellerid',
1607 field => 'listprice',
1608 type => 'varchar(10)',
1615 field => 'invoiceprice',
1616 type => 'varchar(10)',
1625 field => 'borrowernumber',
1627 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1633 field => 'itemnumber',
1635 null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
1642 { field => 'firstname',
1646 { field => 'initials',
1650 { field => 'B_email',
1653 after => 'B_zipcode',
1656 field => 'streetnumber', # street number (hidden if streettable table is empty)
1659 after => 'initials',
1662 field => 'streettype', # street table, list builded from a system table
1665 after => 'streetnumber',
1672 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1678 field => 'B_streettype', # street table, list builded from a system table
1681 after => 'B_streetnumber',
1684 field => 'phonepro',
1690 field => 'address2', # complement address
1696 field => 'emailpro',
1702 field => 'contactfirstname', # contact's firstname
1705 after => 'contactname',
1708 field => 'contacttitle', # contact's title
1711 after => 'contactfirstname',
1715 deletedborrowers => [
1716 { field => 'firstname',
1720 { field => 'initials',
1724 { field => 'B_email',
1727 after => 'B_zipcode',
1730 field => 'streetnumber', # street number (hidden if streettable table is empty)
1733 after => 'initials',
1736 field => 'streettype', # street table, list builded from a system table
1739 after => 'streetnumber',
1746 field => 'B_streetnumber', # street number (hidden if streettable table is empty)
1752 field => 'B_streettype', # street table, list builded from a system table
1755 after => 'B_streetnumber',
1758 field => 'phonepro',
1764 field => 'address2', # complement address
1770 field => 'emailpro',
1776 field => 'contactfirstname', # contact's firstname
1779 after => 'contactname',
1782 field => 'contacttitle', # contact's title
1785 after => 'contactfirstname',
1791 field => 'branchip',
1792 type => 'varchar(15)',
1799 field => 'branchprinter',
1800 type => 'varchar(100)',
1809 field => 'category_type',
1819 field => 'waitingdate',
1831 # { indexname => 'index detail'
1835 { indexname => 'shelfnumber',
1836 content => 'shelfnumber',
1838 { indexname => 'itemnumber',
1839 content => 'itemnumber',
1843 { indexname => 'biblionumber',
1844 content => 'biblionumber',
1848 { indexname => 'homebranch',
1849 content => 'homebranch',
1851 { indexname => 'holdingbranch',
1852 content => 'holdingbranch',
1856 { indexname => 'PRIMARY',
1862 { indexname => 'booksellerid',
1863 content => 'booksellerid',
1867 { indexname => 'basketno',
1868 content => 'basketno',
1871 aqorderbreakdown => [
1872 { indexname => 'ordernumber',
1873 content => 'ordernumber',
1875 { indexname => 'bookfundid',
1876 content => 'bookfundid',
1880 { indexname => 'PRIMARY',
1881 content => 'currency',
1889 type => 'varchar(30)',
1899 my %foreign_keys = (
1901 # { key => 'the key in table' (must be indexed)
1902 # foreigntable => 'the foreigntable name', # (the parent)
1903 # foreignkey => 'the foreign key column(s)' # (in the parent)
1904 # onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
1905 # onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
1909 { key => 'shelfnumber',
1910 foreigntable => 'bookshelf',
1911 foreignkey => 'shelfnumber',
1912 onUpdate => 'CASCADE',
1913 onDelete => 'CASCADE',
1915 { key => 'itemnumber',
1916 foreigntable => 'items',
1917 foreignkey => 'itemnumber',
1918 onUpdate => 'CASCADE',
1919 onDelete => 'CASCADE',
1922 # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
1923 # easily deleted, but branches/itemtype not too easy to empty...
1925 { key => 'biblionumber',
1926 foreigntable => 'biblio',
1927 foreignkey => 'biblionumber',
1928 onUpdate => 'CASCADE',
1929 onDelete => 'CASCADE',
1931 { key => 'itemtype',
1932 foreigntable => 'itemtypes',
1933 foreignkey => 'itemtype',
1934 onUpdate => 'CASCADE',
1935 onDelete => 'RESTRICT',
1939 { key => 'biblioitemnumber',
1940 foreigntable => 'biblioitems',
1941 foreignkey => 'biblioitemnumber',
1942 onUpdate => 'CASCADE',
1943 onDelete => 'CASCADE',
1945 { key => 'homebranch',
1946 foreigntable => 'branches',
1947 foreignkey => 'branchcode',
1948 onUpdate => 'CASCADE',
1949 onDelete => 'RESTRICT',
1951 { key => 'holdingbranch',
1952 foreigntable => 'branches',
1953 foreignkey => 'branchcode',
1954 onUpdate => 'CASCADE',
1955 onDelete => 'RESTRICT',
1958 additionalauthors => [
1959 { key => 'biblionumber',
1960 foreigntable => 'biblio',
1961 foreignkey => 'biblionumber',
1962 onUpdate => 'CASCADE',
1963 onDelete => 'CASCADE',
1967 { key => 'biblionumber',
1968 foreigntable => 'biblio',
1969 foreignkey => 'biblionumber',
1970 onUpdate => 'CASCADE',
1971 onDelete => 'CASCADE',
1975 { key => 'booksellerid',
1976 foreigntable => 'aqbooksellers',
1978 onUpdate => 'CASCADE',
1979 onDelete => 'RESTRICT',
1983 { key => 'basketno',
1984 foreigntable => 'aqbasket',
1985 foreignkey => 'basketno',
1986 onUpdate => 'CASCADE',
1987 onDelete => 'CASCADE',
1989 { key => 'biblionumber',
1990 foreigntable => 'biblio',
1991 foreignkey => 'biblionumber',
1992 onUpdate => 'SET NULL',
1993 onDelete => 'SET NULL',
1997 { key => 'listprice',
1998 foreigntable => 'currency',
1999 foreignkey => 'currency',
2000 onUpdate => 'CASCADE',
2001 onDelete => 'CASCADE',
2003 { key => 'invoiceprice',
2004 foreigntable => 'currency',
2005 foreignkey => 'currency',
2006 onUpdate => 'CASCADE',
2007 onDelete => 'CASCADE',
2010 aqorderbreakdown => [
2011 { key => 'ordernumber',
2012 foreigntable => 'aqorders',
2013 foreignkey => 'ordernumber',
2014 onUpdate => 'CASCADE',
2015 onDelete => 'CASCADE',
2017 { key => 'bookfundid',
2018 foreigntable => 'aqbookfund',
2019 foreignkey => 'bookfundid',
2020 onUpdate => 'CASCADE',
2021 onDelete => 'CASCADE',
2024 branchtransfers => [
2025 { key => 'frombranch',
2026 foreigntable => 'branches',
2027 foreignkey => 'branchcode',
2028 onUpdate => 'CASCADE',
2029 onDelete => 'CASCADE',
2031 { key => 'tobranch',
2032 foreigntable => 'branches',
2033 foreignkey => 'branchcode',
2034 onUpdate => 'CASCADE',
2035 onDelete => 'CASCADE',
2037 { key => 'itemnumber',
2038 foreigntable => 'items',
2039 foreignkey => 'itemnumber',
2040 onUpdate => 'CASCADE',
2041 onDelete => 'CASCADE',
2045 { key => 'categorycode',
2046 foreigntable => 'categories',
2047 foreignkey => 'categorycode',
2048 onUpdate => 'CASCADE',
2049 onDelete => 'CASCADE',
2051 { key => 'itemtype',
2052 foreigntable => 'itemtypes',
2053 foreignkey => 'itemtype',
2054 onUpdate => 'CASCADE',
2055 onDelete => 'CASCADE',
2058 issues => [ # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
2060 { key => 'borrowernumber',
2061 foreigntable => 'borrowers',
2062 foreignkey => 'borrowernumber',
2063 onUpdate => 'SET NULL',
2064 onDelete => 'SET NULL',
2066 { key => 'itemnumber',
2067 foreigntable => 'items',
2068 foreignkey => 'itemnumber',
2069 onUpdate => 'SET NULL',
2070 onDelete => 'SET NULL',
2074 { key => 'borrowernumber',
2075 foreigntable => 'borrowers',
2076 foreignkey => 'borrowernumber',
2077 onUpdate => 'CASCADE',
2078 onDelete => 'CASCADE',
2080 { key => 'biblionumber',
2081 foreigntable => 'biblio',
2082 foreignkey => 'biblionumber',
2083 onUpdate => 'CASCADE',
2084 onDelete => 'CASCADE',
2086 { key => 'itemnumber',
2087 foreigntable => 'items',
2088 foreignkey => 'itemnumber',
2089 onUpdate => 'CASCADE',
2090 onDelete => 'CASCADE',
2092 { key => 'branchcode',
2093 foreigntable => 'branches',
2094 foreignkey => 'branchcode',
2095 onUpdate => 'CASCADE',
2096 onDelete => 'CASCADE',
2099 borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2100 # but prevent deleting a branch as soon as it has 1 borrower !
2101 { key => 'categorycode',
2102 foreigntable => 'categories',
2103 foreignkey => 'categorycode',
2104 onUpdate => 'RESTRICT',
2105 onDelete => 'RESTRICT',
2107 { key => 'branchcode',
2108 foreigntable => 'branches',
2109 foreignkey => 'branchcode',
2110 onUpdate => 'RESTRICT',
2111 onDelete => 'RESTRICT',
2114 deletedborrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
2115 # but prevent deleting a branch as soon as it has 1 borrower !
2116 { key => 'categorycode',
2117 foreigntable => 'categories',
2118 foreignkey => 'categorycode',
2119 onUpdate => 'RESTRICT',
2120 onDelete => 'RESTRICT',
2122 { key => 'branchcode',
2123 foreigntable => 'branches',
2124 foreignkey => 'branchcode',
2125 onUpdate => 'RESTRICT',
2126 onDelete => 'RESTRICT',
2130 { key => 'borrowernumber',
2131 foreigntable => 'borrowers',
2132 foreignkey => 'borrowernumber',
2133 onUpdate => 'CASCADE',
2134 onDelete => 'CASCADE',
2136 { key => 'itemnumber',
2137 foreigntable => 'items',
2138 foreignkey => 'itemnumber',
2139 onUpdate => 'SET NULL',
2140 onDelete => 'SET NULL',
2143 auth_tag_structure => [
2144 { key => 'authtypecode',
2145 foreigntable => 'auth_types',
2146 foreignkey => 'authtypecode',
2147 onUpdate => 'CASCADE',
2148 onDelete => 'CASCADE',
2151 # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
2156 my %column_change = (
2160 from => 'emailaddress',
2165 from => 'streetaddress',
2167 after => 'initials',
2170 from => 'faxnumber',
2175 from => 'textmessaging',
2181 to => 'contactnote',
2182 after => 'opacnote',
2185 from => 'physstreet',
2190 from => 'streetcity',
2192 after => 'B_address',
2205 from => 'homezipcode',
2212 after => 'B_zipcode',
2217 after => 'dateenrolled',
2220 from => 'guarantor',
2221 to => 'guarantorid',
2222 after => 'contactname',
2225 from => 'textmessaging',
2231 to => 'contactnotes',
2232 after => 'opacnotes',
2235 from => 'altrelationship',
2236 to => 'relationship',
2237 after => 'borrowernotes',
2241 deletedborrowers => [
2243 from => 'emailaddress',
2248 from => 'streetaddress',
2250 after => 'initials',
2253 from => 'faxnumber',
2258 from => 'textmessaging',
2264 to => 'contactnote',
2265 after => 'opacnote',
2268 from => 'physstreet',
2273 from => 'streetcity',
2275 after => 'B_address',
2288 from => 'homezipcode',
2295 after => 'B_zipcode',
2300 after => 'dateenrolled',
2303 from => 'guarantor',
2304 to => 'guarantorid',
2305 after => 'contactname',
2308 from => 'textmessaging',
2314 to => 'contactnotes',
2315 after => 'opacnotes',
2318 from => 'altrelationship',
2319 to => 'relationship',
2320 after => 'borrowernotes',
2326 foreach my $table (keys %column_change) {
2327 $sth = $dbh->prepare("show columns from $table");
2330 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2332 $types{$column}->{type} ="$type";
2333 $types{$column}->{null} = "$null";
2334 $types{$column}->{key} = "$key";
2335 $types{$column}->{default} = "$default";
2336 $types{$column}->{extra} = "$extra";
2338 my $tablerows = $column_change{$table};
2339 foreach my $row ( @$tablerows ) {
2340 if ($types{$row->{from}}->{type}) {
2341 print "altering $table $row->{from} to $row->{to}\n";
2342 # ALTER TABLE `borrowers` CHANGE `faxnumber` `fax` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
2343 # alter table `borrowers` change `faxnumber` `fax` type text null after phone
2345 "alter table `$table` change `$row->{from}` `$row->{to}` $types{$row->{from}}->{type} ".
2346 ($types{$row->{from}}->{null} eq 'YES'?" NULL":" NOT NULL").
2347 ($types{$row->{from}}->{default}?" default ".$types{$row->{from}}->{default}:"").
2348 "$types{$row->{from}}->{extra} after $row->{after} ";
2355 #-------------------
2360 # Get version of MySQL database engine.
2361 my $mysqlversion = `mysqld --version`;
2362 $mysqlversion =~ /Ver (\S*) /;
2364 if ( $mysqlversion ge '3.23' ) {
2365 print "Could convert to MyISAM database tables...\n" unless $silent;
2368 #---------------------------------
2371 # Collect all tables into a list
2372 $sth = $dbh->prepare("show tables");
2374 while ( my ($table) = $sth->fetchrow ) {
2375 $existingtables{$table} = 1;
2378 # Now add any missing tables
2379 foreach $table ( keys %requiretables ) {
2380 unless ( $existingtables{$table} ) {
2381 print "Adding $table table...\n" unless $silent;
2382 my $sth = $dbh->prepare("create table $table $requiretables{$table}");
2385 print "Error : $sth->errstr \n";
2391 # now drop useless tables
2392 foreach $table ( keys %dropable_table ) {
2393 if ( $existingtables{$table} ) {
2394 print "Dropping unused table $table\n" if $debug and not $silent;
2395 $dbh->do("drop table $table");
2397 print "Error : $dbh->errstr \n";
2401 <<<<<<< updatedatabase
2404 unless ( $existingtables{'z3950servers'} ) {
2406 #MJR: added syntax entries to close bug 624
2407 print "Adding z3950servers table...\n" unless $silent;
2408 my $sti = $dbh->prepare(
2409 "create table z3950servers (
2422 $sti = $dbh->prepare(
2423 "insert into z3950servers
2424 values ('z3950.loc.gov',
2428 'Library of Congress',
2433 unless ( $existingtables{'issuingrules'} ) {
2434 $dbh->do("alter table categoryitem rename issuingrules");
2435 $dbh->do("ALTER TABLE issuingrules ADD maxissueqty int(4) default NULL");
2436 $dbh->do("ALTER TABLE issuingrules ADD issuelength int(4) default NULL");
2438 "ALTER TABLE issuingrules ADD branchcode varchar(4) NOT NULL default ''"
2440 print "renaming categoryitem\n" unless $silent;
2444 #---------------------------------
2447 foreach $table ( keys %requirefields ) {
2448 print "Check table $table\n" if $debug and not $silent;
2449 $sth = $dbh->prepare("show columns from $table");
2452 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2454 $types{$column} = $type;
2456 foreach $column ( keys %{ $requirefields{$table} } ) {
2457 print " Check column $column [$types{$column}]\n"
2458 if $debug and not $silent;
2459 if ( !$types{$column} ) {
2461 # column doesn't exist
2462 print "Adding $column field to $table table...\n" unless $silent;
2463 $query = "alter table $table
2464 add column $column " . $requirefields{$table}->{$column};
2465 print "Execute: $query\n" if $debug;
2466 my $sti = $dbh->prepare($query);
2469 print "**Error : $sti->errstr \n";
2476 foreach $table ( keys %fielddefinitions ) {
2477 <<<<<<< updatedatabase
2478 print "Check table $table\n" if $debug;
2479 $sth = $dbh->prepare("show columns from $table");
2482 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2484 $definitions->{$column}->{type} = $type;
2485 $definitions->{$column}->{null} = $null;
2486 $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
2487 $definitions->{$column}->{key} = $key;
2488 $definitions->{$column}->{default} = $default;
2489 $definitions->{$column}->{extra} = $extra;
2491 my $fieldrow = $fielddefinitions{$table};
2492 foreach my $row (@$fieldrow) {
2493 my $field = $row->{field};
2494 my $type = $row->{type};
2495 my $null = $row->{null};
2496 # $null = 'YES' if $row->{null} eq 'NULL';
2497 my $key = $row->{key};
2498 my $default = $row->{default};
2499 my $null = $row->{null};
2500 # $default="''" unless $default;
2501 my $extra = $row->{extra};
2502 my $def = $definitions->{$field};
2503 my $after = ($row->{after}?" after ".$row->{after}:"");
2505 unless ( $type eq $def->{type}
2506 && $null eq $def->{null}
2507 && $key eq $def->{key}
2508 && $extra eq $def->{extra} )
2510 if ( $null eq '' ) {
2513 if ( $key eq 'PRI' ) {
2514 $key = 'PRIMARY KEY';
2516 unless ( $extra eq 'auto_increment' ) {
2520 # if it's a new column use "add", if it's an old one, use "change".
2522 if ($definitions->{$field}->{type}) {
2523 $action="change $field"
2527 # if it's a primary key, drop the previous pk, before altering the table
2529 if ($key ne 'PRIMARY KEY') {
2530 $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ? $after");
2532 $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ? $after");
2534 $sth->execute($default);
2535 print " alter or create $field in $table\n" unless $silent;
2539 print "Check table $table\n" if $debug;
2540 $sth = $dbh->prepare("show columns from $table");
2543 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2545 $definitions->{$column}->{type} = $type;
2546 $definitions->{$column}->{null} = $null;
2547 $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
2548 $definitions->{$column}->{key} = $key;
2549 $definitions->{$column}->{default} = $default;
2550 $definitions->{$column}->{extra} = $extra;
2552 my $fieldrow = $fielddefinitions{$table};
2553 foreach my $row (@$fieldrow) {
2554 my $field = $row->{field};
2555 my $type = $row->{type};
2556 my $key = $row->{key};
2557 my $default = $row->{default};
2558 my $null = $row->{null};
2560 # $default="''" unless $default;
2561 my $extra = $row->{extra};
2562 my $def = $definitions->{$field};
2564 unless ( $type eq $def->{type}
2565 && $null eq $def->{null}
2566 && $key eq $def->{key}
2567 && $extra eq $def->{extra} )
2569 if ( $null eq '' ) {
2572 if ( $key eq 'PRI' ) {
2573 $key = 'PRIMARY KEY';
2575 unless ( $extra eq 'auto_increment' ) {
2579 # if it's a new column use "add", if it's an old one, use "change".
2581 if ( $definitions->{$field}->{type} ) {
2582 $action = "change $field";
2588 # if it's a primary key, drop the previous pk, before altering the table
2590 if ( $key ne 'PRIMARY KEY' ) {
2593 "alter table $table $action $field $type $null $key $extra default ?"
2599 "alter table $table drop primary key, $action $field $type $null $key $extra default ?"
2602 $sth->execute($default);
2603 print " Alter $field in $table\n" unless $silent;
2609 <<<<<<< updatedatabase
2611 # Get list of columns from borrowers table
2614 $sth = $dbh->prepare("show columns from borrowers");
2616 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2618 $itemtypes{$column} = $type;
2619 $nullenabled{$column} = $null;
2622 unless ( $itemtypes{'cardnumber'} eq 'varchar(20)' ) {
2623 $itemtypes{'cardnumber'} =~ /varchar\((\d+)\)/;
2625 if ( $oldlength < 16 ) {
2627 "Setting maximum cardnumber length to 16 (was $oldlength) and marking unique.\n"
2631 "alter table borrowers change cardnumber cardnumber varchar(16)");
2634 $sti = $dbh->prepare("alter table borrowers drop index cardnumber");
2637 $sti = $dbh->prepare("alter table borrowers add unique(cardnumber)");
2644 # Get list of columns from items table
2645 $sth = $dbh->prepare("show columns from items");
2647 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2649 $itemtypes{$column} = $type;
2650 $nullenabled{$column} = $null;
2653 unless ( $itemtypes{'barcode'} eq 'varchar(20)' ) {
2654 $itemtypes{'barcode'} =~ /varchar\((\d+)\)/;
2656 if ( $oldlength < 20 ) {
2657 print "Setting maximum barcode length to 20 (was $oldlength).\n"
2660 $dbh->prepare("alter table items change barcode barcode varchar(20)");
2666 # dropping unique barcode index & setting barcode to null allowed.
2668 $sth = $dbh->prepare("show index from items");
2672 $table, $non_unique, $key_name, $Seq_in_index,
2673 $Column_name, $Collation, $cardinality, $sub_part,
2679 if ( $key_name eq 'barcode' && $non_unique eq 0 ) {
2680 print "dropping BARCODE index to enable empty barcodes\n"
2682 $dbh->do("ALTER TABLE `items` DROP INDEX `barcode`");
2685 $dbh->do("ALTER TABLE `items` CHANGE `barcode` `barcode` VARCHAR( 20 )")
2686 unless ( $nullenabled{barcode} eq 'YES' );
2689 # creating fulltext index in bibliothesaurus if needed
2691 $sth = $dbh->prepare("show index from bibliothesaurus");
2696 $table, $non_unique, $key_name, $Seq_in_index,
2697 $Column_name, $Collation, $cardinality, $sub_part,
2703 if ( $key_name eq 'category_2' ) {
2707 print "Creating fulltext index on bibliothesaurus\n" unless $exists or $silent;
2709 'create fulltext index category_2 on bibliothesaurus (category,freelib)')
2713 # creating index in z3950results if needed
2715 $sth = $dbh->prepare("show index from z3950results");
2720 $table, $non_unique, $key_name, $Seq_in_index,
2721 $Column_name, $Collation, $cardinality, $sub_part,
2727 if ( $key_name eq 'query_server' ) {
2731 print "Creating index on z3950results\n" unless $exists or $silent;
2732 $dbh->do('create unique index query_server on z3950results (queryid,server)')
2735 # changing z3950daemon field to NULL in marc_breeding
2737 "ALTER TABLE `marc_breeding` CHANGE `z3950random` `z3950random` VARCHAR( 40 )"
2740 # making borrowernumber an auto_increment field
2742 "ALTER TABLE `borrowers` CHANGE `borrowernumber` `borrowernumber` INTEGER auto_increment"
2745 # changing indexes in marc_*_structure to use frameworkcode
2746 $dbh->do('alter table marc_subfield_structure drop index tab');
2747 $dbh->do('create index tab on marc_subfield_structure (frameworkcode,tab)');
2748 $dbh->do('alter table marc_subfield_structure drop index kohafield');
2750 'create index kohafield on marc_subfield_structure (frameworkcode,kohafield)'
2753 # extending the timestamp in branchtransfers...
2754 my %branchtransfers;
2756 $sth = $dbh->prepare("show columns from branchtransfers");
2758 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2760 $branchtransfers{$column} = $type;
2763 unless ( $branchtransfers{'datesent'} eq 'datetime' ) {
2764 print "Setting type of datesent in branchtransfers to datetime.\n"
2768 "alter table branchtransfers change datesent datesent datetime");
2772 unless ( $branchtransfers{'datearrived'} eq 'datetime' ) {
2773 print "Setting type of datearrived in branchtransfers to datetime.\n"
2777 "alter table branchtransfers change datearrived datearrived datetime");
2781 # changing the branchcategories table around...
2782 my %branchcategories;
2784 $sth = $dbh->prepare("show columns from branchcategories");
2786 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2788 $branchcategories{$column} = $type;
2791 unless ( $branchcategories{'categorycode'} eq 'varchar(4)' ) {
2793 "Setting type of categorycode in branchcategories to varchar(4),\n and making the primary key.\n"
2797 "alter table branchcategories change categorycode categorycode varchar(4) not null"
2802 "alter table branchcategories add primary key (categorycode)");
2806 unless ( $branchcategories{'categoryname'} eq 'text' ) {
2807 print "Changing branchcode in branchcategories to categoryname text.\n"
2811 "alter table branchcategories change branchcode categoryname text");
2815 unless ( $branchcategories{'codedescription'} eq 'text' ) {
2817 "Replacing branchholding in branchcategories with codedescription text.\n"
2821 "alter table branchcategories change branchholding codedescription text"
2826 # changing the items table around...
2829 $sth = $dbh->prepare("show columns from items");
2831 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2833 $items{$column} = $type;
2836 if ( $items{'bulk'} eq "varchar(30)" ) {
2837 print " Setting callnumber in items table\n" unless $silent;
2840 "ALTER TABLE `items` CHANGE `bulk` `itemcallnumber` VARCHAR( 30 ) DEFAULT NULL"
2845 "update marc_subfield_structure set kohafield=\"items.itemcallnumber\" where kohafield=\"items.bulk\""
2850 # changing the marc_subfield_structure table around...
2851 my %marc_subfield_structure;
2853 $sth = $dbh->prepare("show columns from marc_subfield_structure");
2855 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2857 $marc_subfield_structure{$column} = $type;
2860 if ( $marc_subfield_structure{thesaurus_category} ) {
2861 print " changing thesaurus_category in marc_subfield_structure table\n"
2865 "ALTER TABLE marc_subfield_structure CHANGE `thesaurus_category` `authtypecode` VARCHAR(10 ) DEFAULT NULL"
2871 # creating index in issuingrules if needed
2873 $sth = $dbh->prepare("show index from issuingrules");
2878 $table, $non_unique, $key_name, $Seq_in_index,
2879 $Column_name, $Collation, $cardinality, $sub_part,
2885 if ( $key_name eq 'PRIMARY' ) {
2889 print "Creating index on issuing rules\n" unless $exists or $silent;
2891 'ALTER TABLE issuingrules ADD PRIMARY KEY ( branchcode, categorycode, itemtype )'
2895 $dbh->do('ALTER TABLE marc_tag_structure drop primary key');
2897 'ALTER TABLE marc_tag_structure ADD PRIMARY KEY ( frameworkcode, tagfield )'
2900 $dbh->do('ALTER TABLE marc_subfield_structure drop primary key');
2902 'ALTER TABLE marc_subfield_structure ADD PRIMARY KEY ( frameworkcode, tagfield, tagsubfield )'
2906 "alter table marc_subfield_table change tagorder tagorder int not null default '1'"
2909 # Get list of columns from marc_word table
2912 $sth = $dbh->prepare("show columns from marc_word");
2914 while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
2916 $marc_word{$column} = $type;
2917 $nullenabled{$column} = $null;
2919 if ( $marc_word{subfieldid} ) {
2921 #create field tagsubfield, copy tag+subfieldid, then drop tag and subfieldid
2922 print "Modifying marc_word (concat on tag and subfield for better perfs)\n"
2925 "ALTER TABLE `marc_word` ADD `tagsubfield` CHAR( 4 ) NOT NULL AFTER `bibid`"
2927 $dbh->do("update marc_word set tagsubfield=concat(tag,subfieldid)");
2928 $dbh->do("alter table marc_word drop tag");
2929 $dbh->do("alter table marc_word drop subfieldid");
2930 $dbh->do("create index Search_Marc on marc_word (tagsubfield,word)");
2934 # Populate tables with required data
2936 # synch table and deletedtable.
2937 foreach my $table ( ( 'borrowers', 'items', 'biblio', 'biblioitems' ) ) {
2938 my %deletedborrowers;
2939 print "synch'ing $table\n";
2940 $sth = $dbh->prepare("show columns from deleted$table");
2942 while ( my ( $column, $type, $null, $key, $default, $extra ) =
2945 $deletedborrowers{$column} = 1;
2947 $sth = $dbh->prepare("show columns from $table");
2950 while ( my ( $column, $type, $null, $key, $default, $extra ) =
2953 unless ( $deletedborrowers{$column} ) {
2954 my $newcol = "alter table deleted$table add $column $type";
2955 if ( $null eq 'YES' ) {
2956 $newcol .= " NULL ";
2959 $newcol .= " NOT NULL ";
2961 $newcol .= "default $default" if $default;
2962 $newcol .= " after $previous" if $previous;
2963 $previous = $column;
2964 print "creating column $column\n";
2970 <<<<<<< updatedatabase
2972 # fill aqbasket if it's empty and aqorder is not
2973 # => it means it has just been created & must be filled
2974 $sth = $dbh->prepare("select count(*) from aqbasket");
2976 if ( $sth->fetchrow == 0 ) {
2977 $sth = $dbh->prepare("select count(*) from aqorders");
2979 if ( $sth->fetchrow > 0 ) {
2980 print "Populating new table aqbasket\n";
2982 "IMPORTANT NOTE: error message \"Duplicate entry 'X' for key 1\" may appear. it should not be a real trouble\n";
2985 "select distinct basketno,booksellerid,authorisedby,entrydate,booksellerinvoicenumber from aqorders"
2988 my ( $basketno, $booksellerid, $authorisedby, $entrydate,
2989 $booksellerinvoicenumber );
2992 "insert into aqbasket (basketno,creationdate,booksellerid,authorisedby,booksellerinvoicenumber) values (?,?,?,?,?)"
2996 $basketno, $booksellerid,
2997 $authorisedby, $entrydate,
2998 $booksellerinvoicenumber
3004 "$basketno,$entrydate,$booksellerid,$authorisedby,$booksellerinvoicenumber\n";
3005 $sth2->execute( $basketno, $entrydate, $booksellerid, $authorisedby,
3006 $booksellerinvoicenumber );
3011 foreach my $table ( keys %tabledata ) {
3012 print "Checking for data required in table $table...\n" unless $silent;
3013 my $tablerows = $tabledata{$table};
3014 foreach my $row (@$tablerows) {
3015 my $uniquefieldrequired = $row->{uniquefieldrequired};
3016 my $uniquevalue = $row->{$uniquefieldrequired};
3017 my $forceupdate = $row->{forceupdate};
3020 "select $uniquefieldrequired from $table where $uniquefieldrequired=?"
3022 $sth->execute($uniquevalue);
3023 <<<<<<< updatedatabase
3025 foreach my $field (keys %$forceupdate) {
3026 if ($forceupdate->{$field}) {
3027 my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
3028 $sth->execute($row->{$field}, $uniquevalue);
3032 print "Adding row to $table: " unless $silent;
3036 foreach my $field ( keys %$row ) {
3037 next if $field eq 'uniquefieldrequired';
3038 next if $field eq 'forceupdate';
3039 my $value = $row->{$field};
3040 push @values, $value;
3041 print " $field => $value" unless $silent;
3042 $fieldlist .= "$field,";
3043 $placeholders .= "?,";
3045 print "\n" unless $silent;
3046 $fieldlist =~ s/,$//;
3047 $placeholders =~ s/,$//;
3050 "insert into $table ($fieldlist) values ($placeholders)");
3051 $sth->execute(@values);
3057 # check indexes and create them when needed
3059 print "Checking for index required...\n" unless $silent;
3060 foreach my $table ( keys %indexes ) {
3062 # read all indexes from $table
3064 $sth = $dbh->prepare("show index from $table");
3066 my %existingindexes;
3067 while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
3068 $existingindexes{$key_name} = 1;
3070 # read indexes to check
3071 my $tablerows = $indexes{$table};
3072 foreach my $row (@$tablerows) {
3073 my $key_name=$row->{indexname};
3074 if ($existingindexes{$key_name} eq 1) {
3075 # print "$key_name existing";
3077 print "\tCreating index $key_name in $table\n";
3079 if ($row->{indexname} eq 'PRIMARY') {
3080 $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
3082 $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
3085 print "Error $sql : $dbh->err \n" if $dbh->err;
3091 # check foreign keys and create them when needed
3093 print "Checking for foreign keys required...\n" unless $silent;
3094 foreach my $table ( keys %foreign_keys ) {
3096 # read all indexes from $table
3098 $sth = $dbh->prepare("show table status like '$table'");
3100 my $stat = $sth->fetchrow_hashref;
3101 # read indexes to check
3102 my $tablerows = $foreign_keys{$table};
3103 foreach my $row (@$tablerows) {
3104 my $foreign_table=$row->{foreigntable};
3105 if ($stat->{'Comment'} =~/$foreign_table/) {
3106 # print "$foreign_table existing\n";
3108 print "\tCreating foreign key $foreign_table in $table\n";
3109 # first, drop any orphan value in child table
3110 if ($row->{onDelete} ne "RESTRICT") {
3111 my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
3113 print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
3115 my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
3116 $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
3117 $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
3120 print "====================
3121 An error occured during :
3123 It probably means there is something wrong in your DB : a row ($table.$row->{key}) refers to a value in $row->{foreigntable}.$row->{foreignkey} that does not exist. solve the problem and run updater again (or just the previous SQL statement).
3124 You can find those values with select
3125 \t$table.* from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})
3126 ====================\n
3137 # create frameworkcode row in biblio table & fill it with marc_biblio.frameworkcode.
3140 # 1st, get how many biblio we will have to do...
3141 $sth = $dbh->prepare('select count(*) from marc_biblio');
3143 my ($totaltodo) = $sth->fetchrow;
3145 $sth = $dbh->prepare("show columns from biblio");
3148 my $bibliofwexist=0;
3149 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3150 $bibliofwexist=1 if $column eq 'frameworkcode';
3152 unless ($bibliofwexist) {
3153 print "moving biblioframework to biblio table\n";
3154 $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
3155 $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
3157 my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
3159 while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
3160 $sth_update->execute($frameworkcode,$biblionumber);
3162 print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3168 # moving MARC data from marc_subfield_table to biblioitems.marc
3170 $sth = $dbh->prepare("show columns from biblioitems");
3174 while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
3175 $marcdone=1 if ($type eq 'blob' && $column eq 'marc') ;
3177 unless ($marcdone) {
3178 print "moving MARC record to biblioitems table\n";
3179 # changing marc field type
3180 $dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` BLOB NULL DEFAULT NULL ');
3181 # adding marc xml, just for convenience
3182 $dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ');
3183 # moving data from marc_subfield_value to biblio
3184 $sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
3186 my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
3188 while (my ($bibid,$biblionumber) = $sth->fetchrow) {
3189 my $record = MARCgetbiblio($dbh,$bibid);
3190 #Force UTF-8 in record leader
3191 $record->encoding('UTF-8');
3192 print $record->as_formatted if ($biblionumber==3902);
3193 $sth_update->execute($record->as_usmarc(),$record->as_xml_record(),$biblionumber);
3195 print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
3200 foreach my $field ( keys %$forceupdate ) {
3201 if ( $forceupdate->{$field} ) {
3204 "update systempreferences set $field=? where $uniquefieldrequired=?"
3206 $sth->execute( $row->{$field}, $uniquevalue );
3211 print "Adding row to $table: " unless $silent;
3215 foreach my $field ( keys %$row ) {
3216 next if $field eq 'uniquefieldrequired';
3217 next if $field eq 'forceupdate';
3218 my $value = $row->{$field};
3219 push @values, $value;
3220 print " $field => $value" unless $silent;
3221 $fieldlist .= "$field,";
3222 $placeholders .= "?,";
3224 print "\n" unless $silent;
3225 $fieldlist =~ s/,$//;
3226 $placeholders =~ s/,$//;
3229 "insert into $table ($fieldlist) values ($placeholders)");
3230 $sth->execute(@values);
3237 # at last, remove useless fields
3238 foreach $table ( keys %uselessfields ) {
3239 my @fields = split /,/, $uselessfields{$table};
3242 foreach my $fieldtodrop (@fields) {
3243 $fieldtodrop =~ s/\t//g;
3244 $fieldtodrop =~ s/\n//g;
3246 $sth = $dbh->prepare("show columns from $table");
3248 while ( my ( $column, $type, $null, $key, $default, $extra ) =
3251 $exists = 1 if ( $column eq $fieldtodrop );
3254 print "deleting $fieldtodrop field in $table...\n" unless $silent;
3255 my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
3261 <<<<<<< updatedatabase
3263 # MOVE all tables TO UTF-8 and innoDB
3264 $sth = $dbh->prepare("show table status");
3266 while ( my $table = $sth->fetchrow_hashref ) {
3267 # if ($table->{Engine} ne 'InnoDB') {
3268 # $dbh->do("ALTER TABLE $table->{Name} TYPE = innodb");
3269 # print "moving $table->{Name} to InnoDB\n";
3271 unless ($table->{Collation} =~ /^utf8/) {
3272 $dbh->do("ALTER TABLE $table->{Name} CONVERT TO CHARACTER SET utf8");
3273 $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
3274 # FIXME : maybe a ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8 would be better, def char set seems to work fine. If any problem encountered, let's try with convert !
3275 print "moving $table->{Name} to utf8\n";
3285 # those 2 subs are a copy of Biblio.pm, version 2.2.4
3286 # they are useful only once, for moving from 2.2 to 3.0
3287 # the MARCgetbiblio & MARCgetitem subs in Biblio.pm
3288 # are still here, but uses other tables
3289 # (the ones that are filled by updatedatabase !)
3294 # Returns MARC::Record of the biblio passed in parameter.
3295 my ( $dbh, $bibid ) = @_;
3296 my $record = MARC::Record->new();
3301 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
3302 from marc_subfield_table
3303 where bibid=? order by tag,tagorder,subfieldorder
3308 "select subfieldvalue from marc_blob_subfield where blobidlink=?");
3309 $sth->execute($bibid);
3310 my $prevtagorder = 1;
3311 my $prevtag = 'XXX';
3313 my $field; # for >=10 tags
3314 my $prevvalue; # for <10 tags
3315 while ( my $row = $sth->fetchrow_hashref ) {
3317 if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
3318 $sth2->execute( $row->{'valuebloblink'} );
3319 my $row2 = $sth2->fetchrow_hashref;
3321 $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
3323 if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
3324 $previndicator .= " ";
3325 if ( $prevtag < 10 ) {
3326 if ($prevtag ne '000') {
3327 $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX"; # ignore the 1st loop
3329 $record->leader(sprintf("%24s",$prevvalue));
3333 $record->add_fields($field) unless $prevtag eq "XXX";
3336 $prevtagorder = $row->{tagorder};
3337 $prevtag = $row->{tag};
3338 $previndicator = $row->{tag_indicator};
3339 if ( $row->{tag} < 10 ) {
3340 $prevvalue = $row->{subfieldvalue};
3343 $field = MARC::Field->new(
3344 ( sprintf "%03s", $prevtag ),
3345 substr( $row->{tag_indicator} . ' ', 0, 1 ),
3346 substr( $row->{tag_indicator} . ' ', 1, 1 ),
3347 $row->{'subfieldcode'},
3348 $row->{'subfieldvalue'}
3353 if ( $row->{tag} < 10 ) {
3354 $record->add_fields( ( sprintf "%03s", $row->{tag} ),
3355 $row->{'subfieldvalue'} );
3358 $field->add_subfields( $row->{'subfieldcode'},
3359 $row->{'subfieldvalue'} );
3361 $prevtag = $row->{tag};
3362 $previndicator = $row->{tag_indicator};
3366 # the last has not been included inside the loop... do it now !
3367 if ( $prevtag ne "XXX" )
3368 { # check that we have found something. Otherwise, prevtag is still XXX and we
3369 # must return an empty record, not make MARC::Record fail because we try to
3370 # create a record with XXX as field :-(
3371 if ( $prevtag < 10 ) {
3372 $record->add_fields( $prevtag, $prevvalue );
3376 # my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
3377 $record->add_fields($field);
3385 # Returns MARC::Record of the biblio passed in parameter.
3386 my ( $dbh, $bibid, $itemnumber ) = @_;
3387 my $record = MARC::Record->new();
3389 # search MARC tagorder
3392 "select tagorder from marc_subfield_table,marc_subfield_structure where marc_subfield_table.tag=marc_subfield_structure.tagfield and marc_subfield_table.subfieldcode=marc_subfield_structure.tagsubfield and bibid=? and kohafield='items.itemnumber' and subfieldvalue=?"
3394 $sth2->execute( $bibid, $itemnumber );
3395 my ($tagorder) = $sth2->fetchrow_array();
3397 #---- TODO : the leader is missing
3400 "select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
3401 from marc_subfield_table
3402 where bibid=? and tagorder=? order by subfieldcode,subfieldorder
3407 "select subfieldvalue from marc_blob_subfield where blobidlink=?");
3408 $sth->execute( $bibid, $tagorder );
3409 while ( my $row = $sth->fetchrow_hashref ) {
3410 if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
3411 $sth2->execute( $row->{'valuebloblink'} );
3412 my $row2 = $sth2->fetchrow_hashref;
3414 $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
3416 if ( $record->field( $row->{'tag'} ) ) {
3419 #--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
3420 #--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
3421 if ( length( $row->{'tag'} ) < 3 ) {
3422 $row->{'tag'} = "0" . $row->{'tag'};
3424 $field = $record->field( $row->{'tag'} );
3427 $field->add_subfields( $row->{'subfieldcode'},
3428 $row->{'subfieldvalue'} );
3429 $record->delete_field($field);
3430 $record->add_fields($field);
3434 if ( length( $row->{'tag'} ) < 3 ) {
3435 $row->{'tag'} = "0" . $row->{'tag'};
3438 MARC::Field->new( $row->{'tag'}, " ", " ",
3439 $row->{'subfieldcode'} => $row->{'subfieldvalue'} );
3440 $record->add_fields($temp);
3451 # Revision 1.153 2006/07/04 14:36:52 toins
3452 # Head & rel_2_2 merged
3454 <<<<<<< updatedatabase
3455 # Revision 1.152 2006/06/27 09:26:37 btoumi
3456 # modify (initials,phone ) fields property in borrowers and deletedborrowers table
3458 # Revision 1.151 2006/06/22 10:33:14 btoumi
3459 # sorry i forget deletedborrowers table
3460 # modify firstname field from deletedborrowers table
3462 # Revision 1.149 2006/06/20 22:35:47 rangi
3463 # Code to allow the associated borrowers to work
3465 # Revision 1.148 2006/06/17 22:12:01 rangi
3466 # Adding id field to reviews table
3468 # Revision 1.147 2006/06/17 03:36:41 rangi
3469 # Table definition for the reviews table
3471 # Revision 1.146 2006/06/17 03:29:41 rangi
3472 # Variable to allow librarians to switch reviews on or off
3474 # Revision 1.145 2006/06/16 09:45:02 btoumi
3475 # updatedatabase.pl: add change of borrowers table to deletedborrowers table
3476 # deletemem.pl: delete use of warn function
3478 # Revision 1.144 2006/06/08 15:36:31 alaurin
3479 # Add a new system preference 'AutomaticItemReturn' :
3481 # if this prefence is switched on: the document returned in another library than homebranch, the system automaticly transfer the document to his homebranch (with notification for librarian in returns.tmpl) .
3483 # switch off : the document stay in the holdingbranch ...
3486 # - comment C4::acquisition (not using in request.pl).
3487 # - correcting date in request.pl
3488 # -add the new call of function getbranches in request.pl
3490 # Revision 1.143 2006/06/07 02:02:47 bob_lyon
3491 # merging katipo changes...
3493 # adding new preference IssuingInProcess
3495 # Revision 1.142 2006/06/06 23:42:46 bob_lyon
3496 # Merging Katipo changes...
3498 # Adding new system pref where one can still retrieve a correct reading
3499 # record history if one has moved older data from issues to oldissues table
3500 # to speed up issues speed
3502 # Revision 1.141 2006/06/01 03:18:11 rangi
3503 # Adding a new column to the statistics table
3505 # Revision 1.140 2006/05/22 22:40:45 rangi
3506 # Adding new systempreference allowing for the library to add borrowers to institutions (rest homes, parishes, schools, classes etc).
3508 # Revision 1.139 2006/05/19 19:31:29 tgarip1957
3509 # Added new fields to auth_header and auth_subfield_table to allow ZEBRA use of authorities and new MARC framework like structure.
3510 # Authority tables are modified to be compatible with new MARC frameworks. This change is part of Authority Linking & Zebra authorities. Requires change in Mysql database. It will break head unless all changes regarding this is implemented. This warning will take place on all commits regarding this
3512 # Revision 1.138 2006/05/19 16:51:44 alaurin
3513 # update database for :
3514 # - new feature ip and printer management
3515 # adding two fields in branches table (branchip,branchprinter)
3517 # - waiting date : adding one field in reserves table(waiting date) to calculate the Maximum delay to pick up a reserved document when it's available
3519 # new system preference :
3520 # - ReservesMaxPickUpDelay : Maximum delay to pick up a reserved document
3521 # TransfersMaxDaysWarning : Max delay before considering the transfer as potentialy a problem
3523 # Revision 1.137 2006/04/18 09:36:36 plg
3524 # bug fixed: typo fixed in labels and labels_conf tables creation query.
3526 # Revision 1.136 2006/04/17 21:55:33 sushi
3527 # Added 'labels' and 'labels_conf' tables, for spine lable tool.
3529 # Revision 1.100.2.46 2006/06/20 18:02:23 oleonard
3530 # Fixing two minor typos
3532 # Revision 1.100.2.45 2006/06/13 12:34:15 hdl
3533 # Adding publication date to issues arrival. So that two dates can be used.
3535 # Revision 1.100.2.44 2006/06/02 15:21:40 tipaul
3536 # moving dewey to a varchar
3538 # Revision 1.100.2.43 2006/04/27 18:07:40 oleonard
3539 # Adding two new system preferences:
3541 # 1. opacuserlogin shows/hides login-based features like reserves, private shelves, and login forms. On by default.
3542 # 2. opacbookbag shows/hides the book bag (biblio basket). On by default.
3544 # Revision 1.100.2.42 2006/04/22 13:52:12 oleonard
3545 # Adding opacheader and IntranetBiblioDefaultView system preferences
3547 # Revision 1.100.2.41 2006/04/21 08:54:55 hdl
3548 # Adding two new sysprefs :
3549 # - z3950NormalizeAuthor of type YesNo. Set this to yes if you want author field to be filled with authorities fields when importing biblio in z3950
3550 # - z3950AuthorAuthfields, free text : type in comma-separated list of fields to search for author names for AuthorNormalization.
3552 # Adding a feature on a Z3950 import.
3553 # You can now automatically fill author with person name authority contained in the biblio if sysprefs are filled.
3555 # Revision 1.100.2.40 2006/04/18 09:34:15 plg
3556 # bug fixed: typo fixed in labels and labels_conf tables creation query.
3558 # Revision 1.100.2.39 2006/04/17 21:19:52 sushi
3559 # Added labels, and label_conf tables for spine labels tool.
3561 # Revision 1.100.2.38 2006/04/05 14:58:04 kados
3562 # adding TemplateEncoding syspref: allows librarian to specify the
3563 # encoding to use on templates.
3565 # Revision 1.100.2.37 2006/04/04 13:54:10 tipaul
3566 # advancedMARCeditor systempref management
3568 # Revision 1.100.2.36 2006/03/18 22:55:26 kados
3569 # add syspref for the MARC Organization Code of the library
3571 # Revision 1.100.2.35 2006/03/08 17:50:55 kados
3572 # Modifying patronimages: now it can be used to specify the file extension
3573 # of the images (to avoid hard-codeing in templates).
3575 # Revision 1.100.2.34 2006/03/08 13:28:23 tipaul
3576 # changing the size of some new systempref to a bloc (more convenient)
3578 # Revision 1.100.2.33 2006/03/04 06:05:13 kados
3579 # New syspref: AnonSuggestions to allow an anonymous patron to make a
3580 # suggestion (requested by NPL). To enable, set to the borrowernumber
3581 # of the anonymous patron (must be created).
3583 # Revision 1.100.2.32 2006/03/03 16:20:23 kados
3584 # hopefully fixes truncated amazon.com links in syspref
3585 # ----------------------------------------------------------------------
3587 # Revision 1.100.2.31 2006/03/01 21:44:16 kados
3588 # Adds 'opacreadinghistory' syspref for turning this on/off for libraries
3589 # who are scared of their government (ie, in countries where there a
3592 # Revision 1.100.2.30 2006/03/01 15:52:13 kados
3593 # Whoops ... should have checked, that name is already used. Changed it to
3594 # opaclanguagesdisplay.
3596 # Revision 1.100.2.29 2006/03/01 15:51:28 kados
3597 # adds opaclanguages syspref, which allows turning on/off the display of
3598 # the languages pref on OPAC (default is on)
3600 # Revision 1.100.2.28 2006/03/01 15:38:53 kados
3601 # Adding patronimages syspref. Adding opaclayoutstylesheet. Some explainations
3604 # Right now there are three stylesheet sysprefs:
3606 # opacstylesheet - an external stylesheet specified by URL (replaces all other
3609 # opaccolorstylesheet - local stylesheet specified by filename
3610 # opaclayoutstylesheet - local stylesheet specified by filename
3612 # Revision 1.100.2.27 2006/02/27 15:40:32 tipaul
3613 # setting serialadditems systempreference to 0 by default : no behaviour change when upgrading Koha
3615 # Revision 1.100.2.26 2006/02/23 03:19:48 kados
3616 # Adds the 'sortbynonfiling' systempref. With this enabled, Koha will
3617 # correctly sort title searches according to the nonfiling characters
3618 # in the MARC records.
3620 # Revision 1.100.2.25 2006/02/21 20:00:13 kados
3621 # setting default value for LabelMARCView to 'standard'
3622 # ----------------------------------------------------------------------
3624 # Revision 1.100.2.24 2006/02/21 18:40:08 kados
3625 # Adding LabeledMARCView systempref to choose whether tags are displayed
3626 # in standard or economical format. Later, this can be used to display
3627 # 'strict' format with no labels for insane librarians who want that.
3629 # Revision 1.100.2.23 2006/02/07 15:33:35 hdl
3630 # Adding a new system preference : serialsadditem
3632 # Adding two functions in Biblio.pm : getitemlocation and getitemstatus (helpful to get location list and status list, status is supposed to be in relation with items.notforloan)
3634 # Adding a new function in Bull.pm : serialsitemize which take serial id and item information and creates the item
3635 # Modifying statecollection to add a new line (used for data input)
3637 # Revision 1.100.2.22 2006/02/05 21:53:54 kados
3638 # Adds database support for IntranetNav systempref -- used to add HTML
3639 # tags to left-hand navigation menu on Intranet.
3640 # ----------------------------------------------------------------------
3642 # Revision 1.100.2.21 2006/02/04 18:17:00 kados
3643 # Adds opaccolorstylesheet, intranetstylesheet, intranetcolorstylesheet
3646 # Revision 1.100.2.20 2006/02/04 05:16:40 kados
3647 # Allows putting credits at bottom of OPAC page
3649 # Revision 1.100.2.19 2006/02/04 01:44:59 kados
3650 # Adds Fully Preferences-based Amazon.com feature. See mail to koha-devel
3653 # Revision 1.100.2.18 2006/02/03 23:12:23 kados
3654 # Adds system prefs for using Amazon.com content in the OPAC
3656 # Revision 1.100.2.17 2006/02/03 20:55:16 kados
3657 # Adding a new system preference: OpacNav. Can be used to add HTML
3658 # navigation links to the left-hand navbar in the OPAC.
3660 # Revision 1.100.2.16 2005/12/30 11:13:29 tipaul
3661 # * tool to synchronise TABLE and deletedTABLE structures in updatedatabase
3664 # Revision 1.135 2006/04/15 02:37:03 tgarip1957
3665 # Marc record should be set to UTF-8 in leader.Force it.
3666 # XML should be with<record> wrappers
3668 # Revision 1.134 2006/04/14 09:37:29 tipaul
3669 # improvements from SAN Ouest Provence :
3670 # * introducing a category_type into categories. It can be A (adult), C (children), P (Professionnal), I (institution/organisation).
3671 # * each category_type has it's own forms to create members.
3672 # * the borrowers table has been heavily modified (many fields changed), to get something more logic & readable
3673 # * reintroducing guarantor/guanrantee system that is now independant from hardcoded C/A for categories
3674 # * updating templates to fit template rules
3676 # (see mail feb, 17 on koha-devel "new features for borrowers" for more details)
3678 # Revision 1.133 2006/04/13 08:36:42 plg
3679 # new: function C4::Date::get_date_format_string_for_DHTMLcalendar based on
3680 # the system preference prefered date format.
3682 # improvement: book fund list and budget list screen redesigned. Filters on
3683 # each field. Columns are not sortable yet. Using DHTML Calendar to fill date
3684 # fields instead of manual filling. Pagination system. From the book fund
3685 # list, you can reach the budget list, filtered on a book fund, or not. A
3686 # budget can be added only from book fund list screen.
3688 # bug fixed: branchcode was missing in table aqbudget.
3690 # bug fixed: when setting a branchcode to a book fund, all associated budgets
3691 # move to this branchcode.
3693 # modification: when adding/modifying budget/fund, MySQL specific "REPLACE..."
3694 # statements replaced by standard SQL compliant statement.
3696 # bug fixed: when adding/modifying a budget, if the book fund is associated to
3697 # a branch, the branch selection is disabled and set to the book fund branch.
3699 # Revision 1.132 2006/04/06 12:37:05 hdl
3700 # Bugfixing : aqbookfund needed a field.
3702 # Revision 1.131 2006/03/03 17:02:22 tipaul
3703 # commit for holidays and news management.
3704 # (some forgotten files)
3706 # Revision 1.130 2006/03/03 16:35:21 tipaul
3707 # commit for holidays and news management.
3709 # Contrib from Tümer Garip (from Turkey) :
3711 # in /tools/ the holiday.pl script let you define holidays (days where the library is closed), branch by branch. You can define 3 types of holidays :
3712 # - single day : only this day is closed
3713 # - repet weekly (like "sunday") : the day is holiday every week
3714 # - repet yearly (like "July, 4") : this day is closed every year.
3716 # You can also put exception :
3717 # - sunday is holiday, but "2006 March, 5th" the library will be open
3719 # The holidays are used for return date calculation : the return date is set to the next date where the library is open. A systempreference (useDaysMode) set ON (Calendar) or OFF (Normal) the calendar calculation.
3721 # Revision 1.129 2006/02/27 18:19:33 hdl
3722 # New table used in overduerules.pl tools page.
3724 # Revision 1.128 2006/01/25 15:16:06 tipaul
3726 # * removing useless tables
3727 # * adding useful indexes
3728 # * altering some columns definitions
3729 # * The goal being to have updater working fine for foreign keys.
3731 # For me it's done, let me know if it works for you. You can see an updated schema of the DB (with constraints) on the wiki
3733 # Revision 1.127 2006/01/24 17:57:17 tipaul
3734 # DB improvements : adding foreign keys on some tables. partial stuff done.
3736 # Revision 1.126 2006/01/06 16:39:42 tipaul
3737 # synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
3738 # Seems not to break too many things, but i'm probably wrong here.
3739 # at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
3741 # - removing useless directories (koha-html and koha-plucene)
3743 # Revision 1.125 2006/01/04 15:54:55 tipaul
3744 # utf8 is a : go for beta test in HEAD.
3745 # some explanations :
3746 # - updater/updatedatabase => will transform all tables in innoDB (not related to utf8, just to warn you) AND collate them in utf8 / utf8_general_ci. The SQL command is : ALTER TABLE tablename DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci.
3747 # - *-top.inc will show the pages in utf8
3748 # - THE HARD THING : for me, mysql-client and mysql-server were set up to communicate in iso8859-1, whatever the mysql collation ! Thus, pages were improperly shown, as datas were transmitted in iso8859-1 format ! After a full day of investigation, someone on usenet pointed "set NAMES 'utf8'" to explain that I wanted utf8. I could put this in my.cnf, but if I do that, ALL databases will "speak" in utf8, that's not what we want. Thus, I added a line in Context.pm : everytime a DB handle is opened, the communication is set to utf8.
3749 # - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
3751 # Revision 1.124 2005/10/27 12:09:05 tipaul
3752 # new features for serial module :
3753 # - the last 5 issues are now shown, and their status can be changed (but not reverted to "waited", as there can be only one "waited")
3754 # - the library can create a "distribution list". this paper contains a list of borrowers (selected from the borrower list, or manually entered), and print it for a given issue. once printed, the sheet can be put on the issue and distributed to every reader on the list (one by one).
3756 # Revision 1.123 2005/10/26 09:13:37 tipaul
3757 # big commit, still breaking things...
3759 # * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
3760 # * code cleaning (cleaning warnings from perl -w) continued
3762 # Revision 1.122 2005/09/02 14:18:38 tipaul
3763 # new feature : image for itemtypes.
3765 # * run updater/updatedatabase to create imageurl field in itemtypes.
3766 # * go to Koha >> parameters >> itemtypes >> modify (or add) an itemtype. You will see around 20 nice images to choose between (thanks to owen). If you prefer your own image, you also can type a complete url (http://www.myserver.lib/path/to/my/image.gif)
3767 # * go to OPAC, and search something. In the result list, you now have the picture instead of the text itemtype.
3769 # Revision 1.121 2005/08/24 08:49:03 hdl
3770 # Adding a note field in serial table.
3771 # This will allow librarian to mention a note on a peculiar waiting serial number.
3773 # Revision 1.120 2005/08/09 14:10:32 tipaul
3774 # 1st commit to go to zebra.
3775 # don't update your cvs if you want to have a working head...
3777 # this commit contains :
3778 # * updater/updatedatabase : get rid with marc_* tables, but DON'T remove them. As a lot of things uses them, it would not be a good idea for instance to drop them. If you really want to play, you can rename them to test head without them but being still able to reintroduce them...
3779 # * Biblio.pm : modify MARCgetbiblio to find the raw marc record in biblioitems.marc field, not from marc_subfield_table, modify MARCfindframeworkcode to find frameworkcode in biblio.frameworkcode, modify some other subs to use biblio.biblionumber & get rid of bibid.
3780 # * other files : get rid of bibid and use biblionumber instead.
3783 # * does not do anything on zebra yet.
3784 # * if you rename marc_subfield_table, you can't search anymore.
3785 # * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
3786 # * don't try to add a biblio, it would add data poorly... (don't try to delete either, it may work, but that would be a surprise ;-) )
3788 # IMPORTANT NOTE : you need MARC::XML package (http://search.cpan.org/~esummers/MARC-XML-0.7/lib/MARC/File/XML.pm), that requires a recent version of MARC::Record
3789 # Updatedatabase stores the iso2709 data in biblioitems.marc field & an xml version in biblioitems.marcxml Not sure we will keep it when releasing the stable version, but I think it's a good idea to have something readable in sql, at least for development stage.
3791 # Revision 1.119 2005/08/04 16:07:58 tipaul
3792 # Synch really broke this script...
3794 # Revision 1.118 2005/08/04 16:02:55 tipaul
3795 # oops... error in synch between 2.2 and head
3797 # Revision 1.117 2005/08/04 14:24:39 tipaul
3798 # synch'ing 2.2 and head
3800 # Revision 1.116 2005/08/04 08:55:54 tipaul
3801 # Letters / alert system, continuing...
3803 # * adding a package Letters.pm, that manages Letters & alerts.
3804 # * adding feature : it's now possible to define a "letter" for any subscription created. If a letter is defined, users in OPAC can put an alert on the subscription. When an issue is marked "arrived", all users in the alert will recieve a mail (as defined in the "letter"). This last part (= send the mail) is not yet developped. (Should be done this week)
3805 # * adding feature : it's now possible to "put to an alert" in OPAC, for any serial subscription. The alert is stored in a new table, called alert. An alert can be put only if the librarian has activated them in subscription (and they activate it just by choosing a "letter" to sent to borrowers on new issues)
3806 # * adding feature : librarian can see in borrower detail which alerts they have put, and a user can see in opac-detail which alert they have put too.
3808 # Note that the system should be generic enough to manage any type of alert.
3809 # I plan to extend it soon to virtual shelves : a borrower will be able to put an alert on a virtual shelf, to be warned when something is changed in the virtual shelf (mail being sent once a day by cron, or manually by the shelf owner. Anyway, a mail won't be sent on every change, users would be spammed by Koha ;-) )
3811 # Revision 1.115 2005/08/02 16:15:34 tipaul
3812 # adding 2 fields to letter system :
3813 # * module (acquisition, catalogue...) : it will be usefull to show the librarian only letters he may be interested by.
3814 # * title, that will be used as mail subject.
3816 # Revision 1.114 2005/07/28 15:10:13 tipaul
3817 # Introducing new "Letters" system : Letters will be used everytime you want to sent something to someone (through mail or paper). For example, sending a mail for overdues use letter that you can put as parameters. Sending a mail to a borrower when a suggestion is validated uses a letter too.
3818 # the letter table contains 3 fields :
3819 # * code => the code of the letter
3820 # * name => the complete name of the letter
3821 # * content => the complete text. It's a TEXT field type, so has no limits.
3823 # My next goal now is to work on point 2-I "serial issue alert"
3824 # With this feature, in serials, a user can subscribe the "issue alert". For every issue arrived/missing, a mail is sent to all subscribers of this list. The mail warns the user that the issue is arrive or missing. Will be in head.
3825 # (see mail on koha-devel, 2005/04/07)
3827 # The "serial issue alert" will be the 1st to use this letter system that probably needs some tweaking ;-)
3829 # Once it will be stabilised default letters (in any languages) could be added during installer to help the library begin with this new feature.
3831 # Revision 1.113 2005/07/28 08:38:41 tipaul
3832 # For instance, the return date does not rely on the borrower expiration date. A systempref will be added in Koha, to modify return date calculation schema :
3833 # * ReturnBeforeExpiry = yes => return date can't be after expiry date
3834 # * ReturnBeforeExpiry = no => return date can be after expiry date
3836 # Revision 1.112 2005/07/26 08:19:47 hdl
3837 # Adding IndependantBranches System preference variable in order to manage Branch independancy.
3839 # Revision 1.111 2005/07/25 15:35:38 tipaul
3840 # we have decided that moving to Koha 3.0 requires being already in Koha 2.2.x
3841 # So, the updatedatabase script can highly be cleaned (90% removed).
3842 # Let's play with the new Koha DB structure now ;-)