diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 616637c..d241686 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -968,7 +968,7 @@ function install_base_system(&$install_state) { // Enable the user module so that sessions can be recorded during the // upcoming bootstrap step. - \Drupal::moduleHandler()->install(array('user'), FALSE); + \Drupal::moduleHandler()->install(array('user')); // Save the list of other modules to install for the upcoming tasks. // State can be set to the database now that system.module is installed. diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index a1943b2..ba453d3 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -170,8 +170,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_type, $container->get('database'), - $container->get('field.info'), - $container->get('entity.manager') + $container->get('entity.manager'), + $container->get('field.info') ); } @@ -182,12 +182,13 @@ public static function createInstance(ContainerInterface $container, EntityTypeI * The entity type definition. * @param \Drupal\Core\Database\Connection $database * The database connection to be used. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. + * @param \Drupal\field\FieldInfo $field_info + * (optional) The field info service. Defaults to NULL as storage can be + * instantiated before Field module is installed. */ - public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, EntityManagerInterface $entity_manager) { + public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, FieldInfo $field_info = NULL) { parent::__construct($entity_type); $this->database = $database; @@ -305,11 +306,28 @@ public function getRevisionDataTable() { * {@inheritdoc} */ public function getSchema() { + $schema = $this->buildSchema(); + $context = array('entity_type' => $this->entityType); + // TODO Document this hook. + $this->moduleHandler()->alter('entity_schema', $schema, $context); + return $schema; + } + + /** + * Builds the database schema for the related entity type. + * + * @return + * A schema API array. + */ + protected function buildSchema() { return $this->schemaHandler()->getSchema(); } /** - * Gets the schema builder for this storage controller. + * Gets the schema handler for this storage controller. + * + * @return \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler + * The schema handler. */ protected function schemaHandler() { if (!isset($this->schemaHandler)) { @@ -342,8 +360,11 @@ public function getTableMapping() { else { $key_fields = array_filter(array($this->idKey, $this->revisionKey, $this->bundleKey, $this->uuidKey, $this->langcodeKey)); + // Storable fields are single-value base fields that are not defined as + // computed and that do not specify a custom format. + // @todo Add support for multiple-value base fields. $storable_definitions = array_filter($this->fieldDefinitions, function (FieldDefinitionInterface $field_definition) { - return !$field_definition->isComputed() && !$field_definition->hasCustomStorage(); + return !$field_definition->isComputed() && !$field_definition->hasCustomStorage() && !$field_definition->isMultiple(); }); $storable_fields = array_keys($storable_definitions); @@ -417,14 +438,16 @@ protected function processFields($field_names) { $mapping = array(); foreach ($field_names as $field_name) { $columns = isset($this->fieldDefinitions[$field_name]) ? array_keys($this->fieldDefinitions[$field_name]->getColumns()) : array(); - if (count($columns) > 1) { - foreach ($columns as $column) { - $mapping[$field_name][] = $field_name . '__' . $column; + // @todo Remove the entity reference check once we can handle schema + // changes or the Entity reference module stops messing with field + // schema. See: + // - https://drupal.org/node/1498720 + // - https://drupal.org/node/2209981 + foreach ($columns as $index => $column) { + if (!$index || $this->fieldDefinitions[$field_name]->getType() != 'entity_reference') { + $mapping[$field_name][] = $this->schemaHandler()->getFieldColumnName($this->fieldDefinitions[$field_name], $column); } } - else { - $mapping[$field_name] = array($field_name); - } } return $mapping; } diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php index 5276c26..2ca76ad 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Tables.php @@ -15,6 +15,7 @@ use Drupal\Core\Entity\SqlStorageInterface; use Drupal\field\Entity\FieldConfig; use Drupal\field\Field as FieldInfo; +use Drupal\Core\Entity\EntityType; /** * Adds tables and fields to the SQL entity query. @@ -181,10 +182,10 @@ public function addField($field, $type, $langcode) { $entity_tables = array(); if ($data_table = $entity_type->getDataTable()) { $this->sqlQuery->addMetaData('simple_query', FALSE); - $entity_tables[$data_table] = $this->getTableSchema($data_table); + $entity_tables[$data_table] = $this->getTableMapping($data_table, $entity_type_id); } $entity_base_table = $entity_type->getBaseTable(); - $entity_tables[$entity_base_table] = $this->getTableSchema($entity_base_table); + $entity_tables[$entity_base_table] = $this->getTableMapping($entity_base_table, $entity_type_id); $sql_column = $specifier; $table = $this->ensureEntityTable($index_prefix, $specifier, $type, $langcode, $base_table, $entity_id_field, $entity_tables); } @@ -237,8 +238,8 @@ public function addField($field, $type, $langcode) { * @throws \Drupal\Core\Entity\Query\QueryException */ protected function ensureEntityTable($index_prefix, $property, $type, $langcode, $base_table, $id_field, $entity_tables) { - foreach ($entity_tables as $table => $schema) { - if (isset($schema['fields'][$property])) { + foreach ($entity_tables as $table => $mapping) { + if (isset($mapping[$property])) { if (!isset($this->entityTables[$index_prefix . $table])) { $this->entityTables[$index_prefix . $table] = $this->addJoin($type, $table, "%alias.$id_field = $base_table.$id_field", $langcode); } @@ -286,19 +287,21 @@ protected function addJoin($type, $table, $join_condition, $langcode) { * The table name. * * @return array|bool - * The schema for the given table or FALSE if not available. + * The table field mapping for the given table or FALSE if not available. */ - protected function getTableSchema($table) { - $entity_type_id = $this->sqlQuery->getMetaData('entity_type'); + protected function getTableMapping($table, $entity_type_id) { $storage = $this->entityManager->getStorage($entity_type_id); // @todo Stop calling drupal_get_schema() once menu links are converted // to the Entity Field API. See https://drupal.org/node/1842858. $schema = drupal_get_schema($table); if (!$schema && $storage instanceof SqlStorageInterface) { - $storage_schema = $storage->getSchema(); - $schema = isset($storage_schema[$table]) ? $storage_schema[$table] : FALSE; + $mapping = $storage->getTableMapping(); + $mapping = isset($mapping[$table]) ? call_user_func_array('array_merge', $mapping[$table]) : FALSE; + } + else { + $mapping = array_keys($schema['fields']); } - return $schema; + return array_flip($mapping); } } diff --git a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php b/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php index c1e636c..dad9bb1 100644 --- a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php +++ b/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php @@ -100,7 +100,7 @@ public function getSchema() { // Add the schema from field definitions. foreach ($this->storage->getTableMapping() as $table => $field_names) { foreach ($field_names as $field_name => $column_names) { - $this->addFieldSchema($schema[$table], $field_name); + $this->addFieldSchema($schema[$table], $field_name, $column_names); } } @@ -148,12 +148,24 @@ protected function getTables() { * @param \Drupal\Core\Field\FieldDefinitionInterface $definition * The field definition to return the schema for. */ - protected function addFieldSchema(array &$schema, $field_name) { + protected function addFieldSchema(array &$schema, $field_name, $column_names) { $definition = $this->fieldDefinitions[$field_name]; $field_schema = $definition->getSchema(); + $index = 0; foreach ($field_schema['columns'] as $column_name => $column_schema) { - $schema_field_name = $this->getFieldColumnName($definition, $column_name); + // @todo Remove the entity reference check once we can handle schema + // changes or the Entity reference module stops messing with field + // schema. See: + // - https://drupal.org/node/1498720 + // - https://drupal.org/node/2209981 + if ($definition->getType() == 'entity_reference' && $index++ > 0) { + continue; + } + else { + $schema_field_name = $this->getFieldColumnName($definition, $column_name); + } + $schema['fields'][$schema_field_name] = $column_schema; $schema['fields'][$schema_field_name]['description'] = $definition->getDescription(); // Only entity keys are required. @@ -239,9 +251,14 @@ protected function getFieldForeignKeys(FieldDefinitionInterface $definition) { * @return string * The column name. */ - protected function getFieldColumnName(FieldDefinitionInterface $definition, $column) { + public function getFieldColumnName(FieldDefinitionInterface $definition, $column) { $name = $definition->getName(); - return count($definition->getSchema()['columns']) == 1 ? $name : $name . '__' . $column; + // @todo Remove the entity reference check once we can handle schema + // changes or the Entity reference module stops messing with field + // schema. See: + // - https://drupal.org/node/1498720 + // - https://drupal.org/node/2209981 + return count($definition->getSchema()['columns']) == 1 || $definition->getType() == 'entity_reference' ? $name : $name . '__' . $column; } /** @@ -277,7 +294,7 @@ protected function initializeBaseTable() { if ($this->storage->getLayoutType() & ContentEntityDatabaseStorage::LAYOUT_REVISION) { $key = $this->entityType->getKey('revision'); - $schema['indexes'][$this->getEntityIndexName($key)] = array($key); + $schema['unique keys'][$this->getEntityIndexName($key)] = array($key); } return $schema; diff --git a/core/modules/aggregator/aggregator.install b/core/modules/aggregator/aggregator.install index e4bef0e..2b755e1 100644 --- a/core/modules/aggregator/aggregator.install +++ b/core/modules/aggregator/aggregator.install @@ -22,179 +22,3 @@ function aggregator_requirements($phase) { } return $requirements; } - -/** - * Implements hook_schema(). - */ -function aggregator_schema() { - $schema['aggregator_feed'] = array( - 'description' => 'Stores feeds to be parsed by the aggregator.', - 'fields' => array( - 'fid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique feed ID.', - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Title of the feed.', - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this feed.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'url' => array( - 'type' => 'text', - 'not null' => TRUE, - 'description' => 'URL to the feed.', - ), - 'refresh' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'How often to check for new feed items, in seconds.', - ), - 'checked' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Last time feed was checked for new items, as Unix timestamp.', - ), - 'queued' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Time when this feed was queued for refresh, 0 if not queued.', - ), - 'link' => array( - 'type' => 'text', - 'not null' => TRUE, - 'description' => 'The parent website of the feed; comes from the element in the feed.', - ), - 'description' => array( - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - 'description' => "The parent website's description; comes from the element in the feed.", - ), - 'image' => array( - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - 'description' => 'An image representing the feed.', - ), - 'hash' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Calculated hash of the feed data, used for validating cache.', - ), - 'etag' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Entity tag HTTP response header, used for validating cache.', - ), - 'modified' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'When the feed was last modified, as a Unix timestamp.', - ), - ), - 'primary key' => array('fid'), - 'indexes' => array( - 'url' => array(array('url', 255)), - 'queued' => array('queued'), - ), - 'unique keys' => array( - 'title' => array('title'), - ), - ); - - $schema['aggregator_item'] = array( - 'description' => 'Stores the individual items imported from feeds.', - 'fields' => array( - 'iid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique ID for feed item.', - ), - 'fid' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The {aggregator_feed}.fid to which this item belongs.', - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Title of the feed item.', - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this feed item.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'link' => array( - 'type' => 'text', - 'not null' => TRUE, - 'description' => 'Link to the feed item.', - ), - 'author' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Author of the feed item.', - ), - 'description' => array( - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - 'description' => 'Body of the feed item.', - ), - 'timestamp' => array( - 'type' => 'int', - 'not null' => FALSE, - 'description' => 'Posted date of the feed item, as a Unix timestamp.', - ), - 'guid' => array( - 'type' => 'text', - 'not null' => TRUE, - 'description' => 'Unique identifier for the feed item.', - ) - ), - 'primary key' => array('iid'), - 'indexes' => array( - 'fid' => array('fid'), - 'timestamp' => array('timestamp'), - ), - 'foreign keys' => array( - 'aggregator_feed' => array( - 'table' => 'aggregator_feed', - 'columns' => array('fid' => 'fid'), - ), - ), - ); - - return $schema; -} diff --git a/core/modules/block/custom_block/custom_block.install b/core/modules/block/custom_block/custom_block.install index 3474559..a4b555c 100644 --- a/core/modules/block/custom_block/custom_block.install +++ b/core/modules/block/custom_block/custom_block.install @@ -6,123 +6,6 @@ */ /** - * Implements hook_schema(). - */ -function custom_block_schema() { - $schema = array(); - $schema['custom_block'] = array( - 'description' => 'Stores contents of custom-made blocks.', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => "The block's {custom_block}.id.", - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'info' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Block description.', - ), - // Defaults to NULL in order to avoid a brief period of potential - // deadlocks on the index. - 'revision_id' => array( - 'description' => 'The current {block_custom_revision}.revision_id version identifier.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => FALSE, - 'default' => NULL, - ), - 'type' => array( - 'description' => 'The type of this custom block.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '', - ), - 'changed' => array( - 'description' => 'The Unix timestamp when the custom block was most recently saved.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this node.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'primary key' => array('id'), - 'indexes' => array( - 'block_custom_type' => array(array('type', 4)), - ), - 'unique keys' => array( - 'revision_id' => array('revision_id'), - 'uuid' => array('uuid'), - 'info' => array('info'), - ), - 'foreign keys' => array( - 'custom_block_revision' => array( - 'table' => 'custom_block_revision', - 'columns' => array('revision_id' => 'revision_id'), - ), - ), - ); - - $schema['custom_block_revision'] = array( - 'description' => 'Stores contents of custom-made blocks.', - 'fields' => array( - 'id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => "The block's {custom_block}.id.", - ), - // Defaults to NULL in order to avoid a brief period of potential - // deadlocks on the index. - 'revision_id' => array( - 'description' => 'The current version identifier.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'log' => array( - 'description' => 'The log entry explaining the changes in this version.', - 'type' => 'text', - 'not null' => TRUE, - 'size' => 'big', - ), - 'info' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Block description.', - ), - 'changed' => array( - 'description' => 'The Unix timestamp when the version was most recently saved.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('revision_id'), - ); - return $schema; -} - -/** * Implements hook_schema_0(). */ function custom_block_schema_0() { diff --git a/core/modules/comment/comment.install b/core/modules/comment/comment.install index 40fb1a0..1929b7b 100644 --- a/core/modules/comment/comment.install +++ b/core/modules/comment/comment.install @@ -28,229 +28,3 @@ function comment_install() { // @see \Drupal\comment\CommentStorage::updateEntityStatistics(). \Drupal::state()->set('comment.maintain_entity_statistics', TRUE); } - -/** - * Implements hook_schema(). - */ -function comment_schema() { - $schema['comment'] = array( - 'description' => 'Stores comments and associated data.', - 'fields' => array( - 'cid' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique comment ID.', - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'pid' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The {comment}.cid to which this comment is a reply. If set to 0, this comment is not a reply to an existing comment.', - ), - 'entity_id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The entity_id of the entity to which this comment is a reply.', - ), - 'entity_type' => array( - 'type' => 'varchar', - 'not null' => TRUE, - 'default' => 'node', - 'length' => 255, - 'description' => 'The entity_type of the entity to which this comment is a reply.', - ), - 'field_id' => array( - 'type' => 'varchar', - 'not null' => TRUE, - 'default' => 'node.comment', - 'length' => 255, - 'description' => 'The field_id of the field that was used to add this comment.', - ), - 'uid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The {users}.uid who authored the comment. If set to 0, this comment was created by an anonymous user.', - ), - 'subject' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The comment title.', - ), - 'hostname' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => "The author's host name.", - ), - 'created' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The time that the comment was created, as a Unix timestamp.', - ), - 'changed' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The time that the comment was last edited, as a Unix timestamp.', - ), - 'status' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 1, - 'size' => 'tiny', - 'description' => 'The published status of a comment. (0 = Not Published, 1 = Published)', - ), - 'thread' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'description' => "The alphadecimal representation of the comment's place in a thread, consisting of a base 36 string prefixed by an integer indicating its length.", - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 60, - 'not null' => FALSE, - 'description' => "The comment author's name. Uses {users}.name if the user is logged in, otherwise uses the value typed into the comment form.", - ), - 'mail' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => FALSE, - 'description' => "The comment author's e-mail address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on.", - ), - 'homepage' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - 'description' => "The comment author's home page address from the comment form, if user is anonymous, and the 'Anonymous users may/must leave their contact information' setting is turned on.", - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this comment.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'indexes' => array( - 'comment_status_pid' => array('pid', 'status'), - 'comment_num_new' => array( - 'entity_id', - array('entity_type', 32), - array('field_id', 32), - 'status', - 'created', - 'cid', - 'thread', - ), - 'comment_uid' => array('uid'), - 'comment_entity_langcode' => array( - 'entity_id', - array('entity_type', 32), - array('field_id', 32), - 'langcode', - ), - 'comment_created' => array('created'), - ), - 'primary key' => array('cid'), - 'unique keys' => array( - 'uuid' => array('uuid'), - ), - 'foreign keys' => array( - 'comment_author' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - ); - - $schema['comment_entity_statistics'] = array( - 'description' => 'Maintains statistics of entity and comments posts to show "new" and "updated" flags.', - 'fields' => array( - 'entity_id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The entity_id of the entity for which the statistics are compiled.', - ), - 'entity_type' => array( - 'type' => 'varchar', - 'not null' => TRUE, - 'default' => 'node', - 'length' => 255, - 'description' => 'The entity_type of the entity to which this comment is a reply.', - ), - 'field_id' => array( - 'type' => 'varchar', - 'not null' => TRUE, - 'default' => 'node__comment', - 'length' => 255, - 'description' => 'The field_id of the field that was used to add this comment.', - ), - 'cid' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The {comment}.cid of the last comment.', - ), - 'last_comment_timestamp' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The Unix timestamp of the last comment that was posted within this node, from {comment}.changed.', - ), - 'last_comment_name' => array( - 'type' => 'varchar', - 'length' => 60, - 'not null' => FALSE, - 'description' => 'The name of the latest author to post a comment on this node, from {comment}.name.', - ), - 'last_comment_uid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The user ID of the latest author to post a comment on this node, from {comment}.uid.', - ), - 'comment_count' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The total number of comments on this entity.', - ), - ), - 'primary key' => array('entity_id', array('entity_type', 32), array('field_id', 32)), - 'indexes' => array( - 'last_comment_timestamp' => array('last_comment_timestamp'), - 'comment_count' => array('comment_count'), - 'last_comment_uid' => array('last_comment_uid'), - ), - 'foreign keys' => array( - 'last_comment_author' => array( - 'table' => 'users', - 'columns' => array( - 'last_comment_uid' => 'uid', - ), - ), - ), - ); - - return $schema; -} diff --git a/core/modules/comment/lib/Drupal/comment/CommentStorage.php b/core/modules/comment/lib/Drupal/comment/CommentStorage.php index ccc6a74..02a411f 100644 --- a/core/modules/comment/lib/Drupal/comment/CommentStorage.php +++ b/core/modules/comment/lib/Drupal/comment/CommentStorage.php @@ -39,13 +39,13 @@ class CommentStorage extends ContentEntityDatabaseStorage implements CommentStor * The database connection to be used. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\comment\CommentStatisticsInterface $comment_statistics * The comment statistics service. + * @param \Drupal\field\FieldInfo $field_info + * The field info service. */ - public function __construct(EntityTypeInterface $entity_info, Connection $database, FieldInfo $field_info, EntityManagerInterface $entity_manager, CommentStatisticsInterface $comment_statistics) { - parent::__construct($entity_info, $database, $field_info, $entity_manager); + public function __construct(EntityTypeInterface $entity_info, Connection $database, EntityManagerInterface $entity_manager, CommentStatisticsInterface $comment_statistics, FieldInfo $field_info) { + parent::__construct($entity_info, $database, $entity_manager, $field_info); $this->statistics = $comment_statistics; } @@ -56,9 +56,9 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_info, $container->get('database'), - $container->get('field.info'), $container->get('entity.manager'), - $container->get('comment.statistics') + $container->get('comment.statistics'), + $container->get('field.info') ); } @@ -131,4 +131,86 @@ public function getChildCids(array $comments) { ->fetchCol(); } + /** + * {@inheritdoc} + */ + protected function buildSchema() { + $schema = parent::buildSchema(); + + $schema['comment_entity_statistics'] = array( + 'description' => 'Maintains statistics of entity and comments posts to show "new" and "updated" flags.', + 'fields' => array( + 'entity_id' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The entity_id of the entity for which the statistics are compiled.', + ), + 'entity_type' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'default' => 'node', + 'length' => 255, + 'description' => 'The entity_type of the entity to which this comment is a reply.', + ), + 'field_id' => array( + 'type' => 'varchar', + 'not null' => TRUE, + 'default' => 'node__comment', + 'length' => 255, + 'description' => 'The field_id of the field that was used to add this comment.', + ), + 'cid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The {comment}.cid of the last comment.', + ), + 'last_comment_timestamp' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The Unix timestamp of the last comment that was posted within this node, from {comment}.changed.', + ), + 'last_comment_name' => array( + 'type' => 'varchar', + 'length' => 60, + 'not null' => FALSE, + 'description' => 'The name of the latest author to post a comment on this node, from {comment}.name.', + ), + 'last_comment_uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The user ID of the latest author to post a comment on this node, from {comment}.uid.', + ), + 'comment_count' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The total number of comments on this entity.', + ), + ), + 'primary key' => array('entity_id', array('entity_type', 32), array('field_id', 32)), + 'indexes' => array( + 'last_comment_timestamp' => array('last_comment_timestamp'), + 'comment_count' => array('comment_count'), + 'last_comment_uid' => array('last_comment_uid'), + ), + 'foreign keys' => array( + 'last_comment_author' => array( + 'table' => 'users', + 'columns' => array( + 'last_comment_uid' => 'uid', + ), + ), + ), + ); + + return $schema; + } + } diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module index 4ac08c2..7bbc291 100644 --- a/core/modules/entity/entity.module +++ b/core/modules/entity/entity.module @@ -107,6 +107,7 @@ function entity_modules_installed($modules) { $entity_manager = \Drupal::entityManager(); $schema = \Drupal::database()->schema(); $definitions = $entity_manager->getDefinitions(); + $installed = array(); foreach ($modules as $module) { foreach ($definitions as $entity_type_id => $entity_type) { @@ -118,12 +119,16 @@ function entity_modules_installed($modules) { // have been converted to an automatic schema. if (!drupal_get_schema($table_name) && !$schema->tableExists($table_name)) { $schema->createTable($table_name, $table_schema); + $installed[$entity_type_id] = $storage; } } } } } } + + // TODO Document this hook. + \Drupal::moduleHandler()->invokeAll('entity_schema_installed', array($installed)); } /** diff --git a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php index 31ea4e8..de443b4 100644 --- a/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php +++ b/core/modules/entity/lib/Drupal/entity/Tests/EntityDisplayTest.php @@ -261,7 +261,7 @@ public function testBaseFieldComponent() { */ public function testRenameDeleteBundle() { $this->enableModules(array('field_test', 'node', 'system', 'text')); - $this->installSchema('node', array('node')); + $this->installEntitySchema('node'); // Create a node bundle, display and form display object. entity_create('node_type', array('type' => 'article'))->save(); diff --git a/core/modules/file/file.install b/core/modules/file/file.install index fb5a4eb..514d658 100644 --- a/core/modules/file/file.install +++ b/core/modules/file/file.install @@ -6,157 +6,6 @@ */ /** - * Implements hook_schema(). - */ -function file_schema() { - $schema['file_managed'] = array( - 'description' => 'Stores information for uploaded files.', - 'fields' => array( - 'fid' => array( - 'description' => 'File ID.', - '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, - ), - 'uid' => array( - 'description' => 'The {users}.uid of the user who is associated with the file.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'filename' => array( - 'description' => 'Name of the file with no path components. This may differ from the basename of the URI if the file is renamed to avoid overwriting an existing file.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'uri' => array( - 'description' => 'The URI to access the file (either local or remote).', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'binary' => TRUE, - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this file.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'filemime' => array( - 'description' => "The file's MIME type.", - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'filesize' => array( - 'description' => 'The size of the file in bytes.', - 'type' => 'int', - 'size' => 'big', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'status' => array( - 'description' => 'A field indicating the status of the file. Two status are defined in core: temporary (0) and permanent (1). Temporary files older than DRUPAL_MAXIMUM_TEMP_FILE_AGE will be removed during a cron run.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'size' => 'tiny', - ), - 'created' => array( - 'description' => 'UNIX timestamp for when the file added.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'changed' => array( - 'description' => 'UNIX timestamp for when the file was last changed.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'indexes' => array( - 'uid' => array('uid'), - 'status' => array('status'), - 'changed' => array('changed'), - ), - 'unique keys' => array( - 'uuid' => array('uuid'), - 'uri' => array('uri'), - ), - 'primary key' => array('fid'), - 'foreign keys' => array( - 'file_owner' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - ); - - $schema['file_usage'] = array( - 'description' => 'Track where a file is used.', - 'fields' => array( - 'fid' => array( - 'description' => 'File ID.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'module' => array( - 'description' => 'The name of the module that is using the file.', - 'type' => 'varchar', - 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, - 'not null' => TRUE, - 'default' => '', - ), - 'type' => array( - 'description' => 'The name of the object type in which the file is used.', - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'default' => '', - ), - 'id' => array( - 'description' => 'The primary key of the object using the file.', - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'default' => 0, - ), - 'count' => array( - 'description' => 'The number of times this file is used by this object.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('fid', 'type', 'id', 'module'), - 'indexes' => array( - 'type_id' => array('type', 'id'), - 'fid_count' => array('fid', 'count'), - 'fid_module' => array('fid', 'module'), - ), - ); - return $schema; -} - -/** * Implements hook_requirements(). * * Display information about getting upload progress bars working. @@ -195,11 +44,10 @@ function file_requirements($phase) { $value = t('Enabled (PECL uploadprogress)', array('@url' => 'http://pecl.php.net/package/uploadprogress')); } $requirements['file_progress'] = array( - 'title' => t('Upload progress'), - 'value' => $value, - 'description' => $description, + 'title' => t('Upload progress'), + 'value' => $value, + 'description' => $description, ); } - - return $requirements; } + diff --git a/core/modules/file/lib/Drupal/file/FileStorage.php b/core/modules/file/lib/Drupal/file/FileStorage.php index c6f2ccc..f8fc4d7 100644 --- a/core/modules/file/lib/Drupal/file/FileStorage.php +++ b/core/modules/file/lib/Drupal/file/FileStorage.php @@ -38,4 +38,60 @@ public function retrieveTemporaryFiles() { ':changed' => REQUEST_TIME - DRUPAL_MAXIMUM_TEMP_FILE_AGE )); } + + /** + * {@inheritdoc} + */ + protected function buildSchema() { + $schema = parent::buildSchema(); + + $schema['file_usage'] = array( + 'description' => 'Track where a file is used.', + 'fields' => array( + 'fid' => array( + 'description' => 'File ID.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'module' => array( + 'description' => 'The name of the module that is using the file.', + 'type' => 'varchar', + 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, + 'not null' => TRUE, + 'default' => '', + ), + 'type' => array( + 'description' => 'The name of the object type in which the file is used.', + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => '', + ), + 'id' => array( + 'description' => 'The primary key of the object using the file.', + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'default' => 0, + ), + 'count' => array( + 'description' => 'The number of times this file is used by this object.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('fid', 'type', 'id', 'module'), + 'indexes' => array( + 'type_id' => array('type', 'id'), + 'fid_count' => array('fid', 'count'), + 'fid_module' => array('fid', 'module'), + ), + ); + + return $schema; + } + } diff --git a/core/modules/node/node.install b/core/modules/node/node.install index a6af612..2634bb2 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -39,310 +39,6 @@ function node_requirements($phase) { * 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 type of this node.', - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'indexes' => array( - 'node_type' => array(array('type', 4)), - ), - 'unique keys' => array( - 'vid' => array('vid'), - 'uuid' => array('uuid'), - ), - 'foreign keys' => array( - 'node_revision' => array( - 'table' => 'node_revision', - 'columns' => array('vid' => 'vid'), - ), - ), - 'primary key' => array('nid'), - ); - - $schema['node_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, - ), - 'revision_uid' => array( - 'description' => 'The {users}.uid that created this version.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - '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, - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this version.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - ), - 'indexes' => array( - 'nid' => array('nid'), - 'revision_uid' => array('revision_uid'), - 'node_langcode' => array('langcode'), - ), - 'foreign keys' => array( - 'versioned_node' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'version_author' => array( - 'table' => 'users', - 'columns' => array('revision_uid' => 'uid'), - ), - ), - 'primary key' => array('vid'), - ); - - // Node field storage. - $schema['node_field_data'] = array( - 'description' => 'Data table for node base fields.', - 'fields' => array( - 'nid' => array( - 'description' => 'The primary identifier for a node.', - 'type' => 'int', - '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, - ), - '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)), - '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', 'langcode'), - ); - - $schema['node_field_revision'] = array( - 'description' => 'Revision table for node base fields.', - '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' => 'int', - '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, - ), - '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, - ), - '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( - 'uid' => array('uid'), - 'node_default_langcode' => array('default_langcode'), - 'node_langcode' => array('langcode'), - ), - 'foreign keys' => array( - 'versioned_node' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'node_author' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - 'primary key' => array('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.', diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install index b7ed49c..be6f8b2 100644 --- a/core/modules/shortcut/shortcut.install +++ b/core/modules/shortcut/shortcut.install @@ -12,96 +12,6 @@ * Implements hook_schema(). */ function shortcut_schema() { - $schema['shortcut'] = array( - 'description' => 'Stores shortcut items.', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique shortcut ID.', - ), - 'uuid' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - 'description' => 'Unique Key: Universally unique identifier for this shortcut.', - ), - 'shortcut_set' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The bundle of the shortcut.', - ), - 'langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The {language}.langcode of the original variant of this shortcut.', - ), - 'weight' => array( - 'description' => 'Weight among shortcuts in the same shortcut set.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'route_name' => array( - 'description' => 'The machine name of a defined Symfony Route this menu item represents.', - 'type' => 'varchar', - 'length' => 255, - ), - 'route_parameters' => array( - 'description' => 'Serialized array of route parameters of this shortcut.', - 'type' => 'blob', - 'size' => 'big', - 'not null' => FALSE, - 'serialize' => TRUE, - ), - ), - 'primary key' => array('id'), - 'unique keys' => array( - 'uuid' => array('uuid'), - ), - ); - - $schema['shortcut_field_data'] = array( - 'description' => 'Stores shortcut properties.', - 'fields' => array( - 'id' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => 'The {shortcut}.id of the shortcut.', - ), - 'langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The {language}.langcode of this variant of this shortcut.', - ), - 'default_langcode' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 1, - 'description' => 'Boolean indicating whether the current variant is in the original entity language.', - ), - 'title' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => FALSE, - 'description' => 'The title of the shortcut.', - ), - ), - 'foreign keys' => array( - 'shortcut' => array( - 'table' => 'shortcut', - 'columns' => array('id' => 'id'), - ), - ), - 'primary key' => array('id', 'langcode'), - ); $schema['shortcut_set_users'] = array( 'description' => 'Maps users to shortcut sets.', diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php index 5d89844..cbe097c 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DrupalKernel; +use Drupal\Core\Entity\SqlStorageInterface; use Drupal\Core\Entity\Schema\ContentEntitySchemaHandlerInterface; use Drupal\Core\KeyValueStore\KeyValueMemoryFactory; use Drupal\Core\Language\Language; @@ -346,7 +347,7 @@ protected function installEntitySchema($entity_type_id) { $schema_handler = $this->container->get('database')->schema(); $storage = $entity_manager->getStorage($entity_type_id); - if ($storage instanceof ContentEntitySchemaHandlerInterface) { + if ($storage instanceof ContentEntitySchemaHandlerInterface && $storage instanceof SqlStorageInterface) { $schema = $storage->getSchema(); foreach ($schema as $table_name => $table_schema) { $schema_handler->createTable($table_name, $table_schema); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php index 1d49a02..c0a16be 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityCrudHookTest.php @@ -44,9 +44,11 @@ public static function getInfo() { public function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); - $this->installSchema('node', array('node', 'node_revision', 'node_field_data', 'node_field_revision', 'node_access')); - $this->installSchema('comment', array('comment', 'comment_entity_statistics')); + + $this->installSchema('node', array('node_access')); + $this->installEntitySchema('node'); + + $this->installEntitySchema('comment'); } /** @@ -219,7 +221,8 @@ public function testCommentHooks() { * Tests hook invocations for CRUD operations on files. */ public function testFileHooks() { - $this->installSchema('file', array('file_managed', 'file_usage')); + $this->installEntitySchema('file'); + $url = 'public://entity_crud_hook_test.file'; file_put_contents($url, 'Test test test'); $file = entity_create('file', array( @@ -346,7 +349,7 @@ public function testNodeHooks() { * Tests hook invocations for CRUD operations on taxonomy terms. */ public function testTaxonomyTermHooks() { - $this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy')); + $this->installEntitySchema('taxonomy_term'); $vocabulary = entity_create('taxonomy_vocabulary', array( 'name' => 'Test vocabulary', @@ -415,7 +418,7 @@ public function testTaxonomyTermHooks() { * Tests hook invocations for CRUD operations on taxonomy vocabularies. */ public function testTaxonomyVocabularyHooks() { - $this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy')); + $this->installEntitySchema('taxonomy_term'); $vocabulary = entity_create('taxonomy_vocabulary', array( 'name' => 'Test vocabulary', diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php index 7435100..bc29c7e 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityFieldTest.php @@ -40,8 +40,9 @@ public static function getInfo() { public function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); - $this->installSchema('node', array('node', 'node_revision', 'node_field_data', 'node_field_revision', 'node_access')); + + $this->installSchema('node', array('node_access')); + $this->installEntitySchema('node'); $this->installEntitySchema('entity_test_rev'); $this->installEntitySchema('entity_test_mul'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php index e5d8cf4..8d67666 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryRelationshipTest.php @@ -70,7 +70,7 @@ public static function getInfo() { public function setUp() { parent::setUp(); - $this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy')); + $this->installEntitySchema('taxonomy_term'); // We want a taxonomy term reference field. It needs a vocabulary, terms, // a field and an instance. First, create the vocabulary. diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php index ffeb3c8..0c6aeab 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityUnitTestBase.php @@ -42,9 +42,9 @@ public function setUp() { $this->entityManager = $this->container->get('entity.manager'); $this->state = $this->container->get('state'); - $this->installSchema('user', array('users', 'users_roles')); $this->installSchema('system', 'sequences'); + $this->installEntitySchema('user'); $this->installEntitySchema('entity_test'); $this->installConfig(array('field')); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php index 29f348b..40d7708 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php @@ -37,7 +37,6 @@ public static function getInfo() { */ public function setUp() { parent::setUp(); - $this->installSchema('user', array('users_data')); $this->installEntitySchema('entity_test_rev'); $this->installEntitySchema('entity_test_mul'); diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php index 7395dfa..8ab706c 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldAccessTest.php @@ -44,7 +44,7 @@ protected function setUp() { // Install field configuration. $this->installConfig(array('field')); // The users table is needed for creating dummy user accounts. - $this->installSchema('user', array('users')); + $this->installEntitySchema('user'); // Register entity_test text field. entity_test_install(); } diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorage.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorage.php index b7b9201..8a6385a 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorage.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermStorage.php @@ -151,4 +151,90 @@ public function resetWeights($vid) { ->execute(); } + /** + * {@inheritdoc} + */ + public function buildSchema() { + $schema = parent::buildSchema(); + + $schema['taxonomy_term_hierarchy'] = array( + 'description' => 'Stores the hierarchical relationship between terms.', + 'fields' => array( + 'tid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: The {taxonomy_term_data}.tid of the term.', + ), + 'parent' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => "Primary Key: The {taxonomy_term_data}.tid of the term's parent. 0 indicates no parent.", + ), + ), + 'indexes' => array( + 'parent' => array('parent'), + ), + 'foreign keys' => array( + 'taxonomy_term_data' => array( + 'table' => 'taxonomy_term_data', + 'columns' => array('tid' => 'tid'), + ), + ), + 'primary key' => array('tid', 'parent'), + ); + + $schema['taxonomy_index'] = array( + 'description' => 'Maintains denormalized information about node/term relationships.', + 'fields' => array( + 'nid' => array( + 'description' => 'The {node}.nid this record tracks.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'tid' => array( + 'description' => 'The term ID.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'sticky' => array( + 'description' => 'Boolean indicating whether the node is sticky.', + 'type' => 'int', + 'not null' => FALSE, + 'default' => 0, + 'size' => 'tiny', + ), + 'created' => array( + 'description' => 'The Unix timestamp when the node was created.', + 'type' => 'int', + 'not null' => TRUE, + 'default'=> 0, + ), + ), + 'indexes' => array( + 'term_node' => array('tid', 'sticky', 'created'), + 'nid' => array('nid'), + ), + 'foreign keys' => array( + 'tracked_node' => array( + 'table' => 'node', + 'columns' => array('nid' => 'nid'), + ), + 'term' => array( + 'table' => 'taxonomy_term_data', + 'columns' => array('tid' => 'tid'), + ), + ), + ); + + return $schema; + } + } diff --git a/core/modules/taxonomy/taxonomy.install b/core/modules/taxonomy/taxonomy.install deleted file mode 100644 index f76d350..0000000 --- a/core/modules/taxonomy/taxonomy.install +++ /dev/null @@ -1,162 +0,0 @@ - 'Stores term information.', - 'fields' => array( - 'tid' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => 'Primary Key: Unique term ID.', - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'vid' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The ID of the vocabulary to which the term is assigned.', - ), - 'langcode' => array( - 'description' => 'The {language}.langcode of this term.', - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The term name.', - ), - 'description__value' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - 'description' => 'A description of the term.', - ), - 'description__format' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - 'description' => 'The filter format ID of the description.', - ), - 'weight' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The weight of this term in relation to other terms.', - ), - 'changed' => array( - 'description' => 'The Unix timestamp when the term was most recently saved.', - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('tid'), - 'unique keys' => array( - 'uuid' => array('uuid'), - ), - 'indexes' => array( - 'taxonomy_tree' => array(array('vid', 64), 'weight', 'name'), - 'vid_name' => array(array('vid', 64), 'name'), - 'name' => array('name'), - ), - ); - - $schema['taxonomy_term_hierarchy'] = array( - 'description' => 'Stores the hierarchical relationship between terms.', - 'fields' => array( - 'tid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Primary Key: The {taxonomy_term_data}.tid of the term.', - ), - 'parent' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => "Primary Key: The {taxonomy_term_data}.tid of the term's parent. 0 indicates no parent.", - ), - ), - 'indexes' => array( - 'parent' => array('parent'), - ), - 'foreign keys' => array( - 'taxonomy_term_data' => array( - 'table' => 'taxonomy_term_data', - 'columns' => array('tid' => 'tid'), - ), - ), - 'primary key' => array('tid', 'parent'), - ); - - $schema['taxonomy_index'] = array( - 'description' => 'Maintains denormalized information about node/term relationships.', - 'fields' => array( - 'nid' => array( - 'description' => 'The {node}.nid this record tracks.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'tid' => array( - 'description' => 'The term ID.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'sticky' => array( - 'description' => 'Boolean indicating whether the node is sticky.', - 'type' => 'int', - 'not null' => FALSE, - 'default' => 0, - 'size' => 'tiny', - ), - 'created' => array( - 'description' => 'The Unix timestamp when the node was created.', - 'type' => 'int', - 'not null' => TRUE, - 'default'=> 0, - ), - ), - 'indexes' => array( - 'term_node' => array('tid', 'sticky', 'created'), - 'nid' => array('nid'), - ), - 'foreign keys' => array( - 'tracked_node' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'term' => array( - 'table' => 'taxonomy_term_data', - 'columns' => array('tid' => 'tid'), - ), - ), - ); - - return $schema; -} diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php index fc33baf..3023e9f 100644 --- a/core/modules/user/lib/Drupal/user/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Entity/User.php @@ -531,6 +531,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { // @todo Convert this to entity_reference_field, see // https://drupal.org/node/2044859. $fields['roles'] = FieldDefinition::create('string') + ->setCustomStorage(TRUE) ->setLabel(t('Roles')) ->setCardinality(FieldDefinitionInterface::CARDINALITY_UNLIMITED) ->setDescription(t('The roles the user has.')); diff --git a/core/modules/user/lib/Drupal/user/UserStorage.php b/core/modules/user/lib/Drupal/user/UserStorage.php index 81266b4..a17446e 100644 --- a/core/modules/user/lib/Drupal/user/UserStorage.php +++ b/core/modules/user/lib/Drupal/user/UserStorage.php @@ -48,8 +48,6 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt * The entity type definition. * @param \Drupal\Core\Database\Connection $database * The database connection to be used. - * @param \Drupal\field\FieldInfo $field_info - * The field info service. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Entity\Schema\ContentEntitySchemaHandlerInterface $schema_builder @@ -58,9 +56,12 @@ class UserStorage extends ContentEntityDatabaseStorage implements UserStorageInt * The password hashing service. * @param \Drupal\user\UserDataInterface $user_data * The user data service. + * @param \Drupal\field\FieldInfo $field_info + * (optional) The field info service. Defaults to NULL as user storage can + * be instantiated before Field module is installed. */ - public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, EntityManagerInterface $entity_manager, PasswordInterface $password, UserDataInterface $user_data) { - parent::__construct($entity_type, $database, $field_info, $entity_manager); + public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, PasswordInterface $password, UserDataInterface $user_data, FieldInfo $field_info = NULL) { + parent::__construct($entity_type, $database, $entity_manager, $field_info); $this->password = $password; $this->userData = $user_data; @@ -73,10 +74,10 @@ public static function createInstance(ContainerInterface $container, EntityTypeI return new static( $entity_type, $container->get('database'), - $container->get('field.info'), $container->get('entity.manager'), $container->get('password'), - $container->get('user.data') + $container->get('user.data'), + $container->has('field.info') ? $container->get('field.info') : NULL ); } @@ -158,4 +159,93 @@ public function updateLastLoginTimestamp(UserInterface $account) { ->execute(); } + /** + * {@inheritdoc} + */ + public function buildSchema() { + $schema = parent::buildSchema(); + + // The "users" table does not user serial identifiers. + $schema['users']['fields']['uid']['type'] = 'int'; + + $schema['users_data'] = array( + 'description' => 'Stores module data as key/value pairs per user.', + 'fields' => array( + 'uid' => array( + 'description' => 'Primary key: {users}.uid for user.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'module' => array( + 'description' => 'The name of the module declaring the variable.', + 'type' => 'varchar', + 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, + 'not null' => TRUE, + 'default' => '', + ), + 'name' => array( + 'description' => 'The identifier of the data.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'value' => array( + 'description' => 'The value.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + ), + 'serialized' => array( + 'description' => 'Whether value is serialized.', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('uid', 'module', 'name'), + 'indexes' => array( + 'module' => array('module'), + 'name' => array('name'), + ), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + ), + ); + + $schema['users_roles'] = array( + 'description' => 'Maps users to roles.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: {users}.uid for user.', + ), + 'rid' => array( + 'type' => 'varchar', + 'length' => 64, + 'not null' => TRUE, + 'description' => 'Primary Key: ID for the role.', + ), + ), + 'primary key' => array('uid', 'rid'), + 'indexes' => array( + 'rid' => array('rid'), + ), + 'foreign keys' => array( + 'user' => array( + 'table' => 'users', + 'columns' => array('uid' => 'uid'), + ), + ), + ); + + return $schema; + } + } diff --git a/core/modules/user/user.info.yml b/core/modules/user/user.info.yml index 45a421a..dbdb520 100644 --- a/core/modules/user/user.info.yml +++ b/core/modules/user/user.info.yml @@ -6,3 +6,5 @@ version: VERSION core: 8.x required: true configure: user.admin_index +dependencies: + - entity diff --git a/core/modules/user/user.install b/core/modules/user/user.install index c21e295..be4ad62 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -5,243 +5,38 @@ * Install, update and uninstall functions for the user module. */ +use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Language\Language; use Drupal\field\Field; /** - * Implements hook_schema(). + * Implements hook_entity_schema_installed(). */ -function user_schema() { - // The table name here is plural, despite Drupal table naming standards, - // because "user" is a reserved word in many databases. - $schema['users'] = array( - 'description' => 'Stores user data.', - 'fields' => array( - 'uid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'description' => 'Primary Key: Unique user ID.', - 'default' => 0, - ), - 'uuid' => array( - 'description' => 'Unique Key: Universally unique identifier for this entity.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => FALSE, - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 60, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Unique user name.', - ), - 'langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => "The {language}.langcode of the user's profile.", - ), - 'pass' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => "User's password (hashed).", - ), - 'mail' => array( - 'type' => 'varchar', - 'length' => 254, - 'not null' => FALSE, - 'default' => '', - 'description' => "User's e-mail address.", - ), - 'signature' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => "User's signature.", - ), - 'signature_format' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => FALSE, - 'description' => 'The filter format ID of the signature.', - ), - 'created' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Timestamp for when user was created.', - ), - 'access' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Timestamp for previous time user accessed the site.', - ), - 'login' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => "Timestamp for user's last login.", - ), - 'status' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'size' => 'tiny', - 'description' => 'Whether the user is active(1) or blocked(0).', - ), - 'timezone' => array( - 'type' => 'varchar', - 'length' => 32, - 'not null' => FALSE, - 'description' => "User's time zone.", - ), - 'preferred_langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The {language}.langcode that the user prefers for receiving emails and viewing the site.', - ), - 'preferred_admin_langcode' => array( - 'type' => 'varchar', - 'length' => 12, - 'not null' => TRUE, - 'default' => '', - 'description' => 'The {language}.langcode that the user prefers for viewing administration pages.', - ), - 'init' => array( - 'type' => 'varchar', - 'length' => 254, - 'not null' => FALSE, - 'default' => '', - 'description' => 'E-mail address used for initial account creation.', - ), - ), - 'indexes' => array( - 'access' => array('access'), - 'created' => array('created'), - 'mail' => array('mail'), - ), - 'unique keys' => array( - 'uuid' => array('uuid'), - 'name' => array('name'), - ), - 'primary key' => array('uid'), - ); - - $schema['users_data'] = array( - 'description' => 'Stores module data as key/value pairs per user.', - 'fields' => array( - 'uid' => array( - 'description' => 'Primary key: {users}.uid for user.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'module' => array( - 'description' => 'The name of the module declaring the variable.', - 'type' => 'varchar', - 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, - 'not null' => TRUE, - 'default' => '', - ), - 'name' => array( - 'description' => 'The identifier of the data.', - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - ), - 'value' => array( - 'description' => 'The value.', - 'type' => 'blob', - 'not null' => FALSE, - 'size' => 'big', - ), - 'serialized' => array( - 'description' => 'Whether value is serialized.', - 'type' => 'int', - 'size' => 'tiny', - 'unsigned' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('uid', 'module', 'name'), - 'indexes' => array( - 'module' => array('module'), - 'name' => array('name'), - ), - 'foreign keys' => array( - 'uid' => array('users' => 'uid'), - ), - ); - - $schema['users_roles'] = array( - 'description' => 'Maps users to roles.', - 'fields' => array( - 'uid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - 'description' => 'Primary Key: {users}.uid for user.', - ), - 'rid' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'description' => 'Primary Key: ID for the role.', - ), - ), - 'primary key' => array('uid', 'rid'), - 'indexes' => array( - 'rid' => array('rid'), - ), - 'foreign keys' => array( - 'user' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ), - ); - - return $schema; -} - -/** - * Implements hook_install(). - */ -function user_install() { - // Insert a row for the anonymous user. - db_insert('users') - ->fields(array( - 'uid' => 0, - 'uuid' => \Drupal::service('uuid')->generate(), - 'name' => '', - 'mail' => '', - 'langcode' => language_default()->id, - )) - ->execute(); - - // We need some placeholders here as name and mail are uniques. - // This will be changed by the settings form in the installer. - db_insert('users') - ->fields(array( - 'uid' => 1, - 'uuid' => \Drupal::service('uuid')->generate(), - 'name' => 'placeholder-for-uid-1', - 'mail' => 'placeholder-for-uid-1', - 'created' => REQUEST_TIME, - 'status' => 1, - 'langcode' => language_default()->id, - )) - ->execute(); +function user_entity_schema_installed($installed) { + if (isset($installed['user']) && $installed['user'] instanceof ContentEntityDatabaseStorage) { + // Insert a row for the anonymous user. + db_insert('users') + ->fields(array( + 'uid' => 0, + 'uuid' => \Drupal::service('uuid')->generate(), + 'name' => '', + 'mail' => '', + 'langcode' => language_default()->id, + )) + ->execute(); + + // We need some placeholders here as name and mail are uniques. + // This will be changed by the settings form in the installer. + db_insert('users') + ->fields(array( + 'uid' => 1, + 'uuid' => \Drupal::service('uuid')->generate(), + 'name' => 'placeholder-for-uid-1', + 'mail' => 'placeholder-for-uid-1', + 'created' => REQUEST_TIME, + 'status' => 1, + 'langcode' => language_default()->id, + )) + ->execute(); + } }