diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index 746be1f..9aeffb5 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -35,36 +35,6 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements SqlStorageInterface, ContentEntitySchemaHandlerInterface { /** - * The base table layout: no revision or multilingual support for base fields. - * - * @var int - */ - const LAYOUT_BASE = 0; - - /** - * The revision table layout: provides revision support for base fields. - * - * @var int - */ - const LAYOUT_REVISION = 1; - - /** - * The multilingual table layout: provides multilingual support for base - * fields. - * - * @var int - */ - const LAYOUT_MULTILINGUAL = 2; - - /** - * The multilingual revision table layout: provides revision and multilingual - * support for base fields. - * - * @var int - */ - const LAYOUT_MULTILINGUAL_REVISION = 3; - - /** * The base field definitions for this entity type. * * @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] @@ -72,18 +42,6 @@ class ContentEntityDatabaseStorage extends ContentEntityStorageBase implements S protected $storageDefinitions; /** - * The table layout associated to the entity type. - * - * @see static::LAYOUT_BASE - * @see static::LAYOUT_REVISION - * @see static::LAYOUT_MULTILINGUAL - * @see static::LAYOUT_MULTILINGUAL_REVISION - * - * @var int - */ - protected $tableLayout; - - /** * A mapping of schema fields that will be stored per entity table. * * @var \Drupal\Core\Entity\Sql\DefaultTableMapping @@ -186,6 +144,7 @@ public function __construct(EntityTypeInterface $entity_type, Connection $databa $this->database = $database; $this->fieldInfo = $field_info; $this->entityManager = $entity_manager; + // @todo Remove the check for FieldDefinitionInterface::isMultiple() when // multiple-value base fields are supported in // https://drupal.org/node/2248977. @@ -193,13 +152,6 @@ public function __construct(EntityTypeInterface $entity_type, Connection $databa return !$definition->isComputed() && !$definition->hasCustomStorage() && !$definition->isMultiple(); }); - $this->initTableLayout(); - } - - /** - * Initializes table and key names based on the current layout type. - */ - protected function initTableLayout() { $this->idKey = $this->entityType->getKey('id') ?: 'id'; // The uuid and bundle keys are optional. @@ -210,56 +162,21 @@ protected function initTableLayout() { // https://drupal.org/node/2232465 $this->baseTable = $this->entityType->getBaseTable() ?: $this->entityTypeId; - // Retrieve the current table layout type based on the entity type - // definition. - $layout_type = $this->getTableLayout(); - - if ($layout_type & static::LAYOUT_REVISION) { + if ($this->entityType->hasKey('revision')) { $this->revisionKey = $this->entityType->getKey('revision') ?: 'revision_id'; $this->revisionTable = $this->entityType->getRevisionTable() ?: $this->entityTypeId . '_revision'; } - - if ($layout_type & static::LAYOUT_MULTILINGUAL) { + if ($this->entityType->isTranslatable()) { $this->dataTable = $this->entityType->getDataTable() ?: $this->entityTypeId . '_field_data'; $this->langcodeKey = $this->entityType->getKey('langcode') ?: 'langcode'; $this->defaultLangcodeKey = $this->entityType->getKey('default_langcode') ?: 'default_langcode'; } - - if ($layout_type == static::LAYOUT_MULTILINGUAL_REVISION) { + if ($this->entityType->hasKey('revision') && $this->entityType->isTranslatable()) { $this->revisionDataTable = $this->entityType->getRevisionDataTable() ?: $this->entityTypeId . '_field_revision'; } } /** - * Returns the current table layout type. - * - * @return int - * An integer value identifying the current table layout. - * - * @see static::LAYOUT_BASE - * @see static::LAYOUT_REVISION - * @see static::LAYOUT_MULTILINGUAL - * @see static::LAYOUT_MULTILINGUAL_REVISION - */ - public function getTableLayout() { - if (!isset($this->tableLayout)) { - $this->tableLayout = static::LAYOUT_BASE; - if ($this->entityType->hasKey('revision')) { - $this->tableLayout |= static::LAYOUT_REVISION; - } - // @todo Remove the data table check once all entity types are using - // entity query and we have a views data controller. See: - // - https://drupal.org/node/2068325 - // - https://drupal.org/node/1740492 - $data_table = $this->entityType->getDataTable(); - if ($data_table && $this->entityType->isTranslatable()) { - $this->tableLayout |= static::LAYOUT_MULTILINGUAL; - } - } - return $this->tableLayout; - } - - /** * Returns the base table name. * * @return string @@ -342,70 +259,68 @@ public function getTableMapping() { // https://drupal.org/node/2248991. $revision_metadata_fields = array_intersect(array('revision_timestamp', 'revision_uid', 'log'), $all_fields); - switch ($this->getTableLayout()) { + if (!$this->entityType->hasKey('revision') && !$this->entityType->isTranslatable()) { // The base layout stores all the base field values in the base table. - case static::LAYOUT_BASE: - $this->tableMapping->addFieldColumns($this->baseTable, $all_fields); - break; - + $this->tableMapping->addFieldColumns($this->baseTable, $all_fields); + } + elseif ($this->entityType->hasKey('revision') && !$this->entityType->isTranslatable()) { // The revisionable layout stores all the base field values in the base // table, except for revision metadata fields. Revisionable fields // denormalized in the base table but also stored in the revision table // together with the entity ID and the revision ID as identifiers. - case static::LAYOUT_REVISION: - $this->tableMapping->addFieldColumns($this->baseTable, array_diff($all_fields, $revision_metadata_fields)); - - $revision_key_fields = array($this->idKey, $this->revisionKey); - $this->tableMapping->addFieldColumns($this->revisionTable, array_merge($revision_key_fields, $revisionable_fields)); - break; + $this->tableMapping->addFieldColumns($this->baseTable, array_diff($all_fields, $revision_metadata_fields)); + $revision_key_fields = array($this->idKey, $this->revisionKey); + $this->tableMapping->addFieldColumns($this->revisionTable, array_merge($revision_key_fields, $revisionable_fields)); + } + elseif (!$this->entityType->hasKey('revision') && $this->entityType->isTranslatable()) { // Multilingual layouts store key field values in the base table. The // other base field values are stored in the data table, no matter // whether they are translatable or not. The data table holds also a // denormalized copy of the bundle field value to allow for more // performant queries. This means that only the UUID is not stored on // the data table. - case static::LAYOUT_MULTILINGUAL: - $this->tableMapping - ->addFieldColumns($this->baseTable, $key_fields) - ->addFieldColumns($this->dataTable, array_diff($all_fields, array($this->uuidKey))) - // Add the denormalized 'default_langcode' field to the mapping. Its - // value is identical to the query expression - // "base_table.langcode = data_table.langcode" - ->addExtraColumns($this->dataTable, array('default_langcode')); - break; - + $this->tableMapping + ->addFieldColumns($this->baseTable, $key_fields) + ->addFieldColumns($this->dataTable, array_diff($all_fields, array($this->uuidKey))) + // Add the denormalized 'default_langcode' field to the mapping. Its + // value is identical to the query expression + // "base_table.langcode = data_table.langcode" + ->addExtraColumns($this->dataTable, array('default_langcode')); + } + elseif ($this->entityType->hasKey('revision') && $this->entityType->isTranslatable()) { // The revisionable multilingual layout stores key field values in the // base table, except for language, which is stored in the revision // table along with revision metadata. The revision data table holds - // data field values for all the reivisionable fields and the - case static::LAYOUT_MULTILINGUAL_REVISION: - $this->tableMapping->addFieldColumns($this->baseTable, array_diff($key_fields, array($this->langcodeKey))); - - // Like in the multilingual, non-revisionable case the UUID is not - // in the data table. Additionally, do not store revision metadata - // fields in the data table. - $data_fields = array_diff($all_fields, array($this->uuidKey), $revision_metadata_fields); - $this->tableMapping - ->addFieldColumns($this->dataTable, $data_fields) - // Add the denormalized 'default_langcode' field to the mapping. Its - // value is identical to the query expression - // "base_langcode = data_table.langcode" where "base_langcode" is - // the language code of the default revision. - ->addExtraColumns($this->dataTable, array('default_langcode')); - - $revision_base_fields = array_merge(array($this->idKey, $this->revisionKey, $this->langcodeKey), $revision_metadata_fields); - $this->tableMapping->addFieldColumns($this->revisionTable, $revision_base_fields); - - $revision_data_key_fields = array($this->idKey, $this->revisionKey, $this->langcodeKey); - $revision_data_fields = array_diff($revisionable_fields, $revision_metadata_fields); - $this->tableMapping - ->addFieldColumns($this->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields)) - // Add the denormalized 'default_langcode' field to the mapping. Its - // value is identical to the query expression - // "revision_table.langcode = data_table.langcode". - ->addExtraColumns($this->revisionDataTable, array('default_langcode')); - break; + // data field values for all the revisionable fields and the data table + // holds the data field values for all non-revisionable fields. The data + // field values of revisionable fields are denormalized in the data + // table, as well. + $this->tableMapping->addFieldColumns($this->baseTable, array_diff($key_fields, array($this->langcodeKey))); + + // Like in the multilingual, non-revisionable case the UUID is not + // in the data table. Additionally, do not store revision metadata + // fields in the data table. + $data_fields = array_diff($all_fields, array($this->uuidKey), $revision_metadata_fields); + $this->tableMapping + ->addFieldColumns($this->dataTable, $data_fields) + // Add the denormalized 'default_langcode' field to the mapping. Its + // value is identical to the query expression + // "base_langcode = data_table.langcode" where "base_langcode" is + // the language code of the default revision. + ->addExtraColumns($this->dataTable, array('default_langcode')); + + $revision_base_fields = array_merge(array($this->idKey, $this->revisionKey, $this->langcodeKey), $revision_metadata_fields); + $this->tableMapping->addFieldColumns($this->revisionTable, $revision_base_fields); + + $revision_data_key_fields = array($this->idKey, $this->revisionKey, $this->langcodeKey); + $revision_data_fields = array_diff($revisionable_fields, $revision_metadata_fields); + $this->tableMapping + ->addFieldColumns($this->revisionDataTable, array_merge($revision_data_key_fields, $revision_data_fields)) + // Add the denormalized 'default_langcode' field to the mapping. Its + // value is identical to the query expression + // "revision_table.langcode = data_table.langcode". + ->addExtraColumns($this->revisionDataTable, array('default_langcode')); } } diff --git a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php b/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php index f9b007c..013c154 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php @@ -305,6 +305,7 @@ public function testGetSchemaBase($uuid_key) { 'default_langcode' => array( 'description' => 'Boolean indicating whether field values are in the default entity language.', 'type' => 'int', + 'size' => 'tiny', 'not null' => TRUE, 'default' => 1, ),