summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngie Byron <webchick@24967.no-reply.drupal.org>2009-03-29 23:11:09 +0000
committerAngie Byron <webchick@24967.no-reply.drupal.org>2009-03-29 23:11:09 +0000
commit3c8f1540e15e7a6cbd0374eb048f4d36284ee8d6 (patch)
treea04273d2883603d462c9bfef2c728fc8d1e57d26
parenta88a999ca8feb46c61da97a6c0e8df37fae588fb (diff)
downloadbrdo-3c8f1540e15e7a6cbd0374eb048f4d36284ee8d6.tar.gz
brdo-3c8f1540e15e7a6cbd0374eb048f4d36284ee8d6.tar.bz2
#414218 by cha0s: Document hook_update_N()'s ability to use batch API.
-rw-r--r--modules/system/system.api.php41
1 files changed, 39 insertions, 2 deletions
diff --git a/modules/system/system.api.php b/modules/system/system.api.php
index 724a823e5..639d3dad9 100644
--- a/modules/system/system.api.php
+++ b/modules/system/system.api.php
@@ -1576,18 +1576,55 @@ function hook_install() {
* 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 $ret['#finished'] return value
+ * to provide feedback regarding completion level.
+ *
+ * See the batch operations page for more information on how to use the batch API:
+ * @link http://drupal.org/node/146843 http://drupal.org/node/146843 @endlink
+ *
* @return An array with the results of the calls to update_sql(). An upate
* function can force the current and all later updates for this
* module to abort by returning a $ret array with an element like:
* $ret['#abort'] = array('success' => FALSE, 'query' => 'What went wrong');
* The schema version will not be updated in this case, and all the
* aborted updates will continue to appear on update.php as updates that
- * have not yet been run.
+ * have not yet been run. Multipass update functions will also want to pass
+ * back the $ret['#finished'] variable to inform the batch API of progress.
*/
-function hook_update_N() {
+function hook_update_N(&$sandbox = NULL) {
+ // For most updates, the following is sufficient.
$ret = array();
db_add_field($ret, 'mytable1', 'newcol', array('type' => 'int', 'not null' => TRUE));
return $ret;
+
+ // However, for more complex operations that may take a long time,
+ // you may hook into Batch API as in the following example.
+ $ret = array();
+
+ // 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;
+ }
+
+ $users = db_query_range("SELECT uid, name FROM {users} WHERE uid > %d ORDER BY uid ASC", $sandbox['current_uid'], 0, 3);
+ foreach ($users as $user) {
+ $user->name .= '!';
+ $ret[] = update_sql("UPDATE {users} SET name = '$user->name' WHERE uid = $user->uid");
+
+ $sandbox['progress']++;
+ $sandbox['current_uid'] = $user->uid;
+ }
+
+ $ret['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+
+ return $ret;
}
/**