diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index 5969aae6aac881af31b038bc600b8725b26d7a51..2d452752efce706849a8c8c95fae389b04a37538 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -13,13 +13,11 @@ use Drupal\Core\Database\Database; use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException; use Drupal\Core\Entity\Query\QueryInterface; -use Drupal\Core\Entity\Schema\ContentEntitySchemaHandler; use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Core\Entity\Sql\SqlEntityStorageInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldStorageDefinitionInterface; use Drupal\Core\Language\LanguageInterface; -use Drupal\field\Entity\FieldStorageConfig; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -28,7 +26,7 @@ * This class can be used as-is by most content entity types. Entity types * requiring special handling can extend the class. * - * The class uses \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler + * The class uses \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema * internally in order to automatically generate the database schema based on * the defined base fields. Entity types can override * ContentEntityDatabaseStorage::getSchema() to customize the generated @@ -229,12 +227,13 @@ public function getSchema() { /** * Gets the schema handler for this entity storage. * - * @return \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler + * @return \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema * The schema handler. */ protected function schemaHandler() { if (!isset($this->schemaHandler)) { - $this->schemaHandler = new ContentEntitySchemaHandler($this->entityManager, $this->entityType, $this); + $schema_handler_class = $this->entityType->getHandlerClass('storage_schema') ?: 'Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema'; + $this->schemaHandler = new $schema_handler_class($this->entityManager, $this->entityType, $this); } return $this->schemaHandler; } @@ -1024,8 +1023,8 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_nam * @return bool * TRUE if the the column is serial, FALSE otherwise. * - * @see \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler::processBaseTable() - * @see \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler::processRevisionTable() + * @see \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema::processBaseTable() + * @see \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema::processRevisionTable() */ protected function isColumnSerial($table_name, $schema_name) { $result = FALSE; diff --git a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php b/core/lib/Drupal/Core/Entity/Schema/SqlContentEntityStorageSchema.php similarity index 94% rename from core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php rename to core/lib/Drupal/Core/Entity/Schema/SqlContentEntityStorageSchema.php index 4f30d47f7ab72128b79cd41416e31a58abea01b6..830d2ab66b09a154a9e658eccf9dd2cea8577cb2 100644 --- a/core/lib/Drupal/Core/Entity/Schema/ContentEntitySchemaHandler.php +++ b/core/lib/Drupal/Core/Entity/Schema/SqlContentEntityStorageSchema.php @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler. + * Contains \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema. */ namespace Drupal\Core\Entity\Schema; @@ -14,7 +14,7 @@ /** * Defines a schema handler that supports revisionable, translatable entities. */ -class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface { +class SqlContentEntityStorageSchema implements EntitySchemaHandlerInterface { /** * The entity type this schema builder is responsible for. @@ -45,7 +45,7 @@ class ContentEntitySchemaHandler implements EntitySchemaHandlerInterface { protected $schema; /** - * Constructs a ContentEntitySchemaHandler. + * Constructs a SqlContentEntityStorageSchema. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. @@ -64,11 +64,28 @@ public function __construct(EntityManagerInterface $entity_manager, ContentEntit * {@inheritdoc} */ public function getSchema() { - // Prepare basic information about the entity type. - $tables = $this->getTables(); + return $this->getEntitySchema($this->entityType); + } + + /** + * Returns the entity schema for the specified entity type. + * + * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type + * The entity type definition. + * @param bool $reset + * (optional) If set to TRUE static cache will be ignored and a new schema + * array generation will be performed. Defaults to FALSE. + * + * @return array + * A Schema API array describing the entity schema, excluding dedicated + * field tables. + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $entity_type_id = $entity_type->id(); - if (!isset($this->schema[$this->entityType->id()])) { + if (!isset($this->schema[$entity_type_id]) || $reset) { // Initialize the table schema. + $tables = $this->getTables(); $schema[$tables['base_table']] = $this->initializeBaseTable(); if (isset($tables['revision_table'])) { $schema[$tables['revision_table']] = $this->initializeRevisionTable(); @@ -108,10 +125,10 @@ public function getSchema() { $this->processRevisionDataTable($schema[$tables['revision_data_table']]); } - $this->schema[$this->entityType->id()] = $schema; + $this->schema[$entity_type_id] = $schema; } - return $this->schema[$this->entityType->id()]; + return $this->schema[$entity_type_id]; } /** diff --git a/core/modules/aggregator/src/Entity/Feed.php b/core/modules/aggregator/src/Entity/Feed.php index 368e8f11cf9c72445417dbfd9a66be75b63c2896..a70647050a5201e25c7631005b9fbe83159fdebe 100644 --- a/core/modules/aggregator/src/Entity/Feed.php +++ b/core/modules/aggregator/src/Entity/Feed.php @@ -22,6 +22,7 @@ * label = @Translation("Aggregator feed"), * handlers = { * "storage" = "Drupal\aggregator\FeedStorage", + * "storage_schema" = "Drupal\aggregator\FeedStorageSchema", * "view_builder" = "Drupal\aggregator\FeedViewBuilder", * "access" = "Drupal\aggregator\FeedAccessControlHandler", * "views_data" = "Drupal\aggregator\AggregatorFeedViewsData", diff --git a/core/modules/aggregator/src/Entity/Item.php b/core/modules/aggregator/src/Entity/Item.php index 445f42e2e1bf6f3235a729021ce2c4093f676b3a..3f6cba0aa618b752878ed80899c9e81bcf07a0e6 100644 --- a/core/modules/aggregator/src/Entity/Item.php +++ b/core/modules/aggregator/src/Entity/Item.php @@ -23,6 +23,7 @@ * label = @Translation("Aggregator feed item"), * handlers = { * "storage" = "Drupal\aggregator\ItemStorage", + * "storage_schema" = "Drupal\aggregator\ItemStorageSchema", * "view_builder" = "Drupal\aggregator\ItemViewBuilder", * "access" = "Drupal\aggregator\FeedAccessControlHandler", * "views_data" = "Drupal\aggregator\AggregatorItemViewsData" diff --git a/core/modules/aggregator/src/FeedStorage.php b/core/modules/aggregator/src/FeedStorage.php index da784f5c4dc3253d4b8d80d780f1a9a5f2b285c7..10141fa891456dda5bd3a1c668bd036c8e7f50f1 100644 --- a/core/modules/aggregator/src/FeedStorage.php +++ b/core/modules/aggregator/src/FeedStorage.php @@ -7,7 +7,6 @@ namespace Drupal\aggregator; -use Drupal\aggregator\FeedInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; /** @@ -18,29 +17,6 @@ */ class FeedStorage extends ContentEntityDatabaseStorage implements FeedStorageInterface { - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['aggregator_feed']['fields']['url']['not null'] = TRUE; - $schema['aggregator_feed']['fields']['queued']['not null'] = TRUE; - $schema['aggregator_feed']['fields']['title']['not null'] = TRUE; - - $schema['aggregator_feed']['indexes'] += array( - 'aggregator_feed__url' => array(array('url', 255)), - 'aggregator_feed__queued' => array('queued'), - ); - $schema['aggregator_feed']['unique keys'] += array( - 'aggregator_feed__title' => array('title'), - ); - - return $schema; - } - /** * {@inheritdoc} */ diff --git a/core/modules/aggregator/src/FeedStorageSchema.php b/core/modules/aggregator/src/FeedStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..41cfcb1d435b35656ecda549af0fe71e0dd8c039 --- /dev/null +++ b/core/modules/aggregator/src/FeedStorageSchema.php @@ -0,0 +1,41 @@ +<?php + +/** + * @file + * Contains \Drupal\aggregator\FeedStorageSchema. + */ + +namespace Drupal\aggregator; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the feed schema handler. + */ +class FeedStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['aggregator_feed']['fields']['url']['not null'] = TRUE; + $schema['aggregator_feed']['fields']['queued']['not null'] = TRUE; + $schema['aggregator_feed']['fields']['title']['not null'] = TRUE; + + $schema['aggregator_feed']['indexes'] += array( + 'aggregator_feed__url' => array(array('url', 255)), + 'aggregator_feed__queued' => array('queued'), + ); + $schema['aggregator_feed']['unique keys'] += array( + 'aggregator_feed__title' => array('title'), + ); + + return $schema; + } + +} diff --git a/core/modules/aggregator/src/ItemStorage.php b/core/modules/aggregator/src/ItemStorage.php index f2b4aa68319693d6a6b82f4a2cee4c1201fc8cf7..ede7861a7f219881ddda7fe0b43af0f9e6b35005 100644 --- a/core/modules/aggregator/src/ItemStorage.php +++ b/core/modules/aggregator/src/ItemStorage.php @@ -7,9 +7,8 @@ namespace Drupal\aggregator; -use Drupal\aggregator\Entity\Item; -use Drupal\Core\Entity\Query\QueryInterface; use Drupal\Core\Entity\ContentEntityDatabaseStorage; +use Drupal\Core\Entity\Query\QueryInterface; /** * Controller class for aggregators items. @@ -19,29 +18,6 @@ */ class ItemStorage extends ContentEntityDatabaseStorage implements ItemStorageInterface { - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['aggregator_item']['fields']['timestamp']['not null'] = TRUE; - - $schema['aggregator_item']['indexes'] += array( - 'aggregator_item__timestamp' => array('timestamp'), - ); - $schema['aggregator_item']['foreign keys'] += array( - 'aggregator_item__aggregator_feed' => array( - 'table' => 'aggregator_feed', - 'columns' => array('fid' => 'fid'), - ), - ); - - return $schema; - } - /** * {@inheritdoc} */ diff --git a/core/modules/aggregator/src/ItemStorageSchema.php b/core/modules/aggregator/src/ItemStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..3b52c953f1de898b104f32d0cdcaf383d087e3d0 --- /dev/null +++ b/core/modules/aggregator/src/ItemStorageSchema.php @@ -0,0 +1,41 @@ +<?php + +/** + * @file + * Contains \Drupal\aggregator\ItemStorageSchema. + */ + +namespace Drupal\aggregator; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the item schema handler. + */ +class ItemStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['aggregator_item']['fields']['timestamp']['not null'] = TRUE; + + $schema['aggregator_item']['indexes'] += array( + 'aggregator_item__timestamp' => array('timestamp'), + ); + $schema['aggregator_item']['foreign keys'] += array( + 'aggregator_item__aggregator_feed' => array( + 'table' => 'aggregator_feed', + 'columns' => array('fid' => 'fid'), + ), + ); + + return $schema; + } + +} diff --git a/core/modules/block_content/src/BlockContentStorage.php b/core/modules/block_content/src/BlockContentStorage.php deleted file mode 100644 index b98a86112349020f455d32afd1fa5aefcad109e7..0000000000000000000000000000000000000000 --- a/core/modules/block_content/src/BlockContentStorage.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\block_content\BlockContentStorage. - */ - -namespace Drupal\block_content; - -use Drupal\Core\Entity\ContentEntityDatabaseStorage; - -/** - * Provides storage for the 'block_content' entity type. - */ -class BlockContentStorage extends ContentEntityDatabaseStorage { - - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['block_content_field_data']['fields']['info']['not null'] = TRUE; - - $schema['block_content_field_data']['unique keys'] += array( - 'block_content__info' => array('info', 'langcode'), - ); - - return $schema; - } - -} diff --git a/core/modules/block_content/src/BlockContentStorageSchema.php b/core/modules/block_content/src/BlockContentStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..533e5c867405fcc5a60f7ef41836e36a3d44c940 --- /dev/null +++ b/core/modules/block_content/src/BlockContentStorageSchema.php @@ -0,0 +1,35 @@ +<?php + +/** + * @file + * Contains \Drupal\block_content\BlockContentStorageSchema. + */ + +namespace Drupal\block_content; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the block content schema handler. + */ +class BlockContentStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['block_content_field_data']['fields']['info']['not null'] = TRUE; + + $schema['block_content_field_data']['unique keys'] += array( + 'block_content__info' => array('info', 'langcode'), + ); + + return $schema; + } + +} diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php index 310edf3501df38f7f53a7b980efcd8e0a845371a..5e5893d325191520f40e6fd9aba40f9903afd11e 100644 --- a/core/modules/block_content/src/Entity/BlockContent.php +++ b/core/modules/block_content/src/Entity/BlockContent.php @@ -21,7 +21,8 @@ * label = @Translation("Custom Block"), * bundle_label = @Translation("Custom Block type"), * handlers = { - * "storage" = "Drupal\block_content\BlockContentStorage", + * "storage" = "Drupal\Core\Entity\ContentEntityDatabaseStorage", + * "storage_schema" = "Drupal\block_content\BlockContentStorageSchema", * "access" = "Drupal\block_content\BlockContentAccessControlHandler", * "list_builder" = "Drupal\block_content\BlockContentListBuilder", * "view_builder" = "Drupal\block_content\BlockContentViewBuilder", diff --git a/core/modules/comment/src/CommentStorage.php b/core/modules/comment/src/CommentStorage.php index 9639d597b731a43240f97fddde33aa0663de26a6..843c79fe4fce4efb281a6550ea7e912ba54a336b 100644 --- a/core/modules/comment/src/CommentStorage.php +++ b/core/modules/comment/src/CommentStorage.php @@ -9,11 +9,11 @@ use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Database\Connection; -use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -318,48 +318,6 @@ public function loadThread(EntityInterface $entity, $field_name, $mode, $comment return $comments; } - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['comment_field_data']['fields']['created']['not null'] = TRUE; - $schema['comment_field_data']['fields']['thread']['not null'] = TRUE; - - unset($schema['comment_field_data']['indexes']['comment_field__pid__target_id']); - unset($schema['comment_field_data']['indexes']['comment_field__entity_id__target_id']); - $schema['comment_field_data']['indexes'] += array( - 'comment__status_pid' => array('pid', 'status'), - 'comment__num_new' => array( - 'entity_id', - 'entity_type', - 'comment_type', - 'status', - 'created', - 'cid', - 'thread', - ), - 'comment__entity_langcode' => array( - 'entity_id', - 'entity_type', - 'comment_type', - 'default_langcode', - ), - 'comment__created' => array('created'), - ); - $schema['comment_field_data']['foreign keys'] += array( - 'comment__author' => array( - 'table' => 'users', - 'columns' => array('uid' => 'uid'), - ), - ); - - return $schema; - } - /** * {@inheritdoc} */ diff --git a/core/modules/comment/src/CommentStorageSchema.php b/core/modules/comment/src/CommentStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..722f5760018bde459a4bbb1d0fd1fb1c33386b62 --- /dev/null +++ b/core/modules/comment/src/CommentStorageSchema.php @@ -0,0 +1,60 @@ +<?php + +/** + * @file + * Contains \Drupal\comment\CommentStorageSchema. + */ + +namespace Drupal\comment; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the comment schema handler. + */ +class CommentStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['comment_field_data']['fields']['created']['not null'] = TRUE; + $schema['comment_field_data']['fields']['thread']['not null'] = TRUE; + + unset($schema['comment_field_data']['indexes']['comment_field__pid__target_id']); + unset($schema['comment_field_data']['indexes']['comment_field__entity_id__target_id']); + $schema['comment_field_data']['indexes'] += array( + 'comment__status_pid' => array('pid', 'status'), + 'comment__num_new' => array( + 'entity_id', + 'entity_type', + 'comment_type', + 'status', + 'created', + 'cid', + 'thread', + ), + 'comment__entity_langcode' => array( + 'entity_id', + 'entity_type', + 'comment_type', + 'default_langcode', + ), + 'comment__created' => array('created'), + ); + $schema['comment_field_data']['foreign keys'] += array( + 'comment__author' => array( + 'table' => 'users', + 'columns' => array('uid' => 'uid'), + ), + ); + + return $schema; + } + +} diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 43fc3f270d1811774cf71a9800149dfa05876602..9823f9f9d9a50c94b24ff92b25bce6c21210cae2 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -25,6 +25,7 @@ * bundle_label = @Translation("Content type"), * handlers = { * "storage" = "Drupal\comment\CommentStorage", + * "storage_schema" = "Drupal\comment\CommentStorageSchema", * "access" = "Drupal\comment\CommentAccessControlHandler", * "view_builder" = "Drupal\comment\CommentViewBuilder", * "views_data" = "Drupal\comment\CommentViewsData", diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php index 28d1ab653897b7c1e90f389872f8d356a94eadde..b21a18297259ee0a5c4737ea182a9d17a372d46c 100644 --- a/core/modules/file/src/Entity/File.php +++ b/core/modules/file/src/Entity/File.php @@ -23,6 +23,7 @@ * label = @Translation("File"), * handlers = { * "storage" = "Drupal\file\FileStorage", + * "storage_schema" = "Drupal\file\FileStorageSchema", * "access" = "Drupal\file\FileAccessControlHandler", * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", * "views_data" = "Drupal\file\FileViewsData", diff --git a/core/modules/file/src/FileStorage.php b/core/modules/file/src/FileStorage.php index 93dae425a690ea6780f04032fae4db0470f5082a..10ccd42a53d2cddaa9cc5f5411bf27a08a441081 100644 --- a/core/modules/file/src/FileStorage.php +++ b/core/modules/file/src/FileStorage.php @@ -27,29 +27,4 @@ public function spaceUsed($uid = NULL, $status = FILE_STATUS_PERMANENT) { return $query->execute()->fetchField(); } - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['file_managed']['fields']['status']['not null'] = TRUE; - $schema['file_managed']['fields']['changed']['not null'] = TRUE; - $schema['file_managed']['fields']['uri']['not null'] = TRUE; - - // @todo There should be a 'binary' field type or setting. - $schema['file_managed']['fields']['uri']['binary'] = TRUE; - $schema['file_managed']['indexes'] += array( - 'file__status' => array('status'), - 'file__changed' => array('changed'), - ); - $schema['file_managed']['unique keys'] += array( - 'file__uri' => array('uri'), - ); - - return $schema; - } - } diff --git a/core/modules/file/src/FileStorageSchema.php b/core/modules/file/src/FileStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..3e383414a6b4921a0e575bf27564ffc5a2afabec --- /dev/null +++ b/core/modules/file/src/FileStorageSchema.php @@ -0,0 +1,43 @@ +<?php + +/** + * @file + * Contains \Drupal\file\FileStorageSchema. + */ + +namespace Drupal\file; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the file schema handler. + */ +class FileStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['file_managed']['fields']['status']['not null'] = TRUE; + $schema['file_managed']['fields']['changed']['not null'] = TRUE; + $schema['file_managed']['fields']['uri']['not null'] = TRUE; + + // @todo There should be a 'binary' field type or setting. + $schema['file_managed']['fields']['uri']['binary'] = TRUE; + $schema['file_managed']['indexes'] += array( + 'file__status' => array('status'), + 'file__changed' => array('changed'), + ); + $schema['file_managed']['unique keys'] += array( + 'file__uri' => array('uri'), + ); + + return $schema; + } + +} diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php index b96e9d2e2252a434992e2b2fe22878b2303ae9ca..e4bbc04d0f03aa328579a3de5994211fff32e1ce 100644 --- a/core/modules/node/src/Entity/Node.php +++ b/core/modules/node/src/Entity/Node.php @@ -25,6 +25,7 @@ * bundle_label = @Translation("Content type"), * handlers = { * "storage" = "Drupal\node\NodeStorage", + * "storage_schema" = "Drupal\node\NodeStorageSchema", * "view_builder" = "Drupal\node\NodeViewBuilder", * "access" = "Drupal\node\NodeAccessControlHandler", * "views_data" = "Drupal\node\NodeViewsData", diff --git a/core/modules/node/src/NodeStorage.php b/core/modules/node/src/NodeStorage.php index 86cf982621838c1a07cf3daf0ed58502ea4ae565..669f20048306af7fd0341d7124aecac5fffbcb60 100644 --- a/core/modules/node/src/NodeStorage.php +++ b/core/modules/node/src/NodeStorage.php @@ -59,50 +59,4 @@ public function clearRevisionsLanguage($language) { ->execute(); } - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['node_field_data']['fields']['changed']['not null'] = TRUE; - $schema['node_field_data']['fields']['created']['not null'] = TRUE; - $schema['node_field_data']['fields']['default_langcode']['not null'] = TRUE; - $schema['node_field_data']['fields']['promote']['not null'] = TRUE; - $schema['node_field_data']['fields']['status']['not null'] = TRUE; - $schema['node_field_data']['fields']['sticky']['not null'] = TRUE; - $schema['node_field_data']['fields']['title']['not null'] = TRUE; - $schema['node_field_revision']['fields']['default_langcode']['not null'] = TRUE; - - // @todo Revisit index definitions in https://drupal.org/node/2015277. - $schema['node_revision']['indexes'] += array( - 'node__langcode' => array('langcode'), - ); - $schema['node_revision']['foreign keys'] += array( - 'node__revision_author' => array( - 'table' => 'users', - 'columns' => array('revision_uid' => 'uid'), - ), - ); - - $schema['node_field_data']['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)), - ); - - $schema['node_field_revision']['indexes'] += array( - 'node__default_langcode' => array('default_langcode'), - 'node__langcode' => array('langcode'), - ); - - return $schema; - } - } diff --git a/core/modules/node/src/NodeStorageSchema.php b/core/modules/node/src/NodeStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..b7aa91f3a591c4ffdf4b3ebb6e22b8bf15e09c05 --- /dev/null +++ b/core/modules/node/src/NodeStorageSchema.php @@ -0,0 +1,64 @@ +<?php + +/** + * @file + * Contains \Drupal\node\NodeStorageSchema. + */ + +namespace Drupal\node; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the node schema handler. + */ +class NodeStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['node_field_data']['fields']['changed']['not null'] = TRUE; + $schema['node_field_data']['fields']['created']['not null'] = TRUE; + $schema['node_field_data']['fields']['default_langcode']['not null'] = TRUE; + $schema['node_field_data']['fields']['promote']['not null'] = TRUE; + $schema['node_field_data']['fields']['status']['not null'] = TRUE; + $schema['node_field_data']['fields']['sticky']['not null'] = TRUE; + $schema['node_field_data']['fields']['title']['not null'] = TRUE; + $schema['node_field_revision']['fields']['default_langcode']['not null'] = TRUE; + + // @todo Revisit index definitions in https://drupal.org/node/2015277. + $schema['node_revision']['indexes'] += array( + 'node__langcode' => array('langcode'), + ); + $schema['node_revision']['foreign keys'] += array( + 'node__revision_author' => array( + 'table' => 'users', + 'columns' => array('revision_uid' => 'uid'), + ), + ); + + $schema['node_field_data']['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)), + ); + + $schema['node_field_revision']['indexes'] += array( + 'node__default_langcode' => array('default_langcode'), + 'node__langcode' => array('langcode'), + ); + + return $schema; + } + +} diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php index 0f8eaef1f47a097a7c9ad3c9c4f0e0f00e79787c..dbb93f141f07a4b4fe0d1f465641bd56ced4f38e 100644 --- a/core/modules/taxonomy/src/Entity/Term.php +++ b/core/modules/taxonomy/src/Entity/Term.php @@ -22,6 +22,7 @@ * bundle_label = @Translation("Vocabulary"), * handlers = { * "storage" = "Drupal\taxonomy\TermStorage", + * "storage_schema" = "Drupal\taxonomy\TermStorageSchema", * "view_builder" = "Drupal\taxonomy\TermViewBuilder", * "access" = "Drupal\taxonomy\TermAccessControlHandler", * "views_data" = "Drupal\taxonomy\TermViewsData", diff --git a/core/modules/taxonomy/src/TermStorage.php b/core/modules/taxonomy/src/TermStorage.php index 345921c2bfccf93505743c62777ce6eb9d8cf1be..b746a2d71c9100d66c83ad511e67c5db71bbf6fc 100644 --- a/core/modules/taxonomy/src/TermStorage.php +++ b/core/modules/taxonomy/src/TermStorage.php @@ -154,105 +154,6 @@ public function resetWeights($vid) { ->execute(); } - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['taxonomy_term_field_data']['fields']['weight']['not null'] = TRUE; - $schema['taxonomy_term_field_data']['fields']['name']['not null'] = TRUE; - - unset($schema['taxonomy_term_field_data']['indexes']['taxonomy_term_field__vid__target_id']); - unset($schema['taxonomy_term_field_data']['indexes']['taxonomy_term_field__description__format']); - $schema['taxonomy_term_field_data']['indexes'] += array( - 'taxonomy_term__tree' => array('vid', 'weight', 'name'), - 'taxonomy_term__vid_name' => array('vid', 'name'), - 'taxonomy_term__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, - ), - ), - 'primary key' => array('nid', 'tid'), - 'indexes' => array( - 'term_node' => array('tid', 'sticky', 'created'), - ), - 'foreign keys' => array( - 'tracked_node' => array( - 'table' => 'node', - 'columns' => array('nid' => 'nid'), - ), - 'term' => array( - 'table' => 'taxonomy_term_data', - 'columns' => array('tid' => 'tid'), - ), - ), - ); - - return $schema; - } - /** * {@inheritdoc} */ diff --git a/core/modules/taxonomy/src/TermStorageSchema.php b/core/modules/taxonomy/src/TermStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..349c87fec9290ac21090fcce79dcd02452b5aa9f --- /dev/null +++ b/core/modules/taxonomy/src/TermStorageSchema.php @@ -0,0 +1,119 @@ +<?php + +/** + * @file + * Contains \Drupal\taxonomy\TermStorageSchema. + */ + +namespace Drupal\taxonomy; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the term schema handler. + */ +class TermStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset = FALSE); + + if (isset($schema['taxonomy_term_field_data'])) { + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['taxonomy_term_field_data']['fields']['weight']['not null'] = TRUE; + $schema['taxonomy_term_field_data']['fields']['name']['not null'] = TRUE; + + unset($schema['taxonomy_term_field_data']['indexes']['taxonomy_term_field__vid__target_id']); + unset($schema['taxonomy_term_field_data']['indexes']['taxonomy_term_field__description__format']); + $schema['taxonomy_term_field_data']['indexes'] += array( + 'taxonomy_term__tree' => array('vid', 'weight', 'name'), + 'taxonomy_term__vid_name' => array('vid', 'name'), + 'taxonomy_term__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, + ), + ), + 'primary key' => array('nid', 'tid'), + 'indexes' => array( + 'term_node' => array('tid', 'sticky', 'created'), + ), + '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/src/Entity/User.php b/core/modules/user/src/Entity/User.php index a8d51019ca8eaa7ce489fed5430d2f4f679da836..79bdd737640d02d08e2c5aa981850e4c73209129 100644 --- a/core/modules/user/src/Entity/User.php +++ b/core/modules/user/src/Entity/User.php @@ -25,6 +25,7 @@ * label = @Translation("User"), * handlers = { * "storage" = "Drupal\user\UserStorage", + * "storage_schema" = "Drupal\user\UserStorageSchema", * "access" = "Drupal\user\UserAccessControlHandler", * "list_builder" = "Drupal\user\UserListBuilder", * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", diff --git a/core/modules/user/src/UserStorage.php b/core/modules/user/src/UserStorage.php index 65209b8eddfec2bf60a967b6c767d190eddbc4eb..eeb8c3ba655313fa7471db6d656ede0034c639ac 100644 --- a/core/modules/user/src/UserStorage.php +++ b/core/modules/user/src/UserStorage.php @@ -7,9 +7,9 @@ namespace Drupal\user; -use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\ContentEntityDatabaseStorage; +use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; @@ -168,60 +168,4 @@ public function updateLastAccessTimestamp(AccountInterface $account, $timestamp) $this->resetCache(array($account->id())); } - /** - * {@inheritdoc} - */ - public function getSchema() { - $schema = parent::getSchema(); - - // The "users" table does not use serial identifiers. - $schema['users']['fields']['uid']['type'] = 'int'; - - // Marking the respective fields as NOT NULL makes the indexes more - // performant. - $schema['users_field_data']['fields']['access']['not null'] = TRUE; - $schema['users_field_data']['fields']['created']['not null'] = TRUE; - $schema['users_field_data']['fields']['name']['not null'] = TRUE; - - $schema['users_field_data']['indexes'] += array( - 'user__access' => array('access'), - 'user__created' => array('created'), - 'user__mail' => array('mail'), - ); - $schema['users_field_data']['unique keys'] += array( - 'user__name' => array('name', 'langcode'), - ); - - $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/src/UserStorageSchema.php b/core/modules/user/src/UserStorageSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..494e9f08b865fb369febeeab65a9416cfc0ea3a1 --- /dev/null +++ b/core/modules/user/src/UserStorageSchema.php @@ -0,0 +1,74 @@ +<?php + +/** + * @file + * Contains \Drupal\user\UserStorageSchema. + */ + +namespace Drupal\user; + +use Drupal\Core\Entity\ContentEntityTypeInterface; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; + +/** + * Defines the user schema handler. + */ +class UserStorageSchema extends SqlContentEntityStorageSchema { + + /** + * {@inheritdoc} + */ + protected function getEntitySchema(ContentEntityTypeInterface $entity_type, $reset = FALSE) { + $schema = parent::getEntitySchema($entity_type, $reset); + + // The "users" table does not use serial identifiers. + $schema['users']['fields']['uid']['type'] = 'int'; + + // Marking the respective fields as NOT NULL makes the indexes more + // performant. + $schema['users_field_data']['fields']['access']['not null'] = TRUE; + $schema['users_field_data']['fields']['created']['not null'] = TRUE; + $schema['users_field_data']['fields']['name']['not null'] = TRUE; + + $schema['users_field_data']['indexes'] += array( + 'user__access' => array('access'), + 'user__created' => array('created'), + 'user__mail' => array('mail'), + ); + $schema['users_field_data']['unique keys'] += array( + 'user__name' => array('name', 'langcode'), + ); + + $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/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php index fde0d841fca62eb719d4344348767fb8e4ba4904..51ac5df919f64155d8f9a34724a8e283c4e1e955 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php @@ -299,9 +299,9 @@ public function testGetSchema() { // ContentEntityStorageBase::__construct() array('uuid', NULL), array('bundle', NULL), - // ContentEntitySchemaHandler::initializeBaseTable() + // SqlContentEntityStorageSchema::initializeBaseTable() array('id' => 'id'), - // ContentEntitySchemaHandler::processBaseTable() + // SqlContentEntityStorageSchema::processBaseTable() array('id' => 'id'), ))); @@ -331,7 +331,7 @@ public function testGetSchema() { $this->assertEquals($expected, $this->entityStorage->getSchema()); // Test that repeated calls do not result in repeatedly instantiating - // ContentEntitySchemaHandler as getFieldStorageDefinitions() is only + // SqlContentEntityStorageSchema as getFieldStorageDefinitions() is only // expected to be called once. $this->assertEquals($expected, $this->entityStorage->getSchema()); } diff --git a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php b/core/tests/Drupal/Tests/Core/Entity/Schema/SqlContentEntityStorageSchemaTest.php similarity index 98% rename from core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php rename to core/tests/Drupal/Tests/Core/Entity/Schema/SqlContentEntityStorageSchemaTest.php index 0a4afe7293957b7ad36f429cc7072bc437518f8b..f1e6a5b54a4737052e659be0eb4127dbd89371e1 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Schema/ContentEntitySchemaHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Schema/SqlContentEntityStorageSchemaTest.php @@ -2,21 +2,21 @@ /** * @file - * Contains \Drupal\Tests\Core\Entity\Schema\ContentEntitySchemaHandlerTest. + * Contains \Drupal\Tests\Core\Entity\Schema\SqlContentEntityStorageSchemaTest. */ namespace Drupal\Tests\Core\Entity\Schema; use Drupal\Core\Entity\ContentEntityType; -use Drupal\Core\Entity\Schema\ContentEntitySchemaHandler; +use Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema; use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Tests\UnitTestCase; /** - * @coversDefaultClass \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler + * @coversDefaultClass \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema * @group Entity */ -class ContentEntitySchemaHandlerTest extends UnitTestCase { +class SqlContentEntityStorageSchemaTest extends UnitTestCase { /** * The mocked entity manager used in this test. @@ -49,7 +49,7 @@ class ContentEntitySchemaHandlerTest extends UnitTestCase { /** * The content entity schema handler used in this test. * - * @var \Drupal\Core\Entity\Schema\ContentEntitySchemaHandler. + * @var \Drupal\Core\Entity\Schema\SqlContentEntityStorageSchema. */ protected $schemaHandler; @@ -778,7 +778,7 @@ protected function setUpSchemaHandler() { ->method('getFieldStorageDefinitions') ->with($this->entityType->id()) ->will($this->returnValue($this->storageDefinitions)); - $this->schemaHandler = new ContentEntitySchemaHandler( + $this->schemaHandler = new SqlContentEntityStorageSchema( $this->entityManager, $this->entityType, $this->storage