hook_update_N
- Versions
- 4.7 – 5
hook_update_N()- 6 – 7
hook_update_N(&$sandbox)
Perform a single update. For each patch which requires a database change add a new hook_update_N() which will be called by update.php.
The database updates are numbered sequentially according to the version of Drupal you are compatible with.
Schema updates should adhere to the Schema API: http://drupal.org/node/150215
Database updates consist of 3 parts:
- 1 digit for Drupal core compatibility
- 1 digit for your module's major release version (e.g. is this the 5.x-1.* (1) or 5.x-2.* (2) series of your module?)
- 2 digits for sequential counting starting with 00
The 2nd digit should be 0 for initial porting of your module to a new Drupal core API.
Examples:
- mymodule_update_5200()
- This is the first update to get the database ready to run mymodule 5.x-2.*.
- mymodule_update_6000()
- This is the required update for mymodule to run with Drupal core API 6.x.
- mymodule_update_6100()
- This is the first update to get the database ready to run mymodule 6.x-1.*.
- mymodule_update_6200()
- This is the first update to get the database ready to run mymodule 6.x-2.*. Users can directly update from 5.x-2.* to 6.x-2.* and they get all 60XX and 62XX updates, but not 61XX updates, because those reside in the 6.x-1.x branch only.
A good rule of thumb is to remove updates older than two major releases of Drupal. See hook_update_last_removed() to notify Drupal about the removals.
Never renumber update functions.
Further information about releases and release numbers:
- http://drupal.org/handbook/version-info
- http://drupal.org/node/93999 (Overview of contributions branches and tags)
- http://drupal.org/handbook/cvs/releases
Implementations of this hook should be placed in a mymodule.install file in the same directory as mymodule.module. Drupal core's updates are implemented using the system module as a name and stored in database/updates.inc.
If your update task is potentially time-consuming, you'll need to implement a multipass update to avoid PHP timeouts. Multipass updates use the $sandbox parameter provided by the batch API (normally, $context['sandbox']) to store information between successive calls, and the $sandbox['#finished'] value to provide feedback regarding completion level.
See the batch operations page for more information on how to use the batch API: http://drupal.org/node/146843
@throws DrupalUpdateException, PDOException In case of error, update hooks should throw an instance of DrupalUpdateException with a meaningful message for the user. If a database query fails for whatever reason, it will throw a PDOException.
Return value
Optionally update hooks may return a translated string that will be displayed to the user. If no message is returned, no message will be presented to the user.
Related topics
Code
modules/system/system.api.php, line 1975
<?php
function hook_update_N(&$sandbox) {
// For non-multipass updates, the signature can simply be;
// function hook_update_N() {
// For most updates, the following is sufficient.
db_add_field('mytable1', 'newcol', array('type' => 'int', 'not null' => TRUE, 'description' => 'My new integer column.'));
// However, for more complex operations that may take a long time,
// you may hook into Batch API as in the following example.
// Update 3 users at a time to have an exclamation point after their names.
// (They're really happy that we can do batch API in this hook!)
if (!isset($sandbox['progress'])) {
$sandbox['progress'] = 0;
$sandbox['current_uid'] = 0;
// We'll -1 to disregard the uid 0...
$sandbox['max'] = db_query('SELECT COUNT(DISTINCT uid) FROM {users}')->fetchField() - 1;
}
db_select('users', 'u')
->fields('u', array('uid', 'name'))
->condition('uid', $sandbox['current_uid'], '>')
->range(0, 3)
->orderBy('uid', 'ASC')
->execute();
foreach ($users as $user) {
$user->name .= '!';
db_update('users')
->fields(array('name' => $user->name))
->condition('uid', $user->uid)
->execute();
$sandbox['progress']++;
$sandbox['current_uid'] = $user->uid;
}
$sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
// To display a message to the user when the update is completed, return it.
// If you do not want to display a completion message, simply return nothing.
return t('The update did what it was supposed to do.');
// In case of an error, simply throw an exception with an error message.
throw new DrupalUpdateException('Something went wrong; here is what you should do.');
}
?>Login or register to post comments 