Bug 20639: DBRev 18.12.00.023
[koha.git] / installer / data / mysql / updatedatabase.pl
index 41a58a3..f824fba 100755 (executable)
@@ -27,8 +27,7 @@
 
 # NOTE: Please keep the version in kohaversion.pl up-to-date!
 
-use strict;
-use warnings;
+use Modern::Perl;
 
 use feature 'say';
 
@@ -12320,9 +12319,6 @@ if ( $column_has_been_used ) {
 
 $DBversion = "3.23.00.050";
 if ( CheckVersion($DBversion) ) {
-    use Koha::SearchMarcMaps;
-    use Koha::SearchFields;
-    use Koha::SearchEngine::Elasticsearch;
 
     $dbh->do(q|INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
                     VALUES('SearchEngine','Zebra','Choose Search Engine','','Choice')|);
@@ -12384,12 +12380,10 @@ $dbh->do(q|
             ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
         |);
 
-        # Insert default mappings
-        Koha::SearchEngine::Elasticsearch->reset_elasticsearch_mappings;
-
-print "Upgrade to $DBversion done (Bug 12478 - Elasticsearch support for Koha)\n";
+    print "WARNING: If you plan to use Elasticsearch you should go to 'Home › Administration › Search engine configuration' and reset the mappings\n";
+    print "Upgrade to $DBversion done (Bug 12478 - Elasticsearch support for Koha)\n";
     SetVersion($DBversion);
-    }
+}
 
 
 $DBversion = "3.23.00.051";
@@ -13042,7 +13036,7 @@ if ( CheckVersion($DBversion) ) {
         INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('TrackLastPatronActivity', '0', 'If set, the field borrowers.lastseen will be updated everytime a patron is seen', NULL, 'YesNo');
     });
 
-    print "Upgrade to $DBversion done (Bug 16274 - Make the selfregistration branchcode selection configurable)\n";
+    print "Upgrade to $DBversion done (Bug 16276: Add a new pref TrackLastPatronActivity and new column borrowers.lastseen)\n";
     SetVersion($DBversion);
 }
 
@@ -15923,7 +15917,7 @@ if( CheckVersion( $DBversion ) ) {
         INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('UpdateItemWhenLostFromHoldList','',NULL,'This is a list of values to update an item when it is marked as lost from the holds to pull screen','Free');
     } );
     $dbh->do( q{
-        UPDATE systempreferences SET options="batchmod|moredetail|cronjob|additem|pendingreserves", value="batchmod|moredetail|cronjob|additem|pendingreserves" WHERE variable="MarkLostItemsAsReturned";
+        UPDATE systempreferences SET options="batchmod|moredetail|cronjob|additem|pendingreserves" WHERE variable="MarkLostItemsAsReturned";
     } );
 
     SetVersion( $DBversion );
@@ -16129,16 +16123,22 @@ if( CheckVersion( $DBversion ) ) {
 
 $DBversion = '18.06.00.005';
 if( CheckVersion( $DBversion ) ) {
-    $dbh->do( "ALTER IGNORE TABLE aqorders ADD COLUMN created_by int(11) NULL DEFAULT NULL AFTER quantityreceived;" );
-    $dbh->do( "ALTER IGNORE TABLE aqorders ADD CONSTRAINT aqorders_created_by FOREIGN KEY (created_by) REFERENCES borrowers (borrowernumber) ON DELETE SET NULL ON UPDATE CASCADE;" );
-    $dbh->do( "UPDATE aqorders, aqbasket SET aqorders.created_by = aqbasket.authorisedby  WHERE aqorders.basketno = aqbasket.basketno AND aqorders.created_by IS NULL;" );
+    unless ( column_exists('aqorders', 'created_by') ) {
+        $dbh->do( "ALTER TABLE aqorders ADD COLUMN created_by int(11) NULL DEFAULT NULL AFTER quantityreceived;" );
+        unless ( foreign_key_exists('aqorders', 'aqorders_created_by') ) {
+            $dbh->do( "ALTER TABLE aqorders ADD CONSTRAINT aqorders_created_by FOREIGN KEY (created_by) REFERENCES borrowers (borrowernumber) ON DELETE SET NULL ON UPDATE CASCADE;" );
+        }
+        $dbh->do( "UPDATE aqorders, aqbasket SET aqorders.created_by = aqbasket.authorisedby  WHERE aqorders.basketno = aqbasket.basketno AND aqorders.created_by IS NULL;" );
+    }
     SetVersion( $DBversion );
     print "Upgrade to $DBversion done (Bug 12395 - Save order line's creator)\n";
 }
 
 $DBversion = '18.06.00.006';
 if( CheckVersion( $DBversion ) ) {
-    $dbh->do( "ALTER IGNORE TABLE patron_lists ADD COLUMN shared tinyint(1) default 0 AFTER owner;" );
+    unless ( column_exists('patron_lists', 'shared') ) {
+        $dbh->do( "ALTER TABLE patron_lists ADD COLUMN shared tinyint(1) default 0 AFTER owner;" );
+    }
     SetVersion( $DBversion );
     print "Upgrade to $DBversion done (Bug 19524 - Share patron lists between staff)\n";
 }
@@ -16157,7 +16157,7 @@ if( CheckVersion( $DBversion ) ) {
 
 $DBversion = '18.06.00.008';
 if( CheckVersion( $DBversion ) ) {
-    $dbh->do( "ALTER IGNORE TABLE marc_modification_template_actions CHANGE action action ENUM('delete_field','add_field','update_field','move_field','copy_field','copy_and_replace_field')" );
+    $dbh->do( "ALTER TABLE marc_modification_template_actions CHANGE action action ENUM('delete_field','add_field','update_field','move_field','copy_field','copy_and_replace_field')" );
     SetVersion( $DBversion );
     print "Upgrade to $DBversion done (Bug 13560 - need an add option in marc modification templates)\n";
 }
@@ -16214,6 +16214,1401 @@ if( CheckVersion( $DBversion ) ) {
     print "Upgrade to $DBversion done (Bug 17698: Add column issues.noteseen and old_issues.noteseen)\n";
 }
 
+$DBversion = '18.06.00.012';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|INSERT IGNORE INTO permissions (module_bit, code, description) VALUES (11, 'suggestions_manage', 'Manage purchase suggestions');|);
+    $dbh->do(q|INSERT IGNORE INTO user_permissions (borrowernumber, module_bit, code) SELECT borrowernumber, 11, 'suggestions_manage' FROM borrowers WHERE flags & (1 << 2);|);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 11911 - Add separate permission for managing suggestions)\n";
+}
+
+$DBversion = '18.06.00.013';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `account_offset_types` (`type`) VALUES ('Credit Applied');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20997 - Add Koha::Account::Line::apply)\n";
+}
+
+$DBversion = '18.06.00.014';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+            INSERT IGNORE INTO  systempreferences (variable, value, options, explanation) VALUES ('HidePersonalPatronDetailOnCirculation', 0, 'YesNo', 'Hide patrons phone number, email address, street address and city in the circulation page');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21121 - New syspref to allow hiding of private patron data in circulation page)\n";
+}
+
+$DBversion = '18.06.00.015';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{DELETE FROM systempreferences where variable="OCLCAffiliateID";});
+    $dbh->do(q{DELETE FROM systempreferences where variable="XISBN";});
+    $dbh->do(q{DELETE FROM systempreferences where variable="XISBNDailyLimit";});
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21226 - Remove prefs OCLCAffiliateID, XISBN and XISBNDailyLimit)\n";
+}
+
+$DBversion = '18.06.00.016';
+if( CheckVersion( $DBversion ) ) {
+    my $dtf  = Koha::Database->new->schema->storage->datetime_parser;
+    my $days = C4::Context->preference('MaxPickupDelay') || 7;
+    my $date = DateTime->now()->add( days => $days );
+    my $sql  = q|UPDATE reserves SET expirationdate = ? WHERE expirationdate IS NULL AND waitingdate IS NOT NULL|;
+    $dbh->do( $sql, undef, $dtf->format_datetime($date) );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20773 - expirationdate filled for waiting holds)\n";
+}
+
+$DBversion = '18.06.00.017';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|INSERT IGNORE INTO authorised_value_categories (category_name) VALUES ('ROADTYPE');|);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21144: Add ROADTYPE to default authorised values categories)\n";
+}
+
+$DBversion = '18.06.00.018';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+UPDATE items LEFT JOIN issues USING (itemnumber)
+SET items.onloan = NULL
+WHERE issues.itemnumber IS NULL
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20487: Clear items.onloan for unissued items)\n";
+}
+
+$DBversion = '18.06.00.019';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q|
+INSERT IGNORE INTO columns_settings (module, page, tablename, columnname, cannot_be_toggled, is_hidden) VALUES
+("circ", "circulation", "issues-table", "collection", 0, 1),
+("members", "moremember", "issues-table", "collection", 0, 1);
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19719: Default to hiding collection code column)\n";
+}
+
+$DBversion = '18.06.00.020';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'branch_borrower_circ_rules', 'max_holds' ) ) {
+        $dbh->do(q{
+            ALTER TABLE branch_borrower_circ_rules ADD COLUMN max_holds INT(4) NULL DEFAULT NULL AFTER maxonsiteissueqty
+        });
+    }
+    if( !column_exists( 'default_borrower_circ_rules', 'max_holds' ) ) {
+        $dbh->do(q{
+            ALTER TABLE default_borrower_circ_rules ADD COLUMN max_holds INT(4) NULL DEFAULT NULL AFTER maxonsiteissueqty
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15524 - Set limit on maximum possible holds per patron by category)\n";
+}
+
+$DBversion = '18.06.00.021';
+if( CheckVersion( $DBversion ) ) {
+    my $dbh = C4::Context->dbh;
+    unless ( C4::Context->preference('NorwegianPatronDBEnable') ) {
+        $dbh->do(q|
+            DELETE FROM systempreferences
+            WHERE variable IN ('NorwegianPatronDBEnable', 'NorwegianPatronDBEndpoint', 'NorwegianPatronDBUsername', 'NorwegianPatronDBPassword', 'NorwegianPatronDBSearchNLAfterLocalHit')
+        |);
+        if ( TableExists('borrower_sync') ) {
+            $dbh->do(q|DROP TABLE borrower_sync|);
+        }
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21068 - Remove system preferences NorwegianPatronDB*)\n";
+}
+
+$DBversion = '18.06.00.022';
+if( CheckVersion( $DBversion ) ) {
+    my $dbh = C4::Context->dbh;
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('HoldsAutoFill','0',NULL,'If on, librarian will not be asked if hold should be filled, it will be filled automatically','YesNo'),
+        ('HoldsAutoFillPrintSlip','0',NULL,'If on, hold slip print dialog will be displayed automatically','YesNo')
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19383 - Add ability to print hold receipts automatically)\n";
+}
+
+$DBversion = '18.06.00.023';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'aqorders', 'replacementprice' ) ){
+        $dbh->do( "ALTER TABLE aqorders ADD COLUMN replacementprice DECIMAL(28,6)" );
+        $dbh->do( "UPDATE aqorders set replacementprice = rrp WHERE replacementprice IS NULL" );
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18639 - Add replacementprice field to aqorders table)\n";
+}
+
+$DBversion = '18.06.00.024';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'branches', 'pickup_location' ) ){
+        $dbh->do( "ALTER TABLE branches ADD COLUMN pickup_location TINYINT(1) not null default 1" );
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 7534 - Let libraries have configuration for pickup locations)\n";
+}
+
+$DBversion = '18.06.00.025';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('KohaManualBaseURL','https://koha-community.org/manual/','','Where is the Koha manual/documentation located?','Free'),
+        ('KohaManualLanguage','en','en|ar|cs|es|de|fr|it|pt_BR|tr|zh_TW','What is the language of the online manual you want to use?','Choice')
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19817: Add pref KohaManualLanguage and KohaManualBaseURL)\n";
+}
+
+$DBversion = '18.06.00.026';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+INSERT IGNORE INTO  systempreferences (variable, value, options, explanation, type) VALUES ('ArticleRequestsLinkControl', 'always', 'always\|calc', 'Control display of article request link on search results', 'Choice')
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17530 - Add pref ArticleRequestsLinkControl)\n";
+}
+
+$DBversion = '18.06.00.027';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "DROP TABLE IF EXISTS services_throttle" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21235: Remove table services_throttle)\n";
+}
+
+$DBversion = '18.06.00.028';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+('HoldsSplitQueue','nothing','nothing|branch|itemtype|branch_itemtype','In the staff client, split the holds view by the given criteria','Choice'),
+('HoldsSplitQueueNumbering', 'actual', 'actual|virtual', 'If the holds queue is split, decide if the acual priorities should be displayed', 'Choice');
+});
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19469 - Add ability to split view of holds view on record by pickup library and/or itemtype)\n";
+}
+
+$DBversion = '18.06.00.029';
+if( CheckVersion( $DBversion ) ) {
+    unless ( index_exists( 'subscription', 'by_biblionumber' ) ) {
+        $dbh->do(q{
+            CREATE INDEX `by_biblionumber` ON `subscription` (`biblionumber`)
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21288: Slowness in acquisition caused by GetInvoices\n";
+}
+
+$DBversion = '18.06.00.030';
+if( CheckVersion( $DBversion ) ) {
+    if ( column_exists( 'accountlines', 'dispute' ) ) {
+        $dbh->do(q{
+            ALTER TABLE `accountlines`
+                DROP COLUMN `dispute`
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20777 - Remove unused field accountlines.dispute)\n";
+}
+
+$DBversion = '18.06.00.031';
+if( CheckVersion( $DBversion ) ) {
+    # Add table and add column
+    unless (TableExists('patron_consent')) {
+        $dbh->do(q|
+    CREATE TABLE patron_consent (id int AUTO_INCREMENT, borrowernumber int NOT NULL, type enum('GDPR_PROCESSING' ), given_on datetime, refused_on datetime, PRIMARY KEY (id), FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE )
+        |);
+    }
+    unless ( column_exists( 'borrower_modifications', 'gdpr_proc_consent' ) ) {
+        $dbh->do(q|
+    ALTER TABLE borrower_modifications ADD COLUMN gdpr_proc_consent datetime
+        |);
+    }
+    # Add two sysprefs too
+    $dbh->do(q|
+INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type ) VALUES ('PrivacyPolicyURL','',NULL,'This URL is used in messages about GDPR consents.', 'Free')
+    |);
+    $dbh->do(q|
+INSERT IGNORE INTO systempreferences ( variable, value, options, explanation, type ) VALUES ('GDPR_Policy','','Enforced\|Permissive\|Disabled','General Data Protection Regulation - policy', 'Choice')
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20819: Add patron_consent)\n";
+}
+
+$DBversion = '18.06.00.032';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|ALTER TABLE items                   CHANGE COLUMN ccode ccode varchar(80) default NULL|);
+    $dbh->do(q|ALTER TABLE deleteditems            CHANGE COLUMN ccode ccode varchar(80) default NULL|);
+    $dbh->do(q|ALTER TABLE branch_transfer_limits  CHANGE COLUMN ccode ccode varchar(80) default NULL|);
+    $dbh->do(q|ALTER TABLE course_items            CHANGE COLUMN ccode ccode varchar(80) default NULL|);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 5458: length of items.ccode disagrees with authorised_values.authorised_value)\n";
+}
+
+$DBversion = '18.06.00.033';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('AdditionalFieldsInZ3950ResultSearch', '', 'NULL', 'Determines which MARC field/subfields are displayed in -Additional field- column in the result of a search Z3950', 'Free')
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 12747 - Add AdditionalFieldsInZ3950ResultSearch system preference)\n";
+}
+
+$DBversion = '18.06.00.034';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+        INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type)
+        VALUES ('RecordedBooksClientSecret','','30','Client key for RecordedBooks integration','YesNo'),
+               ('RecordedBooksLibraryID','','','Library ID for RecordedBooks integration','Integer'),
+               ('RecordedBooksDomain','','','RecordedBooks domain','Free');
+    |);
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17602 - Integrate support for OneClickdigital/Recorded Books API)\n";
+}
+
+$DBversion = '18.06.00.035';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE `systempreferences` SET options = 'US|CA|DE|FR|IN|JP|UK' WHERE variable = 'AmazonLocale' AND options='US|CA|DE|FR|JP|UK';
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21403 - Add Indian Amazon Affiliate option to AmazonLocale setting)\n";
+}
+
+
+$DBversion = '18.06.00.036';
+if( CheckVersion( $DBversion ) ) {
+    unless (TableExists('circulation_rules')){
+        $dbh->do(q{
+            CREATE TABLE `circulation_rules` (
+              `id` int(11) NOT NULL auto_increment,
+              `branchcode` varchar(10) NULL default NULL,
+              `categorycode` varchar(10) NULL default NULL,
+              `itemtype` varchar(10) NULL default NULL,
+              `rule_name` varchar(32) NOT NULL,
+              `rule_value` varchar(32) NOT NULL,
+              PRIMARY KEY (`id`),
+              CONSTRAINT `circ_rules_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE,
+              CONSTRAINT `circ_rules_ibfk_2` FOREIGN KEY (`categorycode`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE ON UPDATE CASCADE,
+              CONSTRAINT `circ_rules_ibfk_3` FOREIGN KEY (`itemtype`) REFERENCES `itemtypes` (`itemtype`) ON DELETE CASCADE ON UPDATE CASCADE,
+              KEY `rule_name` (`rule_name`),
+              UNIQUE (`branchcode`,`categorycode`,`itemtype`,`rule_name`)
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+    if (column_exists('branch_borrower_circ_rules', 'max_holds') ){
+        $dbh->do(q{
+            INSERT IGNORE INTO circulation_rules ( branchcode, categorycode, itemtype, rule_name, rule_value )
+            SELECT branchcode, categorycode, NULL, 'max_holds', COALESCE( max_holds, '' ) FROM branch_borrower_circ_rules
+        });
+        $dbh->do(q{
+            ALTER TABLE branch_borrower_circ_rules DROP COLUMN max_holds
+        });
+    }
+    if (column_exists('default_borrower_circ_rules', 'max_holds') ){
+        $dbh->do(q{
+            INSERT IGNORE INTO circulation_rules ( branchcode, categorycode, itemtype, rule_name, rule_value )
+            SELECT NULL, categorycode, NULL, 'max_holds', COALESCE( max_holds, '' ) FROM default_borrower_circ_rules
+        });
+        $dbh->do(q{
+            ALTER TABLE default_borrower_circ_rules DROP COLUMN max_holds
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18887 - Introduce new table 'circulation_rules', use for 'max_holds' rules)\n";
+}
+
+$DBversion = '18.06.00.037';
+if( CheckVersion( $DBversion ) ) {
+    unless (TableExists('branches_overdrive')){
+        $dbh->do( q|
+            CREATE TABLE IF NOT EXISTS branches_overdrive (
+                `branchcode` VARCHAR( 10 ) NOT NULL ,
+                `authname` VARCHAR( 255 ) NOT NULL ,
+                PRIMARY KEY (`branchcode`) ,
+                CONSTRAINT `branches_overdrive_ibfk_1` FOREIGN KEY (`branchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE
+            ) ENGINE = INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+        );
+    }
+    $dbh->do("INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('OverDriveAuthname', '', 'Authname for OverDrive Patron Authentication, will be used as fallback if individual branch authname not set', NULL, 'Free');");
+    $dbh->do("INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('OverDriveWebsiteID','', 'WebsiteID provided by OverDrive', NULL, 'Free');");
+    $dbh->do("INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES ('OverDrivePasswordRequired','', 'Does the library require passwords for OverDrive SIP authentication', NULL, 'YesNo');");
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21082 - Add overdrive patron auth method)\n";
+}
+
+$DBversion = '18.06.00.038';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "ALTER TABLE edifact_ean MODIFY branchcode VARCHAR(10) NULL DEFAULT NULL" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21417 - EDI ordering fails when basket and EAN libraries do not match)\n";
+}
+
+$DBversion = '18.06.00.039';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `permissions` (module_bit, code, description) VALUES(3, 'manage_circ_rules_from_any_libraries', 'Manage circ rules for any libraries');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15520 - Add more granular permission for only editing own library's circ rules)\n";
+}
+
+$DBversion = '18.06.00.040';
+if( CheckVersion( $DBversion ) ) {
+    # Stock Rotation Rotas
+    unless (TableExists('stockrotationrotas')){
+        $dbh->do(q{
+          CREATE TABLE `stockrotationrotas` (
+            `rota_id` int(11) auto_increment,         -- Stockrotation rota ID
+            `title` varchar(100) NOT NULL,            -- Title for this rota
+            `description` text NOT NULL,              -- Description for this rota
+            `cyclical` tinyint(1) NOT NULL default 0, -- Should items on this rota keep cycling?
+            `active` tinyint(1) NOT NULL default 0,   -- Is this rota currently active?
+            PRIMARY KEY (`rota_id`),
+            CONSTRAINT `stockrotationrotas_title`
+            UNIQUE (`title`)
+          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+    # Stock Rotation Stages
+    unless (TableExists('stockrotationstages')){
+        $dbh->do(q{
+          CREATE TABLE `stockrotationstages` (
+              `stage_id` int(11) auto_increment,     -- Unique stage ID
+              `position` int(11) NOT NULL,           -- The position of this stage within its rota
+              `rota_id` int(11) NOT NULL,            -- The rota this stage belongs to
+              `branchcode_id` varchar(10) NOT NULL,  -- Branch this stage relates to
+              `duration` int(11) NOT NULL default 4, -- The number of days items shoud occupy this stage
+              PRIMARY KEY (`stage_id`),
+              CONSTRAINT `stockrotationstages_rifk`
+                FOREIGN KEY (`rota_id`)
+                REFERENCES `stockrotationrotas` (`rota_id`)
+                ON UPDATE CASCADE ON DELETE CASCADE,
+              CONSTRAINT `stockrotationstages_bifk`
+                FOREIGN KEY (`branchcode_id`)
+                REFERENCES `branches` (`branchcode`)
+                ON UPDATE CASCADE ON DELETE CASCADE
+          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+    # Stock Rotation Items
+    unless (TableExists('stockrotationitems')){
+        $dbh->do(q{
+          CREATE TABLE `stockrotationitems` (
+              `itemnumber_id` int(11) NOT NULL,         -- Itemnumber to link to a stage & rota
+              `stage_id` int(11) NOT NULL,              -- stage ID to link the item to
+              `indemand` tinyint(1) NOT NULL default 0, -- Should this item be skipped for rotation?
+              `fresh` tinyint(1) NOT NULL default 0,    -- Flag showing item is only just added to rota
+              PRIMARY KEY (itemnumber_id),
+              CONSTRAINT `stockrotationitems_iifk`
+                FOREIGN KEY (`itemnumber_id`)
+                REFERENCES `items` (`itemnumber`)
+                ON UPDATE CASCADE ON DELETE CASCADE,
+              CONSTRAINT `stockrotationitems_sifk`
+                FOREIGN KEY (`stage_id`)
+                REFERENCES `stockrotationstages` (`stage_id`)
+                ON UPDATE CASCADE ON DELETE CASCADE
+          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+    # System preferences
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`,`value`,`explanation`,`options`,`type`)
+        VALUES ('StockRotation','0','If ON, enables the stock rotation module','','YesNo'),
+               ('RotationPreventTransfers','0','If ON, prevent any transfers for items on stock rotation rotas, except for stock rotation transfers','','YesNo');
+    });
+    # Permissions
+    $dbh->do(q{
+        INSERT IGNORE INTO `userflags` (`bit`, `flag`, `flagdesc`, `defaulton`)
+        VALUES (24, 'stockrotation', 'Manage stockrotation operations', 0);
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO `permissions` (`module_bit`, `code`, `description`)
+        VALUES (24, 'manage_rotas', 'Create, edit and delete rotas'),
+               (24, 'manage_rota_items', 'Add and remove items from rotas');
+    });
+    # Notices
+    $dbh->do(q{
+        INSERT IGNORE INTO `letter` (`module`, `code`, `branchcode`, `name`, `is_html`, `title`, `content`, `message_transport_type`)
+        VALUES ('circulation', 'SR_SLIP', '', 'Stock Rotation Slip', 0, 'Stockrotation Report', 'Stockrotation report for [% branch.name %]:\r\n\r\n[% IF branch.items.size %][% branch.items.size %] items to be processed for this branch.\r\n[% ELSE %]No items to be processed for this branch\r\n[% END %][% FOREACH item IN branch.items %][% IF item.reason ne \'in-demand\' %]Title: [% item.title %]\r\nAuthor: [% item.author %]\r\nCallnumber: [% item.callnumber %]\r\nLocation: [% item.location %]\r\nBarcode: [% item.barcode %]\r\nOn loan?: [% item.onloan %]\r\nStatus: [% item.reason %]\r\nCurrent Library: [% item.branch.branchname %] [% item.branch.branchcode %]\r\n\r\n[% END %][% END %]', 'email');
+    });
+    print "Upgrade to $DBversion done (Bug 11897 - Add Stock Rotation Feature)\n";
+    SetVersion( $DBversion );
+}
+
+$DBversion = '18.06.00.041';
+if( CheckVersion( $DBversion ) ) {
+
+     if( !column_exists( 'illrequests', 'price_paid' ) ) {
+        $dbh->do(q{
+            ALTER TABLE illrequests
+                ADD COLUMN price_paid varchar(20) DEFAULT NULL
+                AFTER cost
+        });
+     }
+
+     if( !column_exists( 'illrequestattributes', 'readonly' ) ) {
+        $dbh->do(q{
+            ALTER TABLE illrequestattributes
+                ADD COLUMN readonly tinyint(1) NOT NULL DEFAULT 1
+                AFTER value
+        });
+        $dbh->do(q{
+            UPDATE illrequestattributes SET readonly = 1
+        });
+     }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20772 - Add illrequestattributes.readonly and illrequest.price_paid columns)\n";
+}
+
+$DBversion = '18.06.00.042';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "alter table statistics change column ccode ccode varchar(80) default NULL" );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21617: Make statistics.ccode longer)\n";
+}
+
+$DBversion = "18.06.00.043";
+if ( CheckVersion($DBversion) ) {
+    if ( !column_exists( 'issuingrules', 'holds_per_day' ) ) {
+        $dbh->do(q{
+            ALTER TABLE `issuingrules`
+                ADD COLUMN `holds_per_day` SMALLINT(6) DEFAULT NULL
+                AFTER `holds_per_record`
+        });
+    }
+    print "Upgrade to $DBversion done (Bug 15486: Restrict number of holds placed by day)\n";
+    SetVersion($DBversion);
+}
+
+$DBversion = '18.06.00.044';
+if( CheckVersion( $DBversion ) ) {
+    unless( column_exists( 'creator_batches', 'description' ) ) {
+        $dbh->do(q|ALTER TABLE creator_batches ADD description mediumtext default NULL AFTER batch_id|);
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15766: Add column creator_batches.description)\n";
+}
+
+$DBversion = '18.06.00.045';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q(
+        INSERT IGNORE INTO message_transports
+        (message_attribute_id,message_transport_type,is_digest,letter_module,letter_code)
+        VALUES
+        (2, 'phone', 0, 'circulation', 'PREDUE'),
+        (2, 'phone', 1, 'circulation', 'PREDUEDGST'),
+        (4, 'phone', 0, 'reserves',    'HOLD')
+        ));
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21639 - Add phone transports by default)\n";
+}
+
+$DBversion = '18.06.00.046';
+if( CheckVersion( $DBversion ) ) {
+    unless (TableExists('illcomments')) {
+        $dbh->do(q{
+            CREATE TABLE illcomments (
+                illcomment_id int(11) NOT NULL AUTO_INCREMENT, -- Unique ID of the comment
+                illrequest_id bigint(20) unsigned NOT NULL,    -- ILL request number
+                borrowernumber integer DEFAULT NULL,           -- Link to the user who made the comment (could be librarian, patron or ILL partner library)
+                comment text DEFAULT NULL,                     -- The text of the comment
+                timestamp timestamp DEFAULT CURRENT_TIMESTAMP, -- Date and time when the comment was made
+                PRIMARY KEY  ( illcomment_id ),
+                CONSTRAINT illcomments_bnfk
+                  FOREIGN KEY ( borrowernumber )
+                  REFERENCES  borrowers  ( borrowernumber )
+                  ON UPDATE CASCADE ON DELETE CASCADE,
+                CONSTRAINT illcomments_ifk
+                  FOREIGN KEY (illrequest_id)
+                  REFERENCES illrequests ( illrequest_id )
+                  ON UPDATE CASCADE ON DELETE CASCADE
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+        });
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18591 - Add comments to ILL requests)\n";
+}
+
+$DBversion = '18.06.00.047';
+if( CheckVersion( $DBversion ) ) {
+    # insert the authorized_value_category for CONTROL_NUM_SEQUENCE
+    $dbh->do( "INSERT IGNORE INTO authorised_value_categories values ('CONTROL_NUM_SEQUENCE');" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19263 - Advanced Editor - Rancor - Add auto control number (001) widget)\n";
+}
+
+$DBversion = '18.06.00.048';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "ALTER TABLE stockrotationrotas CHANGE COLUMN description description text" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21682 - Remove default on stockrotationrotas.description)\n";
+}
+
+$DBversion = '18.06.00.049';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE letter SET content = REPLACE(content,"item.reason ne \'in-demand\'","item.reason != \'in-demand\'")
+        WHERE code="SR_SLIP";
+    });
+    print "Upgrade to $DBversion done (Bug 21656 - Stock Rotation Notice, Template Toolkit Syntax Correction)\n";
+    SetVersion( $DBversion );
+}
+
+$DBversion = '18.06.00.050';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES ('OpacHiddenItemsExceptions','',NULL,'List of borrower categories, separated by |, that can see items otherwise hidden by OpacHiddenItems','Textarea');
+    });
+    print "Upgrade to $DBversion done (Bug 14385 - Add OpacHiddenItemExceptions)\n";
+    SetVersion( $DBversion );
+}
+
+$DBversion = '18.06.00.051';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+        ('AdlibrisCoversEnabled', '0', NULL, 'Display cover images in OPAC results and detail listing from Swedish retailer Adlibris.','YesNo'),
+        ('AdlibrisCoversURL', 'http://www.adlibris.com/se/organisationer/showimagesafe.aspx', NULL, 'Base URL for Adlibris cover image web service.', 'Free');
+    });
+    print "Upgrade to $DBversion done (Bug 8630 - Add covers from AdLibris to the OPAC and Intranet)\n";
+    SetVersion( $DBversion );
+}
+
+$DBversion = '18.06.00.052';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO permissions (module_bit, code, description) VALUES
+           ( 3, 'manage_sysprefs', 'Manage global system preferences'),
+           ( 3, 'manage_libraries', 'Manage libraries and library groups'),
+           ( 3, 'manage_itemtypes', 'Manage item types'),
+           ( 3, 'manage_auth_values', 'Manage authorized values'),
+           ( 3, 'manage_patron_categories', 'Manage patron categories'),
+           ( 3, 'manage_patron_attributes', 'Manage extended patron attributes'),
+           ( 3, 'manage_transfers', 'Manage library transfer limits and transport cost matrix'),
+           ( 3, 'manage_item_circ_alerts', 'Manage item circulation alerts'),
+           ( 3, 'manage_cities', 'Manage cities and towns'),
+           ( 3, 'manage_marc_frameworks', 'Manage MARC bibliographic and authority frameworks'),
+           ( 3, 'manage_keywords2koha_mappings', 'Manage keywords to Koha mappings'),
+           ( 3, 'manage_classifications', 'Manage classification sources'),
+           ( 3, 'manage_matching_rules', 'Manage record matching rules'),
+           ( 3, 'manage_oai_sets', 'Manage OAI sets'),
+           ( 3, 'manage_item_search_fields', 'Manage item search fields'),
+           ( 3, 'manage_search_engine_config', 'Manage search engine configuration'),
+           ( 3, 'manage_search_targets', 'Manage Z39.50 and SRU server configuration'),
+           ( 3, 'manage_didyoumean', 'Manage Did you mean? configuration'),
+           ( 3, 'manage_column_config', 'Manage column configuration'),
+           ( 3, 'manage_sms_providers', 'Manage SMS cellular providers'),
+           ( 3, 'manage_audio_alerts', 'Manage audio alerts'),
+           ( 3, 'manage_usage_stats', 'Manage usage statistics settings');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_sysprefs' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_libraries' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_itemtypes' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_auth_values' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_patron_categories' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_patron_attributes' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_transfers' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_item_circ_alerts' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_cities' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_marc_frameworks' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_keywords2koha_mappings' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_classifications' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_matching_rules' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_oai_sets' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_item_search_fields' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_search_engine_config' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_search_targets' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_didyoumean' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_column_config' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_sms_providers' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_audio_alerts' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_usage_stats' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM user_permissions WHERE code = 'parameters_remaining_permissions');
+    });
+    $dbh->do(q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+            SELECT borrowernumber, 3, 'manage_item_search_fields' FROM borrowers WHERE flags & (1 << 2);
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 14391: Add granular permissions to the administration module)\n";
+}
+
+$DBversion = '18.06.00.053';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('ItemsDeniedRenewal','','','This syspref allows to define custom rules for denying renewal of specific items.','Textarea')" );
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15494 - Block renewals by arbitrary item values)\n";
+}
+
+$DBversion = '18.06.00.054';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'search_field', 'weight' ) ) {
+        $dbh->do( "ALTER TABLE `search_field` ADD COLUMN `weight` decimal(5,2) DEFAULT NULL AFTER `type`" );
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18316 - Add column search_field.weight)\n";
+}
+
+$DBversion = '18.06.00.055';
+if( CheckVersion( $DBversion ) ) {
+    unless( column_exists( 'issuingrules', 'note' ) ) {
+        $dbh->do(q|ALTER TABLE `issuingrules` ADD `note` varchar(100) default NULL AFTER `article_requests`|);
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 12365: Add column issuingrules.note)\n";
+}
+
+$DBversion = '18.06.00.056';
+if( CheckVersion( $DBversion ) ) {
+
+    # All attributes we're potentially interested in
+    my $ff_req = $dbh->selectall_arrayref(
+        'SELECT a.illrequest_id, a.type, a.value '.
+        'FROM illrequests r, illrequestattributes a '.
+        'WHERE r.illrequest_id = a.illrequest_id '.
+        'AND r.backend = "FreeForm"',
+        { Slice => {} }
+    );
+
+    # Before we go any further, identify whether we've done
+    # this before, we test for the presence of "container_title"
+    # We stop as soon as we find one
+    foreach my $req(@{$ff_req}) {
+        if ($req->{type} eq 'container_title') {
+            warn "Upgrade already carried out";
+        }
+    }
+
+    # Transform into a hashref with the key of the request ID
+    my $requests = {};
+    foreach my $request(@{$ff_req}) {
+        my $id = $request->{illrequest_id};
+        if (!exists $requests->{$id}) {
+            $requests->{$id} = {};
+        }
+        $requests->{$id}->{$request->{type}} = $request->{value};
+    }
+
+    # Transform any article requests
+    my $transformed = {};
+    foreach my $id(keys %{$requests}) {
+        if (lc($requests->{$id}->{type}) eq 'article') {
+            $transformed->{$id} = $requests->{$id};
+            $transformed->{$id}->{type} = 'article';
+            $transformed->{$id}->{container_title} = $transformed->{$id}->{title}
+                if defined $transformed->{$id}->{title} &&
+                    length $transformed->{$id}->{title} > 0;
+            $transformed->{$id}->{title} = $transformed->{$id}->{article_title}
+                if defined $transformed->{$id}->{article_title} &&
+                    length $transformed->{$id}->{article_title} > 0;
+            $transformed->{$id}->{author} = $transformed->{$id}->{article_author}
+                if defined $transformed->{$id}->{article_author} &&
+                    length $transformed->{$id}->{article_author} > 0;
+            $transformed->{$id}->{pages} = $transformed->{$id}->{article_pages}
+                if defined $transformed->{$id}->{article_pages} &&
+                    length $transformed->{$id}->{article_pages} > 0;
+        }
+    }
+
+    # Now write back the transformed data
+    # Rather than selectively replace, we just remove all attributes we've
+    # transformed and re-write them
+    my @changed = keys %{$transformed};
+    my $changed_str = join(',', @changed);
+
+    if (scalar @changed > 0) {
+        my ($raise_error) = $dbh->{RaiseError};
+        $dbh->{AutoCommit} = 0;
+        $dbh->{RaiseError} = 1;
+        eval {
+            my $del = $dbh->do(
+                "DELETE FROM illrequestattributes ".
+                "WHERE illrequest_id IN ($changed_str)"
+            );
+            foreach my $reqid(keys %{$transformed}) {
+                my $attr = $transformed->{$reqid};
+                foreach my $key(keys %{$attr}) {
+                    my $sth = $dbh->prepare(
+                        'INSERT INTO illrequestattributes '.
+                        '(illrequest_id, type, value) '.
+                        'VALUES '.
+                        '(?, ?, ?)'
+                    );
+                    $sth->execute(
+                        $reqid,
+                        $key,
+                        $attr->{$key}
+                    );
+                }
+            }
+            $dbh->commit;
+        };
+
+        if ($@) {
+            warn "Upgrade to $DBversion failed: $@\n";
+            eval { $dbh->rollback };
+        } else {
+            SetVersion( $DBversion );
+            print "Upgrade to $DBversion done (Bug 21079 - Unify metadata schema across backends)\n";
+        }
+
+        $dbh->{AutoCommit} = 1;
+        $dbh->{RaiseError} = $raise_error;
+    }
+
+}
+
+$DBversion = '18.06.00.057';
+if( CheckVersion( $DBversion ) ) {
+    # System preferences
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`,`value`,`explanation`,`options`,`type`)
+        VALUES ('showLastPatron','0','','If ON, enables the last patron feature in the intranet','YesNo');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20312 - Add showLastPatron systempreference)\n";
+}
+
+$DBversion = '18.06.00.058';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (`variable`, `value`, `options`, `explanation`, `type`) VALUES
+        ('MarcFieldForCreatorId','',NULL,'Where to store the borrowernumber of the record''s creator','Free'),
+        ('MarcFieldForCreatorName','',NULL,'Where to store the name of the record''s creator','Free'),
+        ('MarcFieldForModifierId','',NULL,'Where to store the borrowernumber of the record''s last modifier','Free'),
+        ('MarcFieldForModifierName','',NULL,'Where to store the name of the record''s last modifier','Free')
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19349 - Add system preferences MarcFieldForCreatorId, MarcFieldForCreatorName, MarcFieldForModifierId, MarcFieldForModifierName)\n";
+}
+
+$DBversion = '18.06.00.059';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type`) VALUES  ('EmailSMSSendDriverFromAddress', '', '', 'Email SMS send driver from address override', 'Free');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20356 - Add EmailSMSSendDriverFromAddress system preference)\n";
+}
+
+$DBversion = '18.06.00.060';
+if( CheckVersion( $DBversion ) ) {
+    unless( TableExists( 'class_split_rules' ) ) {
+        $dbh->do(q|
+            CREATE TABLE class_split_rules (
+              class_split_rule varchar(10) NOT NULL default '',
+              description LONGTEXT,
+              split_routine varchar(30) NOT NULL default '',
+              split_regex varchar(255) NOT NULL default '',
+              PRIMARY KEY (class_split_rule),
+              UNIQUE KEY class_split_rule_idx (class_split_rule)
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
+        |);
+
+        $dbh->do(q|
+            ALTER TABLE class_sources
+            ADD COLUMN class_split_rule varchar(10) NOT NULL default ''
+            AFTER class_sort_rule
+        |);
+
+        $dbh->do(q|
+            UPDATE class_sources
+            SET class_split_rule = class_sort_rule
+        |);
+
+        $dbh->do(q|
+            UPDATE class_sources
+            SET class_split_rule = 'generic'
+            WHERE class_split_rule NOT IN('dewey', 'generic', 'lcc')
+        |);
+
+        $dbh->do(q|
+            INSERT INTO class_split_rules(class_split_rule, description, split_routine)
+            VALUES
+            ('dewey', 'Default sorting rules for DDC', 'Dewey'),
+            ('lcc', 'Default sorting rules for LCC', 'LCC'),
+            ('generic', 'Generic call number sorting rules', 'Generic')
+        |);
+
+        $dbh->do(q|
+            ALTER TABLE class_sources
+            ADD CONSTRAINT class_source_ibfk_2 FOREIGN KEY (class_split_rule)
+            REFERENCES class_split_rules (class_split_rule)
+        |);
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15836 - Add class_sort_rules.split_routine and split_regex)\n";
+}
+
+$DBversion = '18.06.00.061';
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences` (`variable`,`value`,`explanation`,`options`,`type`) VALUES
+        ('ElasticsearchIndexStatus_biblios', '0', 'Biblios index status', NULL, NULL),
+        ('ElasticsearchIndexStatus_authorities', '0', 'Authorities index status', NULL, NULL)
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 19893 - Add elasticsearch index status preferences)\n";
+}
+
+$DBversion = '18.06.00.062';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "INSERT IGNORE INTO authorised_value_categories (category_name) VALUES ('PA_CLASS');");
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21730: Add new authorised value category PA_CLASS)\n";
+}
+
+$DBversion = '18.11.00.000';
+if( CheckVersion( $DBversion ) ) {
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (18.11.00 release)\n";
+}
+
+$DBversion = '18.12.00.000';
+if( CheckVersion( $DBversion ) ) {
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (...and Steven!)\n";
+}
+
+$DBversion = '18.12.00.001';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        UPDATE permissions SET code = 'manage_didyoumean' WHERE code = 'manage_didyouean';
+    });
+    $dbh->do(q{
+        UPDATE user_permissions SET code = 'manage_didyoumean' WHERE code = 'manage_didyouean';
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion (Bug 21961 - Fix typo in manage_didyoumean permission)\n";
+}
+
+$DBversion = '18.12.00.002';
+if( CheckVersion( $DBversion ) ) {
+    my $sth = $dbh->prepare(q|SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME='accountlines_ibfk_1'|);
+    $sth->execute;
+    if ($sth->fetchrow_hashref) {
+        $dbh->do(q|
+            ALTER TABLE accountlines DROP FOREIGN KEY accountlines_ibfk_1;
+        |);
+        $dbh->do(q|
+            ALTER TABLE accountlines CHANGE COLUMN borrowernumber borrowernumber INT(11) DEFAULT NULL;
+        |);
+        $dbh->do(q|
+            ALTER TABLE accountlines ADD CONSTRAINT accountlines_ibfk_borrowers FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE SET NULL ON UPDATE CASCADE;
+        |);
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21065 - Set ON DELETE SET NULL on accountlines.borrowernumber)\n";
+}
+
+$DBversion = '18.12.00.003';
+if( CheckVersion( $DBversion ) ) {
+    # On a new installation the class_sources.sql will have failed, so we need to add all missing data
+    my( $sort_cnt ) = $dbh->selectrow_array( q|SELECT COUNT(*) FROM class_sort_rules|);
+    if( !$sort_cnt ) {
+        $dbh->do(q|INSERT INTO `class_sort_rules` (`class_sort_rule`, `description`, `sort_routine`) VALUES
+                               ('dewey', 'Default filing rules for DDC', 'Dewey'),
+                               ('lcc', 'Default filing rules for LCC', 'LCC'),
+                               ('generic', 'Generic call number filing rules', 'Generic')
+            |);
+    }
+
+    my ( $split_cnt ) = $dbh->selectrow_array( q|SELECT COUNT(*) FROM class_split_rules|);
+    if( !$split_cnt ) {
+        $dbh->do(q|INSERT INTO `class_split_rules` (`class_split_rule`, `description`, `split_routine`) VALUES
+                               ('dewey', 'Default splitting rules for DDC', 'Dewey'),
+                               ('lcc', 'Default splitting rules for LCC', 'LCC'),
+                               ('generic', 'Generic call number splitting rules', 'Generic')
+            |);
+    }
+
+    my( $source_cnt ) = $dbh->selectrow_array( q|SELECT COUNT(*) FROM class_sources|);
+    if( !$source_cnt ) {
+        $dbh->do(q|INSERT INTO `class_sources` (`cn_source`, `description`, `used`, `class_sort_rule`, `class_split_rule`) VALUES
+                            ('ddc', 'Dewey Decimal Classification', 1, 'dewey', 'dewey'),
+                            ('lcc', 'Library of Congress Classification', 1, 'lcc', 'lcc'),
+                            ('udc', 'Universal Decimal Classification', 0, 'generic', 'generic'),
+                            ('sudocs', 'SuDoc Classification (U.S. GPO)', 0, 'generic', 'generic'),
+                            ('anscr', 'ANSCR (Sound Recordings)', 0, 'generic', 'generic'),
+                            ('z', 'Other/Generic Classification Scheme', 0, 'generic', 'generic')
+            |);
+
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22024 - Add missing splitting rule definitions)\n";
+}
+
+$DBversion = '18.12.00.004';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'accountlines', 'branchcode' ) ) {
+        $dbh->do("ALTER TABLE accountlines ADD branchcode VARCHAR( 10 ) NULL DEFAULT NULL AFTER manager_id");
+        $dbh->do("ALTER TABLE accountlines ADD CONSTRAINT accountlines_ibfk_branches FOREIGN KEY (branchcode) REFERENCES branches (branchcode) ON DELETE SET NULL ON UPDATE CASCADE");
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 19066 - Add branchcode to accountlines)\n";
+}
+
+$DBversion = '18.12.00.005';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('OverDriveUsername','cardnumber','cardnumber|userid','Which patron information should be passed as OverDrive username','Choice')
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22030: Add OverDriveUsername syspref)\n";
+}
+
+$DBversion = '18.12.00.006';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES
+        ('AccountAutoReconcile','0','If enabled, patron balances will get reconciled automatically on each transaction.',NULL,'YesNo');
+    });
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 21915 - Add a way to automatically reconcile balance for patrons)\n";
+}
+
+$DBversion = '18.12.00.007';
+if( CheckVersion( $DBversion ) ) {
+    if( column_exists( 'issuingrules', 'chargename' ) ) {
+        $dbh->do( "ALTER TABLE issuingrules DROP chargename" );
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21753: Drop chargename from issuingrules )\n";
+}
+
+$DBversion = '18.12.00.008';
+if( CheckVersion( $DBversion ) ) {
+    if( !column_exists( 'subscription', 'mana_id' ) ) {
+        $dbh->do( "ALTER TABLE subscription ADD mana_id int(11) NULL DEFAULT NULL" );
+    }
+
+    if( !column_exists( 'saved_sql', 'mana_id' ) ) {
+        $dbh->do( "ALTER TABLE saved_sql ADD mana_id int(11) NULL DEFAULT NULL" );
+    }
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('Mana','2',NULL,'request to Mana Webservice. Mana centralize common information between other Koha to facilitate the creation of new subscriptions, vendors, report queries etc... You can search, share, import and comment the content of Mana.','YesNo');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('AutoShareWithMana','','','defines datas automatically shared with mana','multiple');
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES
+        ('ManaToken','',NULL,'Security token used for authentication on Mana KB service (anti spam)','Textarea');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 17047 - Mana knowledge base)\n";
+}
+
+$DBversion = '18.12.00.009';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable, value, options, explanation, type) VALUES ('FallbackToSMSIfNoEmail', 0, 'Enable|Disable', 'Send messages by SMS if no patron email is defined', 'YesNo');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21241 - Add FallbackToSMSIfNoEmail syspref )\n";
+}
+
+$DBversion = '18.12.00.010';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            ( variable, value, options, explanation, type )
+        VALUES
+            ('RESTPublicAPI','1',NULL,'If enabled, the REST API will expose the /public endpoints.','YesNo')
+    });
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22061 - Add a /public namespace that can be switched on/off)\n";
+}
+
+$DBversion = '18.12.00.011';
+if( CheckVersion( $DBversion ) ) {
+    if ( column_exists( 'biblio_metadata', 'marcflavour' ) ) {
+        $dbh->do(q{
+            ALTER TABLE biblio_metadata
+                CHANGE COLUMN marcflavour `schema` VARCHAR(16)
+        });
+    }
+    if ( column_exists( 'deletedbiblio_metadata', 'marcflavour' ) ) {
+        $dbh->do(q{
+            ALTER TABLE deletedbiblio_metadata
+                CHANGE COLUMN marcflavour `schema` VARCHAR(16)
+        });
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22155 - biblio_metadata.marcflavour should be renamed 'schema')\n";
+}
+
+$DBversion = '18.12.00.012';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences
+            (variable, value, options, explanation, type )
+        VALUES
+            ('RESTBasicAuth','0',NULL,'If enabled, Basic authentication is enabled for the REST API.','YesNo')
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22132 - Add Basic authentication)\n";
+}
+
+$DBversion = '18.12.00.013';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO permissions (module_bit, code, description) VALUES ( 3, 'manage_mana', 'Manage Mana KB content sharing');
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 22198 - Add ghranular permission setting for Mana KB)\n";
+}
+
+$DBversion = '18.12.00.014';
+if( CheckVersion( $DBversion ) ) {
+    unless( foreign_key_exists( 'messages', 'messages_borrowernumber' ) ) {
+        $dbh->do(q|
+            DELETE m FROM messages m
+            LEFT JOIN borrowers b ON m.borrowernumber=b.borrowernumber
+            WHERE b.borrowernumber IS NULL
+        |);
+        $dbh->do(q|
+            ALTER TABLE messages
+            ADD CONSTRAINT messages_borrowernumber
+            FOREIGN KEY (borrowernumber) REFERENCES borrowers (borrowernumber) ON DELETE CASCADE ON UPDATE CASCADE
+        |);
+    }
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 13515 - Add a FOREIGN KEY constaint on messages.borrowernumber)\n";
+}
+
+$DBversion = '18.12.00.015';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'cardnumber_replaced','cardnumber') WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'previous_cardnumber','before') WHERE module='MEMBERS' AND action='MODIFY'" );
+    $dbh->do( "UPDATE action_logs SET info = REPLACE(info,'new_cardnumber','after') WHERE module='MEMBERS' AND action='MODIFY'" );
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 3820 - Update patron modification logs)\n";
+}
+
+$DBversion = '18.12.00.016';
+if( CheckVersion( $DBversion ) ) {
+
+    if ( !column_exists( 'illrequests', 'status_alias' ) ) {
+        # Fresh upgrade, just add the column and constraint
+        $dbh->do( "ALTER TABLE illrequests ADD COLUMN status_alias varchar(80) DEFAULT NULL AFTER status" );
+    } else {
+        # Migrate all existing foreign keys from referencing authorised_values.id
+        # to referencing authorised_values.authorised_value
+        # First remove the foreign key constraint and index
+        if ( foreign_key_exists( 'illrequests', 'illrequests_safk' ) ) {
+            $dbh->do( "ALTER TABLE illrequests DROP FOREIGN KEY illrequests_safk");
+        }
+        if ( index_exists( 'illrequests', 'illrequests_safk' ) ) {
+            $dbh->do( "DROP INDEX illrequests_safk ON illrequests" );
+        }
+        # Now change the illrequests.status_alias column definition from int to varchar
+        $dbh->do( "ALTER TABLE illrequests MODIFY COLUMN status_alias varchar(80)" );
+        # Now replace all references to authorised_values.id with their
+        # corresponding authorised_values.authorised_value
+        my $sth = $dbh->prepare( "SELECT illrequest_id, status_alias FROM illrequests WHERE status_alias IS NOT NULL" );
+        $sth->execute();
+        while (my @row = $sth->fetchrow_array()) {
+            my $r_id = $row[0];
+            my $av_id = $row[1];
+            # Get the authorised value's authorised_value value
+            my ($av_val) = $dbh->selectrow_array( "SELECT authorised_value FROM authorised_values WHERE id = ?", {}, $av_id );
+            # Now update illrequests.status_alias
+            if ($av_val) {
+                $dbh->do( "UPDATE illrequests SET status_alias = ? WHERE illrequest_id = ?", {}, ($av_val, $r_id) );
+            }
+        }
+    }
+    if ( !foreign_key_exists( 'illrequests', 'illrequests_safk' ) ) {
+        $dbh->do( "ALTER TABLE illrequests ADD CONSTRAINT illrequests_safk FOREIGN KEY (status_alias) REFERENCES authorised_values(authorised_value) ON UPDATE CASCADE ON DELETE SET NULL" );
+    }
+    $dbh->do( "INSERT IGNORE INTO authorised_value_categories SET category_name = 'ILLSTATUS'");
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20581 - Allow manual selection of custom ILL request statuses)\n";
+}
+
+$DBversion = '18.12.00.017';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'fine_increase' ), ( 'fine_decrease' );
+    });
+    $dbh->do(q{
+        UPDATE account_offsets SET type = 'fine_increase' WHERE type = 'Fine Update' AND amount > 0;
+    });
+    $dbh->do(q{
+        UPDATE account_offsets SET type = 'fine_decrease' WHERE type = 'Fine Update' AND amount < 0;
+    });
+
+    $dbh->do(q{
+        DELETE FROM account_offset_types WHERE type = 'Fine Update';
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21747 - Update account_offset_types to include 'fine_increase' and 'fine_decrease')\n";
+}
+
+$DBversion = '18.12.00.018';
+if( CheckVersion( $DBversion ) ) {
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date-of-publication', `label` = 'date-of-publication' WHERE `name` = 'pubdate'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'title-series', `label` = 'title-series' WHERE `name` = 'se'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'identifier-standard', `label` = 'identifier-standard' WHERE `name` = 'identifier-standard'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'author', `label` = 'author' WHERE `name` = 'author'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'control-number', `label` = 'control-number' WHERE `name` = 'control-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'place-of-publication', `label` = 'place-of-publication' WHERE `name` = 'place'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date-of-acquisition', `label` = 'date-of-acquisition' WHERE `name` = 'acqdate'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'isbn', `label` = 'isbn' WHERE `name` = 'isbn'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'koha-auth-number', `label` = 'koha-auth-number' WHERE `name` = 'an'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'subject', `label` = 'subject' WHERE `name` = 'subject'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'publisher', `label` = 'publisher' WHERE `name` = 'publisher'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'record-source', `label` = 'record-source' WHERE `name` = 'record-source'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'title', `label` = 'title' WHERE `name` = 'title'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'local-classification', `label` = 'local-classification' WHERE `name` = 'local-classification'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bib-level', `label` = 'bib-level' WHERE `name` = 'bib-level'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'microform-generation', `label` = 'microform-generation' WHERE `name` = 'microform-generation'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'material-type', `label` = 'material-type' WHERE `name` = 'material-type'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bgf-number', `label` = 'bgf-number' WHERE `name` = 'bgf-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-db', `label` = 'number-db' WHERE `name` = 'number-db'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-natl-biblio', `label` = 'number-natl-biblio' WHERE `name` = 'number-natl-biblio'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'number-legal-deposit', `label` = 'number-legal-deposit' WHERE `name` = 'number-legal-deposit'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'issn', `label` = 'issn' WHERE `name` = 'issn'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'local-number', `label` = 'local-number' WHERE `name` = 'local-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'suppress', `label` = 'supress' WHERE `name` = 'suppress'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'bnb-card-number', `label` = 'bnb-card-number' WHERE `name` = 'bnb-card-number'" );
+  $dbh->do( "UPDATE `search_field` SET `name` = 'date/time-last-modified', `label` = 'date/time-last-modified' WHERE `name` = 'date-time-last-modified'" );
+  $dbh->do( "DELETE FROM `search_field` WHERE `name` = 'lc-cardnumber'" );
+  $dbh->do( "DELETE FROM `search_marc_map` WHERE `id` NOT IN(SELECT `search_marc_map_id` FROM `search_marc_to_field`)" );
+  SetVersion( $DBversion );
+  print "Upgrade to $DBversion done (Bug 19575 - Use canonical field names and resolve aliased fields)\n";
+}
+
+$DBversion = '18.12.00.019';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Reserve Fee' );
+    });
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 21728 - Add 'Reserve Fee' to the account_offset_types table if missing)\n";
+}
+
+$DBversion = '18.12.00.020';
+if( CheckVersion( $DBversion ) ) {
+    if ( TableExists( 'branch_borrower_circ_rules' ) ) {
+        if ( column_exists( 'branch_borrower_circ_rules', 'maxissueqty' ) ) {
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, branchcode, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+                FROM branch_borrower_circ_rules
+            ");
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, branchcode, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+                FROM branch_borrower_circ_rules
+            ");
+            $dbh->do("DROP TABLE branch_borrower_circ_rules");
+        }
+    }
+
+    if ( TableExists( 'default_borrower_circ_rules' ) ) {
+        if ( column_exists( 'default_borrower_circ_rules', 'maxissueqty' ) ) {
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, NULL, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+                FROM default_borrower_circ_rules
+            ");
+            $dbh->do("
+                INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+                SELECT categorycode, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+                FROM default_borrower_circ_rules
+            ");
+            $dbh->do("DROP TABLE default_borrower_circ_rules");
+        }
+    }
+
+    if ( column_exists( 'default_circ_rules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+            FROM default_circ_rules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+            FROM default_circ_rules
+        ");
+        $dbh->do("ALTER TABLE default_circ_rules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    if ( column_exists( 'default_branch_circ_rules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, branchcode, NULL, 'patron_maxissueqty', COALESCE( maxissueqty, '' )
+            FROM default_branch_circ_rules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT NULL, NULL, NULL, 'patron_maxonsiteissueqty', COALESCE( maxonsiteissueqty, '' )
+            FROM default_branch_circ_rules
+        ");
+        $dbh->do("ALTER TABLE default_branch_circ_rules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    if ( column_exists( 'issuingrules', 'maxissueqty' ) ) {
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT IF(categorycode='*', NULL, categorycode),
+                   IF(branchcode='*', NULL, branchcode),
+                   IF(itemtype='*', NULL, itemtype),
+                   'maxissueqty',
+                   COALESCE( maxissueqty, '' )
+            FROM issuingrules
+        ");
+        $dbh->do("
+            INSERT INTO circulation_rules ( categorycode, branchcode, itemtype, rule_name, rule_value )
+            SELECT IF(categorycode='*', NULL, categorycode),
+                   IF(branchcode='*', NULL, branchcode),
+                   IF(itemtype='*', NULL, itemtype),
+                   'maxonsiteissueqty',
+                   COALESCE( maxonsiteissueqty, '' )
+            FROM issuingrules
+        ");
+        $dbh->do("ALTER TABLE issuingrules DROP COLUMN maxissueqty, DROP COLUMN maxonsiteissueqty");
+    }
+
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 18925 - Move maxissueqty and maxonsiteissueqty to circulation_rules)\n";
+}
+
+$DBversion = '18.12.00.021';
+if ( CheckVersion($DBversion) ) {
+
+    if ( !column_exists( 'itemtypes', 'rentalcharge_daily' ) ) {
+        $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_daily` decimal(28,6) default NULL AFTER `rentalcharge`");
+    }
+
+    if ( !column_exists( 'itemtypes', 'rentalcharge_hourly' ) ) {
+        $dbh->do("ALTER TABLE `itemtypes` ADD COLUMN `rentalcharge_hourly` decimal(28,6) default NULL AFTER `rentalcharge_daily`");
+    }
+
+    if ( column_exists( 'itemtypes', 'rental_charge_daily' ) ) {
+        $dbh->do("UPDATE `itemtypes` SET `rentalcharge_daily` = `rental_charge_daily`");
+        $dbh->do("ALTER TABLE `itemtypes` DROP COLUMN `rental_charge_daily`");
+    }
+
+    SetVersion($DBversion);
+    print "Upgrade to $DBversion done (Bug 20912 - Support granular rental charges)\n";
+}
+
+$DBversion = '18.12.00.022';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do( q{
+        INSERT IGNORE INTO permissions (module_bit,code,description)
+        VALUES
+        (3,'manage_additional_fields','Add, edit, or delete additional custom fields for baskets or subscriptions (also requires order_manage or edit_subscription permissions)')
+    });
+    $dbh->do( q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+        SELECT borrowernumber, 3, 'manage_additional_fields' FROM borrowers WHERE borrowernumber IN (SELECT DISTINCT borrowernumber FROM user_permissions WHERE code = 'order_manage' OR code = 'edit_subscription');
+    });
+    $dbh->do( q{
+        INSERT INTO user_permissions (borrowernumber, module_bit, code)
+        SELECT borrowernumber, 3, 'manage_additional_fields' FROM borrowers WHERE borrowernumber IN (SELECT borrowernumber FROM borrowers WHERE MOD(flags DIV POWER(2,11),2)=1 OR MOD(flags DIV POWER(2,15),2) =1);
+    });
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 15774 - Add permission for managing additional fields)\n";
+}
+
+$DBversion = '18.12.00.023';
+if( CheckVersion( $DBversion ) ) {
+    $dbh->do(q|
+      INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type)
+      VALUES ('ILLOpacbackends',NULL,NULL,'ILL backends to enabled for OPAC initiated requests','multiple');
+    |);
+
+    # Always end with this (adjust the bug info)
+    SetVersion( $DBversion );
+    print "Upgrade to $DBversion done (Bug 20639 - Add ILLOpacbackends syspref)\n";
+}
+
 # SEE bug 13068
 # if there is anything in the atomicupdate, read and execute it.