Normally this doesn't cause much of a problem, but wrong update hook numbering just hurts my soul.
The documentation states: "Never renumber update hooks". Well ... screw that :-). Let's try and do it anyway, in a sensible and hopefully elegant manner.
The old and wrong hook_update_N numbering could look like this:
/** * Do stuff ... */ function mymodule_update_7000(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7001(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7100(&$sandbox) { // Do stuff ... }
7000 and 7001 are wrong in this case. Someone has then skipped to 7100 in an attempt to fix the numbering. But has obviously failed. What we really want is:
/** * Do stuff ... */ function mymodule_update_7101(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7102(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7103(&$sandbox) { // Do stuff ... }
How do we get from the old to the new?
/** * Mapping of schema versions (old => new). * * @return array */ function _mymodule_get_mapping() { return array( 7000 => 7101, 7001 => 7102, 7100 => 7103, ); } /** * Implements hook_requirements(). * * Check and fix schema version before updating. */ function mymodule_requirements($phase) { switch ($phase) { case 'update': _mymodule_renumber_schema_version(); break; } } /** * Drush does not invoke hook_requirements('update') for modules other * than 'system'. * * Attempt to intercept the command updatedb (updb), and fix the schema * version if applicable. */ if (drupal_is_cli() && function_exists('drush_get_command')) { $command = drush_get_command(); if (isset($command['command']) && $command['command'] == 'updatedb') { _mymodule_renumber_schema_version(); } } /** * Renumber current schema version according to mapping. */ function _mymodule_renumber_schema_version() { $schema_version = _mymodule_get_current_schema_version(); $mapping = _mymodule_get_mapping(); if (!empty($mapping[$schema_version])) { $new_version = $mapping[$schema_version]; drupal_set_installed_schema_version('mymodule', $new_version); } } /** * Helper function for getting the current schema version. */ function _mymodule_get_current_schema_version() { return db_select('system', 's') ->fields('s', array('schema_version')) ->condition('name', 'mymodule') ->execute() ->fetchField(); } /** * Do stuff ... */ function mymodule_update_7101(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7102(&$sandbox) { // Do stuff ... } /** * Do stuff ... */ function mymodule_update_7103(&$sandbox) { // Do stuff ... }
Caveat: The might very well be some slight problems regarding hook_update_dependencies(), if other modules implement this towards your module.