function SqlContentEntityStorageSchema::updateSharedTableSchema
Same name in other branches
- 9 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::updateSharedTableSchema()
- 8.9.x core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::updateSharedTableSchema()
- 11.x core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::updateSharedTableSchema()
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 1815
Class
- SqlContentEntityStorageSchema
- Defines a schema handler that supports revisionable, translatable entities.
Namespace
Drupal\Core\Entity\SqlCode
protected function updateSharedTableSchema(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) {
if (!$this->storage
->countFieldData($original, TRUE)) {
try {
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();
}
// Since there is no data we may be switching from a dedicated table
// to a schema 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()) {
if (isset($transaction)) {
$transaction->rollBack();
}
}
else {
// Recreate original schema.
$this->createSharedTableSchema($original);
}
throw $e;
}
}
else {
if (empty($storage_definition->getSetting('column_changes_handled')) && $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.');
}
$updated_field_name = $storage_definition->getName();
$table_mapping = $this->getTableMapping($this->entityType, [
$storage_definition,
]);
$column_names = $table_mapping->getColumnNames($updated_field_name);
$schema_handler = $this->database
->schema();
// Iterate over the mapped table to find the ones that host the deleted
// field schema.
$original_schema = $this->loadFieldSchemaData($original);
$schema = [];
foreach ($table_mapping->getTableNames() as $table_name) {
foreach ($table_mapping->getFieldNames($table_name) as $field_name) {
if ($field_name == $updated_field_name) {
$schema[$table_name] = $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names);
// Handle NOT NULL constraints.
foreach ($schema[$table_name]['fields'] as $column_name => $specifier) {
$not_null = !empty($specifier['not null']);
$original_not_null = !empty($original_schema[$table_name]['fields'][$column_name]['not null']);
if ($not_null !== $original_not_null) {
if ($not_null && $this->hasNullFieldPropertyData($table_name, $column_name)) {
throw new EntityStorageException("The {$column_name} column cannot have NOT NULL constraints as it holds NULL values.");
}
$column_schema = $original_schema[$table_name]['fields'][$column_name];
$column_schema['not null'] = $not_null;
$schema_handler->changeField($table_name, $column_name, $column_name, $column_schema);
}
}
// Drop original indexes and unique keys.
if (!empty($original_schema[$table_name]['indexes'])) {
foreach ($original_schema[$table_name]['indexes'] as $name => $specifier) {
$schema_handler->dropIndex($table_name, $name);
}
}
if (!empty($original_schema[$table_name]['unique keys'])) {
foreach ($original_schema[$table_name]['unique keys'] as $name => $specifier) {
$schema_handler->dropUniqueKey($table_name, $name);
}
}
// Create new indexes and unique keys.
if (!empty($schema[$table_name]['indexes'])) {
foreach ($schema[$table_name]['indexes'] as $name => $specifier) {
// Check if the index exists because it might already have been
// created as part of the earlier entity type update event.
$this->addIndex($table_name, $name, $specifier, $schema[$table_name]);
}
}
if (!empty($schema[$table_name]['unique keys'])) {
foreach ($schema[$table_name]['unique keys'] as $name => $specifier) {
$schema_handler->addUniqueKey($table_name, $name, $specifier);
}
}
// After deleting the field schema skip to the next table.
break;
}
}
}
$this->saveFieldSchemaData($storage_definition, $schema);
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.