protected function SqlContentEntityStorageSchema::updateDedicatedTableSchema

protected SqlContentEntityStorageSchema::updateDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original)

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 1258

Class

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

Namespace

Drupal\Core\Entity\Sql

Code

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->storage->getTableMapping();
    $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 = array();
        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[] = array(
              $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));
  }
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Entity!Sql!SqlContentEntityStorageSchema.php/function/SqlContentEntityStorageSchema::updateDedicatedTableSchema/8.1.x