### Eclipse Workspace Patch 1.0
#P Test Drupal 6
Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.216
diff -u -r1.216 update.php
--- update.php	13 Apr 2007 08:56:57 -0000	1.216
+++ update.php	20 Apr 2007 20:35:53 -0000
@@ -283,37 +283,36 @@
  *   The module whose update will be run.
  * @param $number
  *   The update number to run.
- *
- * @return
- *   TRUE if the update was finished. Otherwise, FALSE.
+ * @param $a
+ *   The batch callback working array
  */
-function update_data($module, $number) {
-  $ret = module_invoke($module, 'update_'. $number);
+function update_data($module, $number, &$a) {
+  $function = $module .'_update_'. $number;
+  if (function_exists($function)) {
+    $ret = $function(&$a['sandbox']);
+  }
+
   // Assume the update finished unless the update results indicate otherwise.
-  $finished = 1;
+  $a['finished'] = 1;
   if (isset($ret['#finished'])) {
-    $finished = $ret['#finished'];
+    $a['finished'] = $ret['#finished'];
     unset($ret['#finished']);
   }
 
-  // Save the query and results for display by update_finished_page().
-  if (!isset($_SESSION['update_results'])) {
-    $_SESSION['update_results'] = array();
+  if (!isset($results[$module])) {
+    $a['results'][$module] = array();
   }
-  if (!isset($_SESSION['update_results'][$module])) {
-    $_SESSION['update_results'][$module] = array();
+  if (!isset($results[$module][$number])) {
+    $a['results'][$module][$number] = array();
   }
-  if (!isset($_SESSION['update_results'][$module][$number])) {
-    $_SESSION['update_results'][$module][$number] = array();
-  }
-  $_SESSION['update_results'][$module][$number] = array_merge($_SESSION['update_results'][$module][$number], $ret);
+  $a['results'][$module][$number] = array_merge($a['results'][$module][$number], $ret);
 
-  if ($finished == 1) {
+  if ($a['finished'] == 1) {
     // Update the installed version
     drupal_set_installed_schema_version($module, $number);
   }
 
-  return $finished;
+  return t('Updating @module module', array('@module' => $module));
 }
 
 function update_selection_page() {
@@ -322,7 +321,7 @@
 
   drupal_set_title('Drupal database update');
   // Prevent browser from using cached drupal.js or update.js
-  drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE);
+  //drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE);
   $output .= drupal_get_form('update_script_selection_form');
 
   update_task_list('select');
@@ -377,7 +376,7 @@
   return $form;
 }
 
-function update_update_page() {
+function update_set_batch() {
   // Set the installed version so updates start at the correct place.
   foreach ($_POST['start'] as $module => $version) {
     drupal_set_installed_schema_version($module, $version - 1);
@@ -386,146 +385,39 @@
     if ($version <= $max_version) {
       foreach ($updates as $update) {
         if ($update >= $version) {
-          $_SESSION['update_remaining'][] = array('module' => $module, 'version' => $update);
+          $operations[] = array(
+            'callback' => 'update_data',
+            'arguments' => array($module, $update),
+          );
         }
       }
     }
   }
-
-  // Keep track of total number of updates
-  if (isset($_SESSION['update_remaining'])) {
-    $_SESSION['update_total'] = count($_SESSION['update_remaining']);
-  }
-
-  if ($_POST['has_js']) {
-    return update_progress_page();
-  }
-  else {
-    return update_progress_page_nojs();
+  if ($operations) {
+    global $base_url;
+    $batch = array(
+      'title' => 'Updating',
+      'init_message' => 'Starting updates',
+      'error_message' => 'An unrecoverable error has occured. You can find the error message below. It is advised to copy it to the clipboard for reference.',
+      'finished' => 'update_finished',
+      'operations' => $operations,
+    );
+    batch_open($batch, $base_url .'/update.php', $base_url .'/update.php?op=results');
   }
 }
 
-function update_progress_page() {
-  // Prevent browser from using cached drupal.js or update.js
-  drupal_add_js('misc/progress.js', 'core', 'header', FALSE, TRUE);
-  drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE);
-
-  drupal_set_title('Updating');
-  update_task_list('run');
-  $output = '<div id="progress"></div>';
-  $output .= '<p id="wait">Please wait while your site is being updated.</p>';
-  return $output;
-}
-
-/**
- * Perform updates for one second or until finished.
- *
- * @return
- *   An array indicating the status after doing updates. The first element is
- *   the overall percentage finished. The second element is a status message.
- */
-function update_do_updates() {
-  while (isset($_SESSION['update_remaining']) && ($update = reset($_SESSION['update_remaining']))) {
-    $update_finished = update_data($update['module'], $update['version']);
-    if ($update_finished == 1) {
-      // Dequeue the completed update.
-      unset($_SESSION['update_remaining'][key($_SESSION['update_remaining'])]);
-      $update_finished = 0; // Make sure this step isn't counted double
-    }
-    if (timer_read('page') > 1000) {
-      break;
-    }
-  }
-
-  if ($_SESSION['update_total']) {
-    $percentage = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining']) + $update_finished) / $_SESSION['update_total'] * 100);
-  }
-  else {
-    $percentage = 100;
-  }
-
-  // When no updates remain, clear the caches in case the data has been updated.
-  if (!isset($update['module'])) {
-    cache_clear_all('*', 'cache', TRUE);
-    cache_clear_all('*', 'cache_page', TRUE);
-    cache_clear_all('*', 'cache_menu', TRUE);
-    cache_clear_all('*', 'cache_filter', TRUE);
-    drupal_clear_css_cache();
-  }
-
-  return array($percentage, isset($update['module']) ? 'Updating '. $update['module'] .' module' : 'Updating complete');
-}
-
-/**
- * Perform updates for the JS version and return progress.
- */
-function update_do_update_page() {
-  global $conf;
-
-  // HTTP Post required
-  if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-    drupal_set_message('HTTP Post is required.', 'error');
-    drupal_set_title('Error');
-    return '';
-  }
-
-  // Error handling: if PHP dies, the output will fail to parse as JSON, and
-  // the Javascript will tell the user to continue to the op=error page.
-  list($percentage, $message) = update_do_updates();
-  print drupal_to_js(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
-}
-
-/**
- * Perform updates for the non-JS version and return the status page.
- */
-function update_progress_page_nojs() {
-  drupal_set_title('Updating');
-  update_task_list('run');
-
-  $new_op = 'do_update_nojs';
-  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
-    // This is the first page so return some output immediately.
-    $percentage = 0;
-    $message = 'Starting updates';
-  }
-  else {
-    // This is one of the later requests: do some updates first.
-
-    // Error handling: if PHP dies due to a fatal error (e.g. non-existant
-    // function), it will output whatever is in the output buffer,
-    // followed by the error message. So, we put an explanation in the
-    // buffer to guide the user when an error happens.
-    ob_start();
-    $fallback = '<p class="error">An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference. Please continue to the <a href="update.php?op=error">update summary</a>.</p>';
-    $fallback = theme('maintenance_page', $fallback, FALSE);
-
-    // We strip the end of the page using a marker in the template, so any
-    // additional HTML output by PHP shows up inside the page rather than
-    // below it. While this causes invalid HTML, the same would be true if
-    // we didn't, as content is not allowed to appear after </html> anyway.
-    list($fallback) = explode('<!--partial-->', $fallback);
-    print $fallback;
-
-    // Do updates
-    list($percentage, $message) = update_do_updates();
-    if ($percentage == 100) {
-      $new_op = 'finished';
-    }
-
-    // Updates were successful; wipe the output buffer as it's unneeded.
-    ob_end_clean();
-  }
-
-  drupal_set_html_head('<meta http-equiv="Refresh" content="0; URL=update.php?op='. $new_op .'">');
-  $output = theme('progress_bar', $percentage, $message);
-  $output .= '<p>Updating your site will take a few seconds.</p>';
+function update_finished($success, $results) {
+  // clear the caches in case the data has been updated.
+  cache_clear_all('*', 'cache', TRUE);
+  cache_clear_all('*', 'cache_page', TRUE);
+  cache_clear_all('*', 'cache_filter', TRUE);
+  drupal_clear_css_cache();
 
-  // Note: do not output drupal_set_message()s until the summary page.
-  print theme('maintenance_page', $output, FALSE);
-  return NULL;
+  $_SESSION['update_results'] = $results;
+  $_SESSION['update_success'] = $success;
 }
 
-function update_finished_page($success) {
+function update_finished_page() {
   drupal_set_title('Drupal database update');
   // NOTE: we can't use l() here because the URL would point to 'update.php?q=admin'.
   $links[] = '<a href="'. base_path() .'">Main page</a>';
@@ -533,11 +425,12 @@
 
   update_task_list();
   // Report end result
-  if ($success) {
+  if ($_SESSION['update_success']) {
     $output = '<p>Updates were attempted. If you see no failures below, you may proceed happily to the <a href="index.php?q=admin">administration pages</a>. Otherwise, you may need to update your database manually. All errors have been <a href="index.php?q=admin/logs/watchdog">logged</a>.</p>';
   }
   else {
-    $update = reset($_SESSION['update_remaining']);
+    // TODO
+    $update = reset($results['update_remaining']);
     $output = '<p class="error">The update process was aborted prematurely while running <strong>update #'. $update['version'] .' in '. $update['module'] .'.module</strong>. All other errors have been <a href="index.php?q=admin/logs/watchdog">logged</a>. You may need to check the <code>watchdog</code> database table manually.</p>';
   }
 
@@ -571,8 +464,9 @@
       }
     }
     $output .= '</div>';
-    unset($_SESSION['update_results']);
   }
+  unset($_SESSION['update_results']);
+  unset($_SESSION['update_success']);
 
   return $output;
 }
@@ -780,6 +674,41 @@
 }
 
 /**
+ * Create the batch table.
+ *
+ * This is part of the Drupal 5.x to 6.x migration.
+ */
+function update_create_batch_table() {
+
+  // If cache_filter exists, update is not necessary
+  if (db_table_exists('batch')) {
+    return;
+  }
+
+  $ret = array();
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("CREATE TABLE {batch} (
+        bid int(11) NOT NULL,
+        timestamp int(11) NOT NULL,
+        batch longtext,
+        PRIMARY KEY  (bid)
+      ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
+      break;
+    case 'pgsql':
+      $ret[] = update_sql("CREATE TABLE {batch} (
+        bid int NOT NULL default '0',
+        timestamp int NOT NULL default '0',
+        batch text,
+        PRIMARY KEY  (bid)
+      )");
+     break;
+  }
+  return $ret;
+}
+
+/**
  * Add the update task list to the current page.
  */
 function update_task_list($active = NULL) {
@@ -808,6 +737,7 @@
 // variable_(get|set), which only works after a full bootstrap.
 update_fix_access_table();
 update_create_cache_tables();
+update_create_batch_table();
 
 // Turn error reporting back on. From now on, only fatal errors (which are
 // not passed through the error handler) will cause a message to be printed.
@@ -826,39 +756,39 @@
 
   $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
   switch ($op) {
-    case 'Update':
-      $output = update_update_page();
-      break;
-
-    case 'finished':
-      $output = update_finished_page(TRUE);
-      break;
-
-    case 'error':
-      $output = update_finished_page(FALSE);
+    // update.php ops
+    case '':
+      $output = update_info_page();
       break;
 
-    case 'do_update':
-      $output = update_do_update_page();
+    case 'selection':
+      $output = update_selection_page();
       break;
 
-    case 'do_update_nojs':
-      $output = update_progress_page_nojs();
+    case 'Update':
+      update_set_batch();
+      batch_execute();
       break;
 
-    case 'selection':
-      $output = update_selection_page();
+    case 'results':
+      $output = update_finished_page();
       break;
 
+    // Regular batch ops : defer to batch.inc
     default:
-      $output = update_info_page();
+      update_task_list('run');
+      $output = _batch_page();
       break;
   }
 }
 else {
   $output = update_access_denied_page();
 }
-
 if (isset($output)) {
-  print theme('maintenance_page', $output);
+  if ($output === FALSE) {
+    // TODO : ??
+  }
+  else {
+    print theme('maintenance_page', $output);
+  }
 }
