From b05a49e46261fa5f63cdc64cfa3da2de80a1154b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20Hojtsy?= <gabor@hojtsy.hu>
Date: Thu, 17 Jan 2008 20:05:23 +0000
Subject: [PATCH] #208602 by KarenS: add support for aborting all updates of
 one module, when a critical error happens

---
 update.php | 43 +++++++++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/update.php b/update.php
index e7f750ee50e7..59a8eaa1614d 100644
--- a/update.php
+++ b/update.php
@@ -134,6 +134,13 @@ function db_change_column(&$ret, $table, $column, $column_new, $type, $attribute
  * 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
+ * have not yet been run.
+ *
  * @param $module
  *   The module whose update will be run.
  * @param $number
@@ -142,6 +149,12 @@ function db_change_column(&$ret, $table, $column, $column_new, $type, $attribute
  *   The batch context array
  */
 function update_do_one($module, $number, &$context) {
+  // If updates for this module have been aborted
+  // in a previous step, go no further.
+  if (!empty($context['results'][$module]['#abort'])) {
+    return;
+  }
+
   $function = $module .'_update_'. $number;
   if (function_exists($function)) {
     $ret = $function($context['sandbox']);
@@ -158,9 +171,13 @@ function update_do_one($module, $number, &$context) {
   if (!isset($context['results'][$module][$number])) {
     $context['results'][$module][$number] = array();
   }
-  $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);;
+  $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);
 
-  if ($context['finished'] == 1) {
+  if (!empty($ret['#abort'])) {
+    $context['results'][$module]['#abort'] = TRUE;
+  }
+  // The schema update is not updated once a module's updates have been aborted.
+  if ($context['finished'] == 1 && !empty($context['results'][$module]['#abort'])) {
     // Update the installed version
     drupal_set_installed_schema_version($module, $number);
   }
@@ -317,19 +334,21 @@ function update_results_page() {
     foreach ($_SESSION['update_results'] as $module => $updates) {
       $output .= '<h3>'. $module .' module</h3>';
       foreach ($updates as $number => $queries) {
-        $output .= '<h4>Update #'. $number .'</h4>';
-        $output .= '<ul>';
-        foreach ($queries as $query) {
-          if ($query['success']) {
-            $output .= '<li class="success">'. $query['query'] .'</li>';
+        if ($number != '#abort') {
+          $output .= '<h4>Update #'. $number .'</h4>';
+          $output .= '<ul>';
+          foreach ($queries as $query) {
+            if ($query['success']) {
+              $output .= '<li class="success">'. $query['query'] .'</li>';
+            }
+            else {
+              $output .= '<li class="failure"><strong>Failed:</strong> '. $query['query'] .'</li>';
+            }
           }
-          else {
-            $output .= '<li class="failure"><strong>Failed:</strong> '. $query['query'] .'</li>';
+          if (!count($queries)) {
+            $output .= '<li class="none">No queries</li>';
           }
         }
-        if (!count($queries)) {
-          $output .= '<li class="none">No queries</li>';
-        }
         $output .= '</ul>';
       }
     }
-- 
GitLab