public function SqlContentEntityStorageSchema::onFieldStorageDefinitionDelete in Drupal 9
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::onFieldStorageDefinitionDelete()
- 10 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchema::onFieldStorageDefinitionDelete()
Reacts to the deletion of a field storage definition.
Parameters
\Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition: The field being deleted.
Overrides FieldStorageDefinitionListenerInterface::onFieldStorageDefinitionDelete
File
- core/
lib/ Drupal/ Core/ Entity/ Sql/ SqlContentEntityStorageSchema.php, line 709
Class
- SqlContentEntityStorageSchema
- Defines a schema handler that supports revisionable, translatable entities.
Namespace
Drupal\Core\Entity\SqlCode
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) {
// If the field storage does not have any data, we can safely delete its
// schema.
if (!$this->storage
->countFieldData($storage_definition, TRUE)) {
$this
->performFieldSchemaOperation('delete', $storage_definition);
return;
}
// There's nothing else we can do if the field storage has a custom storage.
if ($storage_definition
->hasCustomStorage()) {
return;
}
$table_mapping = $this
->getTableMapping($this->entityType, [
$storage_definition,
]);
$field_table_name = $table_mapping
->getFieldTableName($storage_definition
->getName());
if ($table_mapping
->requiresDedicatedTableStorage($storage_definition)) {
// Move the table to a unique name while the table contents are being
// deleted.
$table = $table_mapping
->getDedicatedDataTableName($storage_definition);
$new_table = $table_mapping
->getDedicatedDataTableName($storage_definition, TRUE);
$this->database
->schema()
->renameTable($table, $new_table);
if ($this->entityType
->isRevisionable()) {
$revision_table = $table_mapping
->getDedicatedRevisionTableName($storage_definition);
$revision_new_table = $table_mapping
->getDedicatedRevisionTableName($storage_definition, TRUE);
$this->database
->schema()
->renameTable($revision_table, $revision_new_table);
}
}
else {
// Move the field data from the shared table to a dedicated one in order
// to allow it to be purged like any other field.
$shared_table_field_columns = $table_mapping
->getColumnNames($storage_definition
->getName());
// Refresh the table mapping to use the deleted storage definition.
$deleted_storage_definition = $this
->deletedFieldsRepository()
->getFieldStorageDefinitions()[$storage_definition
->getUniqueStorageIdentifier()];
$table_mapping = $this
->getTableMapping($this->entityType, [
$deleted_storage_definition,
]);
$dedicated_table_field_schema = $this
->getDedicatedTableSchema($deleted_storage_definition);
$dedicated_table_field_columns = $table_mapping
->getColumnNames($deleted_storage_definition
->getName());
$dedicated_table_name = $table_mapping
->getDedicatedDataTableName($deleted_storage_definition, TRUE);
$dedicated_table_name_mapping[$table_mapping
->getDedicatedDataTableName($deleted_storage_definition)] = $dedicated_table_name;
if ($this->entityType
->isRevisionable()) {
$dedicated_revision_table_name = $table_mapping
->getDedicatedRevisionTableName($deleted_storage_definition, TRUE);
$dedicated_table_name_mapping[$table_mapping
->getDedicatedRevisionTableName($deleted_storage_definition)] = $dedicated_revision_table_name;
}
// Create the dedicated field tables using "deleted" table names.
foreach ($dedicated_table_field_schema as $name => $table) {
if (!$this->database
->schema()
->tableExists($dedicated_table_name_mapping[$name])) {
$this->database
->schema()
->createTable($dedicated_table_name_mapping[$name], $table);
}
else {
throw new EntityStorageException('The field ' . $storage_definition
->getName() . ' has already been deleted and it is in the process of being purged.');
}
}
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 {
// Copy the data from the base table.
$this->database
->insert($dedicated_table_name)
->from($this
->getSelectQueryForFieldStorageDeletion($field_table_name, $shared_table_field_columns, $dedicated_table_field_columns))
->execute();
// Copy the data from the revision table.
if (isset($dedicated_revision_table_name)) {
if ($this->entityType
->isTranslatable()) {
$revision_table = $storage_definition
->isRevisionable() ? $this->storage
->getRevisionDataTable() : $this->storage
->getDataTable();
}
else {
$revision_table = $storage_definition
->isRevisionable() ? $this->storage
->getRevisionTable() : $this->storage
->getBaseTable();
}
$this->database
->insert($dedicated_revision_table_name)
->from($this
->getSelectQueryForFieldStorageDeletion($revision_table, $shared_table_field_columns, $dedicated_table_field_columns, $field_table_name))
->execute();
}
} catch (\Exception $e) {
if (isset($transaction)) {
$transaction
->rollBack();
}
else {
// Delete the dedicated tables.
foreach ($dedicated_table_field_schema as $name => $table) {
$this->database
->schema()
->dropTable($dedicated_table_name_mapping[$name]);
}
}
throw $e;
}
// Delete the field from the shared tables.
$this
->deleteSharedTableSchema($storage_definition);
}
unset($this->fieldStorageDefinitions[$storage_definition
->getName()]);
}