Handling database changes in Moodle module upgrade
As I work on updated versions of Moodle modules I have found some difficulty in changing the default values of fields. The symptoms of this were successful module upgrades but that the default field values in the database had not changed. This turned out to be a result of my lack of understanding of the module upgrade process.
Here is an example taken from the corepack module table which is used to store statutory course information in our Moodle system:

The version number of this module held in mod/corepack/version.php is 2015052010 as shown. This version number is little off because the date referenced is in the future:
$module->version = 2015052010; //module version (Date: YYYYMMDDXX)
I needed to change the default values of the groupchecktype to 4 (from 9) and feedbacktypes fields to NULL (from ‘test’) in order to move from development defaults to live defaults.
I have to change the contents of the mod/corepack/db/upgrade.php and the version.php file above in order to do this. To trigger the upgrade I need to increment the version number while keeping a note of the current version.
I will set the new version to 2015052020
I have two changes to make. These are done in the upgrade.php file. Note that I check that the oldversion of the module is less than the new version number. If this is true the steps are carried out and then a save point is created. The mistake I was making previously was to have clashing $oldversion values in this file. Each stage must be an incremental version with a value LESS than the current version. (e.g. 2015052015 is less than 2015052020 so change first default, increment to 2015052016 which is still less than 2015052020 but greater than the now ‘old’ value of 2015052015 – generated by the upgrade_mod_savepoint call).
function xmldb_corepack_upgrade($oldversion) { global $DB; $dbman = $DB->get_manager(); // loads ddl manager and xmldb classes if ($oldversion < 2015052015) { // Changing the default of field groupchecktype $table = new xmldb_table('corepack'); $field = new xmldb_field('groupchecktype', XMLDB_TYPE_CHAR, '5', null, null, null, '4', 'reassessmenttext'); // Launch change of default for field groupchecktype. $dbman->change_field_default($table, $field); upgrade_mod_savepoint(true, 2015052015, 'corepack'); } if ($oldversion < 2015052016) { // Changing the default of field feedbacktypes $table = new xmldb_table('corepack'); $field = new xmldb_field('feedbacktypes', XMLDB_TYPE_CHAR, '5', null, null, null, null, 'groupchecklistformat'); // Launch change of default for field feedbacktypes. $dbman->change_field_default($table, $field); // Corepack savepoint reached. upgrade_mod_savepoint(true, 2015052016, 'corepack'); } return true; }
It took a bit of studying the upgrade.php files in other modules to finally put two and two together. Some of the modules (like book) have upgrade scripts which carry the module across major Moodle upgrades.
Now the upgrade is triggered from the admin page:

Now I check the default values in the moodle tables and see that the upgrade has indeed changed the defaults.
Moodle’s XMLDB (database abstraction layer) has taken some getting used to but I’m a bit more confident of dealing with major version changes in my own Moodle modules now.