diff --git a/database/updates.inc b/database/updates.inc index e8103ac898023941c22f414f47b86d63f7f19ad2..e919062929bf848ce61ef501947dae07f77950a0 100644 --- a/database/updates.inc +++ b/database/updates.inc @@ -7,7 +7,7 @@ function system_version($type) { switch ($type) { case SCHEMA: - return 157; + return 159; case SCHEMA_MIN: return 110; @@ -1111,3 +1111,124 @@ function system_update_157() { return $ret; } +function system_update_158() { + $ret = array(); + + switch ($GLOBALS['db_type']) { + case 'mysqli': + case 'mysql': + $ret[] = update_sql("ALTER TABLE {old_revisions} ADD done tinyint(1) NOT NULL DEFAULT 0"); + $ret[] = update_sql("ALTER TABLE {old_revisions} ADD INDEX (done)"); + break; + + case 'pgsql': + break; + } + + return $ret; +} + +/** + * Retrieve data out of the old_revisions table and put into new revision + * system. + * + * The old_revisions table is not deleted because any data which could not be + * put into the new system is retained. + */ +function system_update_159() { + $ret = array(); + + $result = db_query_range("SELECT * FROM {old_revisions} WHERE done = 0 AND type IN ('page', 'story', 'poll', 'book', 'forum')", 0, 20); + + $vid = db_next_id('{node_revisions}_vid'); + while ($node = db_fetch_object($result)) { + $revisions = unserialize($node->revisions); + if (is_array($revisions) && count($revisions) > 0) { + $revisions_query = array(); + $revisions_args = array(); + $book_query = array(); + $book_args = array(); + $forum_query = array(); + $forum_args = array(); + foreach ($revisions as $version) { + $revision = array(); + foreach ($version['node'] as $node_field => $node_value) { + $revision[$node_field] = $node_value; + } + $revision['uid'] = $version['uid']; + $revision['timestamp'] = $version['timestamp']; + $vid++; + $revisions_query[] = "(%d, %d, %d, '%s', '%s', '%s', '%s', %d, %d)"; + $revisions_args = array_merge($revisions_args, array($node->nid, $vid, $revision['uid'], $revision['title'], $revision['body'], $revision['teaser'], $revision['log'], $revision['timestamp'], $revision['format'])); + switch ($node->type) { + case 'forum': + if ($revision['tid'] > 0) { + $forum_query[] = "(%d, %d, %d)"; + $forum_args = array_merge($forum_args, array($vid, $node->nid, $revision['tid'])); + } + break; + + case 'book': + $book_query[] = "(%d, %d, %d, %d)"; + $book_args = array_merge($book_args, array($vid, $node->nid, $revision['parent'], $revision['weight'])); + break; + } + } + if (count($revisions_query)) { + $revision_status = db_query("INSERT INTO {node_revisions} (nid, vid, uid, title, body, teaser, log, timestamp, format) VALUES ". implode(',', $revisions_query), $revisions_args); + } + if (count($forum_query)) { + $forum_status = db_query("INSERT INTO {forum} (vid, nid, tid) VALUES ". implode(',', $forum_query), $forum_args); + } + if (count($book_query)) { + $book_status = db_query("INSERT INTO {book} (vid, nid, parent, weight) VALUES ". implode(',', $book_query), $book_args); + } + $delete = FALSE; + switch ($node->type) { + case 'forum': + if ($forum_status && $revision_status) { + $delete = TRUE; + } + break; + + case 'book': + if ($book_status && $revision_status) { + $delete = TRUE; + } + break; + + default: + if ($revision_status) { + $delete = TRUE; + } + break; + } + + if ($delete) { + db_query('DELETE FROM {old_revisions} WHERE nid = %d', $node->nid); + } + else { + db_query('UPDATE {old_revisions} SET done = 1 WHERE nid = %d', $node->nid); + } + } + } + + switch ($GLOBALS['db_type']) { + case 'mysqli': + case 'mysql': + $ret[] = update_sql("UPDATE {sequences} SET id = $vid WHERE name = '{node_revisions}_vid'"); + break; + + case 'pgsql': + break; + } + + if (db_num_rows($result) < 50) { + $ret[] = update_sql('ALTER TABLE {old_revisions} DROP done'); + } + else { + $ret['#finished'] = FALSE; + } + + return $ret; +} diff --git a/update.php b/update.php index a073c922b4cc9bd452ef6408e2cc9a123813140c..9b16492baf2e99aeb03efd7d13d22c50cffe0ddf 100644 --- a/update.php +++ b/update.php @@ -238,20 +238,45 @@ function update_fix_watchdog() { } } +/** + * Perform one update and store the results which will later be displayed on + * the finished page. + * + * @param $module + * The module whose update will be run. + * @param $number + * The update number to run. + * + * @return + * TRUE if the update was finished. Otherwise, false. + */ function update_data($module, $number) { $ret = module_invoke($module, 'update_'. $number); + // Assume the update finished unless the update results indicate otherwise. + $finished = TRUE; + if (isset($ret['#finished'])) { + $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(); } - else if (!isset($_SESSION['update_results'][$module])) { + if (!isset($_SESSION['update_results'][$module])) { $_SESSION['update_results'][$module] = array(); } - $_SESSION['update_results'][$module][$number] = $ret; + 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); - // Update the installed version - drupal_set_installed_schema_version($module, $number); + if ($finished) { + // Update the installed version + drupal_set_installed_schema_version($module, $number); + } + + return $finished; } function update_selection_page() { @@ -337,11 +362,11 @@ function update_progress_page() { * the overall percent finished. The second element is a status message. */ function update_do_updates() { - foreach ($_SESSION['update_remaining'] as $key => $update) { - update_data($update['module'], $update['version']); - unset($_SESSION['update_remaining'][$key]); - if (timer_read('page') > 1000) { - break; + while (($update = reset($_SESSION['update_remaining'])) && timer_read('page') < 1000) { + $update_finished = update_data($update['module'], $update['version']); + if ($update_finished) { + // Dequeue the completed update. + unset($_SESSION['update_remaining'][key($_SESSION['update_remaining'])]); } }