use C4::Context;
use MARC::Record;
-use MARC::File::XML;
-
+use MARC::File::XML ( BinaryEncoding => 'utf8' );
+
# FIXME - The user might be installing a new database, so can't rely
# on /etc/koha.conf anyway.
my $silent;
GetOptions(
- 's' =>\$silent
- );
+ 's' =>\$silent
+ );
my $dbh = C4::Context->dbh;
print "connected to your DB. Checking & modifying it\n" unless $silent;
$|=1; # flushes output
# Tables to add if they don't exist
my %requiretables = (
- categorytable => "(categorycode char(5) NOT NULL default '',
- description text default '',
- itemtypecodes text default '',
- PRIMARY KEY (categorycode)
- )",
- subcategorytable => "(subcategorycode char(5) NOT NULL default '',
- description text default '',
- itemtypecodes text default '',
- PRIMARY KEY (subcategorycode)
- )",
- mediatypetable => "(mediatypecode char(5) NOT NULL default '',
- description text default '',
- itemtypecodes text default '',
- PRIMARY KEY (mediatypecode)
+ action_logs => "(
+ `timestamp` TIMESTAMP NOT NULL ,
+ `user` INT( 11 ) NOT NULL ,
+ `module` TEXT default '',
+ `action` TEXT default '' ,
+ `object` INT(11) NULL ,
+ `info` TEXT default '' ,
+ PRIMARY KEY ( `timestamp` , `user` )
+ )",
+ letter => "(
+ module varchar(20) NOT NULL default '',
+ code varchar(20) NOT NULL default '',
+ name varchar(100) NOT NULL default '',
+ title varchar(200) NOT NULL default '',
+ content text,
+ PRIMARY KEY (module,code)
+ )",
+ alert =>"(
+ alertid int(11) NOT NULL auto_increment,
+ borrowernumber int(11) NOT NULL default '0',
+ type varchar(10) NOT NULL default '',
+ externalid varchar(20) NOT NULL default '',
+ PRIMARY KEY (alertid),
+ KEY borrowernumber (borrowernumber),
+ KEY type (type,externalid)
+ )",
+ opac_news => "(
+ `idnew` int(10) unsigned NOT NULL auto_increment,
+ `title` varchar(250) NOT NULL default '',
+ `new` text NOT NULL,
+ `lang` varchar(4) NOT NULL default '',
+ `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
+ PRIMARY KEY (`idnew`)
+ )",
+ repeatable_holidays => "(
+ `id` int(11) NOT NULL auto_increment,
+ `branchcode` varchar(4) NOT NULL default '',
+ `weekday` smallint(6) default NULL,
+ `day` smallint(6) default NULL,
+ `month` smallint(6) default NULL,
+ `title` varchar(50) NOT NULL default '',
+ `description` text NOT NULL,
+ PRIMARY KEY (`id`)
+ )",
+ special_holidays => "(
+ `id` int(11) NOT NULL auto_increment,
+ `branchcode` varchar(4) NOT NULL default '',
+ `day` smallint(6) NOT NULL default '0',
+ `month` smallint(6) NOT NULL default '0',
+ `year` smallint(6) NOT NULL default '0',
+ `isexception` smallint(1) NOT NULL default '1',
+ `title` varchar(50) NOT NULL default '',
+ `description` text NOT NULL,
+ PRIMARY KEY (`id`)
+ )",
+ overduerules =>"(`branchcode` varchar(255) NOT NULL default '',
+ `categorycode` char(2) NOT NULL default '',
+ `delay1` int(4) default '0',
+ `letter1` varchar(20) default NULL,
+ `debarred1` char(1) default '0',
+ `delay2` int(4) default '0',
+ `debarred2` char(1) default '0',
+ `letter2` varchar(20) default NULL,
+ `delay3` int(4) default '0',
+ `letter3` varchar(20) default NULL,
+ `debarred3` int(1) default '0',
+ PRIMARY KEY (`branchcode`,`categorycode`)
+ )",
+ cities => "(`cityid` int auto_increment,
+ `city_name` char(100) NOT NULL,
+ `city_zipcode` char(20),
+ PRIMARY KEY (`cityid`)
+ )",
+ roadtype => "(`roadtypeid` int auto_increment,
+ `road_type` char(100) NOT NULL,
+ PRIMARY KEY (`roadtypeid`)
+ )",
+
+ labels => "(
+ labelid int(11) NOT NULL auto_increment,
+ itemnumber varchar(100) NOT NULL default '',
+ timestamp timestamp(14) NOT NULL,
+ PRIMARY KEY (labelid)
+ )",
+
+ labels_conf => "(
+ id int(4) NOT NULL auto_increment,
+ barcodetype char(100) default '',
+ title tinyint(1) default '0',
+ isbn tinyint(1) default '0',
+ itemtype tinyint(1) default '0',
+ barcode tinyint(1) default '0',
+ dewey tinyint(1) default '0',
+ class tinyint(1) default '0',
+ author tinyint(1) default '0',
+ papertype char(100) default '',
+ startrow int(2) default NULL,
+ PRIMARY KEY (id)
+ )",
+ reviews => "(
+ reviewid integer NOT NULL auto_increment,
+ borrowernumber integer,
+ biblionumber integer,
+ review text,
+ approved tinyint,
+ datereviewed datetime,
+ PRIMARY KEY (reviewid)
)",
- action_logs => "(
- `timestamp` TIMESTAMP NOT NULL ,
- `user` INT( 11 ) NOT NULL ,
- `module` TEXT default '',
- `action` TEXT default '' ,
- `object` INT(11) default '' ,
- `info` TEXT default '' ,
- PRIMARY KEY ( `timestamp` , `user` )
- )",
- letter => "(
- module varchar(20) NOT NULL default '',
- code varchar(20) NOT NULL default '',
- name varchar(100) NOT NULL default '',
- title varchar(200) NOT NULL default '',
- content text,
- PRIMARY KEY (module,code)
- )",
- alert =>"(
- alertid int(11) NOT NULL auto_increment,
- borrowernumber int(11) NOT NULL default '0',
- type varchar(10) NOT NULL default '',
- externalid varchar(20) NOT NULL default '',
- PRIMARY KEY (alertid),
- KEY borrowernumber (borrowernumber),
- KEY type (type,externalid)
- )",
- overduerules =>"(`branchcode` varchar(255) NOT NULL default '',
- `categorycode` char(2) NOT NULL default '',
- `delay1` int(4) default '0',
- `letter1` varchar(20) default NULL,
- `debarred1` char(1) default '0',
- `delay2` int(4) default '0',
- `debarred2` char(1) default '0',
- `letter2` varchar(20) default NULL,
- `delay3` int(4) default '0',
- `letter3` varchar(20) default NULL,
- `debarred3` int(1) default '0',
- PRIMARY KEY (`branchcode`,`categorycode`)
- )",
+ subscriptionroutinglist=>"(
+ routingid integer NOT NULL auto_increment,
+ borrowernumber integer,
+ ranking integer,
+ subscriptionid integer,
+ PRIMARY KEY (routingid)
+ )",
+
+ notifys => "(
+ notify_id int(11) NOT NULL default '0',
+ `borrowernumber` int(11) NOT NULL default '0',
+ `itemnumber` int(11) NOT NULL default '0',
+ `notify_date` date NOT NULL default '0000-00-00',
+ `notify_send_date` date default NULL,
+ `notify_level` int(1) NOT NULL default '0',
+ `method` varchar(20) NOT NULL default ''
+ )",
+
+ charges => "(
+ `charge_id` varchar(5) NOT NULL default '',
+ `description` text NOT NULL,
+ `amount` decimal(28,6) NOT NULL default '0.000000',
+ `min` int(4) NOT NULL default '0',
+ `max` int(4) NOT NULL default '0',
+ `level` int(1) NOT NULL default '0',
+ PRIMARY KEY (`charge_id`)
+ )",
+ tags => "(
+ `entry` varchar(255) NOT NULL default '',
+ `weight` bigint(20) NOT NULL default '0',
+ PRIMARY KEY (`entry`)
+ )
+ ",
+ zebraqueue => "(
+ `id` int NOT NULL auto_increment,
+ `biblio_auth_number` int NOT NULL,
+ `operation` char(20) NOT NULL,
+ `server` char(20) NOT NULL ,
+ PRIMARY KEY (`id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci AUTO_INCREMENT=1",
+
);
my %requirefields = (
- subscription => { 'letter' => 'char(20) NULL', 'distributedto' => 'text NULL'},
- itemtypes => { 'imageurl' => 'char(200) NULL'},
+ subscription => { 'letter' => 'char(20) NULL', 'distributedto' => 'text NULL', 'firstacquidate'=>'date NOT NULL','irregularity'=>'TEXT NULL default \'\'','numberpattern'=>'TINYINT(3) NULL default 0', 'callnumber'=>'text NULL', 'hemisphere' =>'TINYINT(3) NULL default 0', 'issuesatonce'=>'TINYINT(3) NOT NULL default 1', 'branchcode' =>'varchar(12) NOT NULL default \'\'', 'manualhistory'=>'TINYINT(1) NOT NULL default 0','internalnotes'=>'LONGTEXT NULL default \'\''},
+ itemtypes => { 'imageurl' => 'char(200) NULL'},
+ aqbookfund => { 'branchcode' => 'varchar(4) NULL'},
+ aqbudget => { 'branchcode' => 'varchar(4) NULL'},
+ auth_header => { 'marc' => 'BLOB NOT NULL', 'linkid' => 'BIGINT(20) NULL'},
+ auth_subfield_structure =>{ 'hidden' => 'TINYINT(3) NOT NULL default 0', 'kohafield' => 'VARCHAR(45) NOT NULL', 'linkid' => 'TINYINT(1) NOT NULL default 0', 'isurl' => 'TINYINT(1)', 'frameworkcode'=>'VARCHAR(8) NOT NULL'},
+ marc_breeding => { 'isbn' => 'varchar(13) NOT NULL'},
+ serial =>{ 'publisheddate' => 'date', 'claimdate' => 'date', 'itemnumber'=>'text NULL','routingnotes'=>'text NULL',},
+ statistics => { 'associatedborrower' => 'integer'},
+ z3950servers =>{ "name" =>"text", "description" => "text NOT NULL",
+ "position" =>"enum('primary','secondary','') NOT NULL default 'primary'", "icon" =>"text",
+ "type" =>"enum('zed','opensearch') NOT NULL default 'zed'",
+ },
+ issues =>{ 'issuedate'=>"date NOT NULL default '0000-00-00'", },
+
# tablename => { 'field' => 'fieldtype' },
);
-my %dropable_table = (
- sessionqueries => 'sessionqueries',
- marcrecorddone => 'marcrecorddone',
- users => 'users',
- itemsprices => 'itemsprices',
- biblioanalysis => 'biblioanalysis',
- borexp => 'borexp',
-# tablename => 'tablename',
+# Enter here the table to delete.
+my @TableToDelete = qw(
+ additionalauthors
+ bibliosubject
+ bibliosubtitle
+ bibliothesaurus
);
my %uselessfields = (
# tablename => "field1,field2",
- );
+ borrowers => "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
+ deletedborrowers=> "suburb,altstreetaddress,altsuburb,altcity,studentnumber,school,area,preferredcont,altcp",
+ );
# the other hash contains other actions that can't be done elsewhere. they are done
# either BEFORE of AFTER everything else, depending on "when" entry (default => AFTER)
my %tabledata = (
# tablename => [
-# { uniquefielrequired => 'fieldname', # the primary key in the table
-# fieldname => fieldvalue,
-# fieldname2 => fieldvalue2,
-# },
+# { uniquefielrequired => 'fieldname', # the primary key in the table
+# fieldname => fieldvalue,
+# fieldname2 => fieldvalue2,
+# },
# ],
systempreferences => [
- {
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'useDaysMode',
+ value => 'Calendar',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'How to calculate return dates : Calendar means holidays will be controled, Days means the return date don\'t depend on holidays',
+ type => 'Choice',
+ options => 'Calendar|Days'
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'BorrowersTitles',
+ value => 'Mr|Mrs|Miss|Ms',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'List all Titles for borrowers',
+ type => 'free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'BorrowerMandatoryField',
+ value => 'cardnumber|surname|address',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'List all mandatory fields for borrowers',
+ type => 'free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'borrowerRelationship',
+ value => 'father|mother,grand-mother',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'The relationships between a guarantor & a guarantee (separated by | or ,)',
+ type => 'free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'ReservesMaxPickUpDelay',
+ value => '10',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Maximum delay to pick up a reserved document',
+ type => 'free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'TransfersMaxDaysWarning',
+ value => '3',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Max delay before considering the transfer has potentialy a problem',
+ type => 'free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'memberofinstitution',
+ value => '0',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Are your patrons members of institutions',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'ReadingHistory',
+ value => '0',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Allow reading record info retrievable from issues and oldissues tables',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'IssuingInProcess',
+ value => '0',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Allow no debt alert if the patron is issuing item that accumulate debt',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'AutomaticItemReturn',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'This Variable allow or not to return automaticly to his homebranch',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'reviewson',
+ value => '0',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Allows patrons to submit reviews from the opac',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'intranet_includes',
+ value => 'includes',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'The includes directory you want for specific look of Koha (includes or includes_npl for example)',
+ type => 'Free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'AutoLocation',
+ value => '0',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'switch to activate or not Autolocation, if Yes, the Librarian can\'t change his location, it\'s defined by branchip',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'serialsadditems',
+ value => '0',
+ forceupdate => {
+ 'explanation' => 1,
+ 'type' => 1
+ },
+ explanation => 'If set, a new item will be automatically added when receiving an issue',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'expandedSearchOption',
+ value => '0',
+ forceupdate => {
+ 'explanation' => 1,
+ 'type' => 1
+ },
+ explanation => 'search among marc field',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'RequestOnOpac',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'option to allow reserves on opac',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'OpacCloud',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Enable / Disable cloud link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'OpacBrowser',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Enable/Disable browser link on OPAC (Require to run misc/cronjobs/build_browser_and_cloud.pl on the server)',
+ type => 'YesNo',
+ },
+ {
uniquefieldrequired => 'variable',
- variable => 'Activate_Log',
- value => 'On',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Turn Log Actions on DB On an Off',
- type => 'YesNo',
+ variable => 'OpacTopissue',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Enable / Disable the top issue link on OPAC',
+ type => 'YesNo',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'OpacAuthorities',
+ value => '1',
+ forceupdate => { 'explanation' => 1,
+ 'type' => 1},
+ explanation => 'Enable / Disable the search authority link on OPAC',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'IndependantBranches',
- value => 0,
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Turn Branch independancy management On an Off',
- type => 'YesNo',
- },
- {
+ variable => 'CataloguingLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log cataloguing action.',
+ type => 'YesNo',
+ },
+ {
uniquefieldrequired => 'variable',
- variable => 'ReturnBeforeExpiry',
- value => 'Off',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
- type => 'YesNo',
+ variable => 'BorrowersLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log borrowers edition/creation/deletion...',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'opacstylesheet',
- value => '',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Enter a complete URL to use an alternate stylesheet in OPAC',
- type => 'free',
+ variable => 'SubscriptionLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log Subscription action',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'opacsmallimage',
- value => '',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Enter a complete URL to an image, will be on top/left instead of the Koha logo',
- type => 'free',
+ variable => 'IssueLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log issue.',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'opaclargeimage',
- value => '',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Enter a complete URL to an image, will be on the main page, instead of the Koha logo',
- type => 'free',
+ variable => 'ReturnLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log the circulation return',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'delimiter',
- value => ';',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'separator for reports exported to spreadsheet',
- type => 'free',
+ variable => 'Version',
+ value => '3.0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Koha Version',
+ type => 'Free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'LetterLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log all the letter sent',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'MIME',
- value => 'OPENOFFICE.ORG',
- forceupdate => { 'explanation' => 1,
- 'type' => 1,
- 'options' => 1},
- explanation => 'Define the default application for report exportations into files',
- type => 'Choice',
- options => 'EXCEL|OPENOFFICE.ORG'
+ variable => 'FinesLog',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want to log fines',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'Delimiter',
- value => ';',
- forceupdate => { 'explanation' => 1,
- 'type' => 1,
- 'options' => 1},
- explanation => 'Define the default separator character for report exportations into files',
- type => 'Choice',
- options => ';|tabulation|,|/|\|#'
+ variable => 'NoZebra',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => 'Active this if you want NOT to use zebra (large libraries should avoid this parameters)',
+ type => 'YesNo',
},
{
uniquefieldrequired => 'variable',
- variable => 'SubscriptionHistory',
- value => ';',
- forceupdate => { 'explanation' => 1,
- 'type' => 1,
- 'options' => 1},
- explanation => 'Define the information level for serials history in OPAC',
- type => 'Choice',
- options => 'simplified|full'
+ variable => 'NoZebraIndexes',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => "Enter a specific hash for NoZebra indexes. Enter : 'indexname' => '100a,245a,500*','index2' => '...'",
+ type => 'Free',
+ },
+ {
+ uniquefieldrequired => 'variable',
+ variable => 'uppercasesurnames',
+ value => '0',
+ forceupdate => {'explanation' => 1, 'type' => 1},
+ explanation => "Force Surnames to be uppercase",
+ type => 'YesNo',
+ },
+ ],
+ userflags => [
+ {
+ uniquefieldrequired => 'bit',
+ bit => '14',
+ flag => 'editauthorities',
+ flagdesc => 'allow to edit authorities',
+ defaulton => '0',
+ },
+ {
+ uniquefieldrequired => 'bit',
+ bit => '15',
+ flag => 'serials',
+ flagdesc => 'allow to manage serials subscriptions',
+ defaulton => '0',
+ },
+ {
+ uniquefieldrequired => 'bit',
+ bit => '16',
+ flag => 'reports',
+ flagdesc => 'allow to access to the reports module',
+ defaulton => '0',
+ },
+ ],
+ authorised_values => [
+ {
+ uniquefieldrequired => 'id',
+ category => 'SUGGEST',
+ authorised_value => 'Not enough budget',
+ lib => 'This book it too much expensive',
+ }
+ ],
+);
+
+my %fielddefinitions = (
+# fieldname => [
+# { field => 'fieldname',
+# type => 'fieldtype',
+# null => '',
+# key => '',
+# default => ''
+# },
+# ],
+ aqbasket => [
+ {
+ field => 'booksellerid',
+ type => 'int(11)',
+ null => 'NOT NULL',
+ key => '',
+ default => '1',
+ extra => '',
+ },
+ ],
+ aqbooksellers => [
+ {
+ field => 'id',
+ type => 'int(11)',
+ null => 'NOT NULL',
+ key => 'PRI',
+ default => '',
+ extra => 'auto_increment',
+ },
+ {
+ field => 'listprice',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'invoiceprice',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ ],
+
+ accountlines => [
+ {
+ field => 'notify_id',
+ type => 'int(11)',
+ null => 'NOT NULL',
+ key => '',
+ default => '0',
+ extra => '',
+ },
+ {
+ field => 'notify_level',
+ type => 'int(2)',
+ null => 'NOT NULL',
+ key => '',
+ default => '0',
+ extra => '',
+ },
+
+ ],
+
+ borrowers => [
+ { field => 'firstname',
+ type => 'text',
+ null => 'NULL',
+ },
+ { field => 'initials',
+ type => 'text',
+ null => 'NULL',
+ },
+ { field => 'B_email',
+ type => 'text',
+ null => 'NULL',
+ after => 'B_zipcode',
+ },
+ {
+ field => 'streetnumber', # street number (hidden if streettable table is empty)
+ type => 'char(10)',
+ null => 'NULL',
+ after => 'initials',
+ },
+ {
+ field => 'streettype', # street table, list builded from a system table
+ type => 'char(50)',
+ null => 'NULL',
+ after => 'streetnumber',
+ },
+ { field => 'phone',
+ type => 'text',
+ null => 'NULL',
+ },
+ {
+ field => 'B_streetnumber', # street number (hidden if streettable table is empty)
+ type => 'char(10)',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'B_streettype', # street table, list builded from a system table
+ type => 'char(50)',
+ null => 'NULL',
+ after => 'B_streetnumber',
+ },
+ {
+ field => 'phonepro',
+ type => 'text',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'address2', # complement address
+ type => 'text',
+ null => 'NULL',
+ after => 'address',
+ },
+ {
+ field => 'emailpro',
+ type => 'text',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'contactfirstname', # contact's firstname
+ type => 'text',
+ null => 'NULL',
+ after => 'contactname',
+ },
+ {
+ field => 'contacttitle', # contact's title
+ type => 'text',
+ null => 'NULL',
+ after => 'contactfirstname',
+ },
+ {
+ field => 'branchcode',
+ type => 'varchar(10)',
+ null => 'NOT NULL',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'categorycode',
+ type => 'varchar(10)',
+ null => 'NOT NULL',
+ default => '',
+ extra => '',
+ }
+ ],
+
+ biblioitems => [
+ {
+ field => 'lcsort',
+ type => 'varchar(25)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'ccode',
+ type => 'varchar(4)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'dewey',
+ type => 'varchar(30)',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'publicationyear',
+ type => 'text',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'collectiontitle',
+ type => 'mediumtext',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'collectionissn',
+ type => 'mediumtext',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'collectionvolume',
+ type => 'mediumtext',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'editionstatement',
+ type => 'text',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'editionresponsability',
+ type => 'text',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+
+ ],
+ deletedbiblioitems => [
+ {
+ field => 'dewey',
+ type => 'varchar(30)',
+ null => 'null',
+ default => '',
+ extra => '',
+ },
+ ],
+ branches => [
+ {
+ field => 'branchip',
+ type => 'varchar(15)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'branchprinter',
+ type => 'varchar(100)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'branchcode',
+ type => 'varchar(10)',
+ null => 'NOT NULL',
+ default => '',
+ extra => '',
+ }
+ ],
+ branchtransfers =>[
+ {
+ field => 'frombranch',
+ type => 'VARCHAR(10)',
+ null => 'NOT NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'tobranch',
+ type => 'VARCHAR(10)',
+ null => 'NOT NULL',
+ key => '',
+ default => '',
+ }
+ ],
+
+ categories => [
+ {
+ field => 'category_type',
+ type => 'char(1)',
+ null => 'NOT NULL',
+ key => '',
+ default => 'A',
+ extra => '',
+ },
+ {
+ field => 'categorycode',
+ type => 'varchar(10)',
+ null => 'NOT NULL',
+ key => 'PRI',
+ default => '',
+ extra => '',
+ },
+ ],
+
+ deletedborrowers => [
+ { field => 'firstname',
+ type => 'text',
+ null => 'NULL',
+ },
+ { field => 'initials',
+ type => 'text',
+ null => 'NULL',
+ },
+ { field => 'B_email',
+ type => 'text',
+ null => 'NULL',
+ after => 'B_zipcode',
+ },
+ {
+ field => 'streetnumber', # street number (hidden if streettable table is empty)
+ type => 'char(10)',
+ null => 'NULL',
+ after => 'initials',
+ },
+ {
+ field => 'streettype', # street table, list builded from a system table
+ type => 'char(50)',
+ null => 'NULL',
+ after => 'streetnumber',
+ },
+ { field => 'phone',
+ type => 'text',
+ null => 'NULL',
+ },
+ {
+ field => 'B_streetnumber', # street number (hidden if streettable table is empty)
+ type => 'char(10)',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'B_streettype', # street table, list builded from a system table
+ type => 'char(50)',
+ null => 'NULL',
+ after => 'B_streetnumber',
+ },
+ {
+ field => 'phonepro',
+ type => 'text',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'address2', # complement address
+ type => 'text',
+ null => 'NULL',
+ after => 'address',
+ },
+ {
+ field => 'emailpro',
+ type => 'text',
+ null => 'NULL',
+ after => 'fax',
+ },
+ {
+ field => 'contactfirstname', # contact's firstname
+ type => 'text',
+ null => 'NULL',
+ after => 'contactname',
+ },
+ {
+ field => 'contacttitle', # contact's title
+ type => 'text',
+ null => 'NULL',
+ after => 'contactfirstname',
+ },
+ ],
+
+ issues => [
+ {
+ field => 'borrowernumber',
+ type => 'int(11)',
+ null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'itemnumber',
+ type => 'int(11)',
+ null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'branchcode',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'issuedate',
+ type => 'date',
+ null => '',
+ key => '',
+ default => '0000-00-00',
+ extra => '',
+ },
+ ],
+
+ items => [
+ {
+ field => 'onloan',
+ type => 'date',
+ null => 'NULL',
+ key => '',
+ default => '0000-00-00',
+ extra => '',
+ },
+ {
+ field => 'cutterextra',
+ type => 'varchar(45)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'issue_date',
+ type => 'date',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'homebranch',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'holdingbranch',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'itype',
+ type => 'varchar(10)',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ ],
+ itemtypes => [
+ {
+ field => 'itemtype',
+ type => 'varchar(10)',
+ default => '',
+ null => 'NOT NULL',
+ key => 'PRI',
+ extra => 'UNIQUE',
+ },
+ {
+ field => 'summary',
+ type => 'TEXT',
+ null => 'NULL',
+ key => '',
+ extra => '',
+ },
+ ],
+ marc_breeding => [
+ {
+ field => 'marc',
+ type => 'LONGBLOB',
+ null => 'NULL',
+ key => '',
+ extra => '',
+ }
+ ],
+ marc_subfield_structure => [
+ {
+ field => 'defaultvalue',
+ type => 'TEXT',
+ null => 'NULL',
+ key => '',
+ extra => '',
+ }
+ ],
+ opac_news => [
+ {
+ field => 'expirationdate',
+ type => 'date',
+ null => 'null',
+ key => '',
+ extra => '',
+ },
+ {
+ field => 'number',
+ type => 'int(11)',
+ null => 'NULL',
+ key => '',
+ default => '0',
+ extra => '',
+ },
+ ],
+ reserves => [
+ {
+ field => 'waitingdate',
+ type => 'date',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ ],
+ serial => [
+ {
+ field => 'notes',
+ type => 'TEXT',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => ''
+ },
+ ],
+ shelfcontents => [
+ {
+ field => 'dateadded',
+ type => 'timestamp',
+ null => 'NULL',
+ },
+ ],
+ systempreferences => [
+ {
+ field => 'value',
+ type => 'text',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ {
+ field => 'explanation',
+ type => 'text',
+ null => 'NULL',
+ key => '',
+ default => '',
+ extra => '',
+ },
+ ],
+ suggestions => [
+ {
+ field => 'reason',
+ type => 'text',
+ null => 'NULL',
+ key => '' ,
+ default => '',
+ extra => '',
+ }
+ ],
+);
+
+my %indexes = (
+# table => [
+# { indexname => 'index detail'
+# }
+# ],
+ aqbooksellers => [
+ { indexname => 'PRIMARY',
+ content => 'id',
+ type => 'PRI',
+ }
+ ],
+ aqbasket => [
+ { indexname => 'booksellerid',
+ content => 'booksellerid',
+ },
+ ],
+ aqorders => [
+ { indexname => 'basketno',
+ content => 'basketno',
+ },
+ ],
+ aqorderbreakdown => [
+ { indexname => 'ordernumber',
+ content => 'ordernumber',
+ },
+ { indexname => 'bookfundid',
+ content => 'bookfundid',
+ },
+ ],
+ biblioitems => [
+ { indexname => 'isbn',
+ content => 'isbn',
+ },
+ { indexname => 'publishercode',
+ content => 'publishercode',
+ },
+ ],
+ branches => [
+ {
+ indexname => 'branchcode',
+ content => 'branchcode',
+ type => 'PRI',
+ }
+ ],
+ branchrelations => [
+ {
+ indexname => 'PRIMARY',
+ content => 'categorycode',
+ type => 'PRI',
+ }
+ ],
+ branchrelations => [
+ { indexname => 'PRIMARY',
+ content => 'branchcode,categorycode',
+ type => 'PRI',
+ },
+ { indexname => 'branchcode',
+ content => 'branchcode',
+ },
+ { indexname => 'categorycode',
+ content => 'categorycode',
+ }
+ ],
+ currency => [
+ { indexname => 'PRIMARY',
+ content => 'currency',
+ type => 'PRI',
+ }
+ ],
+ categories => [
+ {
+ indexname => 'categorycode',
+ content => 'categorycode',
+ }
+ ],
+ items => [
+ { indexname => 'homebranch',
+ content => 'homebranch',
+ },
+ { indexname => 'holdingbranch',
+ content => 'holdingbranch',
+ }
+ ],
+ itemtypes => [
+ {
+ indexname => 'itemtype',
+ content => 'itemtype',
+ }
+ ],
+ shelfcontents => [
+ { indexname => 'shelfnumber',
+ content => 'shelfnumber',
+ },
+ { indexname => 'itemnumber',
+ content => 'itemnumber',
+ }
+ ],
+ userflags => [
+ { indexname => 'PRIMARY',
+ content => 'bit',
+ type => 'PRI',
+ }
+ ]
+);
+
+my %foreign_keys = (
+# table => [
+# { key => 'the key in table' (must be indexed)
+# foreigntable => 'the foreigntable name', # (the parent)
+# foreignkey => 'the foreign key column(s)' # (in the parent)
+# onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
+# onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
+# }
+# ],
+ branchrelations => [
+ { key => 'branchcode',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'categorycode',
+ foreigntable => 'branchcategories',
+ foreignkey => 'categorycode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ shelfcontents => [
+ { key => 'shelfnumber',
+ foreigntable => 'bookshelf',
+ foreignkey => 'shelfnumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'itemnumber',
+ foreigntable => 'items',
+ foreignkey => 'itemnumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
+ # easily deleted, but branches/itemtype not too easy to empty...
+ biblioitems => [
+ { key => 'biblionumber',
+ foreigntable => 'biblio',
+ foreignkey => 'biblionumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'itemtype',
+ foreigntable => 'itemtypes',
+ foreignkey => 'itemtype',
+ onUpdate => 'CASCADE',
+ onDelete => 'RESTRICT',
+ },
+ ],
+ items => [
+ { key => 'biblioitemnumber',
+ foreigntable => 'biblioitems',
+ foreignkey => 'biblioitemnumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'homebranch',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'RESTRICT',
+ },
+ { key => 'holdingbranch',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'RESTRICT',
+ },
+ ],
+ aqbasket => [
+ { key => 'booksellerid',
+ foreigntable => 'aqbooksellers',
+ foreignkey => 'id',
+ onUpdate => 'CASCADE',
+ onDelete => 'RESTRICT',
+ },
+ ],
+ aqorders => [
+ { key => 'basketno',
+ foreigntable => 'aqbasket',
+ foreignkey => 'basketno',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'biblionumber',
+ foreigntable => 'biblio',
+ foreignkey => 'biblionumber',
+ onUpdate => 'SET NULL',
+ onDelete => 'SET NULL',
+ },
+ ],
+ aqbooksellers => [
+ { key => 'listprice',
+ foreigntable => 'currency',
+ foreignkey => 'currency',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'invoiceprice',
+ foreigntable => 'currency',
+ foreignkey => 'currency',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ aqorderbreakdown => [
+ { key => 'ordernumber',
+ foreigntable => 'aqorders',
+ foreignkey => 'ordernumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'bookfundid',
+ foreigntable => 'aqbookfund',
+ foreignkey => 'bookfundid',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ branchtransfers => [
+ { key => 'frombranch',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'tobranch',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'itemnumber',
+ foreigntable => 'items',
+ foreignkey => 'itemnumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ issuingrules => [
+ { key => 'categorycode',
+ foreigntable => 'categories',
+ foreignkey => 'categorycode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'itemtype',
+ foreigntable => 'itemtypes',
+ foreignkey => 'itemtype',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ ],
+ issues => [ # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
+ # for stat purposes
+ { key => 'borrowernumber',
+ foreigntable => 'borrowers',
+ foreignkey => 'borrowernumber',
+ onUpdate => 'SET NULL',
+ onDelete => 'SET NULL',
+ },
+ { key => 'itemnumber',
+ foreigntable => 'items',
+ foreignkey => 'itemnumber',
+ onUpdate => 'SET NULL',
+ onDelete => 'SET NULL',
+ },
+ ],
+ reserves => [
+ { key => 'borrowernumber',
+ foreigntable => 'borrowers',
+ foreignkey => 'borrowernumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'biblionumber',
+ foreigntable => 'biblio',
+ foreignkey => 'biblionumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'itemnumber',
+ foreigntable => 'items',
+ foreignkey => 'itemnumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
+ },
+ { key => 'branchcode',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'hidelostitems',
- value => 'No',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'show or hide "lost" items in OPAC.',
- type => 'YesNo',
- },
- {
- uniquefieldrequired => 'variable',
- variable => 'IndependantBranches',
- value => '0',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Turn Branch independancy management On an Off',
- type => 'YesNo',
+ ],
+ borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
+ # but prevent deleting a branch as soon as it has 1 borrower !
+ { key => 'categorycode',
+ foreigntable => 'categories',
+ foreignkey => 'categorycode',
+ onUpdate => 'RESTRICT',
+ onDelete => 'RESTRICT',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'ReturnBeforeExpiry',
- value => '0',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'If Yes, Returndate on issuing can\'t be after borrower card expiry',
- type => 'YesNo',
+ { key => 'branchcode',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'RESTRICT',
+ onDelete => 'RESTRICT',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'Disable_Dictionary',
- value => '0',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Disables Dictionary buttons if set to yes',
- type => 'YesNo',
+ ],
+ deletedborrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
+ # but prevent deleting a branch as soon as it has 1 borrower !
+ { key => 'categorycode',
+ foreigntable => 'categories',
+ foreignkey => 'categorycode',
+ onUpdate => 'RESTRICT',
+ onDelete => 'RESTRICT',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'hide_marc',
- value => '0',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'hide marc specific datas like subfield code & indicators to library',
- type => 'YesNo',
+ { key => 'branchcode',
+ foreigntable => 'branches',
+ foreignkey => 'branchcode',
+ onUpdate => 'RESTRICT',
+ onDelete => 'RESTRICT',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'NotifyBorrowerDeparture',
- value => '0',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Delay before expiry where a notice is sent when issuing',
- type => 'Integer',
+ ],
+ accountlines => [
+ { key => 'borrowernumber',
+ foreigntable => 'borrowers',
+ foreignkey => 'borrowernumber',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
},
- {
- uniquefieldrequired => 'variable',
- variable => 'OpacPasswordChange',
- value => '1',
- forceupdate => { 'explanation' => 1,
- 'type' => 1},
- explanation => 'Enable/Disable password change in OPAC (disable it when using LDAP auth)',
- type => 'YesNo',
+ { key => 'itemnumber',
+ foreigntable => 'items',
+ foreignkey => 'itemnumber',
+ onUpdate => 'SET NULL',
+ onDelete => 'SET NULL',
},
],
-
-);
-
-my %fielddefinitions = (
-# fieldname => [
-# { field => 'fieldname',
-# type => 'fieldtype',
-# null => '',
-# key => '',
-# default => ''
-# },
-# ],
- serial => [
- {
- field => 'notes',
- type => 'TEXT',
- null => 'NULL',
- key => '',
- default => '',
- extra => ''
+ auth_tag_structure => [
+ { key => 'authtypecode',
+ foreigntable => 'auth_types',
+ foreignkey => 'authtypecode',
+ onUpdate => 'CASCADE',
+ onDelete => 'CASCADE',
},
],
- aqbasket => [
- {
- field => 'booksellerid',
- type => 'int(11)',
- null => 'NOT NULL',
- key => '',
- default => '1',
- extra => '',
- },
- ],
- aqbooksellers => [
- {
- field => 'listprice',
- type => 'varchar(10)',
- null => 'NULL',
- key => '',
- default => '',
- extra => '',
- },
- {
- field => 'invoiceprice',
- type => 'varchar(10)',
- null => 'NULL',
- key => '',
- default => '',
- extra => '',
- },
- ],
- issues => [
- {
- field => 'borrowernumber',
- type => 'int(11)',
- null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
- key => '',
- default => '',
- extra => '',
- },
- {
- field => 'itemnumber',
- type => 'int(11)',
- null => 'NULL', # can be null when a borrower is deleted and the foreign key rule executed
- key => '',
- default => '',
- extra => '',
- },
- ],
+ # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
);
-my %indexes = (
-# table => [
-# { indexname => 'index detail'
-# }
-# ],
- shelfcontents => [
- { indexname => 'shelfnumber',
- content => 'shelfnumber',
- },
- { indexname => 'itemnumber',
- content => 'itemnumber',
- }
- ],
- bibliosubject => [
- { indexname => 'biblionumber',
- content => 'biblionumber',
- }
- ],
- items => [
- { indexname => 'homebranch',
- content => 'homebranch',
- },
- { indexname => 'holdingbranch',
- content => 'holdingbranch',
- }
- ],
- aqbooksellers => [
- { indexname => 'PRIMARY',
- content => 'id',
- type => 'PRIMARY',
- }
- ],
- aqbasket => [
- { indexname => 'booksellerid',
- content => 'booksellerid',
- },
- ],
- aqorders => [
- { indexname => 'basketno',
- content => 'basketno',
- },
- ],
- aqorderbreakdown => [
- { indexname => 'ordernumber',
- content => 'ordernumber',
- },
- { indexname => 'bookfundid',
- content => 'bookfundid',
- },
- ],
- currency => [
- { indexname => 'PRIMARY',
- content => 'currency',
- type => 'PRIMARY',
- }
- ],
-);
-my %foreign_keys = (
-# table => [
-# { key => 'the key in table' (must be indexed)
-# foreigntable => 'the foreigntable name', # (the parent)
-# foreignkey => 'the foreign key column(s)' # (in the parent)
-# onUpdate => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
-# onDelete => 'CASCADE|SET NULL|NO ACTION| RESTRICT',
-# }
-# ],
- shelfcontents => [
- { key => 'shelfnumber',
- foreigntable => 'bookshelf',
- foreignkey => 'shelfnumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemnumber',
- foreigntable => 'items',
- foreignkey => 'itemnumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- # onDelete is RESTRICT on reference tables (branches, itemtype) as we don't want items to be
- # easily deleted, but branches/itemtype not too easy to empty...
- biblioitems => [
- { key => 'biblionumber',
- foreigntable => 'biblio',
- foreignkey => 'biblionumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemtype',
- foreigntable => 'itemtypes',
- foreignkey => 'itemtype',
- onUpdate => 'CASCADE',
- onDelete => 'RESTRICT',
- },
- ],
- items => [
- { key => 'biblioitemnumber',
- foreigntable => 'biblioitems',
- foreignkey => 'biblioitemnumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'homebranch',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'CASCADE',
- onDelete => 'RESTRICT',
- },
- { key => 'holdingbranch',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'CASCADE',
- onDelete => 'RESTRICT',
- },
- ],
- additionalauthors => [
- { key => 'biblionumber',
- foreigntable => 'biblio',
- foreignkey => 'biblionumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- bibliosubject => [
- { key => 'biblionumber',
- foreigntable => 'biblio',
- foreignkey => 'biblionumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- aqbasket => [
- { key => 'booksellerid',
- foreigntable => 'aqbooksellers',
- foreignkey => 'id',
- onUpdate => 'CASCADE',
- onDelete => 'RESTRICT',
- },
- ],
- aqorders => [
- { key => 'basketno',
- foreigntable => 'aqbasket',
- foreignkey => 'basketno',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'biblionumber',
- foreigntable => 'biblio',
- foreignkey => 'biblionumber',
- onUpdate => 'SET NULL',
- onDelete => 'SET NULL',
- },
- ],
- aqbooksellers => [
- { key => 'listprice',
- foreigntable => 'currency',
- foreignkey => 'currency',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'invoiceprice',
- foreigntable => 'currency',
- foreignkey => 'currency',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- aqorderbreakdown => [
- { key => 'ordernumber',
- foreigntable => 'aqorders',
- foreignkey => 'ordernumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'bookfundid',
- foreigntable => 'aqbookfund',
- foreignkey => 'bookfundid',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- branchtransfers => [
- { key => 'frombranch',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'tobranch',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemnumber',
- foreigntable => 'items',
- foreignkey => 'itemnumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- issuingrules => [
- { key => 'categorycode',
- foreigntable => 'categories',
- foreignkey => 'categorycode',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemtype',
- foreigntable => 'itemtypes',
- foreignkey => 'itemtype',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- issues => [ # constraint is SET NULL : when a borrower or an item is deleted, we keep the issuing record
- # for stat purposes
- { key => 'borrowernumber',
- foreigntable => 'borrowers',
- foreignkey => 'borrowernumber',
- onUpdate => 'SET NULL',
- onDelete => 'SET NULL',
- },
- { key => 'itemnumber',
- foreigntable => 'items',
- foreignkey => 'itemnumber',
- onUpdate => 'SET NULL',
- onDelete => 'SET NULL',
- },
- ],
- reserves => [
- { key => 'borrowernumber',
- foreigntable => 'borrowers',
- foreignkey => 'borrowernumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'biblionumber',
- foreigntable => 'biblio',
- foreignkey => 'biblionumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemnumber',
- foreigntable => 'items',
- foreignkey => 'itemnumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'branchcode',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- borrowers => [ # foreign keys are RESTRICT as we don't want to delete borrowers when a branch is deleted
- # but prevent deleting a branch as soon as it has 1 borrower !
- { key => 'categorycode',
- foreigntable => 'categories',
- foreignkey => 'categorycode',
- onUpdate => 'RESTRICT',
- onDelete => 'RESTRICT',
- },
- { key => 'branchcode',
- foreigntable => 'branches',
- foreignkey => 'branchcode',
- onUpdate => 'RESTRICT',
- onDelete => 'RESTRICT',
- },
- ],
- accountlines => [
- { key => 'borrowernumber',
- foreigntable => 'borrowers',
- foreignkey => 'borrowernumber',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- { key => 'itemnumber',
- foreigntable => 'items',
- foreignkey => 'itemnumber',
- onUpdate => 'SET NULL',
- onDelete => 'SET NULL',
- },
- ],
- auth_tag_structure => [
- { key => 'authtypecode',
- foreigntable => 'auth_types',
- foreignkey => 'authtypecode',
- onUpdate => 'CASCADE',
- onDelete => 'CASCADE',
- },
- ],
- # FIXME : don't constraint auth_*_table and auth_word, as they may be replaced by zebra
-);
+# column changes
+my %column_change = (
+ # table
+ borrowers => [
+ {
+ from => 'emailaddress',
+ to => 'email',
+ after => 'city',
+ },
+ {
+ from => 'streetaddress',
+ to => 'address',
+ after => 'initials',
+ },
+ {
+ from => 'faxnumber',
+ to => 'fax',
+ after => 'phone',
+ },
+ {
+ from => 'textmessaging',
+ to => 'opacnote',
+ after => 'userid',
+ },
+ {
+ from => 'altnotes',
+ to => 'contactnote',
+ after => 'opacnote',
+ },
+ {
+ from => 'physstreet',
+ to => 'B_address',
+ after => 'fax',
+ },
+ {
+ from => 'streetcity',
+ to => 'B_city',
+ after => 'B_address',
+ },
+ {
+ from => 'phoneday',
+ to => 'mobile',
+ after => 'phone',
+ },
+ {
+ from => 'zipcode',
+ to => 'zipcode',
+ after => 'city',
+ },
+ {
+ from => 'homezipcode',
+ to => 'B_zipcode',
+ after => 'B_city',
+ },
+ {
+ from => 'altphone',
+ to => 'B_phone',
+ after => 'B_zipcode',
+ },
+ {
+ from => 'expiry',
+ to => 'dateexpiry',
+ after => 'dateenrolled',
+ },
+ {
+ from => 'guarantor',
+ to => 'guarantorid',
+ after => 'contactname',
+ },
+ {
+ from => 'altrelationship',
+ to => 'relationship',
+ after => 'borrowernotes',
+ },
+ ],
+
+ deletedborrowers => [
+ {
+ from => 'emailaddress',
+ to => 'email',
+ after => 'city',
+ },
+ {
+ from => 'streetaddress',
+ to => 'address',
+ after => 'initials',
+ },
+ {
+ from => 'faxnumber',
+ to => 'fax',
+ after => 'phone',
+ },
+ {
+ from => 'textmessaging',
+ to => 'opacnote',
+ after => 'userid',
+ },
+ {
+ from => 'altnotes',
+ to => 'contactnote',
+ after => 'opacnote',
+ },
+ {
+ from => 'physstreet',
+ to => 'B_address',
+ after => 'fax',
+ },
+ {
+ from => 'streetcity',
+ to => 'B_city',
+ after => 'B_address',
+ },
+ {
+ from => 'phoneday',
+ to => 'mobile',
+ after => 'phone',
+ },
+ {
+ from => 'zipcode',
+ to => 'zipcode',
+ after => 'city',
+ },
+ {
+ from => 'homezipcode',
+ to => 'B_zipcode',
+ after => 'B_city',
+ },
+ {
+ from => 'altphone',
+ to => 'B_phone',
+ after => 'B_zipcode',
+ },
+ {
+ from => 'expiry',
+ to => 'dateexpiry',
+ after => 'dateenrolled',
+ },
+ {
+ from => 'guarantor',
+ to => 'guarantorid',
+ after => 'contactname',
+ },
+ {
+ from => 'altrelationship',
+ to => 'relationship',
+ after => 'borrowernotes',
+ },
+ ],
+ );
+
+
+# MOVE all tables TO UTF-8 and innoDB
+$sth = $dbh->prepare("show table status");
+$sth->execute;
+while ( my $table = $sth->fetchrow_hashref ) {
+ next if $table->{Name} eq 'marc_word';
+ next if $table->{Name} eq 'marc_subfield_table';
+ next if $table->{Name} eq 'auth_word';
+ next if $table->{Name} eq 'auth_subfield_table';
+ if ($table->{Engine} ne 'InnoDB') {
+ $dbh->do("ALTER TABLE $table->{Name} TYPE = innodb");
+ print "moving $table->{Name} to InnoDB\n";
+ }
+ unless ($table->{Collation} =~ /^utf8/) {
+ print "moving $table->{Name} to utf8\n";
+ $dbh->do("ALTER TABLE $table->{Name} CONVERT TO CHARACTER SET utf8");
+ $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
+ # 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 !
+ } else {
+ }
+}
+
+
+foreach my $table (keys %column_change) {
+ $sth = $dbh->prepare("show columns from $table");
+ $sth->execute();
+ undef %types;
+ while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
+ {
+ $types{$column}->{type} ="$type";
+ $types{$column}->{null} = "$null";
+ $types{$column}->{key} = "$key";
+ $types{$column}->{default} = "$default";
+ $types{$column}->{extra} = "$extra";
+ } # while
+ my $tablerows = $column_change{$table};
+ foreach my $row ( @$tablerows ) {
+ if ($types{$row->{from}}->{type}) {
+ print "altering $table $row->{from} to $row->{to}\n";
+ # ALTER TABLE `borrowers` CHANGE `faxnumber` `fax` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
+# alter table `borrowers` change `faxnumber` `fax` type text null after phone
+ my $sql =
+ "alter table `$table` change `$row->{from}` `$row->{to}` $types{$row->{from}}->{type} ".
+ ($types{$row->{from}}->{null} eq 'YES'?" NULL":" NOT NULL").
+ ($types{$row->{from}}->{default}?" default ".$types{$row->{from}}->{default}:"").
+ "$types{$row->{from}}->{extra} after $row->{after} ";
+# print "$sql";
+ $dbh->do($sql);
+ }
+ }
+}
+
+# Enter here the field you want to delete from DB.
+# FIXME :: there is a %uselessfield before which seems doing the same things.
+my %fieldtodelete = (
+ # tablename => [fieldname1,fieldname2,...]
+
+); # %fielddelete
+
+print "removing some unused fields...\n";
+foreach my $table ( keys %fieldtodelete ) {
+ foreach my $field ( @{$fieldtodelete{$table}} ){
+ print "removing ".$field." from ".$table;
+ my $sth = $dbh->prepare("ALTER TABLE $table DROP $field");
+ $sth->execute;
+ if ( $sth->err ) {
+ print "Error : $sth->errstr \n";
+ }
+ }
+}
+
+# Enter here the line you want to remove from DB.
+my %linetodelete = (
+ # table name => where clause.
+ userflags => "bit = 8", # delete the 'reserveforself' flags
+
+); # %linetodelete
#-------------------
# Initialize
# Now add any missing tables
foreach $table ( keys %requiretables ) {
unless ( $existingtables{$table} ) {
- print "Adding $table table...\n" unless $silent;
+ print "Adding $table table...\n" unless $silent;
my $sth = $dbh->prepare("create table $table $requiretables{$table}");
$sth->execute;
if ( $sth->err ) {
} # unless exists
} # foreach
-# now drop useless tables
-foreach $table ( keys %dropable_table ) {
- if ( $existingtables{$table} ) {
- print "Dropping unused table $table\n" if $debug and not $silent;
- $dbh->do("drop table $table");
- if ( $dbh->err ) {
- print "Error : $dbh->errstr \n";
- }
- }
-}
-
#---------------------------------
# Columns
# column doesn't exist
print "Adding $column field to $table table...\n" unless $silent;
$query = "alter table $table
- add column $column " . $requirefields{$table}->{$column};
+ add column $column " . $requirefields{$table}->{$column};
print "Execute: $query\n" if $debug;
my $sti = $dbh->prepare($query);
$sti->execute;
} # foreach table
foreach $table ( keys %fielddefinitions ) {
- print "Check table $table\n" if $debug;
- $sth = $dbh->prepare("show columns from $table");
- $sth->execute();
- my $definitions;
- while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
- {
- $definitions->{$column}->{type} = $type;
- $definitions->{$column}->{null} = $null;
- $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
- $definitions->{$column}->{key} = $key;
- $definitions->{$column}->{default} = $default;
- $definitions->{$column}->{extra} = $extra;
- } # while
- my $fieldrow = $fielddefinitions{$table};
- foreach my $row (@$fieldrow) {
- my $field = $row->{field};
- my $type = $row->{type};
- my $null = $row->{null};
-# $null = 'YES' if $row->{null} eq 'NULL';
- my $key = $row->{key};
- my $default = $row->{default};
- my $null = $row->{null};
-# $default="''" unless $default;
- my $extra = $row->{extra};
- my $def = $definitions->{$field};
-
- unless ( $type eq $def->{type}
- && $null eq $def->{null}
- && $key eq $def->{key}
- && $extra eq $def->{extra} )
- {
- if ( $null eq '' ) {
- $null = 'NOT NULL';
- }
- if ( $key eq 'PRI' ) {
- $key = 'PRIMARY KEY';
- }
- unless ( $extra eq 'auto_increment' ) {
- $extra = '';
- }
-
- # if it's a new column use "add", if it's an old one, use "change".
- my $action;
- if ($definitions->{$field}->{type}) {
- $action="change $field"
- } else {
- $action="add";
- }
+ print "Check table $table\n" if $debug;
+ $sth = $dbh->prepare("show columns from $table");
+ $sth->execute();
+ my $definitions;
+ while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
+ {
+ $definitions->{$column}->{type} = $type;
+ $definitions->{$column}->{null} = $null;
+ $definitions->{$column}->{null} = 'NULL' if $null eq 'YES';
+ $definitions->{$column}->{key} = $key;
+ $definitions->{$column}->{default} = $default;
+ $definitions->{$column}->{extra} = $extra;
+ } # while
+ my $fieldrow = $fielddefinitions{$table};
+ foreach my $row (@$fieldrow) {
+ my $field = $row->{field};
+ my $type = $row->{type};
+ my $null = $row->{null};
+# $null = 'YES' if $row->{null} eq 'NULL';
+ my $key = $row->{key};
+ my $default = $row->{default};
+# $default="''" unless $default;
+ my $extra = $row->{extra};
+ my $def = $definitions->{$field};
+ my $after = ($row->{after}?" after ".$row->{after}:"");
+
+ unless ( $type eq $def->{type}
+ && $null eq $def->{null}
+ && $key eq $def->{key}
+ && $extra eq $def->{extra} )
+ {
+ if ( $null eq '' ) {
+ $null = 'NOT NULL';
+ }
+ if ( $key eq 'PRI' ) {
+ $key = 'PRIMARY KEY';
+ }
+ unless ( $extra eq 'auto_increment' ) {
+ $extra = '';
+ }
+
+ # if it's a new column use "add", if it's an old one, use "change".
+ my $action;
+ if ($definitions->{$field}->{type}) {
+ $action="change $field"
+ } else {
+ $action="add";
+ }
# if it's a primary key, drop the previous pk, before altering the table
- my $sth;
- if ($key ne 'PRIMARY KEY') {
- $sth =$dbh->prepare("alter table $table $action $field $type $null $key $extra default ?");
- } else {
- $sth =$dbh->prepare("alter table $table drop primary key, $action $field $type $null $key $extra default ?");
- }
- $sth->execute($default);
- print " Alter $field in $table\n" unless $silent;
- }
- }
+ print " alter or create $field in $table\n" unless $silent;
+ my $query;
+ if ($key ne 'PRIMARY KEY') {
+# warn "alter table $table $action $field $type $null $key $extra default $default $after";
+ $query = "alter table $table $action $field $type $null $key $extra ".($default?"default ".$dbh->quote($default):"")." $after";
+ } else {
+# warn "alter table $table drop primary key, $action $field $type $null $key $extra default $default $after";
+ # something strange : for indexes UNIQUE, they are reported as primary key here.
+ # but if you try to run with drop primary key, it fails.
+ # thus, we run the query twice, one will fail, one will succeed.
+ # strange...
+ $query="alter table $table drop primary key, $action $field $type $null $key $extra ".($default?"default ".$dbh->quote($default):"")." $after";
+ $query="alter table $table $action $field $type $null $key $extra ".($default?"default ".$dbh->quote($default):"")." $after";
+ }
+ $dbh->do($query);
+ }
+ }
}
+print "removing some unused data...\n";
+foreach my $table ( keys %linetodelete ) {
+ foreach my $where ( @{linetodelete{$table}} ){
+ print "DELETE FROM ".$table." where ".$where;
+ print "\n";
+ my $sth = $dbh->prepare("DELETE FROM $table where $where");
+ $sth->execute;
+ if ( $sth->err ) {
+ print "Error : $sth->errstr \n";
+ }
+ }
+}
# Populate tables with required data
-
# synch table and deletedtable.
foreach my $table (('borrowers','items','biblio','biblioitems')) {
- my %deletedborrowers;
- print "synch'ing $table\n";
- $sth = $dbh->prepare("show columns from deleted$table");
- $sth->execute;
- while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
- $deletedborrowers{$column}=1;
- }
- $sth = $dbh->prepare("show columns from $table");
- $sth->execute;
- my $previous;
- while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
- unless ($deletedborrowers{$column}) {
- my $newcol="alter table deleted$table add $column $type";
- if ($null eq 'YES') {
- $newcol .= " NULL ";
- } else {
- $newcol .= " NOT NULL ";
- }
- $newcol .= "default $default" if $default;
- $newcol .= " after $previous" if $previous;
- $previous=$column;
- print "creating column $column\n";
- $dbh->do($newcol);
- }
- }
+ my %deletedborrowers;
+ print "synch'ing $table and deleted$table\n";
+ $sth = $dbh->prepare("show columns from deleted$table");
+ $sth->execute;
+ while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
+ $deletedborrowers{$column}=1;
+ }
+ $sth = $dbh->prepare("show columns from $table");
+ $sth->execute;
+ my $previous;
+ while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ) {
+ unless ($deletedborrowers{$column}) {
+ my $newcol="alter table deleted$table add $column $type";
+ if ($null eq 'YES') {
+ $newcol .= " NULL ";
+ } else {
+ $newcol .= " NOT NULL ";
+ }
+ $newcol .= "default ".$dbh->quote($default) if $default;
+ $newcol .= " after $previous" if $previous;
+ $previous=$column;
+ print "creating column $column\n";
+ $dbh->do($newcol);
+ }
+ }
+}
+#
+# update publisheddate
+#
+$sth = $dbh->prepare("select count(*) from serial where publisheddate is NULL");
+$sth->execute;
+my ($emptypublished) = $sth->fetchrow;
+if ($emptypublished) {
+ print "Updating publisheddate\n";
+ $dbh->do("update serial set publisheddate=planneddate where publisheddate is NULL");
}
-
foreach my $table ( keys %tabledata ) {
print "Checking for data required in table $table...\n" unless $silent;
my $tablerows = $tabledata{$table};
"select $uniquefieldrequired from $table where $uniquefieldrequired=?"
);
$sth->execute($uniquevalue);
- if ($sth->rows) {
- foreach my $field (keys %$forceupdate) {
- if ($forceupdate->{$field}) {
- my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
- $sth->execute($row->{$field}, $uniquevalue);
- }
- }
- } else {
- print "Adding row to $table: " unless $silent;
- my @values;
- my $fieldlist;
- my $placeholders;
- foreach my $field ( keys %$row ) {
- next if $field eq 'uniquefieldrequired';
- next if $field eq 'forceupdate';
- my $value = $row->{$field};
- push @values, $value;
- print " $field => $value" unless $silent;
- $fieldlist .= "$field,";
- $placeholders .= "?,";
- }
- print "\n" unless $silent;
- $fieldlist =~ s/,$//;
- $placeholders =~ s/,$//;
- my $sth =
- $dbh->prepare(
- "insert into $table ($fieldlist) values ($placeholders)");
- $sth->execute(@values);
- }
- }
+ if ($sth->rows) {
+ foreach my $field (keys %$forceupdate) {
+ if ($forceupdate->{$field}) {
+ my $sth=$dbh->prepare("update systempreferences set $field=? where $uniquefieldrequired=?");
+ $sth->execute($row->{$field}, $uniquevalue);
+ }
+ }
+ } else {
+ print "Adding row to $table: " unless $silent;
+ my @values;
+ my $fieldlist;
+ my $placeholders;
+ foreach my $field ( keys %$row ) {
+ next if $field eq 'uniquefieldrequired';
+ next if $field eq 'forceupdate';
+ my $value = $row->{$field};
+ push @values, $value;
+ print " $field => $value" unless $silent;
+ $fieldlist .= "$field,";
+ $placeholders .= "?,";
+ }
+ print "\n" unless $silent;
+ $fieldlist =~ s/,$//;
+ $placeholders =~ s/,$//;
+ print "insert into $table ($fieldlist) values ($placeholders)";
+ my $sth =
+ $dbh->prepare(
+ "insert into $table ($fieldlist) values ($placeholders)");
+ $sth->execute(@values);
+ }
+ }
}
#
#
print "Checking for index required...\n" unless $silent;
foreach my $table ( keys %indexes ) {
- #
- # read all indexes from $table
- #
- $sth = $dbh->prepare("show index from $table");
- $sth->execute;
- my %existingindexes;
- while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
- $existingindexes{$key_name} = 1;
- }
- # read indexes to check
- my $tablerows = $indexes{$table};
- foreach my $row (@$tablerows) {
- my $key_name=$row->{indexname};
- if ($existingindexes{$key_name} eq 1) {
-# print "$key_name existing";
- } else {
- print "Creating $key_name in $table\n";
- my $sql;
- if ($row->{indexname} eq 'PRIMARY') {
- $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
- } else {
- $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
- }
- $dbh->do($sql);
+ #
+ # read all indexes from $table
+ #
+ $sth = $dbh->prepare("show index from $table");
+ $sth->execute;
+ my %existingindexes;
+ while ( my ( $table, $non_unique, $key_name, $Seq_in_index, $Column_name, $Collation, $cardinality, $sub_part, $Packed, $comment ) = $sth->fetchrow ) {
+ $existingindexes{$key_name} = 1;
+ }
+ # read indexes to check
+ my $tablerows = $indexes{$table};
+ foreach my $row (@$tablerows) {
+ my $key_name=$row->{indexname};
+ if ($existingindexes{$key_name} eq 1) {
+# print "$key_name existing";
+ } else {
+ print "\tCreating index $key_name in $table\n";
+ my $sql;
+ if ($row->{indexname} eq 'PRIMARY') {
+ $sql = "alter table $table ADD PRIMARY KEY ($row->{content})";
+ } else {
+ $sql = "alter table $table ADD INDEX $key_name ($row->{content}) $row->{type}";
+ }
+ $dbh->do($sql);
print "Error $sql : $dbh->err \n" if $dbh->err;
- }
- }
+ }
+ }
}
#
#
print "Checking for foreign keys required...\n" unless $silent;
foreach my $table ( keys %foreign_keys ) {
- #
- # read all indexes from $table
- #
- $sth = $dbh->prepare("show table status like '$table'");
- $sth->execute;
- my $stat = $sth->fetchrow_hashref;
- # read indexes to check
- my $tablerows = $foreign_keys{$table};
- foreach my $row (@$tablerows) {
- my $foreign_table=$row->{foreigntable};
- if ($stat->{'Comment'} =~/$foreign_table/) {
-# print "$foreign_table existing\n";
- } else {
- print "Creating $foreign_table in $table\n";
- # first, drop any orphan value in child table
- if ($row->{onDelete} ne "RESTRICT") {
- my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
- $dbh->do($sql);
- print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
- }
- my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
- $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
- $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
- $dbh->do($sql);
- if ($dbh->err) {
- print "====================
+ #
+ # read all indexes from $table
+ #
+ $sth = $dbh->prepare("show table status like '$table'");
+ $sth->execute;
+ my $stat = $sth->fetchrow_hashref;
+ # read indexes to check
+ my $tablerows = $foreign_keys{$table};
+ foreach my $row (@$tablerows) {
+ my $foreign_table=$row->{foreigntable};
+ if ($stat->{'Comment'} =~/$foreign_table/) {
+# print "$foreign_table existing\n";
+ } else {
+ print "\tCreating foreign key $foreign_table in $table\n";
+ # first, drop any orphan value in child table
+ if ($row->{onDelete} ne "RESTRICT") {
+ my $sql = "delete from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})";
+ $dbh->do($sql);
+ print "SQL ERROR: $sql : $dbh->err \n" if $dbh->err;
+ }
+ my $sql="alter table $table ADD FOREIGN KEY $row->{key} ($row->{key}) REFERENCES $row->{foreigntable} ($row->{foreignkey})";
+ $sql .= " on update ".$row->{onUpdate} if $row->{onUpdate};
+ $sql .= " on delete ".$row->{onDelete} if $row->{onDelete};
+ $dbh->do($sql);
+ if ($dbh->err) {
+ print "====================
An error occured during :
\t$sql
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).
\t$table.* from $table where $row->{key} not in (select $row->{foreignkey} from $row->{foreigntable})
====================\n
";
- }
- }
- }
+ }
+ }
+ }
+}
+# now drop useless tables
+foreach $table ( @TableToDelete ) {
+ if ( $existingtables{$table} ) {
+ print "Dropping unused table $table\n" if $debug and not $silent;
+ $dbh->do("drop table $table");
+ if ( $dbh->err ) {
+ print "Error : $dbh->errstr \n";
+ }
+ }
}
#
my $definitions;
my $bibliofwexist=0;
while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
- $bibliofwexist=1 if $column eq 'frameworkcode';
+ $bibliofwexist=1 if $column eq 'frameworkcode';
}
unless ($bibliofwexist) {
- print "moving biblioframework to biblio table\n";
- $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
- $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
- $sth->execute;
- my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
- my $totaldone=0;
- while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
- $sth_update->execute($frameworkcode,$biblionumber);
- $totaldone++;
- print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
- }
- print "\rdone\n";
-}
-
-#
-# moving MARC data from marc_subfield_table to biblioitems.marc
-#
-$sth = $dbh->prepare("show columns from biblioitems");
-$sth->execute();
-my $definitions;
-my $marcdone=0;
-while ( ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow ){
- $marcdone=1 if ($type eq 'blob' && $column eq 'marc') ;
-}
-unless ($marcdone) {
- print "moving MARC record to biblioitems table\n";
- # changing marc field type
- $dbh->do('ALTER TABLE `biblioitems` CHANGE `marc` `marc` BLOB NULL DEFAULT NULL ');
- # adding marc xml, just for convenience
- $dbh->do('ALTER TABLE `biblioitems` ADD `marcxml` TEXT NOT NULL');
- # moving data from marc_subfield_value to biblio
- $sth = $dbh->prepare('select bibid,biblionumber from marc_biblio');
- $sth->execute;
- my $sth_update = $dbh->prepare('update biblioitems set marc=?, marcxml=? where biblionumber=?');
- my $totaldone=0;
- while (my ($bibid,$biblionumber) = $sth->fetchrow) {
- my $record = MARCgetbiblio($dbh,$bibid);
- $sth_update->execute($record->as_usmarc(),$record->as_xml(),$biblionumber);
- $totaldone++;
- print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
- }
- print "\rdone\n";
-}
-
-# MOVE all tables TO UTF-8 and innoDB
-$sth = $dbh->prepare("show table status");
-$sth->execute;
-while ( my $table = $sth->fetchrow_hashref ) {
- if ($table->{Engine} ne 'InnoDB') {
- $dbh->do("ALTER TABLE $table->{Name} TYPE = innodb");
- print "moving $table->{Name} to InnoDB\n";
- }
- unless ($table->{Collation} =~ /^utf8/) {
- $dbh->do("ALTER TABLE $table->{Name} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci");
- # 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 !
- print "moving $table->{Name} to utf8\n";
- } else {
- }
+ print "moving biblioframework to biblio table\n";
+ $dbh->do('ALTER TABLE `biblio` ADD `frameworkcode` VARCHAR( 4 ) NOT NULL AFTER `biblionumber`');
+ $sth = $dbh->prepare('select biblionumber,frameworkcode from marc_biblio');
+ $sth->execute;
+ my $sth_update = $dbh->prepare('update biblio set frameworkcode=? where biblionumber=?');
+ my $totaldone=0;
+ while (my ($biblionumber,$frameworkcode) = $sth->fetchrow) {
+ $sth_update->execute($frameworkcode,$biblionumber);
+ $totaldone++;
+ print "\r$totaldone / $totaltodo" unless ($totaldone % 100);
+ }
+ print "\rdone\n";
}
# at last, remove useless fields
foreach $table ( keys %uselessfields ) {
- my @fields = split /,/,$uselessfields{$table};
- my $fields;
- my $exists;
- foreach my $fieldtodrop (@fields) {
- $fieldtodrop =~ s/\t//g;
- $fieldtodrop =~ s/\n//g;
- $exists =0;
- $sth = $dbh->prepare("show columns from $table");
- $sth->execute;
- while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
- {
- $exists =1 if ($column eq $fieldtodrop);
- }
- if ($exists) {
- print "deleting $fieldtodrop field in $table...\n" unless $silent;
- my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
- $sth->execute;
- }
- }
-} # foreach
-
-
-$sth->finish;
-
-#
-# those 2 subs are a copy of Biblio.pm, version 2.2.4
-# they are useful only once, for moving from 2.2 to 3.0
-# the MARCgetbiblio & MARCgetitem subs in Biblio.pm
-# are still here, but uses other tables
-# (the ones that are filled by updatedatabase !)
-#
-sub MARCgetbiblio {
-
- # Returns MARC::Record of the biblio passed in parameter.
- my ( $dbh, $bibid ) = @_;
- my $record = MARC::Record->new();
-# warn "". $bidid;
-
- my $sth =
- $dbh->prepare(
-"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
- from marc_subfield_table
- where bibid=? order by tag,tagorder,subfieldorder
- "
- );
- my $sth2 =
- $dbh->prepare(
- "select subfieldvalue from marc_blob_subfield where blobidlink=?");
- $sth->execute($bibid);
- my $prevtagorder = 1;
- my $prevtag = 'XXX';
- my $previndicator;
- my $field; # for >=10 tags
- my $prevvalue; # for <10 tags
- while ( my $row = $sth->fetchrow_hashref ) {
-
- if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
- $sth2->execute( $row->{'valuebloblink'} );
- my $row2 = $sth2->fetchrow_hashref;
- $sth2->finish;
- $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
- }
- if ( $row->{tagorder} ne $prevtagorder || $row->{tag} ne $prevtag ) {
- $previndicator .= " ";
- if ( $prevtag < 10 ) {
- if ($prevtag ne '000') {
- $record->add_fields( ( sprintf "%03s", $prevtag ), $prevvalue ) unless $prevtag eq "XXX"; # ignore the 1st loop
- } else {
- $record->leader(sprintf("%24s",$prevvalue));
- }
- }
- else {
- $record->add_fields($field) unless $prevtag eq "XXX";
- }
- undef $field;
- $prevtagorder = $row->{tagorder};
- $prevtag = $row->{tag};
- $previndicator = $row->{tag_indicator};
- if ( $row->{tag} < 10 ) {
- $prevvalue = $row->{subfieldvalue};
- }
- else {
- $field = MARC::Field->new(
- ( sprintf "%03s", $prevtag ),
- substr( $row->{tag_indicator} . ' ', 0, 1 ),
- substr( $row->{tag_indicator} . ' ', 1, 1 ),
- $row->{'subfieldcode'},
- $row->{'subfieldvalue'}
- );
- }
- }
- else {
- if ( $row->{tag} < 10 ) {
- $record->add_fields( ( sprintf "%03s", $row->{tag} ),
- $row->{'subfieldvalue'} );
- }
- else {
- $field->add_subfields( $row->{'subfieldcode'},
- $row->{'subfieldvalue'} );
- }
- $prevtag = $row->{tag};
- $previndicator = $row->{tag_indicator};
- }
- }
-
- # the last has not been included inside the loop... do it now !
- if ( $prevtag ne "XXX" )
- { # check that we have found something. Otherwise, prevtag is still XXX and we
- # must return an empty record, not make MARC::Record fail because we try to
- # create a record with XXX as field :-(
- if ( $prevtag < 10 ) {
- $record->add_fields( $prevtag, $prevvalue );
+ my @fields = split /,/,$uselessfields{$table};
+ my $fields;
+ my $exists;
+ foreach my $fieldtodrop (@fields) {
+ $fieldtodrop =~ s/\t//g;
+ $fieldtodrop =~ s/\n//g;
+ $exists =0;
+ $sth = $dbh->prepare("show columns from $table");
+ $sth->execute;
+ while ( my ( $column, $type, $null, $key, $default, $extra ) = $sth->fetchrow )
+ {
+ $exists =1 if ($column eq $fieldtodrop);
}
- else {
-
- # my $field = MARC::Field->new( $prevtag, "", "", %subfieldlist);
- $record->add_fields($field);
+ if ($exists) {
+ print "deleting $fieldtodrop field in $table...\n" unless $silent;
+ my $sth = $dbh->prepare("alter table $table drop $fieldtodrop");
+ $sth->execute;
}
}
- return $record;
-}
-
-sub MARCgetitem {
-
- # Returns MARC::Record of the biblio passed in parameter.
- my ( $dbh, $bibid, $itemnumber ) = @_;
- my $record = MARC::Record->new();
-
- # search MARC tagorder
- my $sth2 =
- $dbh->prepare(
-"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=?"
- );
- $sth2->execute( $bibid, $itemnumber );
- my ($tagorder) = $sth2->fetchrow_array();
-
- #---- TODO : the leader is missing
- my $sth =
- $dbh->prepare(
-"select bibid,subfieldid,tag,tagorder,tag_indicator,subfieldcode,subfieldorder,subfieldvalue,valuebloblink
- from marc_subfield_table
- where bibid=? and tagorder=? order by subfieldcode,subfieldorder
- "
- );
- $sth2 =
- $dbh->prepare(
- "select subfieldvalue from marc_blob_subfield where blobidlink=?");
- $sth->execute( $bibid, $tagorder );
- while ( my $row = $sth->fetchrow_hashref ) {
- if ( $row->{'valuebloblink'} ) { #---- search blob if there is one
- $sth2->execute( $row->{'valuebloblink'} );
- my $row2 = $sth2->fetchrow_hashref;
- $sth2->finish;
- $row->{'subfieldvalue'} = $row2->{'subfieldvalue'};
- }
- if ( $record->field( $row->{'tag'} ) ) {
- my $field;
-
-#--- this test must stay as this, because of strange behaviour of mySQL/Perl DBI with char var containing a number...
- #--- sometimes, eliminates 0 at beginning, sometimes no ;-\\\
- if ( length( $row->{'tag'} ) < 3 ) {
- $row->{'tag'} = "0" . $row->{'tag'};
- }
- $field = $record->field( $row->{'tag'} );
- if ($field) {
- my $x =
- $field->add_subfields( $row->{'subfieldcode'},
- $row->{'subfieldvalue'} );
- $record->delete_field($field);
- $record->add_fields($field);
- }
- }
- else {
- if ( length( $row->{'tag'} ) < 3 ) {
- $row->{'tag'} = "0" . $row->{'tag'};
- }
- my $temp =
- MARC::Field->new( $row->{'tag'}, " ", " ",
- $row->{'subfieldcode'} => $row->{'subfieldvalue'} );
- $record->add_fields($temp);
- }
+} # foreach
- }
- return $record;
-}
+#
+# Changing aqbookfund's primary key
+#
+$sth=$dbh->prepare("ALTER TABLE `aqbookfund` DROP PRIMARY KEY , ADD PRIMARY KEY ( `bookfundid` , `branchcode` ) ;");
+$sth->execute;
+$sth->finish;
exit;
# $Log$
-# Revision 1.129 2006/02/27 18:19:33 hdl
-# New table used in overduerules.pl tools page.
+# Revision 1.172 2007/07/19 10:21:22 hdl
+# Adding some new fields to biblioitems:
+# collectiontitle
+# collectionissn
+# collectionvolume
+#
+#
+# Changing publicationyear to text.
+#
+# Revision 1.171 2007/07/02 02:30:16 rangi
+# Fix for bug 1296, making surnames uppercase a systems preference
+#
+# Revision 1.170 2007/06/26 13:25:37 tipaul
+# removing some useless tables from updatedatabase
+#
+# Revision 1.169 2007/06/26 09:23:26 tipaul
+# improving OpacBrowser systempref explanation
+#
+# Revision 1.168 2007/06/25 15:02:31 tipaul
+# missing field declaration
+#
+# Revision 1.167 2007/06/15 13:09:08 toins
+# bugfix : bibliotitems.dewey & deletedbiblioitems.dewey mustn't be double(8,6).
+#
+# Revision 1.166 2007/06/08 09:40:12 toins
+# bug fix : items.homebranch must be VARCHAR(10)
+#
+# Revision 1.165 2007/05/23 16:33:10 tipaul
+# skip move to innoDB for the 4 22 tables, that are used to store MARC records, are useless in Koha 3.0 The process is very very long, so the updatedatabase should speed up a lot (by long I mean 1 hour on my Dual core with SCSI disk, for a 50 000 biblios long table
#
-# Revision 1.128 2006/01/25 15:16:06 tipaul
-# updating DB :
-# * removing useless tables
-# * adding useful indexes
-# * altering some columns definitions
-# * The goal being to have updater working fine for foreign keys.
+# Revision 1.164 2007/05/04 16:24:09 tipaul
+# various bugfixes on parameters modules + adding default NoZebraIndexes systempreference if it's empty
#
-# 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
+# Revision 1.163 2007/05/02 16:44:31 tipaul
+# NoZebra SQL index management :
+# * adding 3 subs in Biblio.pm
+# - GetNoZebraIndexes, that get the index structure in a new systempreference (added with this commit)
+# - _DelBiblioNoZebra, that retrieve all index entries for a biblio and remove in a variable the biblio reference
+# - _AddBiblioNoZebra, that add index entries for a biblio.
+# Note that the 2 _Add and _Del subs work only in a hash variable, to speed up things in case of a modif (ie : delete+add). The effective SQL update is done in the ModZebra sub (that existed before, and dealed with zebra index).
+# I think the code has to be more deeply tested, but it works at least partially.
#
-# Revision 1.127 2006/01/24 17:57:17 tipaul
-# DB improvements : adding foreign keys on some tables. partial stuff done.
+# Revision 1.162 2007/04/30 16:16:50 tipaul
+# bugfix for updatedatabase : when there is no default value (NULL fields) + removing bibliothesaurus table+adding NoZebra systempref (False by default)
#
-# Revision 1.126 2006/01/06 16:39:42 tipaul
-# synch'ing head and rel_2_2 (from 2.2.5, including npl templates)
-# Seems not to break too many things, but i'm probably wrong here.
-# at least, new features/bugfixes from 2.2.5 are here (tested on some features on my head local copy)
+# Revision 1.161 2007/04/13 16:27:55 hdl
+# Adding Version variable to systempreferences.
#
-# - removing useless directories (koha-html and koha-plucene)
+# Revision 1.160 2007/03/19 18:35:13 toins
+# - adding default value in marc_subfield_structure.
+# - now marc_subfields_structure displays subfields in tab view.
#
-# Revision 1.125 2006/01/04 15:54:55 tipaul
-# utf8 is a : go for beta test in HEAD.
-# some explanations :
-# - 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.
-# - *-top.inc will show the pages in utf8
-# - 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.
-# - using marcxml field and no more the iso2709 raw marc biblioitems.marc field.
+# Revision 1.159 2007/03/16 01:25:09 kados
+# Using my precrash CVS copy I did the following:
#
-# Revision 1.124 2005/10/27 12:09:05 tipaul
-# new features for serial module :
-# - 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")
-# - 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).
+# cvs -z3 -d:ext:kados@cvs.savannah.nongnu.org:/sources/koha co -P koha
+# find koha.precrash -type d -name "CVS" -exec rm -v {} \;
+# cp -r koha.precrash/* koha/
+# cd koha/
+# cvs commit
#
-# Revision 1.123 2005/10/26 09:13:37 tipaul
-# big commit, still breaking things...
+# This should in theory put us right back where we were before the crash
#
-# * synch with rel_2_2. Probably the last non manual synch, as rel_2_2 should not be modified deeply.
-# * code cleaning (cleaning warnings from perl -w) continued
+# Revision 1.159 2007/03/12 17:52:30 rych
+# add pri key to userflags
#
-# Revision 1.122 2005/09/02 14:18:38 tipaul
-# new feature : image for itemtypes.
+# Revision 1.158 2007/03/09 15:14:57 tipaul
+# rel_3_0 moved to HEAD
#
-# * run updater/updatedatabase to create imageurl field in itemtypes.
-# * 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)
-# * go to OPAC, and search something. In the result list, you now have the picture instead of the text itemtype.
+# Revision 1.157.2.56 2007/01/31 16:22:54 btoumi
+# -add possibility to use isbn with length of 13 characters
+# for Import datas in the reservoir.
+# -modify isbn field in marc_breeding table (varchar 13)
+# -add isbn filter (no - )when u read a notice from reservoir
+# -add filter to have right field 100
#
-# Revision 1.121 2005/08/24 08:49:03 hdl
-# Adding a note field in serial table.
-# This will allow librarian to mention a note on a peculiar waiting serial number.
+# Revision 1.157.2.55 2007/01/30 10:50:19 tipaul
+# adding 2 usefull indexes to biblioitems table
#
-# Revision 1.120 2005/08/09 14:10:32 tipaul
-# 1st commit to go to zebra.
-# don't update your cvs if you want to have a working head...
+# Revision 1.157.2.54 2007/01/29 16:45:52 toins
+# * adding a new default authorised value : SUGGEST.
+# SUGGEST give some reasons to accept or reject a suggestion.
#
-# this commit contains :
-# * 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...
-# * 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.
-# * other files : get rid of bibid and use biblionumber instead.
+# * default value for borrowersMandatoryfield syspref is now "cardnumber|surname|adress"
#
-# What is broken :
-# * does not do anything on zebra yet.
-# * if you rename marc_subfield_table, you can't search anymore.
-# * you can view a biblio & bibliodetails, go to MARC editor, but NOT save any modif.
-# * 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 ;-) )
+# Revision 1.157.2.53 2007/01/26 20:48:37 hdl
+# Serials management : Bugfixes + improvements.
+# - Partial dates are now managed
+# - next Date Calculation with irregularity tested for 1 week and 1 month.
+# - manage if subscription is abouttoexpire or expired.
+# - Adding some information on serials pages about subscription.
+# - Managing irregularity with numbers.
+# - Adding Internal Notes in subscription management.
+# - Repeating Button above pages.
#
-# 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
-# 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.
+# Please run Updatedatabase to change irregularity and add internalnotes field to subscription
#
-# Revision 1.119 2005/08/04 16:07:58 tipaul
-# Synch really broke this script...
+# Revision 1.157.2.52 2007/01/24 13:57:26 tipaul
+# - setting supplierid to auto_increment (HDL : could you check that is works, i'm not 100% sure)
+# - removing 22 -> 30 marc_subfield_table -> marcxml stuff, it's now in misc/migration_tools/22_to_30/
#
-# Revision 1.118 2005/08/04 16:02:55 tipaul
-# oops... error in synch between 2.2 and head
+# Revision 1.157.2.51 2007/01/18 09:58:45 tipaul
+# defaulting NOT NULL fields (to '')
#
-# Revision 1.117 2005/08/04 14:24:39 tipaul
-# synch'ing 2.2 and head
+# Revision 1.157.2.50 2007/01/18 09:39:21 tipaul
+# issuedate must be defaulted with ' '
#
-# Revision 1.116 2005/08/04 08:55:54 tipaul
-# Letters / alert system, continuing...
+# Revision 1.157.2.49 2007/01/18 09:37:30 tipaul
+# removing 2 field definitions that were here twice
#
-# * adding a package Letters.pm, that manages Letters & alerts.
-# * 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)
-# * 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)
-# * 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.
+# Revision 1.157.2.48 2007/01/15 09:55:40 toins
+# adding a new logging systempref : FinesLog.
#
-# Note that the system should be generic enough to manage any type of alert.
-# 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 ;-) )
+# Revision 1.157.2.47 2007/01/12 18:09:49 toins
+# LetterLog added
#
-# Revision 1.115 2005/08/02 16:15:34 tipaul
-# adding 2 fields to letter system :
-# * module (acquisition, catalogue...) : it will be usefull to show the librarian only letters he may be interested by.
-# * title, that will be used as mail subject.
+# Revision 1.157.2.46 2007/01/11 14:35:39 tipaul
+# adding Opac Browser feature : the build_browser_and_cloud.pl script will :
+# - fill the browser table, that enable browsing, digit by digit of a given category, the catalogue. A complete dewey classification is provided in the script, active only for french libraries, of course (although, for instance, the script check that the catalogue is in english for developping convenience)
+# - fill the tags table, that contains the subject cloud.
#
-# Revision 1.114 2005/07/28 15:10:13 tipaul
-# 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.
-# the letter table contains 3 fields :
-# * code => the code of the letter
-# * name => the complete name of the letter
-# * content => the complete text. It's a TEXT field type, so has no limits.
+# The cloud part is a copy of the previous build_tags.pl script that can be deleted : those 2 scripts require to parse all the catalogue to extract interesting data, so they are long. It's useless to parse the catalogue twice !
#
-# My next goal now is to work on point 2-I "serial issue alert"
-# 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.
-# (see mail on koha-devel, 2005/04/07)
+# The commit also add the systempreference to hide/show the OpacBrowse in database & in systempref management script.
#
-# The "serial issue alert" will be the 1st to use this letter system that probably needs some tweaking ;-)
+# IMPROVEMENTS to do :
+# - the script that builds the tables can be improved to update only last week biblios (at the price of a small error in value links, but it's not a problem).
+# - add, in parameters section, a place to edit browser descriptions. The build script has to be updated to to avoid deleting existing browser descriptions.
#
-# Once it will be stabilised default letters (in any languages) could be added during installer to help the library begin with this new feature.
+# Revision 1.157.2.45 2007/01/10 16:52:52 toins
+# Value for Log Features syspref are set to 0 by default.
#
-# Revision 1.113 2005/07/28 08:38:41 tipaul
-# 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 :
-# * ReturnBeforeExpiry = yes => return date can't be after expiry date
-# * ReturnBeforeExpiry = no => return date can be after expiry date
+# Revision 1.157.2.44 2007/01/10 16:31:15 toins
+# new systems preferences :
+# - CataloguingLog (log the update/creation/deletion of a notice if set to 1)
+# - BorrowersLog ( idem for borrowers )
+# - IssueLog (log all issue if set to 1)
+# - ReturnLog (log all return if set to 1)
+# - SusbcriptionLog (log all creation/deletion/update of a subcription)
#
-# Revision 1.112 2005/07/26 08:19:47 hdl
-# Adding IndependantBranches System preference variable in order to manage Branch independancy.
+# All of theses are in a new tab called 'LOGFeatures' in systempreferences.pl
#
-# Revision 1.111 2005/07/25 15:35:38 tipaul
-# we have decided that moving to Koha 3.0 requires being already in Koha 2.2.x
-# So, the updatedatabase script can highly be cleaned (90% removed).
-# Let's play with the new Koha DB structure now ;-)
+# Revision 1.157.2.43 2007/01/10 14:13:17 toins
+# opac_news.displayed is replaced by opac_news.number.
+# This field say how are ordered the news on the template.
#
+# Revision 1.157.2.42 2007/01/09 14:09:01 toins
+# 2 field added to opac_news.('expirationdate' and 'displayed').