You are here

protected function SqlContentEntityStorageSchema::getDedicatedTableSchema in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::getDedicatedTableSchema()

Gets the SQL schema for a dedicated table.

Parameters

\Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition: The field storage definition.

\Drupal\Core\Entity\ContentEntityTypeInterface $entity_type: (optional) The entity type definition. Defaults to the one provided by the entity storage.

Return value

array The schema definition for the table with the following keys:

  • fields: The schema definition for the each field columns.
  • indexes: The schema definition for the indexes.
  • unique keys: The schema definition for the unique keys.
  • foreign keys: The schema definition for the foreign keys.

Throws

\Drupal\Core\Field\FieldException Exception thrown if the schema contains reserved column names.

See also

hook_schema()

6 calls to SqlContentEntityStorageSchema::getDedicatedTableSchema()
SqlContentEntityStorageSchema::createDedicatedTableSchema in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
Creates the schema for a field stored in a dedicated table.
SqlContentEntityStorageSchema::getSchemaFromStorageDefinition in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
Gets the schema data for the given field storage definition.
SqlContentEntityStorageSchema::onFieldStorageDefinitionDelete in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
Reacts to the deletion of a field storage definition.
SqlContentEntityStorageSchema::preUpdateEntityTypeSchema in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
Allows subscribers to prepare their schema before data copying.
SqlContentEntityStorageSchema::updateDedicatedTableSchema in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
Updates the schema for a field stored in a shared table.

... See full list

1 method overrides SqlContentEntityStorageSchema::getDedicatedTableSchema()
TermStorageSchema::getDedicatedTableSchema in core/modules/taxonomy/src/TermStorageSchema.php
Gets the SQL schema for a dedicated table.

File

core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php, line 2236

Class

SqlContentEntityStorageSchema
Defines a schema handler that supports revisionable, translatable entities.

Namespace

Drupal\Core\Entity\Sql

Code

protected function getDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition, ContentEntityTypeInterface $entity_type = NULL) {
  $entity_type = $entity_type ?: $this->entityType;
  $description_current = "Data storage for {$storage_definition->getTargetEntityTypeId()} field {$storage_definition->getName()}.";
  $description_revision = "Revision archive storage for {$storage_definition->getTargetEntityTypeId()} field {$storage_definition->getName()}.";
  $id_definition = $this->fieldStorageDefinitions[$entity_type
    ->getKey('id')];
  if ($id_definition
    ->getType() == 'integer') {
    $id_schema = [
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
      'description' => 'The entity id this data is attached to',
    ];
  }
  else {
    $id_schema = [
      'type' => 'varchar_ascii',
      'length' => 128,
      'not null' => TRUE,
      'description' => 'The entity id this data is attached to',
    ];
  }

  // Define the revision ID schema.
  if (!$entity_type
    ->isRevisionable()) {
    $revision_id_schema = $id_schema;
    $revision_id_schema['description'] = 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id';
  }
  elseif ($this->fieldStorageDefinitions[$entity_type
    ->getKey('revision')]
    ->getType() == 'integer') {
    $revision_id_schema = [
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
      'description' => 'The entity revision id this data is attached to',
    ];
  }
  else {
    $revision_id_schema = [
      'type' => 'varchar',
      'length' => 128,
      'not null' => TRUE,
      'description' => 'The entity revision id this data is attached to',
    ];
  }
  $data_schema = [
    'description' => $description_current,
    'fields' => [
      'bundle' => [
        'type' => 'varchar_ascii',
        'length' => 128,
        'not null' => TRUE,
        'default' => '',
        'description' => 'The field instance bundle to which this row belongs, used when deleting a field instance',
      ],
      'deleted' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
        'default' => 0,
        'description' => 'A boolean indicating whether this data item has been deleted',
      ],
      'entity_id' => $id_schema,
      'revision_id' => $revision_id_schema,
      'langcode' => [
        'type' => 'varchar_ascii',
        'length' => 32,
        'not null' => TRUE,
        'default' => '',
        'description' => 'The language code for this data item.',
      ],
      'delta' => [
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'description' => 'The sequence number for this data item, used for multi-value fields',
      ],
    ],
    'primary key' => [
      'entity_id',
      'deleted',
      'delta',
      'langcode',
    ],
    'indexes' => [
      'bundle' => [
        'bundle',
      ],
      'revision_id' => [
        'revision_id',
      ],
    ],
  ];

  // Check that the schema does not include forbidden column names.
  $schema = $storage_definition
    ->getSchema();
  $properties = $storage_definition
    ->getPropertyDefinitions();
  $table_mapping = $this
    ->getTableMapping($entity_type, [
    $storage_definition,
  ]);
  if (array_intersect(array_keys($schema['columns']), $table_mapping
    ->getReservedColumns())) {
    throw new FieldException("Illegal field column names on {$storage_definition->getName()}");
  }

  // Add field columns.
  foreach ($schema['columns'] as $column_name => $attributes) {
    $real_name = $table_mapping
      ->getFieldColumnName($storage_definition, $column_name);
    $data_schema['fields'][$real_name] = $attributes;

    // A dedicated table only contain rows for actual field values, and no
    // rows for entities where the field is empty. Thus, we can safely
    // enforce 'not null' on the columns for the field's required properties.
    // Fields can have dynamic properties, so we need to make sure that the
    // property is statically defined.
    if (isset($properties[$column_name])) {
      $data_schema['fields'][$real_name]['not null'] = $properties[$column_name]
        ->isRequired();
    }
  }

  // Add indexes.
  foreach ($schema['indexes'] as $index_name => $columns) {
    $real_name = $this
      ->getFieldIndexName($storage_definition, $index_name);
    foreach ($columns as $column_name) {

      // Indexes can be specified as either a column name or an array with
      // column name and length. Allow for either case.
      if (is_array($column_name)) {
        $data_schema['indexes'][$real_name][] = [
          $table_mapping
            ->getFieldColumnName($storage_definition, $column_name[0]),
          $column_name[1],
        ];
      }
      else {
        $data_schema['indexes'][$real_name][] = $table_mapping
          ->getFieldColumnName($storage_definition, $column_name);
      }
    }
  }

  // Add unique keys.
  foreach ($schema['unique keys'] as $index_name => $columns) {
    $real_name = $this
      ->getFieldIndexName($storage_definition, $index_name);
    foreach ($columns as $column_name) {

      // Unique keys can be specified as either a column name or an array with
      // column name and length. Allow for either case.
      if (is_array($column_name)) {
        $data_schema['unique keys'][$real_name][] = [
          $table_mapping
            ->getFieldColumnName($storage_definition, $column_name[0]),
          $column_name[1],
        ];
      }
      else {
        $data_schema['unique keys'][$real_name][] = $table_mapping
          ->getFieldColumnName($storage_definition, $column_name);
      }
    }
  }

  // Add foreign keys.
  foreach ($schema['foreign keys'] as $specifier => $specification) {
    $real_name = $this
      ->getFieldIndexName($storage_definition, $specifier);
    $data_schema['foreign keys'][$real_name]['table'] = $specification['table'];
    foreach ($specification['columns'] as $column_name => $referenced) {
      $sql_storage_column = $table_mapping
        ->getFieldColumnName($storage_definition, $column_name);
      $data_schema['foreign keys'][$real_name]['columns'][$sql_storage_column] = $referenced;
    }
  }
  $dedicated_table_schema = [
    $table_mapping
      ->getDedicatedDataTableName($storage_definition) => $data_schema,
  ];

  // If the entity type is revisionable, construct the revision table.
  if ($entity_type
    ->isRevisionable()) {
    $revision_schema = $data_schema;
    $revision_schema['description'] = $description_revision;
    $revision_schema['primary key'] = [
      'entity_id',
      'revision_id',
      'deleted',
      'delta',
      'langcode',
    ];
    $revision_schema['fields']['revision_id']['not null'] = TRUE;
    $revision_schema['fields']['revision_id']['description'] = 'The entity revision id this data is attached to';
    $dedicated_table_schema += [
      $table_mapping
        ->getDedicatedRevisionTableName($storage_definition) => $revision_schema,
    ];
  }
  return $dedicated_table_schema;
}