[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/modules/system/ -> system.install (source)

   1  <?php
   2  // $Id: system.install,v 1.238.2.25 2010/11/03 12:29:24 goba Exp $
   3  
   4  /**
   5   * Test and report Drupal installation requirements.
   6   *
   7   * @param $phase
   8   *   The current system installation phase.
   9   * @return
  10   *   An array of system requirements.
  11   */
  12  function system_requirements($phase) {
  13    $requirements = array();
  14    // Ensure translations don't break at install time
  15    $t = get_t();
  16  
  17    // Report Drupal version
  18    if ($phase == 'runtime') {
  19      $requirements['drupal'] = array(
  20        'title' => $t('Drupal'),
  21        'value' => VERSION,
  22        'severity' => REQUIREMENT_INFO,
  23        'weight' => -10,
  24      );
  25    }
  26  
  27    // Web server information.
  28    $software = $_SERVER['SERVER_SOFTWARE'];
  29    $requirements['webserver'] = array(
  30      'title' => $t('Web server'),
  31      'value' => $software,
  32    );
  33  
  34    // Test PHP version
  35    $requirements['php'] = array(
  36      'title' => $t('PHP'),
  37      'value' => ($phase == 'runtime') ? l(phpversion(), 'admin/reports/status/php') : phpversion(),
  38    );
  39    if (version_compare(phpversion(), DRUPAL_MINIMUM_PHP) < 0) {
  40      $requirements['php']['description'] = $t('Your PHP installation is too old. Drupal requires at least PHP %version.', array('%version' => DRUPAL_MINIMUM_PHP));
  41      $requirements['php']['severity'] = REQUIREMENT_ERROR;
  42    }
  43  
  44    // Test PHP register_globals setting.
  45    $requirements['php_register_globals'] = array(
  46      'title' => $t('PHP register globals'),
  47    );
  48    $register_globals = trim(ini_get('register_globals'));
  49    // Unfortunately, ini_get() may return many different values, and we can't
  50    // be certain which values mean 'on', so we instead check for 'not off'
  51    // since we never want to tell the user that their site is secure
  52    // (register_globals off), when it is in fact on. We can only guarantee
  53    // register_globals is off if the value returned is 'off', '', or 0.
  54    if (!empty($register_globals) && strtolower($register_globals) != 'off') {
  55      $requirements['php_register_globals']['description'] = $t('<em>register_globals</em> is enabled. Drupal requires this configuration directive to be disabled. Your site may not be secure when <em>register_globals</em> is enabled. The PHP manual has instructions for <a href="http://php.net/configuration.changes">how to change configuration settings</a>.');
  56      $requirements['php_register_globals']['severity'] = REQUIREMENT_ERROR;
  57      $requirements['php_register_globals']['value'] = $t("Enabled ('@value')", array('@value' => $register_globals));
  58    }
  59    else {
  60      $requirements['php_register_globals']['value'] = $t('Disabled');
  61    }
  62  
  63    // Test PHP memory_limit
  64    $memory_limit = ini_get('memory_limit');
  65    $requirements['php_memory_limit'] = array(
  66      'title' => $t('PHP memory limit'),
  67      'value' => $memory_limit == -1 ? t('-1 (Unlimited)') : $memory_limit,
  68    );
  69  
  70    if ($memory_limit && $memory_limit != -1 && parse_size($memory_limit) < parse_size(DRUPAL_MINIMUM_PHP_MEMORY_LIMIT)) {
  71      $description = '';
  72      if ($phase == 'install') {
  73        $description = $t('Consider increasing your PHP memory limit to %memory_minimum_limit to help prevent errors in the installation process.', array('%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
  74      }
  75      elseif ($phase == 'update') {
  76        $description = $t('Consider increasing your PHP memory limit to %memory_minimum_limit to help prevent errors in the update process.', array('%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
  77      }
  78      elseif ($phase == 'runtime') {
  79        $description = $t('Depending on your configuration, Drupal can run with a %memory_limit PHP memory limit. However, a %memory_minimum_limit PHP memory limit or above is recommended, especially if your site uses additional custom or contributed modules.', array('%memory_limit' => $memory_limit, '%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
  80      }
  81  
  82      if (!empty($description)) {
  83        if ($php_ini_path = get_cfg_var('cfg_file_path')) {
  84          $description .= ' '. $t('Increase the memory limit by editing the memory_limit parameter in the file %configuration-file and then restart your web server (or contact your system administrator or hosting provider for assistance).', array('%configuration-file' => $php_ini_path));
  85        }
  86        else {
  87          $description .= ' '. $t('Contact your system administrator or hosting provider for assistance with increasing your PHP memory limit.');
  88        }
  89  
  90        $requirements['php_memory_limit']['description'] = $description .' '. $t('See the <a href="@url">Drupal requirements</a> for more information.', array('@url' => 'http://drupal.org/requirements'));
  91        $requirements['php_memory_limit']['severity'] = REQUIREMENT_WARNING;
  92      }
  93    }
  94  
  95    // Test DB version
  96    global $db_type;
  97    if (function_exists('db_status_report')) {
  98      $requirements += db_status_report($phase);
  99    }
 100  
 101    // Test settings.php file writability
 102    if ($phase == 'runtime') {
 103      $conf_dir = drupal_verify_install_file(conf_path(), FILE_NOT_WRITABLE, 'dir');
 104      $conf_file = drupal_verify_install_file(conf_path() .'/settings.php', FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE);
 105      if (!$conf_dir || !$conf_file) {
 106        $requirements['settings.php'] = array(
 107          'value' => $t('Not protected'),
 108          'severity' => REQUIREMENT_ERROR,
 109          'description' => '',
 110        );
 111        if (!$conf_dir) {
 112          $requirements['settings.php']['description'] .= $t('The directory %file is not protected from modifications and poses a security risk. You must change the directory\'s permissions to be non-writable. ', array('%file' => conf_path()));
 113        }
 114        if (!$conf_file) {
 115          $requirements['settings.php']['description'] .= $t('The file %file is not protected from modifications and poses a security risk. You must change the file\'s permissions to be non-writable.', array('%file' => conf_path() .'/settings.php'));
 116        }
 117      }
 118      else {
 119        $requirements['settings.php'] = array(
 120          'value' => $t('Protected'),
 121        );
 122      }
 123      $requirements['settings.php']['title'] = $t('Configuration file');
 124    }
 125  
 126    // Report cron status.
 127    if ($phase == 'runtime') {
 128      // Cron warning threshold defaults to two days.
 129      $threshold_warning = variable_get('cron_threshold_warning', 172800);
 130      // Cron error threshold defaults to two weeks.
 131      $threshold_error = variable_get('cron_threshold_error', 1209600);
 132      // Cron configuration help text.
 133      $help = $t('For more information, see the online handbook entry for <a href="@cron-handbook">configuring cron jobs</a>.', array('@cron-handbook' => 'http://drupal.org/cron'));
 134  
 135      // Determine when cron last ran. If never, use the install time to
 136      // determine the warning or error status.
 137      $cron_last = variable_get('cron_last', NULL);
 138      $never_run = FALSE;
 139      if (!is_numeric($cron_last)) {
 140        $never_run = TRUE;
 141        $cron_last = variable_get('install_time', 0);
 142      }
 143  
 144      // Determine severity based on time since cron last ran.
 145      $severity = REQUIREMENT_OK;
 146      if (time() - $cron_last > $threshold_error) {
 147        $severity = REQUIREMENT_ERROR;
 148      }
 149      else if ($never_run || (time() - $cron_last > $threshold_warning)) {
 150        $severity = REQUIREMENT_WARNING;
 151      }
 152  
 153      // If cron hasn't been run, and the user is viewing the main
 154      // administration page, instead of an error, we display a helpful reminder
 155      // to configure cron jobs.
 156      if ($never_run && $severity != REQUIREMENT_ERROR && $_GET['q'] == 'admin' && user_access('administer site configuration')) {
 157        drupal_set_message($t('Cron has not run. Please visit the <a href="@status">status report</a> for more information.', array('@status' => url('admin/reports/status'))));
 158      }
 159  
 160      // Set summary and description based on values determined above.
 161      if ($never_run) {
 162        $summary = $t('Never run');
 163        $description = $t('Cron has not run.') .' '. $help;
 164      }
 165      else {
 166        $summary = $t('Last run !time ago', array('!time' => format_interval(time() - $cron_last)));
 167        $description = '';
 168        if ($severity != REQUIREMENT_OK) {
 169          $description = $t('Cron has not run recently.') .' '. $help;
 170        }
 171      }
 172  
 173      $requirements['cron'] = array(
 174        'title' => $t('Cron maintenance tasks'),
 175        'severity' => $severity,
 176        'value' => $summary,
 177        'description' => $description .' '. $t('You can <a href="@cron">run cron manually</a>.', array('@cron' => url('admin/reports/status/run-cron'))),
 178      );
 179    }
 180  
 181    // Test files directory
 182    $directory = file_directory_path();
 183    $requirements['file system'] = array(
 184      'title' => $t('File system'),
 185    );
 186  
 187    // For installer, create the directory if possible.
 188    if ($phase == 'install' && !is_dir($directory) && @mkdir($directory)) {
 189      @chmod($directory, 0775); // Necessary for non-webserver users.
 190    }
 191  
 192    $is_writable = is_writable($directory);
 193    $is_directory = is_dir($directory);
 194    if (!$is_writable || !$is_directory) {
 195      $description = '';
 196      $requirements['file system']['value'] = $t('Not writable');
 197      if (!$is_directory) {
 198        $error = $t('The directory %directory does not exist.', array('%directory' => $directory));
 199      }
 200      else {
 201        $error = $t('The directory %directory is not writable.', array('%directory' => $directory));
 202      }
 203      // The files directory requirement check is done only during install and runtime.
 204      if ($phase == 'runtime') {
 205        $description = $error .' '. $t('You may need to set the correct directory at the <a href="@admin-file-system">file system settings page</a> or change the current directory\'s permissions so that it is writable.', array('@admin-file-system' => url('admin/settings/file-system')));
 206      }
 207      elseif ($phase == 'install') {
 208        // For the installer UI, we need different wording. 'value' will
 209        // be treated as version, so provide none there.
 210        $description = $error .' '. $t('An automated attempt to create this directory failed, possibly due to a permissions problem. To proceed with the installation, either create the directory and modify its permissions manually, or ensure that the installer has the permissions to create it automatically. For more information, please see INSTALL.txt or the <a href="@handbook_url">on-line handbook</a>.', array('@handbook_url' => 'http://drupal.org/server-permissions'));
 211        $requirements['file system']['value'] = '';
 212      }
 213      if (!empty($description)) {
 214        $requirements['file system']['description'] = $description;
 215        $requirements['file system']['severity'] = REQUIREMENT_ERROR;
 216      }
 217    }
 218    else {
 219      if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC) {
 220        $requirements['file system']['value'] = $t('Writable (<em>public</em> download method)');
 221      }
 222      else {
 223        $requirements['file system']['value'] = $t('Writable (<em>private</em> download method)');
 224      }
 225    }
 226  
 227    // See if updates are available in update.php.
 228    if ($phase == 'runtime') {
 229      $requirements['update'] = array(
 230        'title' => $t('Database updates'),
 231        'severity' => REQUIREMENT_OK,
 232        'value' => $t('Up to date'),
 233      );
 234  
 235      // Check installed modules.
 236      foreach (module_list() as $module) {
 237        $updates = drupal_get_schema_versions($module);
 238        if ($updates !== FALSE) {
 239          $default = drupal_get_installed_schema_version($module);
 240          if (max($updates) > $default) {
 241            $requirements['update']['severity'] = REQUIREMENT_ERROR;
 242            $requirements['update']['value'] = $t('Out of date');
 243            $requirements['update']['description'] = $t('Some modules have database schema updates to install. You should run the <a href="@update">database update script</a> immediately.', array('@update' => base_path() .'update.php'));
 244            break;
 245          }
 246        }
 247      }
 248    }
 249  
 250    // Verify the update.php access setting
 251    if ($phase == 'runtime') {
 252      if (!empty($GLOBALS['update_free_access'])) {
 253        $requirements['update access'] = array(
 254          'value' => $t('Not protected'),
 255          'severity' => REQUIREMENT_ERROR,
 256          'description' => $t('The update.php script is accessible to everyone without authentication check, which is a security risk. You must change the $update_free_access value in your settings.php back to FALSE.'),
 257        );
 258      }
 259      else {
 260        $requirements['update access'] = array(
 261          'value' => $t('Protected'),
 262        );
 263      }
 264      $requirements['update access']['title'] = $t('Access to update.php');
 265    }
 266  
 267    // Test Unicode library
 268    include_once  './includes/unicode.inc';
 269    $requirements = array_merge($requirements, unicode_requirements());
 270  
 271    if ($phase == 'runtime') {
 272      // Check for update status module.
 273      if (!module_exists('update')) {
 274        $requirements['update status'] = array(
 275          'value' => $t('Not enabled'),
 276          'severity' => REQUIREMENT_WARNING,
 277          'description' => $t('Update notifications are not enabled. It is <strong>highly recommended</strong> that you enable the update status module from the <a href="@module">module administration page</a> in order to stay up-to-date on new releases. For more information please read the <a href="@update">Update status handbook page</a>.', array('@update' => 'http://drupal.org/handbook/modules/update', '@module' => url('admin/build/modules'))),
 278        );
 279      }
 280      else {
 281        $requirements['update status'] = array(
 282          'value' => $t('Enabled'),
 283        );
 284      }
 285      $requirements['update status']['title'] = $t('Update notifications');
 286  
 287      // Check that Drupal can issue HTTP requests.
 288      if (variable_get('drupal_http_request_fails', TRUE) && !system_check_http_request()) {
 289        $requirements['http requests'] = array(
 290          'title' => $t('HTTP request status'),
 291          'value' => $t('Fails'),
 292          'severity' => REQUIREMENT_ERROR,
 293          'description' => $t('Your system or network configuration does not allow Drupal to access web pages, resulting in reduced functionality. This could be due to your webserver configuration or PHP settings, and should be resolved in order to download information about available updates, fetch aggregator feeds, sign in via OpenID, or use other network-dependent services.'),
 294        );
 295      }
 296    }
 297  
 298    return $requirements;
 299  }
 300  
 301  /**
 302   * Implementation of hook_install().
 303   */
 304  function system_install() {
 305    if ($GLOBALS['db_type'] == 'pgsql') {
 306      // We create some custom types and functions using global names instead of
 307      // prefixing them like we do with table names. If this function is ever
 308      // called again (for example, by the test framework when creating prefixed
 309      // test databases), the global names will already exist. We therefore avoid
 310      // trying to create them again in that case.
 311  
 312      // Create unsigned types.
 313      if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'int_unsigned_check'"))) {
 314        db_query("CREATE DOMAIN int_unsigned integer CHECK (VALUE >= 0)");
 315      }
 316      if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'smallint_unsigned_check'"))) {
 317        db_query("CREATE DOMAIN smallint_unsigned smallint CHECK (VALUE >= 0)");
 318      }
 319      if (!db_result(db_query("SELECT COUNT(*) FROM pg_constraint WHERE conname = 'bigint_unsigned_check'"))) {
 320        db_query("CREATE DOMAIN bigint_unsigned bigint CHECK (VALUE >= 0)");
 321      }
 322  
 323      // Create functions.
 324      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric) RETURNS numeric AS
 325        \'SELECT CASE WHEN (($1 > $2) OR ($2 IS NULL)) THEN $1 ELSE $2 END;\'
 326        LANGUAGE \'sql\''
 327      );
 328      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric, numeric) RETURNS numeric AS
 329        \'SELECT greatest($1, greatest($2, $3));\'
 330        LANGUAGE \'sql\''
 331      );
 332      if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'rand'"))) {
 333        db_query('CREATE OR REPLACE FUNCTION "rand"() RETURNS float AS
 334          \'SELECT random();\'
 335          LANGUAGE \'sql\''
 336        );
 337      }
 338  
 339      if (!db_result(db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'concat'"))) {
 340        db_query('CREATE OR REPLACE FUNCTION "concat"(text, text) RETURNS text AS
 341          \'SELECT $1 || $2;\'
 342          LANGUAGE \'sql\''
 343        );
 344      }
 345      db_query('CREATE OR REPLACE FUNCTION "if"(boolean, text, text) RETURNS text AS
 346        \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
 347        LANGUAGE \'sql\''
 348      );
 349      db_query('CREATE OR REPLACE FUNCTION "if"(boolean, integer, integer) RETURNS integer AS
 350        \'SELECT CASE WHEN $1 THEN $2 ELSE $3 END;\'
 351        LANGUAGE \'sql\''
 352      );
 353    }
 354  
 355    // Create tables.
 356    $modules = array('system', 'filter', 'block', 'user', 'node', 'comment', 'taxonomy');
 357    foreach ($modules as $module) {
 358      drupal_install_schema($module);
 359    }
 360  
 361    // Clear out module list and hook implementation statics before calling
 362    // system_theme_data().
 363    module_list(TRUE, FALSE);
 364    module_implements('', FALSE, TRUE);
 365  
 366    // Load system theme data appropriately.
 367    system_theme_data();
 368  
 369    // Inserting uid 0 here confuses MySQL -- the next user might be created as
 370    // uid 2 which is not what we want. So we insert the first user here, the
 371    // anonymous user. uid is 1 here for now, but very soon it will be changed
 372    // to 0.
 373    db_query("INSERT INTO {users} (name, mail) VALUES('%s', '%s')", '', '');
 374  
 375    // We need some placeholders here as name and mail are uniques and data is
 376    // presumed to be a serialized array. Install will change uid 1 immediately
 377    // anyways. So we insert the superuser here, the uid is 2 here for now, but
 378    // very soon it will be changed to 1.
 379    db_query("INSERT INTO {users} (name, mail, created, data) VALUES('%s', '%s', %d, '%s')", 'placeholder-for-uid-1', 'placeholder-for-uid-1', time(), serialize(array()));
 380  
 381    // This sets the above two users uid 0 (anonymous). We avoid an explicit 0
 382    // otherwise MySQL might insert the next auto_increment value.
 383    db_query("UPDATE {users} SET uid = uid - uid WHERE name = '%s'", '');
 384  
 385    // This sets uid 1 (superuser). We skip uid 2 but that's not a big problem.
 386    db_query("UPDATE {users} SET uid = 1 WHERE name = '%s'", 'placeholder-for-uid-1');
 387  
 388    db_query("INSERT INTO {role} (name) VALUES ('%s')", 'anonymous user');
 389    $rid_anonymous = db_last_insert_id('role', 'rid');
 390  
 391    db_query("INSERT INTO {role} (name) VALUES ('%s')", 'authenticated user');
 392    $rid_authenticated = db_last_insert_id('role', 'rid');
 393  
 394    // Sanity check to ensure the anonymous and authenticated role IDs are the 
 395    // same as the drupal defined constants. In certain situations, this will 
 396    // not be true
 397    if ($rid_anonymous != DRUPAL_ANONYMOUS_RID) {
 398      db_query("UPDATE {role} SET rid = %d WHERE rid = %d", DRUPAL_ANONYMOUS_RID, $rid_anonymous);
 399    }
 400  
 401    if ($rid_authenticated != DRUPAL_AUTHENTICATED_RID) {
 402      db_query("UPDATE {role} SET rid = %d WHERE rid = %d", DRUPAL_AUTHENTICATED_RID, $rid_authenticated);
 403    }
 404  
 405    db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", DRUPAL_ANONYMOUS_RID, 'access content', 0);
 406    db_query("INSERT INTO {permission} (rid, perm, tid) VALUES (%d, '%s', %d)", DRUPAL_AUTHENTICATED_RID, 'access comments, access content, post comments, post comments without approval', 0);
 407  
 408    db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", 'theme_default', 's:7:"garland";');
 409  
 410    db_query("UPDATE {system} SET status = %d WHERE type = '%s' AND name = '%s'", 1, 'theme', 'garland');
 411    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)", 'user', '0', 'garland', 1, 0, 'left', '', -1);
 412    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)", 'user', '1', 'garland', 1, 0, 'left', '', -1);
 413    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, pages, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', '%s', %d)", 'system', '0', 'garland', 1, 10, 'footer', '', -1);
 414  
 415    db_query("INSERT INTO {node_access} (nid, gid, realm, grant_view, grant_update, grant_delete) VALUES (%d, %d, '%s', %d, %d, %d)", 0, 0, 'all', 1, 0, 0);
 416  
 417    // Add input formats.
 418    db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Filtered HTML', ',' . DRUPAL_ANONYMOUS_RID . ',' . DRUPAL_AUTHENTICATED_RID . ',', 1);
 419    $filtered_html_format = db_last_insert_id('filter_formats', 'format');
 420    db_query("INSERT INTO {filter_formats} (name, roles, cache) VALUES ('%s', '%s', %d)", 'Full HTML', '', 1);
 421    $full_html_format = db_last_insert_id('filter_formats', 'format');
 422  
 423    // Enable filters for each input format.
 424  
 425    // Filtered HTML:
 426    // URL filter.
 427    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $filtered_html_format, 'filter', 2, 0);
 428    // HTML filter.
 429    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $filtered_html_format, 'filter', 0, 1);
 430    // Line break filter.
 431    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $filtered_html_format, 'filter', 1, 2);
 432    // HTML corrector filter.
 433    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $filtered_html_format, 'filter', 3, 10);
 434  
 435    // Full HTML:
 436    // URL filter.
 437    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $full_html_format, 'filter', 2, 0);
 438    // Line break filter.
 439    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $full_html_format, 'filter', 1, 1);
 440    // HTML corrector filter.
 441    db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $full_html_format, 'filter', 3, 10);
 442  
 443    db_query("INSERT INTO {variable} (name, value) VALUES ('%s','%s')", 'filter_html_1', 'i:1;');
 444    db_query("INSERT INTO {variable} (name, value) VALUES ('%s', '%s')", 'node_options_forum', 'a:1:{i:0;s:6:"status";}');
 445  }
 446  
 447  /**
 448   * Implementation of hook_schema().
 449   */
 450  function system_schema() {
 451    // NOTE: {variable} needs to be created before all other tables, as
 452    // some database drivers, e.g. Oracle and DB2, will require variable_get()
 453    // and variable_set() for overcoming some database specific limitations.
 454    $schema['variable'] = array(
 455      'description' => 'Named variable/value pairs created by Drupal core or any other module or theme. All variables are cached in memory at the start of every Drupal request so developers should not be careless about what is stored here.',
 456      'fields' => array(
 457        'name' => array(
 458          'description' => 'The name of the variable.',
 459          'type' => 'varchar',
 460          'length' => 128,
 461          'not null' => TRUE,
 462          'default' => ''),
 463        'value' => array(
 464          'description' => 'The value of the variable.',
 465          'type' => 'text',
 466          'not null' => TRUE,
 467          'size' => 'big'),
 468        ),
 469      'primary key' => array('name'),
 470      );
 471  
 472    $schema['actions'] = array(
 473      'description' => 'Stores action information.',
 474      'fields' => array(
 475        'aid' => array(
 476          'description' => 'Primary Key: Unique actions ID.',
 477          'type' => 'varchar',
 478          'length' => 255,
 479          'not null' => TRUE,
 480          'default' => '0'),
 481        'type' => array(
 482          'description' => 'The object that that action acts on (node, user, comment, system or custom types.)',
 483          'type' => 'varchar',
 484          'length' => 32,
 485          'not null' => TRUE,
 486          'default' => ''),
 487        'callback' => array(
 488          'description' => 'The callback function that executes when the action runs.',
 489          'type' => 'varchar',
 490          'length' => 255,
 491          'not null' => TRUE,
 492          'default' => ''),
 493        'parameters' => array(
 494          'description' => 'Parameters to be passed to the callback function.',
 495          'type' => 'text',
 496          'not null' => TRUE,
 497          'size' => 'big'),
 498        'description' => array(
 499          'description' => 'Description of the action.',
 500          'type' => 'varchar',
 501          'length' => 255,
 502          'not null' => TRUE,
 503          'default' => '0'),
 504        ),
 505      'primary key' => array('aid'),
 506      );
 507  
 508    $schema['actions_aid'] = array(
 509      'description' => 'Stores action IDs for non-default actions.',
 510      'fields' => array(
 511        'aid' => array(
 512          'description' => 'Primary Key: Unique actions ID.',
 513          'type' => 'serial',
 514          'unsigned' => TRUE,
 515          'not null' => TRUE),
 516        ),
 517      'primary key' => array('aid'),
 518      );
 519  
 520    $schema['batch'] = array(
 521      'description' => t('Stores details about batches (processes that run in multiple HTTP requests).'),
 522      'fields' => array(
 523        'bid' => array(
 524          'description' => 'Primary Key: Unique batch ID.',
 525          'type' => 'serial',
 526          'unsigned' => TRUE,
 527          'not null' => TRUE),
 528        'token' => array(
 529          'description' => "A string token generated against the current user's session id and the batch id, used to ensure that only the user who submitted the batch can effectively access it.",
 530          'type' => 'varchar',
 531          'length' => 64,
 532          'not null' => TRUE),
 533        'timestamp' => array(
 534          'description' => 'A Unix timestamp indicating when this batch was submitted for processing. Stale batches are purged at cron time.',
 535          'type' => 'int',
 536          'not null' => TRUE),
 537        'batch' => array(
 538          'description' => 'A serialized array containing the processing data for the batch.',
 539          'type' => 'text',
 540          'not null' => FALSE,
 541          'size' => 'big')
 542        ),
 543      'primary key' => array('bid'),
 544      'indexes' => array('token' => array('token')),
 545      );
 546  
 547    $schema['cache'] = array(
 548      'description' => 'Generic cache table for caching things not separated out into their own tables. Contributed modules may also use this to store cached items.',
 549      'fields' => array(
 550        'cid' => array(
 551          'description' => 'Primary Key: Unique cache ID.',
 552          'type' => 'varchar',
 553          'length' => 255,
 554          'not null' => TRUE,
 555          'default' => ''),
 556        'data' => array(
 557          'description' => 'A collection of data to cache.',
 558          'type' => 'blob',
 559          'not null' => FALSE,
 560          'size' => 'big'),
 561        'expire' => array(
 562          'description' => 'A Unix timestamp indicating when the cache entry should expire, or 0 for never.',
 563          'type' => 'int',
 564          'not null' => TRUE,
 565          'default' => 0),
 566        'created' => array(
 567          'description' => 'A Unix timestamp indicating when the cache entry was created.',
 568          'type' => 'int',
 569          'not null' => TRUE,
 570          'default' => 0),
 571        'headers' => array(
 572          'description' => 'Any custom HTTP headers to be added to cached data.',
 573          'type' => 'text',
 574          'not null' => FALSE),
 575        'serialized' => array(
 576          'description' => 'A flag to indicate whether content is serialized (1) or not (0).',
 577          'type' => 'int',
 578          'size' => 'small',
 579          'not null' => TRUE,
 580          'default' => 0)
 581        ),
 582      'indexes' => array('expire' => array('expire')),
 583      'primary key' => array('cid'),
 584      );
 585  
 586    $schema['cache_form'] = $schema['cache'];
 587    $schema['cache_form']['description'] = 'Cache table for the form system to store recently built forms and their storage data, to be used in subsequent page requests.';
 588    $schema['cache_page'] = $schema['cache'];
 589    $schema['cache_page']['description'] = 'Cache table used to store compressed pages for anonymous users, if page caching is enabled.';
 590    $schema['cache_menu'] = $schema['cache'];
 591    $schema['cache_menu']['description'] = 'Cache table for the menu system to store router information as well as generated link trees for various menu/page/user combinations.';
 592  
 593    $schema['files'] = array(
 594      'description' => 'Stores information for uploaded files.',
 595      'fields' => array(
 596        'fid' => array(
 597          'description' => 'Primary Key: Unique files ID.',
 598          'type' => 'serial',
 599          'unsigned' => TRUE,
 600          'not null' => TRUE),
 601        'uid' => array(
 602          'description' => 'The {users}.uid of the user who is associated with the file.',
 603          'type' => 'int',
 604          'unsigned' => TRUE,
 605          'not null' => TRUE,
 606          'default' => 0),
 607        'filename' => array(
 608          'description' => 'Name of the file.',
 609          'type' => 'varchar',
 610          'length' => 255,
 611          'not null' => TRUE,
 612          'default' => ''),
 613        'filepath' => array(
 614          'description' => 'Path of the file relative to Drupal root.',
 615          'type' => 'varchar',
 616          'length' => 255,
 617          'not null' => TRUE,
 618          'default' => ''),
 619        'filemime' => array(
 620          'description' => 'The file MIME type.',
 621          'type' => 'varchar',
 622          'length' => 255,
 623          'not null' => TRUE,
 624          'default' => ''),
 625        'filesize' => array(
 626          'description' => 'The size of the file in bytes.',
 627          'type' => 'int',
 628          'unsigned' => TRUE,
 629          'not null' => TRUE,
 630          'default' => 0),
 631        'status' => array(
 632          'description' => 'A flag indicating whether file is temporary (0) or permanent (1).',
 633          'type' => 'int',
 634          'not null' => TRUE,
 635          'default' => 0),
 636        'timestamp' => array(
 637          'description' => 'UNIX timestamp for when the file was added.',
 638          'type' => 'int',
 639          'unsigned' => TRUE,
 640          'not null' => TRUE,
 641          'default' => 0),
 642        ),
 643      'indexes' => array(
 644        'uid' => array('uid'),
 645        'status' => array('status'),
 646        'timestamp' => array('timestamp'),
 647        ),
 648      'primary key' => array('fid'),
 649      );
 650  
 651    $schema['flood'] = array(
 652      'description' => 'Flood controls the threshold of events, such as the number of contact attempts.',
 653      'fields' => array(
 654        'fid' => array(
 655          'description' => 'Unique flood event ID.',
 656          'type' => 'serial',
 657          'not null' => TRUE),
 658        'event' => array(
 659          'description' => 'Name of event (e.g. contact).',
 660          'type' => 'varchar',
 661          'length' => 64,
 662          'not null' => TRUE,
 663          'default' => ''),
 664        'hostname' => array(
 665          'description' => 'Hostname of the visitor.',
 666          'type' => 'varchar',
 667          'length' => 128,
 668          'not null' => TRUE,
 669          'default' => ''),
 670        'timestamp' => array(
 671          'description' => 'Timestamp of the event.',
 672          'type' => 'int',
 673          'not null' => TRUE,
 674          'default' => 0)
 675        ),
 676      'primary key' => array('fid'),
 677      'indexes' => array(
 678        'allow' => array('event', 'hostname', 'timestamp'),
 679      ),
 680      );
 681  
 682    $schema['history'] = array(
 683      'description' => 'A record of which {users} have read which {node}s.',
 684      'fields' => array(
 685        'uid' => array(
 686          'description' => 'The {users}.uid that read the {node} nid.',
 687          'type' => 'int',
 688          'not null' => TRUE,
 689          'default' => 0),
 690        'nid' => array(
 691          'description' => 'The {node}.nid that was read.',
 692          'type' => 'int',
 693          'not null' => TRUE,
 694          'default' => 0),
 695        'timestamp' => array(
 696          'description' => 'The Unix timestamp at which the read occurred.',
 697          'type' => 'int',
 698          'not null' => TRUE,
 699          'default' => 0)
 700        ),
 701      'primary key' => array('uid', 'nid'),
 702      'indexes' => array(
 703        'nid' => array('nid'),
 704      ),
 705      );
 706    $schema['menu_router'] = array(
 707      'description' => 'Maps paths to various callbacks (access, page and title)',
 708      'fields' => array(
 709        'path' => array(
 710          'description' => 'Primary Key: the Drupal path this entry describes',
 711          'type' => 'varchar',
 712          'length' => 255,
 713          'not null' => TRUE,
 714          'default' => ''),
 715        'load_functions' => array(
 716          'description' => 'A serialized array of function names (like node_load) to be called to load an object corresponding to a part of the current path.',
 717          'type' => 'text',
 718          'not null' => TRUE,),
 719        'to_arg_functions' => array(
 720          'description' => 'A serialized array of function names (like user_uid_optional_to_arg) to be called to replace a part of the router path with another string.',
 721          'type' => 'text',
 722          'not null' => TRUE,),
 723        'access_callback' => array(
 724          'description' => 'The callback which determines the access to this router path. Defaults to user_access.',
 725          'type' => 'varchar',
 726          'length' => 255,
 727          'not null' => TRUE,
 728          'default' => ''),
 729        'access_arguments' => array(
 730          'description' => 'A serialized array of arguments for the access callback.',
 731          'type' => 'text',
 732          'not null' => FALSE),
 733        'page_callback' => array(
 734          'description' => 'The name of the function that renders the page.',
 735          'type' => 'varchar',
 736          'length' => 255,
 737          'not null' => TRUE,
 738          'default' => ''),
 739        'page_arguments' => array(
 740          'description' => 'A serialized array of arguments for the page callback.',
 741          'type' => 'text',
 742          'not null' => FALSE),
 743        'fit' => array(
 744          'description' => 'A numeric representation of how specific the path is.',
 745          'type' => 'int',
 746          'not null' => TRUE,
 747          'default' => 0),
 748        'number_parts' => array(
 749          'description' => 'Number of parts in this router path.',
 750          'type' => 'int',
 751          'not null' => TRUE,
 752          'default' => 0,
 753          'size' => 'small'),
 754        'tab_parent' => array(
 755          'description' => 'Only for local tasks (tabs) - the router path of the parent page (which may also be a local task).',
 756          'type' => 'varchar',
 757          'length' => 255,
 758          'not null' => TRUE,
 759          'default' => ''),
 760        'tab_root' => array(
 761          'description' => 'Router path of the closest non-tab parent page. For pages that are not local tasks, this will be the same as the path.',
 762          'type' => 'varchar',
 763          'length' => 255,
 764          'not null' => TRUE,
 765          'default' => ''),
 766        'title' => array(
 767          'description' => 'The title for the current page, or the title for the tab if this is a local task.',
 768          'type' => 'varchar',
 769          'length' => 255,
 770          'not null' => TRUE,
 771          'default' => ''),
 772        'title_callback' => array(
 773          'description' => 'A function which will alter the title. Defaults to t()',
 774          'type' => 'varchar',
 775          'length' => 255,
 776          'not null' => TRUE,
 777          'default' => ''),
 778        'title_arguments' => array(
 779          'description' => 'A serialized array of arguments for the title callback. If empty, the title will be used as the sole argument for the title callback.',
 780          'type' => 'varchar',
 781          'length' => 255,
 782          'not null' => TRUE,
 783          'default' => ''),
 784        'type' => array(
 785          'description' => 'Numeric representation of the type of the menu item, like MENU_LOCAL_TASK.',
 786          'type' => 'int',
 787          'not null' => TRUE,
 788          'default' => 0),
 789        'block_callback' => array(
 790          'description' => 'Name of a function used to render the block on the system administration page for this item.',
 791          'type' => 'varchar',
 792          'length' => 255,
 793          'not null' => TRUE,
 794          'default' => ''),
 795        'description' => array(
 796          'description' => 'A description of this item.',
 797          'type' => 'text',
 798          'not null' => TRUE),
 799        'position' => array(
 800          'description' => 'The position of the block (left or right) on the system administration page for this item.',
 801          'type' => 'varchar',
 802          'length' => 255,
 803          'not null' => TRUE,
 804          'default' => ''),
 805        'weight' => array(
 806          'description' => 'Weight of the element. Lighter weights are higher up, heavier weights go down.',
 807          'type' => 'int',
 808          'not null' => TRUE,
 809          'default' => 0),
 810        'file' => array(
 811          'description' => 'The file to include for this element, usually the page callback function lives in this file.',
 812          'type' => 'text',
 813          'size' => 'medium')
 814        ),
 815      'indexes' => array(
 816        'fit' => array('fit'),
 817        'tab_parent' => array('tab_parent'),
 818        'tab_root_weight_title' => array(array('tab_root', 64), 'weight', 'title'),      
 819        ),
 820      'primary key' => array('path'),
 821      );
 822  
 823    $schema['menu_links'] = array(
 824      'description' => 'Contains the individual links within a menu.',
 825      'fields' => array(
 826       'menu_name' => array(
 827          'description' => "The menu name. All links with the same menu name (such as 'navigation') are part of the same menu.",
 828          'type' => 'varchar',
 829          'length' => 32,
 830          'not null' => TRUE,
 831          'default' => ''),
 832        'mlid' => array(
 833          'description' => 'The menu link ID (mlid) is the integer primary key.',
 834          'type' => 'serial',
 835          'unsigned' => TRUE,
 836          'not null' => TRUE),
 837        'plid' => array(
 838          'description' => 'The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.',
 839          'type' => 'int',
 840          'unsigned' => TRUE,
 841          'not null' => TRUE,
 842          'default' => 0),
 843        'link_path' => array(
 844          'description' => 'The Drupal path or external path this link points to.',
 845          'type' => 'varchar',
 846          'length' => 255,
 847          'not null' => TRUE,
 848          'default' => ''),
 849        'router_path' => array(
 850          'description' => 'For links corresponding to a Drupal path (external = 0), this connects the link to a {menu_router}.path for joins.',
 851          'type' => 'varchar',
 852          'length' => 255,
 853          'not null' => TRUE,
 854          'default' => ''),
 855        'link_title' => array(
 856        'description' => 'The text displayed for the link, which may be modified by a title callback stored in {menu_router}.',
 857          'type' => 'varchar',
 858          'length' => 255,
 859          'not null' => TRUE,
 860          'default' => ''),
 861        'options' => array(
 862          'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.',
 863          'type' => 'text',
 864          'not null' => FALSE),
 865        'module' => array(
 866          'description' => 'The name of the module that generated this link.',
 867          'type' => 'varchar',
 868          'length' => 255,
 869          'not null' => TRUE,
 870          'default' => 'system'),
 871        'hidden' => array(
 872          'description' => 'A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)',
 873          'type' => 'int',
 874          'not null' => TRUE,
 875          'default' => 0,
 876          'size' => 'small'),
 877        'external' => array(
 878          'description' => 'A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).',
 879          'type' => 'int',
 880          'not null' => TRUE,
 881          'default' => 0,
 882          'size' => 'small'),
 883        'has_children' => array(
 884          'description' => 'Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).',
 885          'type' => 'int',
 886          'not null' => TRUE,
 887          'default' => 0,
 888          'size' => 'small'),
 889        'expanded' => array(
 890          'description' => 'Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded)',
 891          'type' => 'int',
 892          'not null' => TRUE,
 893          'default' => 0,
 894          'size' => 'small'),
 895        'weight' => array(
 896          'description' => 'Link weight among links in the same menu at the same depth.',
 897          'type' => 'int',
 898          'not null' => TRUE,
 899          'default' => 0),
 900        'depth' => array(
 901          'description' => 'The depth relative to the top level. A link with plid == 0 will have depth == 1.',
 902          'type' => 'int',
 903          'not null' => TRUE,
 904          'default' => 0,
 905          'size' => 'small'),
 906        'customized' => array(
 907          'description' => 'A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).',
 908          'type' => 'int',
 909          'not null' => TRUE,
 910          'default' => 0,
 911          'size' => 'small'),
 912        'p1' => array(
 913          'description' => 'The first mlid in the materialized path. If N = depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.',
 914          'type' => 'int',
 915          'unsigned' => TRUE,
 916          'not null' => TRUE,
 917          'default' => 0),
 918        'p2' => array(
 919          'description' => 'The second mlid in the materialized path. See p1.',
 920          'type' => 'int',
 921          'unsigned' => TRUE,
 922          'not null' => TRUE,
 923          'default' => 0),
 924        'p3' => array(
 925          'description' => 'The third mlid in the materialized path. See p1.',
 926          'type' => 'int',
 927          'unsigned' => TRUE,
 928          'not null' => TRUE,
 929          'default' => 0),
 930        'p4' => array(
 931          'description' => 'The fourth mlid in the materialized path. See p1.',
 932          'type' => 'int',
 933          'unsigned' => TRUE,
 934          'not null' => TRUE,
 935          'default' => 0),
 936        'p5' => array(
 937          'description' => 'The fifth mlid in the materialized path. See p1.',
 938          'type' => 'int',
 939          'unsigned' => TRUE,
 940          'not null' => TRUE,
 941          'default' => 0),
 942        'p6' => array(
 943          'description' => 'The sixth mlid in the materialized path. See p1.',
 944          'type' => 'int',
 945          'unsigned' => TRUE,
 946          'not null' => TRUE,
 947          'default' => 0),
 948        'p7' => array(
 949          'description' => 'The seventh mlid in the materialized path. See p1.',
 950          'type' => 'int',
 951          'unsigned' => TRUE,
 952          'not null' => TRUE,
 953          'default' => 0),
 954        'p8' => array(
 955          'description' => 'The eighth mlid in the materialized path. See p1.',
 956          'type' => 'int',
 957          'unsigned' => TRUE,
 958          'not null' => TRUE,
 959          'default' => 0),
 960        'p9' => array(
 961          'description' => 'The ninth mlid in the materialized path. See p1.',
 962          'type' => 'int',
 963          'unsigned' => TRUE,
 964          'not null' => TRUE,
 965          'default' => 0),
 966        'updated' => array(
 967          'description' => 'Flag that indicates that this link was generated during the update from Drupal 5.',
 968          'type' => 'int',
 969          'not null' => TRUE,
 970          'default' => 0,
 971          'size' => 'small'),
 972        ),
 973      'indexes' => array(
 974        'path_menu' => array(array('link_path', 128), 'menu_name'),
 975        'menu_plid_expand_child' => array(
 976          'menu_name', 'plid', 'expanded', 'has_children'),
 977        'menu_parents' => array(
 978          'menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
 979        'router_path' => array(array('router_path', 128)),
 980        ),
 981      'primary key' => array('mlid'),
 982      );
 983  
 984    $schema['semaphore'] = array(
 985      'description' => 'Table for holding semaphores, locks, flags, etc. that cannot be stored as Drupal variables since they must not be cached.',
 986      'fields' => array(
 987        'name' => array(
 988          'description' => 'Primary Key: Unique name.',
 989          'type' => 'varchar',
 990          'length' => 255,
 991          'not null' => TRUE,
 992          'default' => ''),
 993        'value' => array(
 994          'description' => 'A value.',
 995          'type' => 'varchar',
 996          'length' => 255,
 997          'not null' => TRUE,
 998          'default' => ''),
 999        'expire' => array(
1000          'description' => 'A Unix timestamp with microseconds indicating when the semaphore should expire.',
1001          'type' => 'float',
1002          'size' => 'big',
1003          'not null' => TRUE),
1004        ),
1005      'indexes' => array('expire' => array('expire')),
1006      'primary key' => array('name'),
1007      );
1008  
1009    $schema['sessions'] = array(
1010      'description' => "Drupal's session handlers read and write into the sessions table. Each record represents a user session, either anonymous or authenticated.",
1011      'fields' => array(
1012        'uid' => array(
1013          'description' => 'The {users}.uid corresponding to a session, or 0 for anonymous user.',
1014          'type' => 'int',
1015          'unsigned' => TRUE,
1016          'not null' => TRUE),
1017        'sid' => array(
1018          'description' => "Primary key: A session ID. The value is generated by PHP's Session API.",
1019          'type' => 'varchar',
1020          'length' => 64,
1021          'not null' => TRUE,
1022          'default' => ''),
1023        'hostname' => array(
1024          'description' => 'The IP address that last used this session ID (sid).',
1025          'type' => 'varchar',
1026          'length' => 128,
1027          'not null' => TRUE,
1028          'default' => ''),
1029        'timestamp' => array(
1030          'description' => 'The Unix timestamp when this session last requested a page. Old records are purged by PHP automatically.',
1031          'type' => 'int',
1032          'not null' => TRUE,
1033          'default' => 0),
1034        'cache' => array(
1035          'description' => "The time of this user's last post. This is used when the site has specified a minimum_cache_lifetime. See cache_get().",
1036          'type' => 'int',
1037          'not null' => TRUE,
1038          'default' => 0),
1039        'session' => array(
1040          'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.',
1041          'type' => 'text',
1042          'not null' => FALSE,
1043          'size' => 'big')
1044        ),
1045      'primary key' => array('sid'),
1046      'indexes' => array(
1047        'timestamp' => array('timestamp'),
1048        'uid' => array('uid')
1049        ),
1050      );
1051  
1052    $schema['system'] = array(
1053      'description' => "A list of all modules, themes, and theme engines that are or have been installed in Drupal's file system.",
1054      'fields' => array(
1055        'filename' => array(
1056          'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. modules/node/node.module.',
1057          'type' => 'varchar',
1058          'length' => 255,
1059          'not null' => TRUE,
1060          'default' => ''),
1061        'name' => array(
1062          'description' => 'The name of the item; e.g. node.',
1063          'type' => 'varchar',
1064          'length' => 255,
1065          'not null' => TRUE,
1066          'default' => ''),
1067        'type' => array(
1068          'description' => 'The type of the item, either module, theme, or theme_engine.',
1069          'type' => 'varchar',
1070          'length' => 255,
1071          'not null' => TRUE,
1072          'default' => ''),
1073        'owner' => array(
1074          'description' => "A theme's 'parent'. Can be either a theme or an engine.",
1075          'type' => 'varchar',
1076          'length' => 255,
1077          'not null' => TRUE,
1078          'default' => ''),
1079        'status' => array(
1080          'description' => 'Boolean indicating whether or not this item is enabled.',
1081          'type' => 'int',
1082          'not null' => TRUE,
1083          'default' => 0),
1084        'throttle' => array(
1085          'description' => 'Boolean indicating whether this item is disabled when the throttle.module disables throttleable items.',
1086          'type' => 'int',
1087          'not null' => TRUE,
1088          'default' => 0,
1089          'size' => 'tiny'),
1090        'bootstrap' => array(
1091          'description' => "Boolean indicating whether this module is loaded during Drupal's early bootstrapping phase (e.g. even before the page cache is consulted).",
1092          'type' => 'int',
1093          'not null' => TRUE,
1094          'default' => 0),
1095        'schema_version' => array(
1096          'description' => "The module's database schema version number. -1 if the module is not installed (its tables do not exist); 0 or the largest N of the module's hook_update_N() function that has either been run or existed when the module was first installed.",
1097          'type' => 'int',
1098          'not null' => TRUE,
1099          'default' => -1,
1100          'size' => 'small'),
1101        'weight' => array(
1102          'description' => "The order in which this module's hooks should be invoked relative to other modules. Equal-weighted modules are ordered by name.",
1103          'type' => 'int',
1104          'not null' => TRUE,
1105          'default' => 0),
1106        'info' => array(
1107          'description' => "A serialized array containing information from the module's .info file; keys can include name, description, package, version, core, dependencies, dependents, and php.",
1108          'type' => 'text',
1109          'not null' => FALSE)
1110        ),
1111      'primary key' => array('filename'),
1112      'indexes' =>
1113        array(
1114          'modules' => array(array('type', 12), 'status', 'weight', 'filename'),
1115          'bootstrap' => array(array('type', 12), 'status', 'bootstrap', 'weight', 'filename'),
1116          'type_name' => array(array('type', 12), 'name'),
1117        ),
1118      );
1119  
1120    $schema['url_alias'] = array(
1121      'description' => 'A list of URL aliases for Drupal paths; a user may visit either the source or destination path.',
1122      'fields' => array(
1123        'pid' => array(
1124          'description' => 'A unique path alias identifier.',
1125          'type' => 'serial',
1126          'unsigned' => TRUE,
1127          'not null' => TRUE),
1128        'src' => array(
1129          'description' => 'The Drupal path this alias is for; e.g. node/12.',
1130          'type' => 'varchar',
1131          'length' => 128,
1132          'not null' => TRUE,
1133          'default' => ''),
1134        'dst' => array(
1135          'description' => 'The alias for this path; e.g. title-of-the-story.',
1136          'type' => 'varchar',
1137          'length' => 128,
1138          'not null' => TRUE,
1139          'default' => ''),
1140        'language' => array(
1141          'description' => 'The language this alias is for; if blank, the alias will be used for unknown languages. Each Drupal path can have an alias for each supported language.',
1142          'type' => 'varchar',
1143          'length' => 12,
1144          'not null' => TRUE,
1145          'default' => '')
1146        ),
1147      'unique keys' => array('dst_language_pid' => array('dst', 'language', 'pid')),
1148      'primary key' => array('pid'),
1149      'indexes' => array('src_language_pid' => array('src', 'language', 'pid')),
1150      );
1151  
1152    return $schema;
1153  }
1154  
1155  // Updates for core.
1156  
1157  function system_update_last_removed() {
1158    return 1021;
1159  }
1160  
1161  /**
1162   * @defgroup updates-5.x-extra Extra system updates for 5.x
1163   * @{
1164   */
1165  
1166  /**
1167   * Add index on users created column.
1168   */
1169  function system_update_1022() {
1170    $ret = array();
1171    db_add_index($ret, 'users', 'created', array('created'));
1172    // Also appears as system_update_6004(). Ensure we don't update twice.
1173    variable_set('system_update_1022', TRUE);
1174    return $ret;
1175  }
1176  
1177  /**
1178   * @} End of "defgroup updates-5.x-extra"
1179   */
1180  
1181  /**
1182   * @defgroup updates-5.x-to-6.x System updates from 5.x to 6.x
1183   * @{
1184   */
1185  
1186  /**
1187   * Remove auto_increment from {boxes} to allow adding custom blocks with
1188   * visibility settings.
1189   */
1190  function system_update_6000() {
1191    $ret = array();
1192    switch ($GLOBALS['db_type']) {
1193      case 'mysql':
1194      case 'mysqli':
1195        $max = (int)db_result(db_query('SELECT MAX(bid) FROM {boxes}'));
1196        $ret[] = update_sql('ALTER TABLE {boxes} CHANGE COLUMN bid bid int NOT NULL');
1197        $ret[] = update_sql("REPLACE INTO {sequences} VALUES ('{boxes}_bid', $max)");
1198        break;
1199    }
1200    return $ret;
1201  }
1202  
1203  /**
1204   * Add version id column to {term_node} to allow taxonomy module to use revisions.
1205   */
1206  function system_update_6001() {
1207    $ret = array();
1208  
1209    // Add vid to term-node relation.  The schema says it is unsigned.
1210    db_add_field($ret, 'term_node', 'vid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
1211    db_drop_primary_key($ret, 'term_node');
1212    db_add_primary_key($ret, 'term_node', array('vid', 'tid', 'nid'));
1213    db_add_index($ret, 'term_node', 'vid', array('vid'));
1214  
1215    db_query('UPDATE {term_node} SET vid = (SELECT vid FROM {node} n WHERE {term_node}.nid = n.nid)');
1216    return $ret;
1217  }
1218  
1219  /**
1220   * Increase the maximum length of variable names from 48 to 128.
1221   */
1222  function system_update_6002() {
1223    $ret = array();
1224    db_drop_primary_key($ret, 'variable');
1225    db_change_field($ret, 'variable', 'name', 'name', array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
1226    db_add_primary_key($ret, 'variable', array('name'));
1227    return $ret;
1228  }
1229  
1230  /**
1231   * Add index on comments status column.
1232   */
1233  function system_update_6003() {
1234    $ret = array();
1235    db_add_index($ret, 'comments', 'status', array('status'));
1236    return $ret;
1237  }
1238  
1239  /**
1240   * This update used to add an index on users created column (#127941).
1241   * However, system_update_1022() does the same thing.  This update
1242   * tried to detect if 1022 had already run but failed to do so,
1243   * resulting in an "index already exists" error.
1244   *
1245   * Adding the index here is never necessary.  Sites installed before
1246   * 1022 will run 1022, getting the update.  Sites installed on/after 1022
1247   * got the index when the table was first created.  Therefore, this
1248   * function is now a no-op.
1249   */
1250  function system_update_6004() {
1251    return array();
1252  }
1253  
1254  /**
1255   * Add language to url_alias table and modify indexes.
1256   */
1257  function system_update_6005() {
1258    $ret = array();
1259    switch ($GLOBALS['db_type']) {
1260      case 'pgsql':
1261        db_add_column($ret, 'url_alias', 'language', 'varchar(12)', array('default' => "''", 'not null' => TRUE));
1262  
1263        // As of system.install:1.85 (before the new language
1264        // subsystem), new installs got a unique key named
1265        // url_alias_dst_key on url_alias.dst.  Unfortunately,
1266        // system_update_162 created a unique key inconsistently named
1267        // url_alias_dst_idx on url_alias.dst (keys should have the _key
1268        // suffix, indexes the _idx suffix).  Therefore, sites installed
1269        // before system_update_162 have a unique key with a different
1270        // name than sites installed after system_update_162().  Now, we
1271        // want to drop the unique key on dst which may have either one
1272        // of two names and create a new unique key on (dst, language).
1273        // There is no way to know which key name exists so we have to
1274        // drop both, causing an SQL error.  Thus, we just hide the
1275        // error and only report the update_sql results that work.
1276        $err = error_reporting(0);
1277        $ret1 = update_sql('DROP INDEX {url_alias}_dst_idx');
1278        if ($ret1['success']) {
1279    $ret[] = $ret1;
1280        }
1281        $ret1 = array();
1282        db_drop_unique_key($ret, 'url_alias', 'dst');
1283        foreach ($ret1 as $r) {
1284    if ($r['success']) {
1285      $ret[] = $r;
1286    }
1287        }
1288        error_reporting($err);
1289  
1290        $ret[] = update_sql('CREATE UNIQUE INDEX {url_alias}_dst_language_idx ON {url_alias}(dst, language)');
1291        break;
1292      case 'mysql':
1293      case 'mysqli':
1294        $ret[] = update_sql("ALTER TABLE {url_alias} ADD language varchar(12) NOT NULL default ''");
1295        $ret[] = update_sql("ALTER TABLE {url_alias} DROP INDEX dst");
1296        $ret[] = update_sql("ALTER TABLE {url_alias} ADD UNIQUE dst_language (dst, language)");
1297        break;
1298    }
1299    return $ret;
1300  }
1301  
1302  /**
1303   * Drop useless indices on node_counter table.
1304   */
1305  function system_update_6006() {
1306    $ret = array();
1307    switch ($GLOBALS['db_type']) {
1308      case 'pgsql':
1309        $ret[] = update_sql('DROP INDEX {node_counter}_daycount_idx');
1310        $ret[] = update_sql('DROP INDEX {node_counter}_totalcount_idx');
1311        $ret[] = update_sql('DROP INDEX {node_counter}_timestamp_idx');
1312        break;
1313      case 'mysql':
1314      case 'mysqli':
1315        $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX daycount");
1316        $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX totalcount");
1317        $ret[] = update_sql("ALTER TABLE {node_counter} DROP INDEX timestamp");
1318        break;
1319    }
1320    return $ret;
1321  }
1322  
1323  /**
1324   * Change the severity column in the watchdog table to the new values.
1325   */
1326  function system_update_6007() {
1327    $ret = array();
1328    $ret[] = update_sql("UPDATE {watchdog} SET severity = ". WATCHDOG_NOTICE ." WHERE severity = 0");
1329    $ret[] = update_sql("UPDATE {watchdog} SET severity = ". WATCHDOG_WARNING ." WHERE severity = 1");
1330    $ret[] = update_sql("UPDATE {watchdog} SET severity = ". WATCHDOG_ERROR ." WHERE severity = 2");
1331    return $ret;
1332  }
1333  
1334  /**
1335   * Add info files to themes.  The info and owner columns are added by
1336   * update_fix_d6_requirements() in update.php to avoid a large number
1337   * of error messages from update.php.  All we need to do here is copy
1338   * description to owner and then drop description.
1339   */
1340  function system_update_6008() {
1341    $ret = array();
1342    $ret[] = update_sql('UPDATE {system} SET owner = description');
1343    db_drop_field($ret, 'system', 'description');
1344  
1345    // Rebuild system table contents.
1346    module_rebuild_cache();
1347    system_theme_data();
1348  
1349    return $ret;
1350  }
1351  
1352  /**
1353   * The PHP filter is now a separate module.
1354   */
1355  function system_update_6009() {
1356    $ret = array();
1357  
1358    // If any input format used the Drupal 5 PHP filter.
1359    if (db_result(db_query("SELECT COUNT(format) FROM {filters} WHERE module = 'filter' AND delta = 1"))) {
1360      // Enable the PHP filter module.
1361      $ret[] = update_sql("UPDATE {system} SET status = 1 WHERE name = 'php' AND type = 'module'");
1362      // Update the input filters.
1363      $ret[] = update_sql("UPDATE {filters} SET delta = 0, module = 'php' WHERE module = 'filter' AND delta = 1");
1364    }
1365  
1366    // With the removal of the PHP evaluator filter, the deltas of the line break
1367    // and URL filter have changed.
1368    $ret[] = update_sql("UPDATE {filters} SET delta = 1 WHERE module = 'filter' AND delta = 2");
1369    $ret[] = update_sql("UPDATE {filters} SET delta = 2 WHERE module = 'filter' AND delta = 3");
1370  
1371    return $ret;
1372  }
1373  
1374  /**
1375   * Add variable replacement for watchdog messages.
1376   *
1377   * The variables field is NOT NULL and does not have a default value.
1378   * Existing log messages should not be translated in the new system,
1379   * so we insert 'N;' (serialize(NULL)) as the temporary default but
1380   * then remove the default value to match the schema.
1381   */
1382  function system_update_6010() {
1383    $ret = array();
1384    db_add_field($ret, 'watchdog', 'variables', array('type' => 'text', 'size' => 'big', 'not null' => TRUE, 'initial' => 'N;'));
1385    return $ret;
1386  }
1387  
1388  /**
1389   * Add language support to nodes
1390   */
1391  function system_update_6011() {
1392    $ret = array();
1393    switch ($GLOBALS['db_type']) {
1394      case 'pgsql':
1395        db_add_column($ret, 'node', 'language', 'varchar(12)', array('default' => "''", 'not null' => TRUE));
1396        break;
1397      case 'mysql':
1398      case 'mysqli':
1399        $ret[] = update_sql("ALTER TABLE {node} ADD language varchar(12) NOT NULL default ''");
1400        break;
1401    }
1402    return $ret;
1403  }
1404  
1405  /**
1406   * Add serialized field to cache tables.  This is now handled directly
1407   * by update.php, so this function is a no-op.
1408   */
1409  function system_update_6012() {
1410    return array();
1411  }
1412  
1413  /**
1414   * Rebuild cache data for theme system changes
1415   */
1416  function system_update_6013() {
1417    // Rebuild system table contents.
1418    module_rebuild_cache();
1419    system_theme_data();
1420  
1421    return array(array('success' => TRUE, 'query' => 'Cache rebuilt.'));
1422  }
1423  
1424  /**
1425   * Record that the installer is done, so it is not
1426   * possible to run the installer on upgraded sites.
1427   */
1428  function system_update_6014() {
1429    variable_set('install_task', 'done');
1430  
1431    return array(array('success' => TRUE, 'query' => "variable_set('install_task')"));
1432  }
1433  
1434  /**
1435   * Add the form cache table.
1436   */
1437  function system_update_6015() {
1438    $ret = array();
1439  
1440    switch ($GLOBALS['db_type']) {
1441      case 'pgsql':
1442        $ret[] = update_sql("CREATE TABLE {cache_form} (
1443          cid varchar(255) NOT NULL default '',
1444          data bytea,
1445          expire int NOT NULL default '0',
1446          created int NOT NULL default '0',
1447          headers text,
1448          serialized smallint NOT NULL default '0',
1449          PRIMARY KEY (cid)
1450      )");
1451        $ret[] = update_sql("CREATE INDEX {cache_form}_expire_idx ON {cache_form} (expire)");
1452        break;
1453      case 'mysql':
1454      case 'mysqli':
1455        $ret[] = update_sql("CREATE TABLE {cache_form} (
1456          cid varchar(255) NOT NULL default '',
1457          data longblob,
1458          expire int NOT NULL default '0',
1459          created int NOT NULL default '0',
1460          headers text,
1461          serialized int(1) NOT NULL default '0',
1462          PRIMARY KEY (cid),
1463          INDEX expire (expire)
1464        ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
1465        break;
1466    }
1467  
1468    return $ret;
1469  }
1470  
1471  /**
1472   * Make {node}'s primary key be nid, change nid,vid to a unique key.
1473   * Add primary keys to block, filters, flood, permission, and term_relation.
1474   */
1475  function system_update_6016() {
1476    $ret = array();
1477  
1478    switch ($GLOBALS['db_type']) {
1479      case 'pgsql':
1480        $ret[] = update_sql("ALTER TABLE {node} ADD CONSTRAINT {node}_nid_vid_key UNIQUE (nid, vid)");
1481        db_add_column($ret, 'blocks', 'bid', 'serial');
1482        $ret[] = update_sql("ALTER TABLE {blocks} ADD PRIMARY KEY (bid)");
1483        db_add_column($ret, 'filters', 'fid', 'serial');
1484        $ret[] = update_sql("ALTER TABLE {filters} ADD PRIMARY KEY (fid)");
1485        db_add_column($ret, 'flood', 'fid', 'serial');
1486        $ret[] = update_sql("ALTER TABLE {flood} ADD PRIMARY KEY (fid)");
1487        db_add_column($ret, 'permission', 'pid', 'serial');
1488        $ret[] = update_sql("ALTER TABLE {permission} ADD PRIMARY KEY (pid)");
1489        db_add_column($ret, 'term_relation', 'trid', 'serial');
1490        $ret[] = update_sql("ALTER TABLE {term_relation} ADD PRIMARY KEY (trid)");
1491        db_add_column($ret, 'term_synonym', 'tsid', 'serial');
1492        $ret[] = update_sql("ALTER TABLE {term_synonym} ADD PRIMARY KEY (tsid)");
1493        break;
1494      case 'mysql':
1495      case 'mysqli':
1496        $ret[] = update_sql('ALTER TABLE {node} ADD UNIQUE KEY nid_vid (nid, vid)');
1497        $ret[] = update_sql("ALTER TABLE {blocks} ADD bid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1498        $ret[] = update_sql("ALTER TABLE {filters} ADD fid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1499        $ret[] = update_sql("ALTER TABLE {flood} ADD fid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1500        $ret[] = update_sql("ALTER TABLE {permission} ADD pid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1501        $ret[] = update_sql("ALTER TABLE {term_relation} ADD trid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1502        $ret[] = update_sql("ALTER TABLE {term_synonym} ADD tsid int NOT NULL AUTO_INCREMENT PRIMARY KEY");
1503        break;
1504    }
1505  
1506    return $ret;
1507  }
1508  
1509  /**
1510   * Rename settings related to user.module email notifications.
1511   */
1512  function system_update_6017() {
1513    $ret = array();
1514    // Maps old names to new ones.
1515    $var_names = array(
1516      'admin'    => 'register_admin_created',
1517      'approval' => 'register_pending_approval',
1518      'welcome'  => 'register_no_approval_required',
1519      'pass'     => 'password_reset',
1520    );
1521    foreach ($var_names as $old => $new) {
1522      foreach (array('_subject', '_body') as $suffix) {
1523        $old_name = 'user_mail_'. $old . $suffix;
1524        $new_name = 'user_mail_'. $new . $suffix;
1525        if ($old_val = variable_get($old_name, FALSE)) {
1526          variable_set($new_name, $old_val);
1527          variable_del($old_name);
1528          $ret[] = array('success' => TRUE, 'query' => "variable_set($new_name)");
1529          $ret[] = array('success' => TRUE, 'query' => "variable_del($old_name)");
1530          if ($old_name == 'user_mail_approval_body') {
1531            drupal_set_message('Saving an old value of the welcome message body for users that are pending administrator approval. However, you should consider modifying this text, since Drupal can now be configured to automatically notify users and send them their login information when their accounts are approved. See the <a href="'. url('admin/user/settings') .'">User settings</a> page for details.');
1532          }
1533        }
1534      }
1535    }
1536    return $ret;
1537  }
1538  
1539  /**
1540   * Add HTML corrector to HTML formats or replace the old module if it was in use.
1541   */
1542  function system_update_6018() {
1543    $ret = array();
1544  
1545    // Disable htmlcorrector.module, if it exists and replace its filter.
1546    if (module_exists('htmlcorrector')) {
1547      module_disable(array('htmlcorrector'));
1548      $ret[] = update_sql("UPDATE {filter_formats} SET module = 'filter', delta = 3 WHERE module = 'htmlcorrector'");
1549      $ret[] = array('success' => TRUE, 'query' => 'HTML Corrector module was disabled; this functionality has now been added to core.');
1550      return $ret;
1551    }
1552  
1553    // Otherwise, find any format with 'HTML' in its name and add the filter at the end.
1554    $result = db_query("SELECT format, name FROM {filter_formats} WHERE name LIKE '%HTML%'");
1555    while ($format = db_fetch_object($result)) {
1556      $weight = db_result(db_query("SELECT MAX(weight) FROM {filters} WHERE format = %d", $format->format));
1557      db_query("INSERT INTO {filters} (format, module, delta, weight) VALUES (%d, '%s', %d, %d)", $format->format, 'filter', 3, max(10, $weight + 1));
1558      $ret[] = array('success' => TRUE, 'query' => "HTML corrector filter added to the '". $format->name ."' input format.");
1559    }
1560  
1561    return $ret;
1562  }
1563  
1564  /**
1565   * Reconcile small differences in the previous, manually created mysql
1566   * and pgsql schemas so they are the same and can be represented by a
1567   * single schema structure.
1568   *
1569   * Note that the mysql and pgsql cases make different changes.  This
1570   * is because each schema needs to be tweaked in different ways to
1571   * conform to the new schema structure.  Also, since they operate on
1572   * tables defined by many optional core modules which may not ever
1573   * have been installed, they must test each table for existence.  If
1574   * the modules are first installed after this update exists the tables
1575   * will be created from the schema structure and will start out
1576   * correct.
1577   */
1578  function system_update_6019() {
1579    $ret = array();
1580  
1581    switch ($GLOBALS['db_type']) {
1582      case 'pgsql':
1583        // Remove default ''.
1584        if (db_table_exists('aggregator_feed')) {
1585          db_field_set_no_default($ret, 'aggregator_feed', 'description');
1586          db_field_set_no_default($ret, 'aggregator_feed', 'image');
1587        }
1588        db_field_set_no_default($ret, 'blocks', 'pages');
1589        if (db_table_exists('contact')) {
1590          db_field_set_no_default($ret, 'contact', 'recipients');
1591          db_field_set_no_default($ret, 'contact', 'reply');
1592        }
1593        db_field_set_no_default($ret, 'watchdog', 'location');
1594        db_field_set_no_default($ret, 'node_revisions', 'body');
1595        db_field_set_no_default($ret, 'node_revisions', 'teaser');
1596        db_field_set_no_default($ret, 'node_revisions', 'log');
1597  
1598        // Update from pgsql 'float' (which means 'double precision') to
1599        // schema 'float' (which in pgsql means 'real').
1600        if (db_table_exists('search_index')) {
1601          db_change_field($ret, 'search_index', 'score', 'score', array('type' => 'float'));
1602        }
1603        if (db_table_exists('search_total')) {
1604          db_change_field($ret, 'search_total', 'count', 'count', array('type' => 'float'));
1605        }
1606  
1607        // Replace unique index dst_language with a unique constraint.  The
1608        // result is the same but the unique key fits our current schema
1609        // structure.  Also, the postgres documentation implies that
1610        // unique constraints are preferable to unique indexes.  See
1611        // http://www.postgresql.org/docs/8.2/interactive/indexes-unique.html.
1612        if (db_table_exists('url_alias')) {
1613          db_drop_index($ret, 'url_alias', 'dst_language');
1614          db_add_unique_key($ret, 'url_alias', 'dst_language',
1615            array('dst', 'language'));
1616        }
1617  
1618        // Fix term_node pkey: mysql and pgsql code had different orders.
1619        if (db_table_exists('term_node')) {
1620          db_drop_primary_key($ret, 'term_node');
1621          db_add_primary_key($ret, 'term_node', array('vid', 'tid', 'nid'));
1622        }
1623  
1624        // Make boxes.bid unsigned.
1625        db_drop_primary_key($ret, 'boxes');
1626        db_change_field($ret, 'boxes', 'bid', 'bid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('bid')));
1627  
1628        // Fix primary key
1629        db_drop_primary_key($ret, 'node');
1630        db_add_primary_key($ret, 'node', array('nid'));
1631  
1632        break;
1633  
1634      case 'mysql':
1635      case 'mysqli':
1636        // Rename key 'link' to 'url'.
1637        if (db_table_exists('aggregator_feed')) {
1638          db_drop_unique_key($ret, 'aggregator_feed', 'link');
1639          db_add_unique_key($ret, 'aggregator_feed', 'url', array('url'));
1640        }
1641  
1642        // Change to size => small.
1643        if (db_table_exists('boxes')) {
1644          db_change_field($ret, 'boxes', 'format', 'format', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1645        }
1646  
1647        // Change to size => small.
1648        // Rename index 'lid' to 'nid'.
1649        if (db_table_exists('comments')) {
1650          db_change_field($ret, 'comments', 'format', 'format', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1651          db_drop_index($ret, 'comments', 'lid');
1652          db_add_index($ret, 'comments', 'nid', array('nid'));
1653        }
1654  
1655        // Change to size => small.
1656        db_change_field($ret, 'cache', 'serialized', 'serialized', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1657        db_change_field($ret, 'cache_filter', 'serialized', 'serialized', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1658        db_change_field($ret, 'cache_page', 'serialized', 'serialized', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1659        db_change_field($ret, 'cache_form', 'serialized', 'serialized', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0));
1660  
1661        // Remove default => 0, set auto increment.
1662        $new_uid = 1 + db_result(db_query('SELECT MAX(uid) FROM {users}'));
1663        $ret[] = update_sql('UPDATE {users} SET uid = '. $new_uid .' WHERE uid = 0');
1664        db_drop_primary_key($ret, 'users');
1665        db_change_field($ret, 'users', 'uid', 'uid', array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array('uid')));
1666        $ret[] = update_sql('UPDATE {users} SET uid = 0 WHERE uid = '. $new_uid);
1667  
1668        // Special field names.
1669        $map = array('node_revisions' => 'vid');
1670        // Make sure these tables have proper auto_increment fields.
1671        foreach (array('boxes', 'files', 'node', 'node_revisions') as $table) {
1672          $field = isset($map[$table]) ? $map[$table] : $table[0] .'id';
1673          db_drop_primary_key($ret, $table);
1674          db_change_field($ret, $table, $field, $field, array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), array('primary key' => array($field)));
1675        }
1676  
1677        break;
1678    }
1679  
1680    return $ret;
1681  }
1682  
1683  /**
1684   * Create the tables for the new menu system.
1685   */
1686  function system_update_6020() {
1687    $ret = array();
1688  
1689    $schema['menu_router'] = array(
1690      'fields' => array(
1691        'path'             => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1692        'load_functions'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1693        'to_arg_functions' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1694        'access_callback'  => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1695        'access_arguments' => array('type' => 'text', 'not null' => FALSE),
1696        'page_callback'    => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1697        'page_arguments'   => array('type' => 'text', 'not null' => FALSE),
1698        'fit'              => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
1699        'number_parts'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1700        'tab_parent'       => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1701        'tab_root'         => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1702        'title'            => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1703        'title_callback'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1704        'title_arguments'  => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1705        'type'             => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
1706        'block_callback'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1707        'description'      => array('type' => 'text', 'not null' => TRUE),
1708        'position'         => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1709        'weight'           => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
1710        'file'             => array('type' => 'text', 'size' => 'medium')
1711      ),
1712      'indexes' => array(
1713        'fit'        => array('fit'),
1714        'tab_parent' => array('tab_parent')
1715      ),
1716      'primary key' => array('path'),
1717    );
1718  
1719    $schema['menu_links'] = array(
1720      'fields' => array(
1721        'menu_name'    => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
1722        'mlid'         => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
1723        'plid'         => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1724        'link_path'    => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1725        'router_path'  => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1726        'link_title'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1727        'options'      => array('type' => 'text', 'not null' => FALSE),
1728        'module'       => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => 'system'),
1729        'hidden'       => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1730        'external'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1731        'has_children' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1732        'expanded'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1733        'weight'       => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
1734        'depth'        => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1735        'customized'   => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1736        'p1'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1737        'p2'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1738        'p3'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1739        'p4'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1740        'p5'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1741        'p6'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1742        'p7'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1743        'p8'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1744        'p9'           => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
1745        'updated'      => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
1746      ),
1747      'indexes' => array(
1748        'path_menu'              => array(array('link_path', 128), 'menu_name'),
1749        'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded', 'has_children'),
1750        'menu_parents'           => array('menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
1751        'router_path'            => array(array('router_path', 128)),
1752      ),
1753      'primary key' => array('mlid'),
1754    );
1755  
1756    foreach ($schema as $name => $table) {
1757      db_create_table($ret, $name, $table);
1758    }
1759    return $ret;
1760  }
1761  
1762  /**
1763   * Migrate the menu items from the old menu system to the new menu_links table.
1764   */
1765  function system_update_6021() {
1766    $ret = array('#finished' => 0);
1767    $menus = array(
1768      'navigation' => array(
1769        'menu_name' => 'navigation',
1770        'title' => 'Navigation',
1771        'description' => 'The navigation menu is provided by Drupal and is the main interactive menu for any site. It is usually the only menu that contains personalized links for authenticated users, and is often not even visible to anonymous users.',
1772      ),
1773      'primary-links' => array(
1774        'menu_name' => 'primary-links',
1775        'title' => 'Primary links',
1776        'description' => 'Primary links are often used at the theme layer to show the major sections of a site. A typical representation for primary links would be tabs along the top.',
1777      ),
1778      'secondary-links' => array(
1779        'menu_name' => 'secondary-links',
1780        'title' => 'Secondary links',
1781        'description' => 'Secondary links are often used for pages like legal notices, contact details, and other secondary navigation items that play a lesser role than primary links.',
1782      ),
1783    );
1784    // Multi-part update
1785    if (!isset($_SESSION['system_update_6021'])) {
1786      db_add_field($ret, 'menu', 'converted', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
1787      $_SESSION['system_update_6021_max'] = db_result(db_query('SELECT COUNT(*) FROM {menu}'));
1788      $_SESSION['menu_menu_map'] = array(1 => 'navigation');
1789      // 0 => FALSE is for new menus, 1 => FALSE is for the navigation.
1790      $_SESSION['menu_item_map'] = array(0 => FALSE, 1 => FALSE);
1791      $table = array(
1792        'fields' => array(
1793          'menu_name'   => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
1794          'title'       => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
1795          'description' => array('type' => 'text', 'not null' => FALSE),
1796        ),
1797        'primary key' => array('menu_name'),
1798      );
1799      db_create_table($ret, 'menu_custom', $table);
1800      db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", $menus['navigation']);
1801      $_SESSION['system_update_6021'] = 0;
1802    }
1803  
1804    $limit = 50;
1805    while ($limit-- && ($item = db_fetch_array(db_query_range('SELECT * FROM {menu} WHERE converted = 0', 0, 1)))) {
1806      // If it's not a menu...
1807      if ($item['pid']) {
1808        // Let's climb up until we find an item with a converted parent.
1809        $item_original = $item;
1810        while ($item && !isset($_SESSION['menu_item_map'][$item['pid']])) {
1811          $item = db_fetch_array(db_query('SELECT * FROM {menu} WHERE mid = %d', $item['pid']));
1812        }
1813        // This can only occur if the menu entry is a leftover in the menu table.
1814        // These do not appear in Drupal 5 anyways, so we skip them.
1815        if (!$item) {
1816          db_query('UPDATE {menu} SET converted = %d WHERE mid = %d', 1, $item_original['mid']);
1817          $_SESSION['system_update_6021']++;
1818          continue;
1819        }
1820      }
1821      // We need to recheck because item might have changed.
1822      if ($item['pid']) {
1823        // Fill the new fields.
1824        $item['link_title'] = $item['title'];
1825        $item['link_path'] = drupal_get_normal_path($item['path']);
1826        // We know the parent is already set. If it's not FALSE then it's an item.
1827        if ($_SESSION['menu_item_map'][$item['pid']]) {
1828          // The new menu system parent link id.
1829          $item['plid'] = $_SESSION['menu_item_map'][$item['pid']]['mlid'];
1830          // The new menu system menu name.
1831          $item['menu_name'] = $_SESSION['menu_item_map'][$item['pid']]['menu_name'];
1832        }
1833        else {
1834          // This a top level element.
1835          $item['plid'] = 0;
1836          // The menu name is stored among the menus.
1837          $item['menu_name'] = $_SESSION['menu_menu_map'][$item['pid']];
1838        }
1839        // Is the element visible in the menu block?
1840        $item['hidden'] = !($item['type'] & MENU_VISIBLE_IN_TREE);
1841        // Is it a custom(ized) element?
1842        if ($item['type'] & (MENU_CREATED_BY_ADMIN | MENU_MODIFIED_BY_ADMIN)) {
1843          $item['customized'] = TRUE;
1844        }
1845        // Items created via the menu module need to be assigned to it.
1846        if ($item['type'] & MENU_CREATED_BY_ADMIN) {
1847          $item['module'] = 'menu';
1848          $item['router_path'] = '';
1849          $item['updated'] = TRUE;
1850        }
1851        else {
1852          $item['module'] = 'system';
1853          $item['router_path'] = $item['path'];
1854          $item['updated'] = FALSE;
1855        }
1856        if ($item['description']) {
1857          $item['options']['attributes']['title'] = $item['description'];
1858        }      
1859        
1860        // Save the link.
1861        menu_link_save($item);
1862        $_SESSION['menu_item_map'][$item['mid']] = array('mlid' => $item['mlid'], 'menu_name' => $item['menu_name']);
1863      }
1864      elseif (!isset($_SESSION['menu_menu_map'][$item['mid']])) {
1865        $item['menu_name'] = 'menu-'. preg_replace('/[^a-zA-Z0-9]/', '-', strtolower($item['title']));
1866        $item['menu_name'] = substr($item['menu_name'], 0, 20);
1867        $original_menu_name = $item['menu_name'];
1868        $i = 0;
1869        while (db_result(db_query("SELECT menu_name FROM {menu_custom} WHERE menu_name = '%s'", $item['menu_name']))) {
1870          $item['menu_name'] = $original_menu_name . ($i++);
1871        }
1872        if ($item['path']) {
1873          // Another bunch of bogus entries. Apparently, these are leftovers
1874          // from Drupal 4.7 .
1875          $_SESSION['menu_bogus_menus'][] = $item['menu_name'];
1876        }
1877        else {
1878          // Add this menu to the list of custom menus.
1879          db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '')", $item['menu_name'], $item['title']);
1880        }
1881        $_SESSION['menu_menu_map'][$item['mid']] = $item['menu_name'];
1882        $_SESSION['menu_item_map'][$item['mid']] = FALSE;
1883      }
1884      db_query('UPDATE {menu} SET converted = %d WHERE mid = %d', 1, $item['mid']);
1885      $_SESSION['system_update_6021']++;
1886    }
1887  
1888    if ($_SESSION['system_update_6021'] >= $_SESSION['system_update_6021_max']) {
1889      if (!empty($_SESSION['menu_bogus_menus'])) {
1890        // Remove entries in bogus menus. This is secure because we deleted
1891        // every non-alpanumeric character from the menu name.
1892        $ret[] = update_sql("DELETE FROM {menu_links} WHERE menu_name IN ('". implode("', '", $_SESSION['menu_bogus_menus']) ."')");
1893      }
1894  
1895      $menu_primary_menu = variable_get('menu_primary_menu', 0);
1896      // Ensure that we wind up with a system menu named 'primary-links'.
1897      if (isset($_SESSION['menu_menu_map'][2])) {
1898        // The primary links menu that ships with Drupal 5 has mid = 2.  If this
1899        // menu hasn't been deleted by the site admin, we use that.
1900        $updated_primary_links_menu = 2;
1901      }
1902      elseif (isset($_SESSION['menu_menu_map'][$menu_primary_menu]) && $menu_primary_menu > 1) {
1903        // Otherwise, we use the menu that is currently assigned to the primary
1904        // links region of the theme, as long as it exists and isn't the
1905        // Navigation menu.
1906        $updated_primary_links_menu = $menu_primary_menu;
1907      }
1908      else {
1909        // As a last resort, create 'primary-links' as a new menu.
1910        $updated_primary_links_menu = 0;
1911        db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", $menus['primary-links']);
1912      }
1913  
1914      if ($updated_primary_links_menu) {
1915        // Change the existing menu name to 'primary-links'.
1916        $replace = array('%new_name' => 'primary-links', '%desc' => $menus['primary-links']['description'], '%old_name' => $_SESSION['menu_menu_map'][$updated_primary_links_menu]);
1917        $ret[] = update_sql(strtr("UPDATE {menu_custom} SET menu_name = '%new_name', description = '%desc' WHERE menu_name = '%old_name'", $replace));
1918        $ret[] = update_sql("UPDATE {menu_links} SET menu_name = 'primary-links' WHERE menu_name = '". $_SESSION['menu_menu_map'][$updated_primary_links_menu] ."'");
1919        $_SESSION['menu_menu_map'][$updated_primary_links_menu] = 'primary-links';
1920      }
1921  
1922      $menu_secondary_menu = variable_get('menu_secondary_menu', 0);
1923      // Ensure that we wind up with a system menu named 'secondary-links'.
1924      if (isset($_SESSION['menu_menu_map'][$menu_secondary_menu]) && $menu_secondary_menu > 1 && $menu_secondary_menu != $updated_primary_links_menu) {
1925        // We use the menu that is currently assigned to the secondary links
1926        // region of the theme, as long as (a) it exists, (b) it isn't the
1927        // Navigation menu, (c) it isn't the same menu we assigned as the
1928        // system 'primary-links' menu above, and (d) it isn't the same menu
1929        // assigned to the primary links region of the theme.
1930        $updated_secondary_links_menu = $menu_secondary_menu;
1931      }
1932      else {
1933        // Otherwise, create 'secondary-links' as a new menu.
1934        $updated_secondary_links_menu = 0;
1935        db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", $menus['secondary-links']);
1936      }
1937  
1938      if ($updated_secondary_links_menu) {
1939        // Change the existing menu name to 'secondary-links'.
1940        $replace = array('%new_name' => 'secondary-links', '%desc' => $menus['secondary-links']['description'], '%old_name' => $_SESSION['menu_menu_map'][$updated_secondary_links_menu]);
1941        $ret[] = update_sql(strtr("UPDATE {menu_custom} SET menu_name = '%new_name', description = '%desc' WHERE menu_name = '%old_name'", $replace));
1942        $ret[] = update_sql("UPDATE {menu_links} SET menu_name = 'secondary-links' WHERE menu_name = '". $_SESSION['menu_menu_map'][$updated_secondary_links_menu] ."'");
1943        $_SESSION['menu_menu_map'][$updated_secondary_links_menu] = 'secondary-links';
1944      }
1945  
1946      // Update menu OTF preferences.
1947      $mid = variable_get('menu_parent_items', 0);
1948      $menu_name = ($mid && isset($_SESSION['menu_menu_map'][$mid])) ? $_SESSION['menu_menu_map'][$mid] : 'navigation';
1949      variable_set('menu_default_node_menu', $menu_name);
1950      variable_del('menu_parent_items');
1951  
1952      // Update the source of the primary and secondary links.
1953      $menu_name = ($menu_primary_menu && isset($_SESSION['menu_menu_map'][$menu_primary_menu])) ? $_SESSION['menu_menu_map'][$menu_primary_menu] : '';
1954      variable_set('menu_primary_links_source', $menu_name);
1955      variable_del('menu_primary_menu');
1956  
1957      $menu_name = ($menu_secondary_menu && isset($_SESSION['menu_menu_map'][$menu_secondary_menu])) ? $_SESSION['menu_menu_map'][$menu_secondary_menu] : '';
1958      variable_set('menu_secondary_links_source', $menu_name);
1959      variable_del('menu_secondary_menu');
1960  
1961      // Skip the navigation menu - it is handled by the user module.
1962      unset($_SESSION['menu_menu_map'][1]);
1963      // Update the deltas for all menu module blocks.
1964      foreach ($_SESSION['menu_menu_map'] as $mid => $menu_name) {
1965        // This is again secure because we deleted every non-alpanumeric
1966        // character from the menu name.
1967        $ret[] = update_sql("UPDATE {blocks} SET delta = '". $menu_name ."' WHERE module = 'menu' AND delta = '". $mid ."'");
1968        $ret[] = update_sql("UPDATE {blocks_roles} SET delta = '". $menu_name ."' WHERE module = 'menu' AND delta = '". $mid ."'");
1969      }
1970      $ret[] = array('success' => TRUE, 'query' => 'Relocated '. $_SESSION['system_update_6021'] .' existing items to the new menu system.');
1971      $ret[] = update_sql("DROP TABLE {menu}");
1972      unset($_SESSION['system_update_6021'], $_SESSION['system_update_6021_max'], $_SESSION['menu_menu_map'], $_SESSION['menu_item_map'], $_SESSION['menu_bogus_menus']);
1973      // Create the menu overview links - also calls menu_rebuild(). If menu is
1974      // disabled, then just call menu_rebuild.
1975      if (function_exists('menu_enable')) {
1976        menu_enable();
1977      }
1978      else {
1979        menu_rebuild();
1980      }
1981      $ret['#finished'] = 1;
1982    }
1983    else {
1984      $ret['#finished'] = $_SESSION['system_update_6021'] / $_SESSION['system_update_6021_max'];
1985    }
1986    return $ret;
1987  }
1988  
1989  /**
1990   * Update files tables to associate files to a uid by default instead of a nid.
1991   * Rename file_revisions to upload since it should only be used by the upload
1992   * module used by upload to link files to nodes.
1993   */
1994  function system_update_6022() {
1995    $ret = array();
1996  
1997    // Rename the nid field to vid, add status and timestamp fields, and indexes.
1998    db_drop_index($ret, 'files', 'nid');
1999    db_change_field($ret, 'files', 'nid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2000    db_add_field($ret, 'files', 'status', array('type' => 'int', 'not null' => TRUE, 'default' => 0));
2001    db_add_field($ret, 'files', 'timestamp', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2002    db_add_index($ret, 'files', 'uid', array('uid'));
2003    db_add_index($ret, 'files', 'status', array('status'));
2004    db_add_index($ret, 'files', 'timestamp', array('timestamp'));
2005  
2006    // Rename the file_revisions table to upload then add nid column. Since we're
2007    // changing the table name we need to drop and re-add the indexes and
2008    // the primary key so both mysql and pgsql end up with the correct index
2009    // names.
2010    db_drop_primary_key($ret, 'file_revisions');
2011    db_drop_index($ret, 'file_revisions', 'vid');
2012    db_rename_table($ret, 'file_revisions', 'upload');
2013    db_add_field($ret, 'upload', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2014    db_add_index($ret, 'upload', 'nid', array('nid'));
2015    db_add_primary_key($ret, 'upload', array('vid', 'fid'));
2016    db_add_index($ret, 'upload', 'fid', array('fid'));
2017  
2018    // The nid column was renamed to uid. Use the old nid to find the node's uid.
2019    update_sql('UPDATE {files} SET uid = (SELECT n.uid FROM {node} n WHERE {files}.uid = n.nid)');
2020    update_sql('UPDATE {upload} SET nid = (SELECT r.nid FROM {node_revisions} r WHERE {upload}.vid = r.vid)');
2021  
2022    // Mark all existing files as FILE_STATUS_PERMANENT.
2023    $ret[] = update_sql('UPDATE {files} SET status = 1');
2024  
2025    return $ret;
2026  }
2027  
2028  function system_update_6023() {
2029    $ret = array();
2030  
2031    // nid is DEFAULT 0
2032    db_drop_index($ret, 'node_revisions', 'nid');
2033    db_change_field($ret, 'node_revisions', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2034    db_add_index($ret, 'node_revisions', 'nid', array('nid'));
2035    return $ret;
2036  }
2037  
2038  /**
2039   * Add translation fields to nodes used by translation module.
2040   */
2041  function system_update_6024() {
2042    $ret = array();
2043    db_add_field($ret, 'node', 'tnid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2044    db_add_field($ret, 'node', 'translate', array('type' => 'int', 'not null' => TRUE, 'default' => 0));
2045    db_add_index($ret, 'node', 'tnid', array('tnid'));
2046    db_add_index($ret, 'node', 'translate', array('translate'));
2047    return $ret;
2048  }
2049  
2050  /**
2051   * Increase the maximum length of node titles from 128 to 255.
2052   */
2053  function system_update_6025() {
2054    $ret = array();
2055    db_drop_index($ret, 'node', 'node_title_type');
2056    db_change_field($ret, 'node', 'title', 'title', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
2057    db_add_index($ret, 'node', 'node_title_type', array('title', array('type', 4)));
2058    db_change_field($ret, 'node_revisions', 'title', 'title', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''));
2059    return $ret;
2060  }
2061  
2062  /**
2063   * Display warning about new Update status module.
2064   */
2065  function system_update_6026() {
2066    $ret = array();
2067  
2068    // Notify user that new update module exists.
2069    drupal_set_message('Drupal can check periodically for important bug fixes and security releases using the new update status module. This module can be turned on from the <a href="'. url('admin/build/modules') .'">modules administration page</a>. For more information please read the <a href="http://drupal.org/handbook/modules/update">Update status handbook page</a>.');
2070  
2071    return $ret;
2072  }
2073  
2074  /**
2075   * Add block cache.
2076   */
2077  function system_update_6027() {
2078    $ret = array();
2079  
2080    // Create the blocks.cache column.
2081    db_add_field($ret, 'blocks', 'cache', array('type' => 'int', 'not null' => TRUE, 'default' => 1, 'size' => 'tiny'));
2082  
2083    // The cache_block table is created in update_fix_d6_requirements() since
2084    // calls to cache_clear_all() would otherwise cause warnings.
2085  
2086    // Fill in the values for the new 'cache' column in the {blocks} table.
2087    foreach (module_list() as $module) {
2088      if ($module_blocks = module_invoke($module, 'block', 'list')) {
2089        foreach ($module_blocks as $delta => $block) {
2090          if (isset($block['cache'])) {
2091            db_query("UPDATE {blocks} SET cache = %d WHERE module = '%s' AND delta = '%s'", $block['cache'], $module, $delta);
2092          }
2093        }
2094      }
2095    }
2096  
2097    return $ret;
2098  }
2099  
2100  /**
2101   * Add the node load cache table.
2102   */
2103  function system_update_6028() {
2104    // Removed node_load cache to discuss it more for Drupal 7.
2105    return array();
2106  }
2107  
2108  /**
2109   * Enable the dblog module on sites that upgrade, since otherwise
2110   * watchdog logging will stop unexpectedly.
2111   */
2112  function system_update_6029() {
2113    // The watchdog table is now owned by dblog, which is not yet
2114    // "installed" according to the system table, but the table already
2115    // exists.  We set the module as "installed" here to avoid an error
2116    // later.
2117    //
2118    // Although not the case for the initial D6 release, it is likely
2119    // that dblog.install will have its own update functions eventually.
2120    // However, dblog did not exist in D5 and this update is part of the
2121    // initial D6 release, so we know that dblog is not installed yet.
2122    // It is therefore correct to install it as version 0.  If
2123    // dblog updates exist, the next run of update.php will get them.
2124    drupal_set_installed_schema_version('dblog', 0);
2125    module_enable(array('dblog'));
2126    menu_rebuild();
2127    return array(array('success' => TRUE, 'query' => "'dblog' module enabled."));
2128  }
2129  
2130  /**
2131   * Add the tables required by actions.inc.
2132   */
2133  function system_update_6030() {
2134    $ret = array();
2135  
2136    // Rename the old contrib actions table if it exists so the contrib version
2137    // of the module can do something with the old data.
2138    if (db_table_exists('actions')) {
2139      db_rename_table($ret, 'actions', 'actions_old_contrib');
2140    }
2141  
2142    $schema['actions'] = array(
2143      'fields' => array(
2144        'aid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'),
2145        'type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''),
2146        'callback' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
2147        'parameters' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'),
2148        'description' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '0'),
2149      ),
2150      'primary key' => array('aid'),
2151    );
2152  
2153    $schema['actions_aid'] = array(
2154      'fields' => array(
2155        'aid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE),
2156      ),
2157      'primary key' => array('aid'),
2158    );
2159  
2160    db_create_table($ret, 'actions', $schema['actions']);
2161    db_create_table($ret, 'actions_aid', $schema['actions_aid']);
2162  
2163    return $ret;
2164  }
2165  
2166  /**
2167   * Ensure that installer cannot be run again after updating from Drupal 5.x to 6.x
2168   * Actually, this is already done by system_update_6014(), so this is now a no-op.
2169   */
2170  function system_update_6031() {
2171    return array();
2172  }
2173  
2174  /**
2175   * profile_fields.name used to be nullable but is part of a unique key
2176   * and so shouldn't be.
2177   */
2178  function system_update_6032() {
2179    $ret = array();
2180    if (db_table_exists('profile_fields')) {
2181      db_drop_unique_key($ret, 'profile_fields', 'name');
2182      db_change_field($ret, 'profile_fields', 'name', 'name', array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''));
2183      db_add_unique_key($ret, 'profile_fields', 'name', array('name'));
2184    }
2185    return $ret;
2186  }
2187  
2188  /**
2189   * Change node_comment_statistics to be not autoincrement.
2190   */
2191  function system_update_6033() {
2192    $ret = array();
2193    if (db_table_exists('node_comment_statistics')) {
2194      // On pgsql but not mysql, db_change_field() drops all keys
2195      // involving the changed field, which in this case is the primary
2196      // key.  The normal approach is explicitly drop the pkey, change the
2197      // field, and re-create the pkey.
2198      //
2199      // Unfortunately, in this case that won't work on mysql; we CANNOT
2200      // drop the pkey because on mysql auto-increment fields must be
2201      // included in at least one key or index.
2202      //
2203      // Since we cannot drop the pkey before db_change_field(), after
2204      // db_change_field() we may or may not still have a pkey.  The
2205      // simple way out is to re-create the pkey only when using pgsql.
2206      // Realistic requirements trump idealistic purity.
2207      db_change_field($ret, 'node_comment_statistics', 'nid', 'nid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2208      if ($GLOBALS['db_type'] == 'pgsql') {
2209        db_add_primary_key($ret, 'node_comment_statistics', array('nid'));
2210      }
2211    }
2212    return $ret;
2213  }
2214  
2215  /**
2216   * Rename permission "administer access control" to "administer permissions".
2217   */
2218  function system_update_6034() {
2219    $ret = array();
2220    $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
2221    while ($role = db_fetch_object($result)) {
2222      $renamed_permission = preg_replace('/administer access control/', 'administer permissions', $role->perm);
2223      if ($renamed_permission != $role->perm) {
2224        $ret[] = update_sql("UPDATE {permission} SET perm = '$renamed_permission' WHERE rid = $role->rid");
2225      }
2226    }
2227    return $ret;
2228  }
2229  
2230  /**
2231   * Change index on system table for better performance.
2232   */
2233  function system_update_6035() {
2234    $ret = array();
2235    db_drop_index($ret, 'system', 'weight');
2236    db_add_index($ret, 'system', 'modules', array(array('type', 12), 'status', 'weight', 'filename'));
2237    db_add_index($ret, 'system', 'bootstrap', array(array('type', 12), 'status', 'bootstrap', 'weight', 'filename'));
2238    return $ret;
2239  }
2240  
2241  /**
2242   * Change the search schema and indexing.
2243   *
2244   * The table data is preserved where possible in MYSQL and MYSQLi using
2245   * ALTER IGNORE. Other databases don't support that, so for them the
2246   * tables are dropped and re-created, and will need to be re-indexed
2247   * from scratch.
2248   */
2249  function system_update_6036() {
2250    $ret = array();
2251    if (db_table_exists('search_index')) {
2252      // Create the search_dataset.reindex column.
2253      db_add_field($ret, 'search_dataset', 'reindex', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0));
2254  
2255      // Drop the search_index.from fields which are no longer used.
2256      db_drop_index($ret, 'search_index', 'from_sid_type');
2257      db_drop_field($ret, 'search_index', 'fromsid');
2258      db_drop_field($ret, 'search_index', 'fromtype');
2259  
2260      // Drop the search_dataset.sid_type index, so that it can be made unique.
2261      db_drop_index($ret, 'search_dataset', 'sid_type');
2262  
2263      // Create the search_node_links Table.
2264      $search_node_links_schema = array(
2265        'fields' => array(
2266          'sid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
2267          'type'     => array('type' => 'varchar', 'length' => 16, 'not null' => TRUE, 'default' => ''),
2268          'nid'      => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
2269          'caption'    => array('type' => 'text', 'size' => 'big', 'not null' => FALSE),
2270        ),
2271        'primary key' => array('sid', 'type', 'nid'),
2272        'indexes' => array('nid' => array('nid')),
2273      );
2274      db_create_table($ret, 'search_node_links', $search_node_links_schema);
2275  
2276      // with the change to search_dataset.reindex, the search queue is handled differently,
2277      // and this is no longer needed
2278      variable_del('node_cron_last');
2279  
2280      // Add a unique index for the search_index.
2281      if ($GLOBALS['db_type'] == 'mysql' || $GLOBALS['db_type'] == 'mysqli') {
2282        // Since it's possible that some existing sites have duplicates,
2283        // create the index using the IGNORE keyword, which ignores duplicate errors.
2284        // However, pgsql doesn't support it
2285        $ret[] = update_sql("ALTER IGNORE TABLE {search_index} ADD UNIQUE KEY word_sid_type (word, sid, type)");
2286        $ret[] = update_sql("ALTER IGNORE TABLE {search_dataset} ADD UNIQUE KEY sid_type (sid, type)");
2287  
2288        // Everything needs to be reindexed.
2289        $ret[] = update_sql("UPDATE {search_dataset} SET reindex = 1");
2290      }
2291      else {
2292        // Delete the existing tables if there are duplicate values
2293        if (db_result(db_query("SELECT sid FROM {search_dataset} GROUP BY sid, type HAVING COUNT(*) > 1")) || db_result(db_query("SELECT sid FROM {search_index} GROUP BY word, sid, type HAVING COUNT(*) > 1"))) {
2294          $ret[] = update_sql('DELETE FROM {search_dataset}');
2295          $ret[] = update_sql('DELETE FROM {search_index}');
2296          $ret[] = update_sql('DELETE FROM {search_total}');
2297        }
2298        else {
2299          // Everything needs to be reindexed.
2300          $ret[] = update_sql("UPDATE {search_dataset} SET reindex = 1");
2301        }
2302  
2303        // create the new indexes
2304        db_add_unique_key($ret, 'search_index', 'word_sid_type', array('word', 'sid', 'type'));
2305        db_add_unique_key($ret, 'search_dataset', 'sid_type', array('sid', 'type'));
2306      }
2307    }
2308    return $ret;
2309  }
2310  
2311  /**
2312   * Create consistent empty region for disabled blocks.
2313   */
2314  function system_update_6037() {
2315    $ret = array();
2316    db_change_field($ret, 'blocks', 'region', 'region', array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''));
2317    $ret[] = update_sql("UPDATE {blocks} SET region = '' WHERE status = 0");
2318    return $ret;
2319  }
2320  
2321  /**
2322   * Ensure that "Account" is not used as a Profile category.
2323   */
2324  function system_update_6038() {
2325    $ret = array();
2326    if (db_table_exists('profile_fields')) {
2327      $ret[] = update_sql("UPDATE {profile_fields} SET category = 'Account settings' WHERE LOWER(category) = 'account'");
2328      if ($affectedrows = db_affected_rows()) {
2329        drupal_set_message('There were '. $affectedrows .' profile fields that used a reserved category name. They have been assigned to the category "Account settings".');
2330      }
2331    }
2332    return $ret;
2333  }
2334  
2335  /**
2336   * Rename permissions "edit foo content" to "edit any foo content".
2337   * Also update poll module permission "create polls" to "create
2338   * poll content".
2339   */
2340  function system_update_6039() {
2341    $ret = array();
2342    $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
2343    while ($role = db_fetch_object($result)) {
2344      $renamed_permission = preg_replace('/(?<=^|,\ )edit\ ([a-zA-Z0-9_\-]+)\ content(?=,|$)/', 'edit any $1 content', $role->perm);
2345      $renamed_permission = preg_replace('/(?<=^|,\ )create\ polls(?=,|$)/', 'create poll content', $renamed_permission);
2346      if ($renamed_permission != $role->perm) {
2347        $ret[] = update_sql("UPDATE {permission} SET perm = '$renamed_permission' WHERE rid = $role->rid");
2348      }
2349    }
2350    return $ret;
2351  }
2352  
2353  /**
2354   * Add a weight column to the upload table.
2355   */
2356  function system_update_6040() {
2357    $ret = array();
2358    if (db_table_exists('upload')) {
2359      db_add_field($ret, 'upload', 'weight', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
2360    }
2361    return $ret;
2362  }
2363  
2364  /**
2365   * Change forum vocabulary not to be required by default and set the weight of the forum.module 1 higher than the taxonomy.module.
2366   */
2367  function system_update_6041() {
2368    $weight = intval((db_result(db_query("SELECT weight FROM {system} WHERE name = 'taxonomy'"))) + 1);
2369    $ret = array();
2370    $vid = intval(variable_get('forum_nav_vocabulary', ''));
2371    if (db_table_exists('vocabulary') && $vid) {
2372      $ret[] = update_sql("UPDATE {vocabulary} SET required = 0 WHERE vid = " . $vid);
2373      $ret[] = update_sql("UPDATE {system} SET weight = ". $weight ." WHERE name = 'forum'");
2374    }
2375    return $ret;
2376  }
2377  
2378  /**
2379   * Upgrade recolored theme stylesheets to new array structure.
2380   */
2381  function system_update_6042() {
2382    foreach (list_themes() as $theme) {
2383      $stylesheet = variable_get('color_'. $theme->name .'_stylesheet', NULL);
2384      if (!empty($stylesheet)) {
2385        variable_set('color_'. $theme->name .'_stylesheets', array($stylesheet));
2386        variable_del('color_'. $theme->name .'_stylesheet');
2387      }
2388    }
2389    return array();
2390  }
2391  
2392  /**
2393   * Update table indices to make them more rational and useful.
2394   */
2395  function system_update_6043() {
2396    $ret = array();
2397    // Required modules first.
2398    // Add new system module indexes.
2399    db_add_index($ret, 'flood', 'allow', array('event', 'hostname', 'timestamp'));
2400    db_add_index($ret, 'history', 'nid', array('nid'));
2401    // Change length of theme field in {blocks} to be consistent with module, and
2402    // to avoid a MySQL error regarding a too-long index.  Also add new indices.
2403    db_change_field($ret, 'blocks', 'theme', 'theme', array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),array(
2404                    'unique keys' => array('tmd' => array('theme', 'module', 'delta'),),
2405                    'indexes' => array('list' => array('theme', 'status', 'region', 'weight', 'module'),),));
2406    db_add_index($ret, 'blocks_roles', 'rid', array('rid'));
2407    // Improve filter module indices.
2408    db_drop_index($ret, 'filters', 'weight');
2409    db_add_unique_key($ret, 'filters', 'fmd', array('format', 'module', 'delta'));
2410    db_add_index($ret, 'filters', 'list', array('format', 'weight', 'module', 'delta'));
2411    // Drop unneeded keys form the node table.
2412    db_drop_index($ret, 'node', 'status');
2413    db_drop_unique_key($ret, 'node', 'nid_vid');
2414    // Improve user module indices.
2415    db_add_index($ret, 'users', 'mail', array('mail'));
2416    db_add_index($ret, 'users_roles', 'rid', array('rid'));
2417  
2418    // Optional modules - need to check if the tables exist.
2419    // Alter aggregator module's tables primary keys to make them more useful.
2420    if (db_table_exists('aggregator_category_feed')) {
2421      db_drop_primary_key($ret, 'aggregator_category_feed');
2422      db_add_primary_key($ret, 'aggregator_category_feed', array('cid', 'fid'));
2423      db_add_index($ret, 'aggregator_category_feed', 'fid', array('fid'));
2424    }
2425    if (db_table_exists('aggregator_category_item')) {
2426      db_drop_primary_key($ret, 'aggregator_category_item');
2427      db_add_primary_key($ret, 'aggregator_category_item', array('cid', 'iid'));
2428      db_add_index($ret, 'aggregator_category_item', 'iid', array('iid'));
2429    }
2430    // Alter contact module's table to add an index.
2431    if (db_table_exists('contact')) {
2432      db_add_index($ret, 'contact', 'list', array('weight', 'category'));
2433    }
2434    // Alter locale table to add a primary key, drop an index.
2435    if (db_table_exists('locales_target')) {
2436      db_add_primary_key($ret, 'locales_target', array('language', 'lid', 'plural'));
2437    }
2438    // Alter a poll module table to add a primary key.
2439    if (db_table_exists('poll_votes')) {
2440      db_drop_index($ret, 'poll_votes', 'nid');
2441      db_add_primary_key($ret, 'poll_votes', array('nid', 'uid', 'hostname'));
2442    }
2443    // Alter a profile module table to add a primary key.
2444    if (db_table_exists('profile_values')) {
2445      db_drop_index($ret, 'profile_values', 'uid');
2446      db_drop_index($ret, 'profile_values', 'fid');
2447      db_change_field($ret,'profile_values' ,'fid', 'fid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,), array('indexes' => array('fid' => array('fid'),)));
2448      db_change_field($ret,'profile_values' ,'uid', 'uid', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,));
2449      db_add_primary_key($ret, 'profile_values', array('uid', 'fid'));
2450    }
2451    // Alter a statistics module table to add an index.
2452    if (db_table_exists('accesslog')) {
2453      db_add_index($ret, 'accesslog', 'uid', array('uid'));
2454    }
2455    // Alter taxonomy module's tables.
2456    if (db_table_exists('term_data')) {
2457      db_drop_index($ret, 'term_data', 'vid');
2458      db_add_index($ret, 'term_data', 'vid_name', array('vid', 'name'));
2459      db_add_index($ret, 'term_data', 'taxonomy_tree', array('vid', 'weight', 'name'));
2460    }
2461    if (db_table_exists('term_node')) {
2462      db_drop_primary_key($ret, 'term_node');
2463      db_drop_index($ret, 'term_node', 'tid');
2464      db_add_primary_key($ret, 'term_node', array('tid', 'vid'));
2465    }
2466    if (db_table_exists('term_relation')) {
2467      db_drop_index($ret, 'term_relation', 'tid1');
2468      db_add_unique_key($ret, 'term_relation', 'tid1_tid2', array('tid1', 'tid2'));
2469    }
2470    if (db_table_exists('term_synonym')) {
2471      db_drop_index($ret, 'term_synonym', 'name');
2472      db_add_index($ret, 'term_synonym', 'name_tid', array('name', 'tid'));
2473    }
2474    if (db_table_exists('vocabulary')) {
2475      db_add_index($ret, 'vocabulary', 'list', array('weight', 'name'));
2476    }
2477    if (db_table_exists('vocabulary_node_types')) {
2478      db_drop_primary_key($ret, 'vocabulary_node_types');
2479      db_add_primary_key($ret, 'vocabulary_node_types', array('type', 'vid'));
2480      db_add_index($ret, 'vocabulary_node_types', 'vid', array('vid'));
2481    }
2482    // If we updated in RC1 or before ensure we don't update twice.
2483    variable_set('system_update_6043_RC2', TRUE);
2484  
2485    return $ret;
2486  }
2487  
2488  /**
2489   * RC1 to RC2 index cleanup.
2490   */
2491  function system_update_6044() {
2492    $ret = array();
2493  
2494    // Delete invalid entries in {term_node} after system_update_6001.
2495    $ret[] = update_sql("DELETE FROM {term_node} WHERE vid = 0");
2496  
2497    // Only execute the rest of this function if 6043 was run in RC1 or before.
2498    if (variable_get('system_update_6043_RC2', FALSE)) {
2499      variable_del('system_update_6043_RC2');
2500      return $ret;
2501    }
2502  
2503    // User module indices.
2504    db_drop_unique_key($ret, 'users', 'mail');
2505    db_add_index($ret, 'users', 'mail', array('mail'));
2506  
2507    // Optional modules - need to check if the tables exist.
2508    // Alter taxonomy module's tables.
2509    if (db_table_exists('term_data')) {
2510      db_drop_unique_key($ret, 'term_data', 'vid_name');
2511      db_add_index($ret, 'term_data', 'vid_name', array('vid', 'name'));
2512    }
2513    if (db_table_exists('term_synonym')) {
2514      db_drop_unique_key($ret, 'term_synonym', 'name_tid', array('name', 'tid'));
2515      db_add_index($ret, 'term_synonym', 'name_tid', array('name', 'tid'));
2516    }
2517  
2518    return $ret;
2519  }
2520  
2521  /**
2522   * Update blog, book and locale module permissions.
2523   *
2524   * Blog module got "edit own blog" replaced with the more granular "create
2525   * blog entries", "edit own blog entries" and "delete own blog entries"
2526   * permissions. We grant create and edit to previously privileged users, but
2527   * delete is not granted to be in line with other permission changes in Drupal 6.
2528   *
2529   * Book module's "edit book pages" was upgraded to the bogus "edit book content"
2530   * in Drupal 6 RC1 instead of "edit any book content", which would be correct.
2531   *
2532   * Locale module introduced "administer languages" and "translate interface"
2533   * in place of "administer locales".
2534   *
2535   * Modeled after system_update_6039().
2536   */
2537  function system_update_6045() {
2538    $ret = array();
2539    $result = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
2540    while ($role = db_fetch_object($result)) {
2541      $renamed_permission = preg_replace('/(?<=^|,\ )edit\ own\ blog(?=,|$)/', 'create blog entries, edit own blog entries', $role->perm);
2542      $renamed_permission = preg_replace('/(?<=^|,\ )edit\ book\ content(?=,|$)/', 'edit any book content', $renamed_permission);
2543      $renamed_permission = preg_replace('/(?<=^|,\ )administer\ locales(?=,|$)/', 'administer languages, translate interface', $renamed_permission);
2544      if ($renamed_permission != $role->perm) {
2545        $ret[] = update_sql("UPDATE {permission} SET perm = '$renamed_permission' WHERE rid = $role->rid");
2546      }
2547    }
2548  
2549    // Notify user that delete permissions may have been changed. This was in
2550    // effect since system_update_6039(), but there was no user notice.
2551    drupal_set_message('Drupal now has separate edit and delete permissions. Previously, users who were able to edit content were automatically allowed to delete it. For added security, delete permissions for individual core content types have been <strong>removed</strong> from all roles on your site (only roles with the "administer nodes" permission can now delete these types of content). If you would like to reenable any individual delete permissions, you can do this at the <a href="'. url('admin/user/permissions', array('fragment' => 'module-node')) .'">permissions page</a>.');
2552    return $ret;
2553  }
2554  
2555  /**
2556   * Ensure that the file_directory_path variable is set (using the old 5.x
2557   * default, if necessary), so that the changed 6.x default won't break
2558   * existing sites.
2559   */
2560  function system_update_6046() {
2561    $ret = array();
2562    if (!variable_get('file_directory_path', FALSE)) {
2563      variable_set('file_directory_path', 'files');
2564      $ret[] = array('success' => TRUE, 'query' => "variable_set('file_directory_path')");
2565    }
2566    return $ret;
2567  }
2568  
2569  /**
2570   * Fix cache mode for blocks inserted in system_install() in fresh installs of previous RC.
2571   */
2572  function system_update_6047() {
2573    $ret = array();
2574    $ret[] = update_sql("UPDATE {blocks} SET cache = -1 WHERE module = 'user' AND delta IN ('0', '1')");
2575    $ret[] = update_sql("UPDATE {blocks} SET cache = -1 WHERE module = 'system' AND delta = '0'");
2576    return $ret;
2577  }
2578  
2579  /**
2580   * @} End of "defgroup updates-5.x-to-6.x"
2581   */
2582  
2583  /**
2584   * @defgroup updates-6.x-extra Extra system updates for 6.x
2585   * @{
2586   */
2587  
2588  /**
2589  * Increase the size of the 'load_functions' and 'to_arg_functions' fields in table 'menu_router'.
2590  */
2591  function system_update_6048() {
2592    $ret = array();
2593    db_change_field($ret, 'menu_router', 'load_functions', 'load_functions', array('type' => 'text', 'not null' => TRUE,));
2594    db_change_field($ret, 'menu_router', 'to_arg_functions', 'to_arg_functions', array('type' => 'text', 'not null' => TRUE,));
2595  
2596    return $ret;
2597  }
2598  
2599  /**
2600   * Replace src index on the {url_alias} table with src, language.
2601   */
2602  function system_update_6049() {
2603    $ret = array();
2604    db_drop_index($ret, 'url_alias', 'src');
2605    db_add_index($ret, 'url_alias', 'src_language', array('src', 'language'));
2606    return $ret;
2607  }
2608  
2609  /**
2610   * Clear any menu router blobs stored in the cache table.
2611   */
2612  function system_update_6050() {
2613    $ret = array();
2614    cache_clear_all('router:', 'cache_menu', TRUE);
2615    return $ret;
2616  }
2617  
2618  /**
2619   * Create a signature_format column.
2620   */
2621  function system_update_6051() {
2622    $ret = array();
2623  
2624    if (!db_column_exists('users', 'signature_format')) {
2625  
2626      // Set future input formats to FILTER_FORMAT_DEFAULT to ensure a safe default
2627      // when incompatible modules insert into the users table. An actual format
2628      // will be assigned when users save their signature.
2629  
2630      $schema = array(
2631        'type' => 'int',
2632        'size' => 'small',
2633        'not null' => TRUE,
2634        'default' => FILTER_FORMAT_DEFAULT,
2635        'description' => 'The {filter_formats}.format of the signature.',
2636      );
2637  
2638      db_add_field($ret, 'users', 'signature_format', $schema);
2639  
2640      // Set the format of existing signatures to the current default input format.
2641      if ($current_default_filter = variable_get('filter_default_format', 0)) {
2642        $ret[] = update_sql("UPDATE {users} SET signature_format = ". $current_default_filter);
2643      }
2644  
2645      drupal_set_message("User signatures no longer inherit comment input formats. Each user's signature now has its own associated format that can be selected on the user's account page. Existing signatures have been set to your site's default input format.");
2646    }
2647  
2648    return $ret;
2649  }
2650  
2651  /**
2652   * Add a missing index on the {menu_router} table.
2653   */
2654  function system_update_6052() {
2655    $ret = array();
2656    db_add_index($ret, 'menu_router', 'tab_root_weight_title', array(array('tab_root', 64), 'weight', 'title'));
2657    return $ret;
2658  }
2659  
2660  /**
2661   * Add a {system} index on type and name.
2662   */
2663  function system_update_6053() {
2664    $ret = array();
2665    db_add_index($ret, 'system', 'type_name', array(array('type', 12), 'name'));
2666    return $ret;
2667  }
2668  
2669  /**
2670   * Add semaphore table.
2671   */
2672  function system_update_6054() {
2673    $ret = array();
2674  
2675    // The table may have already been added by update_fix_d6_requirements(), so
2676    // check for its existence before creating.
2677    if (!db_table_exists('semaphore')) {
2678      $schema['semaphore'] = array(
2679        'fields' => array(
2680          'name' => array(
2681            'type' => 'varchar',
2682            'length' => 255,
2683            'not null' => TRUE,
2684            'default' => ''),
2685          'value' => array(
2686            'type' => 'varchar',
2687            'length' => 255,
2688            'not null' => TRUE,
2689            'default' => ''),
2690          'expire' => array(
2691            'type' => 'float',
2692            'size' => 'big',
2693            'not null' => TRUE),
2694          ),
2695        'indexes' => array('expire' => array('expire')),
2696        'primary key' => array('name'),
2697      );
2698      db_create_table($ret, 'semaphore', $schema['semaphore']);
2699    }
2700  
2701    return $ret;
2702  }
2703  
2704  /**
2705   * Improve indexes on the {url_alias} table.
2706   */
2707  function system_update_6055() {
2708    $ret = array();
2709    db_drop_index($ret, 'url_alias', 'src_language');
2710    db_drop_unique_key($ret, 'url_alias', 'dst_language');
2711    db_add_index($ret, 'url_alias', 'src_language_pid', array('src', 'language', 'pid'));
2712    db_add_unique_key($ret, 'url_alias', 'dst_language_pid', array('dst', 'language', 'pid'));
2713    return $ret;
2714  }
2715  
2716  /**
2717   * @} End of "defgroup updates-6.x-extra"
2718   * The next series of updates should start at 7000.
2719   */
2720  


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7