=== modified file 'includes/update.inc'
--- includes/update.inc 2009-08-22 18:24:14 +0000
+++ includes/update.inc 2009-08-23 01:54:39 +0000
@@ -273,7 +273,7 @@ function update_fix_d7_requirements() {
*
* Install profiles are now treated as modules by Drupal, and have an upgrade path
* based on their schema version in the system table.
- *
+ *
* The install profile will be set to schema_version 0, as it has already been
* installed. Any other hook_update_N functions provided by the install profile
* will be run by update.php.
@@ -365,13 +365,28 @@ function update_parse_db_url($db_url) {
* Perform one update and store the results which will later be displayed on
* the finished page.
*
- * An update 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
+ * If an update function completes successfully, it should return a message
+ * as a string indicating success, for example:
+ * @code
+ * return t('New index added successfully.');
+ * @endcode
+ *
+ * If it fails for whatever reason, it should throw an instance of
+ * DrupalUpdateException with an appropriate error message, for example:
+ * @code
+ * throw new DrupalUpdateException(t('Description of what went wrong'));
+ * @endcode
+ *
+ * If an exception is thrown, the current and all later updates for this module
+ * will be aborded. 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.
*
+ * If an update function needs to be re-run as part of a batch process, it
+ * should accept the $context array by reference as its first parameter
+ * and set the #finished property to the percentage completed that it is, as a
+ * decmial fraction of 1.
+ *
* @param $module
* The module whose update will be run.
* @param $number
@@ -386,9 +401,44 @@ function update_do_one($module, $number,
return;
}
+ if (!isset($context['log'])) {
+ $context['log'] = (bool) variable_get('update_log_queries', FALSE);
+ }
+
+ $ret = array();
$function = $module . '_update_' . $number;
if (function_exists($function)) {
- $ret = $function($context['sandbox']);
+ try {
+ if ($context['log']) {
+ Database::startLog($function);
+ }
+ $ret = array(
+ 'results' => array(
+ 'success' => TRUE,
+ 'query' => $function($context['sandbox']),
+ ),
+ );
+
+ // @TODO Remove this block after all updates have been converted to
+ // return only strings.
+ if (is_array($ret['results']['query'])) {
+ $ret = $ret['results']['query'];
+ }
+ }
+ // @TODO We may want to do different error handling for different exception
+ // types, but for now we'll just print the message.
+ catch (DrupalUpdateException $e) {
+ $ret['results'] = array('success' => FALSE, 'query' => $e->getMessage());
+ $ret['#abort'] = TRUE;
+ }
+ catch (Exception $e) {
+ $ret['results'] = array('success' => FALSE, 'query' => $e->getMessage());
+ $ret['#abort'] = TRUE;
+ }
+
+ if ($context['log']) {
+ $ret['queries'] = Database::getLog($function);
+ }
}
if (isset($ret['#finished'])) {
@@ -416,6 +466,11 @@ function update_do_one($module, $number,
}
/**
+ * @class Exception class used to throw error if a module update fails.
+ */
+class DrupalUpdateException extends Exception { }
+
+/**
* Start the database update batch process.
*
* @param $start
@@ -516,7 +571,7 @@ function update_finished($success, $resu
function update_get_update_list() {
// Make sure that the system module is first in the list of updates.
$ret = array('system' => array());
-
+
$modules = drupal_get_installed_schema_version(NULL, FALSE, TRUE);
foreach ($modules as $module => $schema_version) {
$pending = array();
@@ -530,7 +585,7 @@ function update_get_update_list() {
$ret[$module]['warning'] = '' . $module . ' module can not be updated. Its schema version is ' . $schema_version . '. Updates up to and including ' . $last_removed . ' have been removed in this release. In order to update ' . $module . ' module, you will first need to upgrade to the last version in which these updates were available.';
continue;
}
-
+
$updates = drupal_map_assoc($updates);
foreach (array_keys($updates) as $update) {
if ($update > $schema_version) {
@@ -548,7 +603,7 @@ function update_get_update_list() {
}
}
}
-
+
if (empty($ret['system'])) {
unset($ret['system']);
}
=== modified file 'modules/system/system.install'
--- modules/system/system.install 2009-08-22 18:24:14 +0000
+++ modules/system/system.install 2009-08-23 01:56:26 +0000
@@ -44,7 +44,7 @@ function system_requirements($phase) {
'severity' => REQUIREMENT_INFO,
'weight' => -9
);
- }
+ }
}
// Web server information.
@@ -2455,7 +2455,66 @@ function system_update_7036() {
return $ret;
}
+
+/**
+ * Test update 1. This should succeed and use the legacy return format.
+ *
+ * DO NOT COMMIT THIS FUNCTION.
+ */
+function system_update_9001() {
+
+ $ret[] = array('success' => TRUE, 'query' => t('This is the return message.'));
+ return $ret;
+}
+
/**
- * @} End of "defgroup updates-6.x-to-7.x"
- * The next series of updates should start at 8000.
+ * Test update 2. This should succeed.
+ *
+ * DO NOT COMMIT THIS FUNCTION.
*/
+function system_update_9002() {
+
+ // Do something interesting here.
+ return t('Yay, it worked');
+}
+
+/**
+ * Test update 3. This makes sure batching works.
+ *
+ * DO NOT COMMIT THIS FUNCITON.
+ */
+function system_update_9003(&$sandbox) {
+
+ if (empty($sandbox['step'])) {
+ $sandbox['step'] = 1;
+ }
+
+ if ($sandbox['step'] == 1) {
+ $sandbox['step'] = 2;
+ $sandbox['#finished'] = 0.5;
+ }
+
+ return t('Finished running when step is: ' . $sandbox['step']);
+}
+
+/**
+ * Test update 4. This should fail.
+ *
+ * DO NOT COMMIT THIS FUNCTION.
+ */
+function system_update_9004() {
+
+ throw new DrupalUpdateException(t('This is an error message.'));
+
+ return t('You should not see this message.');
+}
+
+/**
+ * Test update 5. This shouldn't even run.
+ *
+ * DO NOT COMMIT THIS FUNCTION.
+ */
+function system_update_9005() {
+ return t('You should not see this message, either.');
+}
+