protected SqlContentEntityStorageSchema::updateSharedTableSchema(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 1350
Class
- SqlContentEntityStorageSchema
- Defines a schema handler that supports revisionable, translatable entities.
Namespace
Drupal\Core\Entity\Sql
Code
protected function updateSharedTableSchema(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) { if (!$this->storage->countFieldData($original, TRUE)) { 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 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()) { $transaction->rollback(); } else { // Recreate original schema. $this->createSharedTableSchema($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.'); } $updated_field_name = $storage_definition->getName(); $table_mapping = $this->storage->getTableMapping(); $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 = array(); 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, $field_name, $field_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); } }
Please login to continue.