node.install

Install, update and uninstall functions for the node module.

File

drupal/core/modules/node/node.install
View source
<?php

/**
 * @file
 * Install, update and uninstall functions for the node module.
 */
use Drupal\Core\Language\Language;

/**
 * Implements hook_schema().
 */
function node_schema() {
  $schema['node'] = array(
    'description' => 'The base table for nodes.',
    'fields' => array(
      'nid' => array(
        'description' => 'The primary identifier for a node.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'uuid' => array(
        'description' => 'Unique Key: Universally unique identifier for this entity.',
        'type' => 'varchar',
        'length' => 128,
        'not null' => FALSE,
      ),
      // Defaults to NULL in order to avoid a brief period of potential
      // deadlocks on the index.
      'vid' => array(
        'description' => 'The current {node_field_revision}.vid version identifier.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => FALSE,
        'default' => NULL,
      ),
      'type' => array(
        'description' => 'The {node_type}.type of this node.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of this node.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      // @todo Remove the following columns when removing the legacy Content
      //   Translation module. See http://drupal.org/node/1952062.
      'tnid' => array(
        'description' => 'The translation set ID for this node, which equals the node ID of the source post in each set.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'translate' => array(
        'description' => 'A boolean indicating whether this translation page needs to be updated.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'node_type' => array(
        array(
          'type',
          4,
        ),
      ),
      'tnid' => array(
        'tnid',
      ),
      'translate' => array(
        'translate',
      ),
    ),
    'unique keys' => array(
      'vid' => array(
        'vid',
      ),
      'uuid' => array(
        'uuid',
      ),
    ),
    'foreign keys' => array(
      'node_revision' => array(
        'table' => 'node_field_revision',
        'columns' => array(
          'vid' => 'vid',
        ),
      ),
    ),
    'primary key' => array(
      'nid',
    ),
  );

  // Node field storage.
  $schema['node_field_data'] = array(
    'description' => 'Base table for node properties.',
    'fields' => array(
      'nid' => array(
        'description' => 'The primary identifier for a node.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'vid' => array(
        'description' => 'The current {node_field_revision}.vid version identifier.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'type' => array(
        'description' => 'The {node_type}.type of this node.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of these node property values.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      'default_langcode' => array(
        'description' => 'Boolean indicating whether the property values are in the {language}.langcode of this node.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'title' => array(
        'description' => 'The title of this node, always treated as non-markup plain text.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'Boolean indicating whether the node translation is published (visible to non-administrators).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the node translation was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the node translation was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'comment' => array(
        'description' => 'Whether comments are allowed on this node translation: 0 = no, 1 = closed (read only), 2 = open (read/write).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'promote' => array(
        'description' => 'Boolean indicating whether the node translation should be displayed on the front page.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'sticky' => array(
        'description' => 'Boolean indicating whether the node translation should be displayed at the top of lists in which it appears.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'node_changed' => array(
        'changed',
      ),
      'node_created' => array(
        'created',
      ),
      'node_default_langcode' => array(
        'default_langcode',
      ),
      'node_langcode' => array(
        'langcode',
      ),
      'node_frontpage' => array(
        'promote',
        'status',
        'sticky',
        'created',
      ),
      'node_status_type' => array(
        'status',
        'type',
        'nid',
      ),
      'node_title_type' => array(
        'title',
        array(
          'type',
          4,
        ),
      ),
      'node_type' => array(
        array(
          'type',
          4,
        ),
      ),
      'nid' => array(
        'nid',
      ),
      'vid' => array(
        'vid',
      ),
      'uid' => array(
        'uid',
      ),
    ),
    'foreign keys' => array(
      'node_base' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'node_author' => array(
        'table' => 'users',
        'columns' => array(
          'uid' => 'uid',
        ),
      ),
    ),
    'primary key' => array(
      'nid',
      'vid',
      'langcode',
    ),
  );
  $schema['node_field_revision'] = array(
    'description' => 'Stores information about each saved version of a {node}.',
    'fields' => array(
      'nid' => array(
        'description' => 'The {node} this version belongs to.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'vid' => array(
        'description' => 'The primary identifier for this version.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of this version.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      'default_langcode' => array(
        'description' => 'Boolean indicating whether the property values of this version are in the {language}.langcode of this node.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'log' => array(
        'description' => 'The log entry explaining the changes in this version.',
        'type' => 'text',
        'not null' => FALSE,
        'size' => 'big',
      ),
      'revision_timestamp' => array(
        'description' => 'The Unix timestamp when the version was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'revision_uid' => array(
        'description' => 'The {users}.uid that created this version.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'title' => array(
        'description' => 'The title of this version, always treated as non-markup plain text.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that created this node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the node was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the version was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'comment' => array(
        'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'promote' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'sticky' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
      'uid' => array(
        'uid',
      ),
      'revision_uid' => array(
        'revision_uid',
      ),
      'vid' => array(
        'vid',
      ),
      'node_default_langcode' => array(
        'default_langcode',
      ),
      'node_langcode' => array(
        'langcode',
      ),
    ),
    'foreign keys' => array(
      'versioned_node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'version_author' => array(
        'table' => 'users',
        'columns' => array(
          'uid' => 'uid',
        ),
      ),
    ),
    'primary key' => array(
      'nid',
      'vid',
      'langcode',
    ),
  );
  $schema['node_access'] = array(
    'description' => 'Identifies which realm/grant pairs a user must possess in order to view, update, or delete specific nodes.',
    'fields' => array(
      'nid' => array(
        'description' => 'The {node}.nid this record affects.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of this node.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      'fallback' => array(
        'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 1,
      ),
      'gid' => array(
        'description' => "The grant ID a user must possess in the specified realm to gain this row's privileges on the node.",
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'realm' => array(
        'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'grant_view' => array(
        'description' => 'Boolean indicating whether a user with the realm/grant pair can view this node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'grant_update' => array(
        'description' => 'Boolean indicating whether a user with the realm/grant pair can edit this node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'grant_delete' => array(
        'description' => 'Boolean indicating whether a user with the realm/grant pair can delete this node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
    ),
    'primary key' => array(
      'nid',
      'gid',
      'realm',
      'langcode',
    ),
    'foreign keys' => array(
      'affected_node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
    ),
  );
  $schema['node_type'] = array(
    'description' => 'Stores information about all defined {node} types.',
    'fields' => array(
      'type' => array(
        'description' => 'The machine-readable name of this type.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
      ),
      'name' => array(
        'description' => 'The human-readable name of this type.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'base' => array(
        'description' => 'The base string used to construct callbacks corresponding to this node type.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
      ),
      'module' => array(
        'description' => 'The module defining this node type.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
      ),
      'description' => array(
        'description' => 'A brief description of this type.',
        'type' => 'text',
        'not null' => TRUE,
        'size' => 'medium',
      ),
      'help' => array(
        'description' => 'Help information shown to the user when creating a {node} of this type.',
        'type' => 'text',
        'not null' => TRUE,
        'size' => 'medium',
      ),
      'has_title' => array(
        'description' => 'Boolean indicating whether this type uses the {node}.title field.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'size' => 'tiny',
      ),
      'title_label' => array(
        'description' => 'The label displayed for the title field on the edit form.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'custom' => array(
        'description' => 'A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'modified' => array(
        'description' => 'A boolean indicating whether this type has been modified by an administrator; currently not used in any way.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'locked' => array(
        'description' => 'A boolean indicating whether the administrator can change the machine name of this type.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'disabled' => array(
        'description' => 'A boolean indicating whether the node type is disabled.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
        'size' => 'tiny',
      ),
      'orig_type' => array(
        'description' => 'The original machine-readable name of this node type. This may be different from the current type name if the locked field is 0.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
    'primary key' => array(
      'type',
    ),
  );
  return $schema;
}

/**
 * Implements hook_install().
 */
function node_install() {

  // Populate the node access table.
  db_insert('node_access')
    ->fields(array(
    'nid' => 0,
    'gid' => 0,
    'realm' => 'all',
    'grant_view' => 1,
    'grant_update' => 0,
    'grant_delete' => 0,
  ))
    ->execute();
}

/**
 * Implements hook_uninstall().
 *
 * @see node_ranking()
 * @see _node_rankings()
 */
function node_uninstall() {

  // Delete node type variables.
  $types = db_query('SELECT type FROM {node_type}')
    ->fetchCol();
  foreach ($types as $type) {
    db_delete('variable')
      ->condition(db_or()
      ->condition('name', 'node_preview_' . $type)
      ->condition('name', 'node_options_' . $type)
      ->condition('name', 'node_submitted_' . $type)
      ->condition('name', 'node_permissions_' . $type)
      ->condition('name', 'node_type_language_translation_enabled_' . $type))
      ->execute();
    config('language.settings')
      ->clear('node. ' . $type . '.language.default_configuration')
      ->save();
  }

  // Delete node search ranking variables.
  variable_del('node_rank_relevance');
  variable_del('node_rank_sticky');
  variable_del('node_rank_promote');
  variable_del('node_rank_recent');

  // Delete remaining general module variables.
  Drupal::state()
    ->delete('node.node_access_needs_rebuild');
  variable_del('node_admin_theme');
  variable_del('node_recent_block_count');

  // Delete any stored state.
  Drupal::state()
    ->delete('node.cron_last');
}

/**
 * Fetches node types directly from the database.
 *
 * @ingroup update_api
 */
function _update_7000_node_get_types() {
  $node_types = db_query('SELECT * FROM {node_type}')
    ->fetchAllAssoc('type', PDO::FETCH_OBJ);

  // Create default settings for orphaned nodes.
  $all_types = db_query('SELECT DISTINCT type FROM {node}')
    ->fetchCol();
  $extra_types = array_diff($all_types, array_keys($node_types));
  foreach ($extra_types as $type) {
    $type_object = new stdClass();
    $type_object->type = $type;

    // In Drupal 6, whether you have a body field or not is a flag in the node
    // type table. If it's enabled, nodes may or may not have an empty string
    // for the bodies. As we can't detect what this setting should be in
    // Drupal 7 without access to the Drupal 6 node type settings, we assume
    // the default, which is to enable the body field.
    $type_object->has_body = 1;
    $type_object->body_label = 'Body';
    $node_types[$type_object->type] = $type_object;
  }
  return $node_types;
}

/**
 * @addtogroup updates-7.x-to-8.x
 * @{
 */

/**
 * Rename node type language variable names.
 *
 * @see http://drupal.org/node/540294
 *
 * @ingroup config_upgrade
 */
function node_update_8001() {
  $types = db_query('SELECT type FROM {node_type}')
    ->fetchCol();
  foreach ($types as $type) {
    $node_type_language = update_variable_get('language_content_type_' . $type);
    if (isset($node_type_language)) {
      update_variable_set('node_type_language_' . $type, $node_type_language);
    }
    update_variable_del('language_content_type_' . $type);
  }
}

/**
 * Rename node.language field to node.langcode.
 */
function node_update_8002() {
  $spec = array(
    'description' => 'The {language}.langcode of this node.',
    'type' => 'varchar',
    'length' => 12,
    'not null' => TRUE,
    'default' => '',
  );
  db_change_field('node', 'language', 'langcode', $spec);
}

/**
 * Rename node type language variable names.
 */
function node_update_8003() {
  $types = db_query('SELECT type FROM {node_type}')
    ->fetchCol();
  foreach ($types as $type) {
    update_variable_set('node_type_language_default_' . $type, Language::LANGCODE_NOT_SPECIFIED);
    $node_type_language = update_variable_get('node_type_language_' . $type, 0);
    if ($node_type_language == 0) {
      update_variable_set('node_type_language_show_' . $type, FALSE);
    }
    if ($node_type_language == 2) {

      // Translation was enabled, so enable it again and
      // unhide the language selector. Because if language is
      // Language::LANGCODE_NOT_SPECIFIED and the selector hidden, translation
      // cannot be enabled.
      update_variable_set('node_type_language_show_' . $type, TRUE);
      update_variable_set('node_type_language_translation_enabled_' . $type, TRUE);
    }
    update_variable_del('node_type_language_' . $type);
  }
}

/**
 * Create a UUID column for nodes.
 */
function node_update_8004() {
  $spec = array(
    'description' => 'Unique Key: Universally unique identifier for this entity.',
    'type' => 'varchar',
    'length' => 128,
    'not null' => FALSE,
  );
  $keys = array(
    'unique keys' => array(
      'uuid' => array(
        'uuid',
      ),
    ),
  );

  // Account for sites having the contributed UUID module installed.
  if (db_field_exists('node', 'uuid')) {
    db_change_field('node', 'uuid', 'uuid', $spec, $keys);
  }
  else {
    db_add_field('node', 'uuid', $spec, $keys);
  }
}

/**
 * Make *id fields unsigned.
 */
function node_update_8005() {
  db_drop_index('node', 'uid');
  db_change_field('node', 'uid', 'uid', array(
    'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  ), array(
    'indexes' => array(
      'uid' => array(
        'uid',
      ),
    ),
  ));
  db_drop_index('node_revision', 'uid');
  db_change_field('node_revision', 'uid', 'uid', array(
    'description' => 'The {users}.uid that created this version.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  ), array(
    'indexes' => array(
      'uid' => array(
        'uid',
      ),
    ),
  ));
  db_drop_primary_key('history');
  db_drop_index('history', 'nid');
  db_change_field('history', 'uid', 'uid', array(
    'description' => 'The {users}.uid that read the {node} nid.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  ));
  db_change_field('history', 'nid', 'nid', array(
    'description' => 'The {node}.nid that was read.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  ), array(
    'primary key' => array(
      'uid',
      'nid',
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
    ),
  ));
}

/**
 * Generate a UUID for all nodes.
 */
function node_update_8006(&$sandbox) {
  if (!isset($sandbox['progress'])) {
    $sandbox['progress'] = 0;
    $sandbox['last'] = 0;
    $sandbox['max'] = db_query('SELECT COUNT(nid) FROM {node} WHERE uuid IS NULL')
      ->fetchField();
  }
  $nids = db_query_range('SELECT nid FROM {node} WHERE nid > :nid AND uuid IS NULL ORDER BY nid ASC', 0, 10, array(
    ':nid' => $sandbox['last'],
  ))
    ->fetchCol();
  update_add_uuids($sandbox, 'node', 'nid', $nids);
  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
}

/**
 * Move the language default values to config.
 */
function node_update_8007() {
  $types = db_query('SELECT type FROM {node_type}')
    ->fetchCol();
  foreach ($types as $type) {
    $language_default = update_variable_get('node_type_language_default_' . $type, NULL);
    $language_show = update_variable_get('node_type_language_show_' . $type, NULL);
    if (isset($language_default) || isset($language_show)) {
      $values = array(
        'langcode' => $language_default,
        'language_show' => $language_show,
      );
      config('language.settings')
        ->set('node.' . $type . '.language.default_configuration', $values)
        ->save();
    }
  }
}

/**
 * Rename default menu names.
 */
function node_update_8008() {

  // System menu's new block deltas are prefixed with 'menu-'.
  $map = array(
    'navigation' => 'menu-tools',
    'management' => 'menu-admin',
    'user-menu' => 'menu-account',
    'main-menu' => 'menu-main',
  );
  foreach ($map as $old => $new) {
    db_update('block_node_type')
      ->condition('module', 'system')
      ->condition('delta', $old)
      ->fields(array(
      'delta' => $new,
    ))
      ->execute();
  }
}

/**
 * Coverts default_nodes_main variable to config.
 *
 * @ingroup config_upgrade
 */
function node_update_8009() {
  update_variables_to_config('node.settings', array(
    'default_nodes_main' => 'items_per_page',
  ));
}

/**
 * Moves node_access_needs_rebuild from variable to state.
 *
 * @ingroup config_upgrade
 */
function node_update_8010() {
  update_variables_to_state(array(
    'node_access_needs_rebuild' => 'node.node_access_needs_rebuild',
  ));
}

/**
 * Moves node cron last run time from variable to state.
 *
 * @ingroup config_upgrade
 */
function node_update_8011() {
  update_variables_to_state(array(
    'node_cron_last' => 'node.cron_last',
  ));
}

/**
 * Enable History module.
 */
function node_update_8012() {

  // Enable the history module without re-installing the schema.
  module_enable(array(
    'history',
  ));
}

/**
 * Renames global revision permissions to use the word 'all'.
 */
function node_update_8013() {
  $actions = array(
    'view',
    'delete',
    'revert',
  );
  foreach ($actions as $action) {
    db_update('role_permission')
      ->fields(array(
      'permission' => $action . ' all revisions',
    ))
      ->condition('permission', $action . ' revisions')
      ->condition('module', 'node')
      ->execute();
  }
}

/**
 * Empty update. See http://drupal.org/node/1836392.
 */
function node_update_8014() {
}

/**
 * Add language support to the {node_access} table.
 */
function node_update_8015() {

  // Add the langcode field.
  $langcode_field = array(
    'type' => 'varchar',
    'length' => 12,
    'not null' => TRUE,
    'default' => '',
    'description' => 'The {language}.langcode of this node.',
  );
  db_add_field('node_access', 'langcode', $langcode_field);

  // Add the fallback field.
  $fallback_field = array(
    'description' => 'Boolean indicating whether this record should be used as a fallback if a language condition is not provided.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 1,
  );
  db_add_field('node_access', 'fallback', $fallback_field);
  db_drop_primary_key('node_access');
  db_add_primary_key('node_access', array(
    'nid',
    'gid',
    'realm',
    'langcode',
  ));
}

/**
 * Upgrade node schema to the standard entity SQL schema: schema definition.
 */
function _node_update_8016_schema() {
  $schema = array();
  $schema['node_field_data'] = array(
    'description' => 'Base table for node properties.',
    'fields' => array(
      'nid' => array(
        'description' => 'The primary identifier for a node.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'vid' => array(
        'description' => 'The current {node_field_revision}.vid version identifier.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'type' => array(
        'description' => 'The {node_type}.type of this node.',
        'type' => 'varchar',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of these node property values.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      'default_langcode' => array(
        'description' => 'Boolean indicating whether the property values are in the {language}.langcode of this node.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'title' => array(
        'description' => 'The title of this node, always treated as non-markup plain text.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that owns this node; initially, this is the user that created it.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'Boolean indicating whether the node translation is published (visible to non-administrators).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the node translation was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the node translation was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'comment' => array(
        'description' => 'Whether comments are allowed on this node translation: 0 = no, 1 = closed (read only), 2 = open (read/write).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'promote' => array(
        'description' => 'Boolean indicating whether the node translation should be displayed on the front page.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'sticky' => array(
        'description' => 'Boolean indicating whether the node translation should be displayed at the top of lists in which it appears.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'node_changed' => array(
        'changed',
      ),
      'node_created' => array(
        'created',
      ),
      'node_frontpage' => array(
        'promote',
        'status',
        'sticky',
        'created',
      ),
      'node_status_type' => array(
        'status',
        'type',
        'nid',
      ),
      'node_title_type' => array(
        'title',
        array(
          'type',
          4,
        ),
      ),
      'node_type' => array(
        array(
          'type',
          4,
        ),
      ),
      'nid' => array(
        'nid',
      ),
      'vid' => array(
        'vid',
      ),
      'uid' => array(
        'uid',
      ),
    ),
    'foreign keys' => array(
      'node_base' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'node_author' => array(
        'table' => 'users',
        'columns' => array(
          'uid' => 'uid',
        ),
      ),
    ),
    'primary key' => array(
      'nid',
      'vid',
      'langcode',
    ),
  );
  $schema['node_field_revision'] = array(
    'description' => 'Stores information about each saved version of a {node}.',
    'fields' => array(
      'nid' => array(
        'description' => 'The {node} this version belongs to.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'vid' => array(
        'description' => 'The primary identifier for this version.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'langcode' => array(
        'description' => 'The {language}.langcode of this version.',
        'type' => 'varchar',
        'length' => 12,
        'not null' => TRUE,
        'default' => '',
      ),
      'default_langcode' => array(
        'description' => 'Boolean indicating whether the property values of this version are in the {language}.langcode of this node.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'log' => array(
        'description' => 'The log entry explaining the changes in this version.',
        'type' => 'text',
        'not null' => FALSE,
        'size' => 'big',
      ),
      'revision_timestamp' => array(
        'description' => 'The Unix timestamp when the version was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'revision_uid' => array(
        'description' => 'The {users}.uid that created this version.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'title' => array(
        'description' => 'The title of this version, always treated as non-markup plain text.',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'uid' => array(
        'description' => 'The {users}.uid that created this node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'status' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) is published (visible to non-administrators).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 1,
      ),
      'created' => array(
        'description' => 'The Unix timestamp when the node was created.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'changed' => array(
        'description' => 'The Unix timestamp when the version was most recently saved.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'comment' => array(
        'description' => 'Whether comments are allowed on this node (at the time of this revision): 0 = no, 1 = closed (read only), 2 = open (read/write).',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'promote' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed on the front page.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'sticky' => array(
        'description' => 'Boolean indicating whether the node (at the time of this revision) should be displayed at the top of lists in which it appears.',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
      'uid' => array(
        'uid',
      ),
      'revision_uid' => array(
        'revision_uid',
      ),
      'vid' => array(
        'vid',
      ),
    ),
    'foreign keys' => array(
      'versioned_node' => array(
        'table' => 'node',
        'columns' => array(
          'nid' => 'nid',
        ),
      ),
      'version_author' => array(
        'table' => 'users',
        'columns' => array(
          'uid' => 'uid',
        ),
      ),
    ),
    'primary key' => array(
      'nid',
      'vid',
      'langcode',
    ),
  );
  return $schema;
}

/**
 * Upgrade node schema to the standard entity SQL schema: create new tables.
 */
function node_update_8016() {
  foreach (_node_update_8016_schema() as $table => $table_schema) {
    db_create_table($table, $table_schema);
  }
}

/**
 * Upgrade node schema to the standard entity SQL schema: migrate data.
 */
function node_update_8017(&$sandbox) {
  if (!isset($sandbox['progress'])) {

    // Initialize the batch status.
    $sandbox['progress'] = 0;
    $sandbox['max'] = db_query('SELECT COUNT(vid) FROM {node_revision}')
      ->fetchField();
  }

  // Prepare the new records.
  $queries = array();
  $schema = _node_update_8016_schema();
  $result = db_query_range('SELECT nr.*, nr.timestamp AS revision_timestamp, nr.uid as revision_uid, 1 AS default_langcode, n.langcode, n.vid = nr.vid AS default_revision, n.uid, n.changed, n.created, n.type FROM {node_revision} nr JOIN {node} n ON nr.nid = n.nid ORDER BY nr.nid ASC, nr.vid ASC', $sandbox['progress'], 50);
  foreach ($result as $row) {
    $sandbox['progress']++;
    foreach ($schema as $table => $table_schema) {

      // We need to store the data table record only when dealing with the
      // default revision.
      if ($row->default_revision || $table == 'node_field_revision') {
        $fields = array_keys($table_schema['fields']);
        $record = array();
        foreach ($fields as $field) {
          if (isset($row->{$field})) {
            $record[$field] = $row->{$field};
          }
        }
        if (!isset($queries[$table])) {
          $queries[$table] = db_insert($table)
            ->fields($fields);
        }
        $queries[$table]
          ->values($record);
      }
    }
  }

  // Store the new records.
  foreach ($queries as $query) {
    $query
      ->execute();
  }
  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
}

/**
 * Upgrade node schema to the standard entity SQL schema: delete old fields.
 */
function node_update_8018() {
  $indexes = array(
    'node_changed',
    'node_created',
    'node_frontpage',
    'node_status_type',
    'node_title_type',
    'uid',
  );
  foreach ($indexes as $index) {
    db_drop_index('node', $index);
  }
  $fields = array(
    'title',
    'uid',
    'status',
    'created',
    'changed',
    'comment',
    'promote',
    'sticky',
  );
  foreach ($fields as $field) {
    db_drop_field('node', $field);
  }
}

/**
 * @} End of "addtogroup updates-7.x-to-8.x"
 * The next series of updates should start at 9000.
 */

Functions

Namesort descending Description
node_install Implements hook_install().
node_schema Implements hook_schema().
node_uninstall Implements hook_uninstall().
node_update_8001 Rename node type language variable names.
node_update_8002 Rename node.language field to node.langcode.
node_update_8003 Rename node type language variable names.
node_update_8004 Create a UUID column for nodes.
node_update_8005 Make *id fields unsigned.
node_update_8006 Generate a UUID for all nodes.
node_update_8007 Move the language default values to config.
node_update_8008 Rename default menu names.
node_update_8009 Coverts default_nodes_main variable to config.
node_update_8010 Moves node_access_needs_rebuild from variable to state.
node_update_8011 Moves node cron last run time from variable to state.
node_update_8012 Enable History module.
node_update_8013 Renames global revision permissions to use the word 'all'.
node_update_8014 Empty update. See http://drupal.org/node/1836392.
node_update_8015 Add language support to the {node_access} table.
node_update_8016 Upgrade node schema to the standard entity SQL schema: create new tables.
node_update_8017 Upgrade node schema to the standard entity SQL schema: migrate data.
node_update_8018 Upgrade node schema to the standard entity SQL schema: delete old fields.
_node_update_8016_schema Upgrade node schema to the standard entity SQL schema: schema definition.
_update_7000_node_get_types Fetches node types directly from the database.