protected function SqlContentEntityStorageSchema::updateDedicatedTableSchema in Drupal 10
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::updateDedicatedTableSchema()
 - 9 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::updateDedicatedTableSchema()
 
Updates the schema for a field stored in a shared table.
Parameters
\Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition: The storage definition of the field being updated.
\Drupal\Core\Field\FieldStorageDefinitionInterface $original: The original storage definition; i.e., the definition before the update.
Throws
\Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException Thrown when the update to the field is forbidden.
\Exception Rethrown exception if the table recreation fails.
File
- core/
lib/ Drupal/ Core/ Entity/ Sql/ SqlContentEntityStorageSchema.php, line 1724  
Class
- SqlContentEntityStorageSchema
 - Defines a schema handler that supports revisionable, translatable entities.
 
Namespace
Drupal\Core\Entity\SqlCode
protected function updateDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
  if (!$this->storage
    ->countFieldData($original, TRUE)) {
    // There is no data. Re-create the tables completely.
    if ($this->database
      ->supportsTransactionalDDL()) {
      // If the database supports transactional DDL, we can go ahead and rely
      // on it. If not, we will have to rollback manually if something fails.
      $transaction = $this->database
        ->startTransaction();
    }
    try {
      // Since there is no data we may be switching from a shared table schema
      // to a dedicated table schema, hence we should use the proper API.
      $this
        ->performFieldSchemaOperation('delete', $original);
      $this
        ->performFieldSchemaOperation('create', $storage_definition);
    } catch (\Exception $e) {
      if ($this->database
        ->supportsTransactionalDDL()) {
        $transaction
          ->rollBack();
      }
      else {
        // Recreate tables.
        $this
          ->performFieldSchemaOperation('create', $original);
      }
      throw $e;
    }
  }
  else {
    if ($this
      ->hasColumnChanges($storage_definition, $original)) {
      throw new FieldStorageDefinitionUpdateForbiddenException('The SQL storage cannot change the schema for an existing field (' . $storage_definition
        ->getName() . ' in ' . $storage_definition
        ->getTargetEntityTypeId() . ' entity) with data.');
    }
    // There is data, so there are no column changes. Drop all the prior
    // indexes and create all the new ones, except for all the priors that
    // exist unchanged.
    $table_mapping = $this
      ->getTableMapping($this->entityType, [
      $storage_definition,
    ]);
    $table = $table_mapping
      ->getDedicatedDataTableName($original);
    $revision_table = $table_mapping
      ->getDedicatedRevisionTableName($original);
    // Get the field schemas.
    $schema = $storage_definition
      ->getSchema();
    $original_schema = $original
      ->getSchema();
    // Gets the SQL schema for a dedicated tables.
    $actual_schema = $this
      ->getDedicatedTableSchema($storage_definition);
    foreach ($original_schema['indexes'] as $name => $columns) {
      if (!isset($schema['indexes'][$name]) || $columns != $schema['indexes'][$name]) {
        $real_name = $this
          ->getFieldIndexName($storage_definition, $name);
        $this->database
          ->schema()
          ->dropIndex($table, $real_name);
        $this->database
          ->schema()
          ->dropIndex($revision_table, $real_name);
      }
    }
    $table = $table_mapping
      ->getDedicatedDataTableName($storage_definition);
    $revision_table = $table_mapping
      ->getDedicatedRevisionTableName($storage_definition);
    foreach ($schema['indexes'] as $name => $columns) {
      if (!isset($original_schema['indexes'][$name]) || $columns != $original_schema['indexes'][$name]) {
        $real_name = $this
          ->getFieldIndexName($storage_definition, $name);
        $real_columns = [];
        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)) {
            $real_columns[] = [
              $table_mapping
                ->getFieldColumnName($storage_definition, $column_name[0]),
              $column_name[1],
            ];
          }
          else {
            $real_columns[] = $table_mapping
              ->getFieldColumnName($storage_definition, $column_name);
          }
        }
        // Check if the index exists because it might already have been
        // created as part of the earlier entity type update event.
        $this
          ->addIndex($table, $real_name, $real_columns, $actual_schema[$table]);
        $this
          ->addIndex($revision_table, $real_name, $real_columns, $actual_schema[$revision_table]);
      }
    }
    $this
      ->saveFieldSchemaData($storage_definition, $this
      ->getDedicatedTableSchema($storage_definition));
  }
}