Index: update.php
===================================================================
RCS file: /cvs/drupal/drupal/update.php,v
retrieving revision 1.158
diff -u -F^f -r1.158 update.php
--- update.php	11 Oct 2005 20:46:17 -0000	1.158
+++ update.php	8 Nov 2005 06:44:56 -0000
@@ -17,49 +17,222 @@
 // Enforce access checking?
 $access_check = TRUE;
 
-if (!ini_get("safe_mode")) {
-  set_time_limit(180);
+
+define('SCHEMA', 0);
+define('SCHEMA_MIN', 1);
+
+/**
+ * Includes install files.
+ */
+function update_include_install_files() {
+  // The system module (Drupal core) is currently a special case
+  include_once './database/updates.inc';
+
+  foreach (module_list() as $module) {
+    $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install';
+    if (is_file($install_file)) {
+      include_once $install_file;
+    }
+  }
+}
+
+function update_sql($sql) {
+  $result = db_query($sql);
+  return array('success' => $result !== FALSE, 'query' => check_plain($sql));
 }
 
-include_once './database/updates.inc';
+/**
+ * If the schema version for Drupal core is stored in the the variables table
+ * (4.6.x and earlier) move it to the schema_version column of the system
+ * table.
+ */
+function update_fix_schema_version() {
+  if ($update_start = variable_get('update_start', FALSE)) {
+    // Some updates were made to the 4.6 branch and 4.7 branch. This sets
+    // temporary variables to provent the updates from being executed twice and
+    // throwing errors.
+    switch ($update_start) {
+      case '2005-04-14':
+        variable_set('update_132_done', TRUE);
+        break;
+
+      case '2005-05-06':
+        variable_set('update_132_done', TRUE);
+        variable_set('update_135_done', TRUE);
+        break;
+
+      case '2005-05-07':
+        variable_set('update_132_done', TRUE);
+        variable_set('update_135_done', TRUE);
+        variable_set('update_137_done', TRUE);
+        break;
+
+    }
+
+    $sql_updates = array(
+      '2004-10-31: first update since Drupal 4.5.0 release' => 110,
+      '2004-11-07' => 111, '2004-11-15' => 112, '2004-11-28' => 113,
+      '2004-12-05' => 114, '2005-01-07' => 115, '2005-01-14' => 116,
+      '2005-01-18' => 117, '2005-01-19' => 118, '2005-01-20' => 119,
+      '2005-01-25' => 120, '2005-01-26' => 121, '2005-01-27' => 122,
+      '2005-01-28' => 123, '2005-02-11' => 124, '2005-02-23' => 125,
+      '2005-03-03' => 126, '2005-03-18' => 127, '2005-03-21' => 128,
+      // The following three updates were made on the 4.6 branch
+      '2005-04-14' => 129, '2005-05-06' => 129, '2005-05-07' => 129,
+      '2005-04-08: first update since Drupal 4.6.0 release' => 129,
+      '2005-04-10' => 130, '2005-04-11' => 131, '2005-04-14' => 132,
+      '2005-04-24' => 133, '2005-04-30' => 134, '2005-05-06' => 135,
+      '2005-05-08' => 136, '2005-05-09' => 137, '2005-05-10' => 138,
+      '2005-05-11' => 139, '2005-05-12' => 140, '2005-05-22' => 141,
+      '2005-07-29' => 142, '2005-07-30' => 143, '2005-08-08' => 144,
+      '2005-08-15' => 145, '2005-08-25' => 146, '2005-09-07' => 147,
+      '2005-09-18' => 148, '2005-09-27' => 149, '2005-10-15' => 150,
+      '2005-10-23' => 151, '2005-10-28' => 152, '2005-11-03' => 153
+    );
+    db_query('ALTER TABLE {system} ADD schema_version smallint(2) unsigned not null');
+    update_set_installed_version('system', $sql_updates[$update_start]);
+    variable_del('update_start');
+  }
+}
 
-function update_data($start) {
-  global $sql_updates;
-  $output = '';
-  $sql_updates = array_slice($sql_updates, ($start-- ? $start : 0));
-  foreach ($sql_updates as $date => $func) {
-    $output .= '<h3 class="update">'. $date .'</h3><pre class="update">';
-    $ret = $func();
-    foreach ($ret as $return) {
-      $output .= $return[1];
+/**
+ * System update 130 changes the sessions table, which breaks the update
+ * script's ability to use session variables. This changes the table
+ * appropriately.
+ *
+ * This code, including the 'update_sessions_fixed' variable, may be removed
+ * when update 130 is removed. It is part of the Drupal 4.6 to 4.7 migration.
+ */
+function update_fix_sessions() {
+  if (update_get_installed_version('system') < 130 && !variable_get('update_sessions_fixed', FALSE)) {
+    if ($GLOBALS['db_type'] == 'mysql') {
+      db_query("ALTER TABLE {sessions} ADD cache int(11) NOT NULL default '0' AFTER timestamp");
+    }
+    elseif ($GLOBALS['db_type'] == 'pgsql') {
+      db_add_column($ret, 'sessions', 'cache', 'int', array('default' => 0, 'not null' => TRUE));
     }
-    variable_set("update_start", $date);
-    $output .= "</pre>\n";
+
+    variable_set('update_sessions_fixed', TRUE);
   }
-  db_query('DELETE FROM {cache}');
-  return $output;
 }
 
-function update_selection_page() {
-  global $sql_updates;
+/**
+ * System update 142 changes the watchdog table, which breaks the update
+ * script's ability to use logging. This changes the table appropriately.
+ *
+ * This code, including the 'update_watchdog_fixed' variable,  may be removed
+ * when update 142 is removed. It is part of the Drupal 4.6 to 4.7 migration.
+ */
+function update_fix_watchdog() {
+  if (update_get_installed_version('system') < 142 && !variable_get('update_watchdog_fixed', FALSE)) {
+    switch ($GLOBALS['db_type']) {
+      case 'pgsql':
+        db_add_column($ret, 'watchdog', 'referer', 'varchar(128)', array('not null' => TRUE, 'default' => ''));
+        break;
+      case 'mysql':
+      case 'mysqli':
+        $ret[] = db_query("ALTER TABLE {watchdog} ADD COLUMN referer varchar(128) NOT NULL");
+        break;
+    }
+
+    variable_set('update_watchdog_fixed', TRUE);
+  }
+}
+
+function update_data($module, $number) {
+  $ret = module_invoke($module, 'update_'. $number);
+
+  // Save the query and results for display by update_finished_page().
+  if (!isset($_SESSION['update_results'])) {
+    $_SESSION['update_results'] = array();
+  }
+  else if (!isset($_SESSION['update_results'][$module])) {
+    $_SESSION['update_results'][$module] = array();
+  }
+  $_SESSION['update_results'][$module][$number] = $ret;
+  
+  // Update the installed version
+  update_set_installed_version($module, $number);
+}
+
+/**
+ * Returns an array of availiable schema versions for a module.
+ *
+ * @param $module
+ *   A module name.
+ * @return
+ *   If the module has updates, an array of available updates. Otherwise,
+ *   FALSE.
+ */
+function update_get_versions($module) {
+  if (!($max = module_invoke($module, 'version', SCHEMA))) {
+    return FALSE;
+  }
+  if (!($min = module_invoke($module, 'version', SCHEMA_MIN))) {
+    $min = 1;
+  }
+  return range($min, $max);
+}
+
+/**
+ * Returns the currently installed schema version for a module.
+ *
+ * @param $module
+ *   A module name.
+ * @return
+ *   The currently installed schema version.
+ */
+function update_get_installed_version($module, $reset = FALSE) {
+  static $versions;
+
+  if ($reset) {
+    unset($versions);
+  }
+
+  if (!$versions) {
+    $versions = array();
+    $result = db_query("SELECT name, schema_version FROM {system} WHERE type = 'module'");
+    while ($row = db_fetch_object($result)) {
+      $versions[$row->name] = $row->schema_version;
+    }
+  }
+
+  return $versions[$module];
+}
+
+/**
+ * Update the installed version information for a module.
+ *
+ * @param $module
+ *   A module name.
+ * @param $version
+ *   The new schema version.
+ */
+function update_set_installed_version($module, $version) {
+  db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s'", $version, $module);
+}
+
+function update_advanced_selection_page() {
+  $form = array();
+  $form['start'] = array('#tree' => TRUE);
+  foreach (module_list() as $module) {
+    if (module_hook($module, 'version')) {
+      $updates = drupal_map_assoc(update_get_versions($module));
+      $updates[] = 'No updates available';
+
+      $form['start'][$module] = array(
+        '#type' => 'select',
+        '#title' => t('%name module', array('%name' => $module)),
+        '#default_value' => array_search(update_get_installed_version($module), $updates) + 1,
+        '#options' => $updates,
+        '#description' => t('This defaults to the first available update since the last update you performed.')
+      );
+    }
+  }
 
-  $start = variable_get("update_start", 0);
-  $i = 1;
-  foreach ($sql_updates as $date => $sql) {
-    $dates[$i++] = $date;
-    if ($date == $start) {
-      $selected = $i;
-    }
-  }
-  $dates[$i] = "No updates available";
-
-  // make update form and output it.
-  $form['start'] = array(
-    '#type' => 'select',
-    '#title' => t('Perform updates from'),
-    '#default_value' => (isset($selected) ? $selected : -1),
-    '#options' => $dates,
-    '#description' => t('This defaults to the first available update since the last update you performed.')
+  $form['has_js'] = array(
+    '#type' => 'hidden',
+    '#default_value' => FALSE
   );
   $form['submit'] = array(
     '#type' => 'submit',
@@ -67,21 +240,141 @@ function update_selection_page() {
   );
 
   drupal_set_title('Drupal database update');
+  drupal_add_js('misc/update.js');
   return drupal_get_form('update_script_selection_form', $form);
 }
 
+function update_update_page() {
+  // Set the installed version so updates start at the correct place.
+  $_SESSION['update_remaining'] = array();
+  foreach ($_POST['edit']['start'] as $module => $version) {
+    update_set_installed_version($module, $version - 1);
+    $max_version = max(update_get_versions($module));
+    if ($version <= $max_version) {
+      foreach (range($version, $max_version) as $update) {
+        $_SESSION['update_remaining'][] = array('module' => $module, 'version' => $update);
+      }
+    }
+  }
+
+  if ($_POST['edit']['has_js']) {
+    return update_progress_page();
+  }
+  else {
+    return update_progress_page_nojs();
+  }
+}
+
+function update_progress_page() {
+  drupal_add_js('misc/progress.js');
+  drupal_add_js('misc/update.js');
+
+  drupal_set_title('Updating');
+  $output = '<div id="progress"></div>';
+  $output .= '<p>Updating your site will take a few seconds.</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 percent finished. The second element is a status message.
+ */
 function update_do_updates() {
-  $edit = $_POST['edit'];
+  foreach ($_SESSION['update_remaining'] as $key => $update) {
+    update_data($update['module'], $update['version']);
+    unset($_SESSION['update_remaining'][$key]);
+    if (timer_read('page') > 1000) {
+      break;
+    }
+  }
+
+  if ($_SESSION['update_total']) {
+    $percent = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining'])) / $_SESSION['update_total'] * 100);
+  }
+  else {
+    $percent = 100;
+  }
+  return array($percent, 'Updating '. $update['module'] .' module');
+}
+
+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 '';
+  }
+
+  // Any errors which happen would cause the result to not be parsed properly,
+  // so we need to supporess them. All errors are still logged.
+  if (!isset($conf['error_level'])) {
+    $conf['error_level'] = 0;
+  }
+  ini_set('display_errors', FALSE);
+
+  print implode('|', update_do_updates());
+}
+
+function update_progress_page_nojs() {
+  $new_op = 'do_update_nojs';
+  if ($_SERVER['REQUEST_METHOD'] == 'GET') {
+    list($percent, $message) = update_do_updates();
+    if ($percent == 100) {
+      $new_op = 'finished';
+    }
+  }
+  else {
+    // This is the first page so return some output immediately.
+    $percent = 0;
+    $message = 'Starting updates...';
+  }
+
+  drupal_set_html_head('<meta http-equiv="Refresh" content="0; URL=update.php?op='. $new_op .'">');
+  drupal_set_title('Updating');
+  $output = theme('progress_bar', $percent, $message);
+  $output .= '<p>Updating your site will take a few seconds.</p>';
+
+  return $output;
+}
+
+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=\"index.php\">main page</a>";
-  $links[] = "<a href=\"index.php?q=admin\">administration pages</a>";
+  $links[] = '<a href="">main page</a>';
+  $links[] = '<a href="?q=admin">administration pages</a>';
   $output = theme('item_list', $links);
-  $output .= update_data($edit['start']);
-  $output .= '<p>Updates were attempted. If you see no failures above, you may proceed happily to the <a href="index.php?q=admin">administration pages</a>. Otherwise, you may need to update your database manually.</p>';
+  $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">logged</a>.</p>';
   if ($GLOBALS['access_check'] == FALSE) {
     $output .= "<p><strong>Reminder: don't forget to set the <code>\$access_check</code> value at the top of <code>update.php</code> back to <code>TRUE</code>.</strong>";
   }
+
+  // Output a list of queryies executed
+  if ($_SESSION['update_results']) {
+    $output .= '<h2>The following queries were executed</h2>';
+    foreach ($_SESSION['update_results'] as $module => $updates) {
+      $output .= '<h3>'. $module .' module</h3>';
+      foreach ($updates as $number => $queries) {
+        $output .= '<h4>Update #'. $number .'</h4>';
+        $output .= '<ul id="update-results">';
+        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>';
+          }
+        }
+        $output .= '</ul>';
+      }
+    }
+    unset($_SESSION['update_results']);
+  }
+
   return $output;
 }
 
@@ -90,7 +383,7 @@ function update_info_page() {
   $output = "<ol>\n";
   $output .= "<li>Use this script to <strong>upgrade an existing Drupal installation</strong>. You don't need this script when installing Drupal from scratch.</li>";
   $output .= "<li>Before doing anything, backup your database. This process will change your database and its values, and some things might get lost.</li>\n";
-  $output .= "<li>Update your Drupal sources, check the notes below and <a href=\"update.php?op=update\">run the database upgrade script</a>. Don't upgrade your database twice as it may cause problems.</li>\n";
+  $output .= "<li>Update your Drupal sources, check the notes below and <a href=\"update.php?op=selection\">run the database upgrade script</a>. Don't upgrade your database twice as it may cause problems.</li>\n";
   $output .= "<li>Go through the various administration pages to change the existing and new settings to your liking.</li>\n";
   $output .= "</ol>";
   $output .= '<p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>';
@@ -109,34 +402,48 @@ function update_access_denied_page() {
 }
 
 include_once './includes/bootstrap.inc';
+drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 drupal_maintenance_theme();
 
-if (isset($_GET["op"])) {
-  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-
-  // Access check:
-  if (($access_check == 0) || ($user->uid == 1)) {
-    $op = isset($_POST['op']) ? $_POST['op'] : '';
-    switch ($op) {
-      case 'Update':
-        $output = update_do_updates();
-        break;
-
-      default:
-        $output = update_selection_page();
-        break;
-    }
-  }
-  else {
-    $output = update_access_denied_page();
+// Access check:
+if (($access_check == FALSE) || ($user->uid == 1)) {
+  update_include_install_files();
+
+  update_fix_schema_version();
+  update_fix_sessions();
+  update_fix_watchdog();
+
+  $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
+  switch ($op) {
+    case 'Update':
+      $output = update_update_page();
+      break;
+
+    case 'finished':
+      $output = update_finished_page();
+      break;
+
+    case 'do_update':
+      $output = update_do_update_page();
+      break;
+
+    case 'do_update_nojs':
+      $output = update_progress_page_nojs();
+      break;
+
+    case 'selection':
+      $output = update_advanced_selection_page();
+      break;
+
+    default:
+      $output = update_info_page();
+      break;
   }
 }
 else {
-  drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
-  $output = update_info_page();
+  $output = update_access_denied_page();
 }
 
 if (isset($output)) {
   print theme('maintenance_page', $output);
 }
-
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.144
diff -u -F^f -r1.144 updates.inc
--- database/updates.inc	6 Nov 2005 11:33:28 -0000	1.144
+++ database/updates.inc	8 Nov 2005 06:44:57 -0000
@@ -57,56 +57,17 @@
  *
  */
 
+function system_version($type) {
+  switch ($type) {
+    case SCHEMA:
+      return 153;
 
-// Define the various updates in an array("date : comment" => "function");
-$sql_updates = array(
-  "2004-10-31: first update since Drupal 4.5.0 release" => "update_110",
-  "2004-11-07" => "update_111",
-  "2004-11-15" => "update_112",
-  "2004-11-28" => "update_113",
-  "2004-12-05" => "update_114",
-  "2005-01-07" => "update_115",
-  "2005-01-14" => "update_116",
-  "2005-01-18" => "update_117",
-  "2005-01-19" => "update_118",
-  "2005-01-20" => "update_119",
-  "2005-01-25" => "update_120",
-  "2005-01-26" => "update_121",
-  "2005-01-27" => "update_122",
-  "2005-01-28" => "update_123",
-  "2005-02-11" => "update_124",
-  "2005-02-23" => "update_125",
-  "2005-03-03" => "update_126",
-  "2005-03-18" => "update_127",
-  "2005-03-21" => "update_128",
-  "2005-04-08: first update since Drupal 4.6.0 release" => "update_129",
-  "2005-04-10" => "update_130",
-  "2005-04-11" => "update_131",
-  "2005-04-14" => "update_132",
-  "2005-04-24" => "update_133",
-  "2005-04-30" => "update_134",
-  "2005-05-06" => "update_135",
-  "2005-05-08" => "update_136",
-  "2005-05-09" => "update_137",
-  "2005-05-10" => "update_138",
-  "2005-05-11" => "update_139",
-  "2005-05-12" => "update_140",
-  "2005-05-22" => "update_141",
-  "2005-07-29" => "update_142",
-  "2005-07-30" => "update_143",
-  "2005-08-08" => "update_144",
-  "2005-08-15" => "update_145",
-  "2005-08-25" => "update_146",
-  "2005-09-07" => "update_147",
-  "2005-09-18" => "update_148",
-  "2005-09-27" => "update_149",
-  "2005-10-15" => "update_150",
-  "2005-10-23" => "update_151",
-  "2005-10-28" => "update_152",
-  "2005-11-03" => "update_153"
-);
+    case SCHEMA_MIN:
+      return 110;
+  }
+}
 
-function update_110() {
+function system_update_110() {
   $ret = array();
 
   // TODO: needs PGSQL version
@@ -190,7 +151,7 @@ function update_110() {
   return $ret;
 }
 
-function update_111() {
+function system_update_111() {
   $ret = array();
 
   $ret[] = update_sql("DELETE FROM {variable} WHERE name LIKE 'throttle_%'");
@@ -205,7 +166,7 @@ function update_111() {
   return $ret;
 }
 
-function update_112() {
+function system_update_112() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -226,7 +187,7 @@ function update_112() {
   return $ret;
 }
 
-function update_113() {
+function system_update_113() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -257,7 +218,7 @@ function update_113() {
   return $ret;
 }
 
-function update_114() {
+function system_update_114() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql("CREATE TABLE {queue} (
@@ -311,7 +272,7 @@ function update_114() {
   return $ret;
 }
 
-function update_115() {
+function system_update_115() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql("ALTER TABLE {watchdog} ADD severity tinyint(3) unsigned NOT NULL default '0'");
@@ -325,11 +286,11 @@ function update_115() {
   return $ret;
 }
 
-function update_116() {
+function system_update_116() {
   return array(update_sql("DELETE FROM {system} WHERE name = 'admin'"));
 }
 
-function update_117() {
+function system_update_117() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql("CREATE TABLE {vocabulary_node_types} (
@@ -346,7 +307,7 @@ function update_117() {
   return $ret;
 }
 
-function update_118() {
+function system_update_118() {
   $ret = array();
   $result = db_query('SELECT vid, nodes FROM {vocabulary}');
   while ($vocabulary = db_fetch_object($result)) {
@@ -363,7 +324,7 @@ function update_118() {
   return $ret;
 }
 
-function update_119() {
+function system_update_119() {
   $ret = array();
 
   foreach (node_get_types() as $type => $name) {
@@ -394,7 +355,7 @@ function update_119() {
   return $ret;
 }
 
-function update_120() {
+function system_update_120() {
   $ret = array();
 
   // Rewrite old URL aliases.  Works for both PostgreSQL and MySQL
@@ -410,7 +371,7 @@ function update_120() {
   return $ret;
 }
 
-function update_121() {
+function system_update_121() {
   $ret = array();
 
   // Remove the unused page table.
@@ -419,7 +380,7 @@ function update_121() {
   return $ret;
 }
 
-function update_122() {
+function system_update_122() {
 
   $ret = array();
   $ret[] = update_sql("ALTER TABLE {blocks} ADD types text");
@@ -427,7 +388,7 @@ function update_122() {
 
 }
 
-function update_123() {
+function system_update_123() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -449,7 +410,7 @@ function update_123() {
   return $ret;
 }
 
-function update_124() {
+function system_update_124() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -497,7 +458,7 @@ function update_124() {
   return $ret;
 }
 
-function update_125() {
+function system_update_125() {
   // Postgres only update.
   $ret = array();
 
@@ -516,7 +477,7 @@ function update_125() {
   return $ret;
 }
 
-function update_126() {
+function system_update_126() {
   variable_set('forum_block_num_0', variable_get('forum_block_num', 5));
   variable_set('forum_block_num_1', variable_get('forum_block_num', 5));
   variable_del('forum_block_num');
@@ -524,7 +485,7 @@ function update_126() {
   return array();
 }
 
-function update_127() {
+function system_update_127() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'pgsql') {
     $ret[] = update_sql("ALTER TABLE {poll} RENAME voters TO polled");
@@ -535,7 +496,7 @@ function update_127() {
   return $ret;
 }
 
-function update_128() {
+function system_update_128() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -548,7 +509,7 @@ function update_128() {
   return $ret;
 }
 
-function update_129() {
+function system_update_129() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -561,18 +522,16 @@ function update_129() {
   return $ret;
 }
 
-function update_130() {
+function system_update_130() {
   $ret = array();
-  if ($GLOBALS['db_type'] == 'mysql') {
-    $ret[] = update_sql("ALTER TABLE {sessions} ADD cache int(11) NOT NULL default '0'");
-  }
-  elseif ($GLOBALS['db_type'] == 'pgsql') {
-    db_add_column($ret, 'sessions', 'cache', 'int', array('default' => 0, 'not null' => TRUE));
-  }
+
+  // This update has been moved to update_fix_sessions in update.php because it
+  // is needed for the basic functioning of the update script.
+  
   return $ret;
 }
 
-function update_131() {
+function system_update_131() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -586,30 +545,34 @@ function update_131() {
   return $ret;
 }
 
-function update_132() {
+function system_update_132() {
   /**
    * PostgreSQL only update.
    */
   $ret = array();
 
-  if ($GLOBALS['db_type'] == 'pgsql') {
-    $ret[] = update_sql('DROP TABLE {search_total}');
-    $ret[] = update_sql("CREATE TABLE {search_total} (
-              word varchar(50) NOT NULL default '',
-              count float default NULL)");
-    $ret[] = update_sql('CREATE INDEX {search_total}_word_idx ON {search_total}(word)');
+  if (variable_get('update_132_done', FALSE)) {
+    if ($GLOBALS['db_type'] == 'pgsql') {
+      $ret[] = update_sql('DROP TABLE {search_total}');
+      $ret[] = update_sql("CREATE TABLE {search_total} (
+        word varchar(50) NOT NULL default '',
+             count float default NULL)");
+      $ret[] = update_sql('CREATE INDEX {search_total}_word_idx ON {search_total}(word)');
+
+      /**
+       * Wipe the search index
+       */
+      include_once './modules/search.module';
+      search_wipe();
+    }
 
-    /**
-     * Wipe the search index
-     */
-    include_once './modules/search.module';
-    search_wipe();
+    variable_del('update_132_done');
   }
 
   return $ret;
 }
 
-function update_133() {
+function system_update_133() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -630,7 +593,7 @@ function update_133() {
   return $ret;
 }
 
-function update_134() {
+function system_update_134() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql('ALTER TABLE {blocks} DROP types');
@@ -641,16 +604,20 @@ function update_134() {
   return $ret;
 }
 
-function update_135() {
-  $result = db_query("SELECT delta FROM {blocks} WHERE module = 'aggregator'");
-  while ($block = db_fetch_object($result)) {
-    list($type, $id) = explode(':', $block->delta);
-    db_query("UPDATE {blocks} SET delta = '%s' WHERE module = 'aggregator' AND delta = '%s'", $type .'-'. $id, $block->delta);
+function system_update_135() {
+  if (variable_get('update_135_done', FALSE)) {
+    $result = db_query("SELECT delta FROM {blocks} WHERE module = 'aggregator'");
+    while ($block = db_fetch_object($result)) {
+      list($type, $id) = explode(':', $block->delta);
+      db_query("UPDATE {blocks} SET delta = '%s' WHERE module = 'aggregator' AND delta = '%s'", $type .'-'. $id, $block->delta);
+    }
+
+    variable_del('update_135_done');
   }
   return array();
 }
 
-function update_136() {
+function system_update_136() {
   $ret = array();
 
   switch ($GLOBALS['db_type']) {
@@ -670,26 +637,30 @@ function update_136() {
   return $ret;
 }
 
-function update_137() {
+function system_update_137() {
   $ret = array();
 
-  if ($GLOBALS['db_type'] == 'mysql') {
-    $ret[] = update_sql("ALTER TABLE {locales_source} CHANGE location location varchar(255) NOT NULL default ''");
-  }
-  elseif ($GLOBALS['db_type'] == 'pgsql') {
-    db_change_column($ret, 'locales_source', 'location', 'location', 'varchar(255)', array('not null' => TRUE, 'default' => ''));
+  if (variable_get('update_137_done', FALSE)) {
+    if ($GLOBALS['db_type'] == 'mysql') {
+      $ret[] = update_sql("ALTER TABLE {locales_source} CHANGE location location varchar(255) NOT NULL default ''");
+    }
+    elseif ($GLOBALS['db_type'] == 'pgsql') {
+      db_change_column($ret, 'locales_source', 'location', 'location', 'varchar(255)', array('not null' => TRUE, 'default' => ''));
+    }
+    variable_del('update_137_done');
   }
+
   return $ret;
 }
 
-function update_138() {
+function system_update_138() {
   $ret = array();
   // duplicate of update_97 which never got into the default database.* files.
   $ret[] = update_sql("INSERT INTO {url_alias} (src, dst) VALUES ('node/feed', 'rss.xml')");
   return $ret;
 }
 
-function update_139() {
+function system_update_139() {
   $ret = array();
   switch ($GLOBALS['db_type']) {
     case 'pgsql':
@@ -704,7 +675,7 @@ function update_139() {
   return $ret;
 }
 
-function update_140() {
+function system_update_140() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -716,7 +687,7 @@ function update_140() {
   return $ret;
 }
 
-function update_141() {
+function system_update_141() {
   $ret = array();
 
   variable_del('upload_maxsize_total');
@@ -724,21 +695,16 @@ function update_141() {
   return $ret;
 }
 
-function update_142() {
+function system_update_142() {
   $ret = array();
-  switch ($GLOBALS['db_type']) {
-    case 'pgsql':
-      db_add_column($ret, 'watchdog', 'referer', 'varchar(128)', array('not null' => TRUE, 'default' => ''));
-      break;
-    case 'mysql':
-    case 'mysqli':
-      $ret[] = update_sql("ALTER TABLE {watchdog} ADD COLUMN referer varchar(128) NOT NULL");
-      break;
-  }
+
+  // This update has been moved to update_fix_sessions in update.php because it
+  // is needed for the basic functioning of the update script.
+
   return $ret;
 }
 
-function update_143() {
+function system_update_143() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -757,7 +723,7 @@ function update_143() {
   return $ret;
 }
 
-function update_144() {
+function system_update_144() {
   $ret = array();
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql("ALTER TABLE {node} CHANGE type type VARCHAR(32) NOT NULL");
@@ -774,7 +740,7 @@ function update_144() {
   return $ret;
 }
 
-function update_145() {
+function system_update_145() {
   $default_theme = variable_get('theme_default', 'bluemarine');
   $ret = array();
 
@@ -806,7 +772,7 @@ function update_145() {
   return $ret;
 }
 
-function update_146() {
+function system_update_146() {
   $ret = array();
 
   if ($GLOBALS['db_type'] == 'mysql') {
@@ -895,7 +861,7 @@ function update_146() {
   while ($row = db_fetch_object($result)) {
     db_query("UPDATE {node_revisions} SET log = '%s' WHERE vid = %d", $row->log, $row->nid);
   }
-
+  
   if ($GLOBALS['db_type'] == 'mysql') {
     $ret[] = update_sql("ALTER TABLE {book} DROP log");
     $ret[] = update_sql("ALTER TABLE {node} DROP teaser");
@@ -914,7 +880,7 @@ function update_146() {
   return $ret;
 }
 
-function update_147() {
+function system_update_147() {
   $ret = array();
 
   // this update is mysql only, pgsql should get it right in the first try.
@@ -925,7 +891,7 @@ function update_147() {
   return $ret;
 }
 
-function update_148() {
+function system_update_148() {
   $ret = array();
 
   // Add support for tracking users' session ids (useful for tracking anon users)
@@ -937,12 +903,12 @@ function update_148() {
     case 'mysqli':
       $ret[] = update_sql("ALTER TABLE {accesslog} ADD sid varchar(32) NOT NULL default ''");
       break;
- }
+  }
 
   return $ret;
 }
 
-function update_149() {
+function system_update_149() {
   $ret = array();
 
   switch ($GLOBALS['db_type']) {
@@ -960,7 +926,7 @@ function update_149() {
   return $ret;
 }
 
-function update_150() {
+function system_update_150() {
   $ret = array();
 
   $ret[] = update_sql("DELETE FROM {variable} WHERE name = 'node_cron_last'");
@@ -1029,7 +995,7 @@ function update_150() {
   return $ret;
 }
 
-function update_151() {
+function system_update_151() {
   $ret = array();
 
   $ts = variable_get('theme_settings', null);
@@ -1106,7 +1072,7 @@ function update_151() {
   return $ret;
 }
 
-function update_152() {
+function system_update_152() {
   $ret = array();
 
   // Postgresql only update
@@ -1122,7 +1088,7 @@ function update_152() {
   return $ret;
 }
 
-function update_153(){
+function system_update_153(){
   $ret = array();
   switch ($GLOBALS['db_type']) {
     case 'pgsql':
@@ -1237,17 +1203,3 @@ function db_change_column(&$ret, $table,
   // We don't drop columns for now
   // $ret[] = update_sql("ALTER TABLE {". $table ."} DROP ". $column ."_old");
 }
-
-
-function update_sql($sql) {
-  $edit = $_POST["edit"];
-  $result = db_query($sql);
-  if ($result) {
-    return array('1', check_plain($sql) ."\n<span class=\"success\">OK</span>\n");
-  }
-  else {
-    return array('0', check_plain($sql) ."\n<span class=\"failure\">FAILED</span>\n");
-  }
-}
-
-?>
Index: includes/database.mysql.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v
retrieving revision 1.40
diff -u -F^f -r1.40 database.mysql.inc
--- includes/database.mysql.inc	4 Nov 2005 13:02:51 -0000	1.40
+++ includes/database.mysql.inc	8 Nov 2005 06:44:57 -0000
@@ -105,7 +105,7 @@ function _db_query($query, $debug = 0) {
     return $result;
   }
   else {
-    trigger_error(mysql_error() ."\nquery: ". htmlspecialchars($query), E_USER_ERROR);
+    trigger_error(mysql_error() ."\nquery: ". htmlspecialchars($query), E_USER_WARNING);
     return FALSE;
   }
 }
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.264
diff -u -F^f -r1.264 theme.inc
--- includes/theme.inc	3 Nov 2005 19:33:37 -0000	1.264
+++ includes/theme.inc	8 Nov 2005 06:44:58 -0000
@@ -974,6 +974,16 @@ function theme_username($object) {
   return $output;
 }
 
+function theme_progress_bar($percent, $message) {
+  $output = '<div id="progress" class="progress">';
+  $output .= '<div class="percentage">'. $percent .'%</div>';
+  $output .= '<div class="status">'. $message .'</div>';
+  $output .= '<div class="bar"><div class="filled" style="width: '. $percent .'%"></div></div>';
+  $output .= '</div>';
+
+  return $output;
+}
+
 /**
  * @} End of "defgroup themeable".
  */
Index: misc/drupal.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/drupal.js,v
retrieving revision 1.9
diff -u -F^f -r1.9 drupal.js
--- misc/drupal.js	22 Oct 2005 15:14:46 -0000	1.9
+++ misc/drupal.js	8 Nov 2005 06:44:58 -0000
@@ -67,7 +67,7 @@ function HTTPGet(uri, callbackFunction, 
 /**
  * Creates an HTTP POST request and sends the response to the callback function
  */
-function HTTPPost(uri, object, callbackFunction, callbackParameter) {
+function HTTPPost(uri, callbackFunction, callbackParameter, object) {
   var xmlHttp = new XMLHttpRequest();
   var bAsync = true;
   if (!callbackFunction) {
Index: misc/maintenance.css
===================================================================
RCS file: /cvs/drupal/drupal/misc/maintenance.css,v
retrieving revision 1.3
diff -u -F^f -r1.3 maintenance.css
--- misc/maintenance.css	11 Aug 2005 13:00:17 -0000	1.3
+++ misc/maintenance.css	8 Nov 2005 06:44:58 -0000
@@ -9,8 +9,13 @@
 }
 h1 {
   margin: 1.6em 0 1.1em 0;
+}
+h1, h2, h3, h4, h5, h6 {
   font-family: sans-serif;
 }
+ul {
+  margin: 0;
+}
 :link {
   color: #0073ba;
   font-weight: bold;
@@ -20,13 +25,17 @@
   font-weight: bold;
 }
 
-/* Update styles */
-h3.update {
-  font-size: 1em;
+div.messages {
+  border: 1px solid #ddd;
+  padding: 0.4em;
+  margin-top: 1em;
 }
-pre.update span.success {
-  color: #6bb521;
+
+div.error {
+  border: 1px solid #daa;
 }
-pre.update span.failure {
+
+/* Update styles */
+#update-results li.failure strong {
   color: #b63300;
 }
Index: misc/progress.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/progress.js,v
retrieving revision 1.2
diff -u -F^f -r1.2 progress.js
--- misc/progress.js	7 Sep 2005 13:49:39 -0000	1.2
+++ misc/progress.js	8 Nov 2005 06:44:58 -0000
@@ -2,12 +2,17 @@
  * A progressbar object. Initialized with the given id. Must be inserted into
  * the DOM afterwards through progressBar.element.
  *
+ * method is the function which will perform the HTTP request to get the
+ * progress bar status. Either HTTPGet or HTTPPost.
+ *
  * e.g. pb = new progressBar('myProgressBar');
  *      some_element.appendChild(pb.element);
  */
-function progressBar(id) {
+function progressBar(id, callback, method) {
   var pb = this;
   this.id = id;
+  this.method = method ? method : HTTPGet;
+  this.callback = callback;
 
   this.element = document.createElement('div');
   this.element.id = id;
@@ -36,6 +41,9 @@ function progressBar(id) {
       divs[i].innerHTML = status;
     }
   }
+  if (this.callback) {
+    this.callback(percentage, status);
+  }
 }
 
 /**
@@ -61,14 +69,14 @@ function progressBar(id) {
   if (this.timer) {
     clearTimeout(this.timer);
   }
-  HTTPGet(this.uri, this.receivePing, this);
+  this.method(this.uri, this.receivePing, this);
 }
 
 /**
  * HTTP callback function. Passes data back to the progressbar and sets a new
  * timer for the next ping.
  */
-progressBar.prototype.receivePing = function(string, xmlhttp, pb) {
+progressBar.prototype.receivePing = function (string, xmlhttp, pb) {
   if (xmlhttp.status != 200) {
     return alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ pb.uri);
   }
