Commit d42d61a7 authored by alexpott's avatar alexpott

Issue #2398689 by jeqq: Follow-up: Applying entity schema updates still fails...

Issue #2398689 by jeqq: Follow-up: Applying entity schema updates still fails when both field and entity type definitions changes
parent 9d21438a
...@@ -106,6 +106,16 @@ public function getChangeSummary() { ...@@ -106,6 +106,16 @@ public function getChangeSummary() {
*/ */
public function applyUpdates() { public function applyUpdates() {
foreach ($this->getChangeList() as $entity_type_id => $change_list) { foreach ($this->getChangeList() as $entity_type_id => $change_list) {
// Process entity type definition changes before storage definitions ones
// this is necessary when you change an entity type from non-revisionable
// to revisionable and at the same time add revisionable fields to the
// entity type.
if (!empty($change_list['entity_type']) && $change_list['entity_type'] == static::DEFINITION_UPDATED) {
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$original = $this->entityManager->getLastInstalledDefinition($entity_type_id);
$this->entityManager->onEntityTypeUpdate($entity_type, $original);
}
// Process field storage definition changes. // Process field storage definition changes.
if (!empty($change_list['field_storage_definitions'])) { if (!empty($change_list['field_storage_definitions'])) {
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
...@@ -127,15 +137,6 @@ public function applyUpdates() { ...@@ -127,15 +137,6 @@ public function applyUpdates() {
} }
} }
} }
// Process entity type definition changes after storage definitions ones
// as entity type updates might create base fields as well. That way, if
// both occur at the same time it does not lead to problems due to the
// base field creation being applied twice.
if (!empty($change_list['entity_type']) && $change_list['entity_type'] == static::DEFINITION_UPDATED) {
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$original = $this->entityManager->getLastInstalledDefinition($entity_type_id);
$this->entityManager->onEntityTypeUpdate($entity_type, $original);
}
} }
} }
......
...@@ -1076,7 +1076,11 @@ protected function performFieldSchemaOperation($operation, FieldStorageDefinitio ...@@ -1076,7 +1076,11 @@ protected function performFieldSchemaOperation($operation, FieldStorageDefinitio
protected function createDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition) { protected function createDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition) {
$schema = $this->getDedicatedTableSchema($storage_definition); $schema = $this->getDedicatedTableSchema($storage_definition);
foreach ($schema as $name => $table) { foreach ($schema as $name => $table) {
$this->database->schema()->createTable($name, $table); // Check if the table exists because it might already have been
// created as part of the earlier entity type update event.
if (!$this->database->schema()->tableExists($name)) {
$this->database->schema()->createTable($name, $table);
}
} }
$this->saveFieldSchemaData($storage_definition, $schema); $this->saveFieldSchemaData($storage_definition, $schema);
} }
...@@ -1109,11 +1113,19 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor ...@@ -1109,11 +1113,19 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
$schema[$table_name] = $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names); $schema[$table_name] = $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names);
if (!$only_save) { if (!$only_save) {
foreach ($schema[$table_name]['fields'] as $name => $specifier) { foreach ($schema[$table_name]['fields'] as $name => $specifier) {
$schema_handler->addField($table_name, $name, $specifier); // Check if the field exists because it might already have been
// created as part of the earlier entity type update event.
if (!$schema_handler->fieldExists($table_name, $name)) {
$schema_handler->addField($table_name, $name, $specifier);
}
} }
if (!empty($schema[$table_name]['indexes'])) { if (!empty($schema[$table_name]['indexes'])) {
foreach ($schema[$table_name]['indexes'] as $name => $specifier) { foreach ($schema[$table_name]['indexes'] as $name => $specifier) {
$schema_handler->addIndex($table_name, $name, $specifier); // Check if the index exists because it might already have been
// created as part of the earlier entity type update event.
if (!$schema_handler->indexExists($table_name, $name)) {
$schema_handler->addIndex($table_name, $name, $specifier);
}
} }
} }
if (!empty($schema[$table_name]['unique keys'])) { if (!empty($schema[$table_name]['unique keys'])) {
......
...@@ -100,6 +100,21 @@ protected function addBaseField($type = 'string') { ...@@ -100,6 +100,21 @@ protected function addBaseField($type = 'string') {
$this->entityManager->clearCachedDefinitions(); $this->entityManager->clearCachedDefinitions();
} }
/**
* Adds a new revisionable base field to the 'entity_test_update' entity type.
*
* @param string $type
* (optional) The field type for the new field. Defaults to 'string'.
*/
protected function addRevisionableBaseField($type = 'string') {
$definitions['new_base_field'] = BaseFieldDefinition::create($type)
->setName('new_base_field')
->setLabel(t('A new revisionable base field'))
->setRevisionable(TRUE);
$this->state->set('entity_test_update.additional_base_field_definitions', $definitions);
$this->entityManager->clearCachedDefinitions();
}
/** /**
* Modifies the new base field from 'string' to 'text'. * Modifies the new base field from 'string' to 'text'.
*/ */
......
...@@ -541,20 +541,47 @@ public function testDefinitionEvents() { ...@@ -541,20 +541,47 @@ public function testDefinitionEvents() {
} }
/** /**
* Tests updating entity schema and creating a base field at the same time when there are no existing entities. * Tests updating entity schema and creating a base field.
*
* This tests updating entity schema and creating a base field at the same
* time when there are no existing entities.
*/ */
public function testEntityTypeSchemaUpdateAndBaseFieldCreateWithoutData() { public function testEntityTypeSchemaUpdateAndBaseFieldCreateWithoutData() {
$this->updateEntityTypeToRevisionable(); $this->updateEntityTypeToRevisionable();
$this->addBaseField(); $this->addBaseField();
$message = 'Successfully updated entity schema and created base field at the same time.';
// Entity type updates create base fields as well, thus make sure doing both
// at the same time does not lead to errors due to the base field being
// created twice.
try {
$this->entityDefinitionUpdateManager->applyUpdates();
$this->pass($message);
}
catch (\Exception $e) {
$this->fail($message);
throw $e;
}
}
/**
* Tests updating entity schema and creating a revisionable base field.
*
* This tests updating entity schema and creating a revisionable base field
* at the same time when there are no existing entities.
*/
public function testEntityTypeSchemaUpdateAndRevisionableBaseFieldCreateWithoutData() {
$this->updateEntityTypeToRevisionable();
$this->addRevisionableBaseField();
$message = 'Successfully updated entity schema and created revisionable base field at the same time.';
// Entity type updates create base fields as well, thus make sure doing both // Entity type updates create base fields as well, thus make sure doing both
// at the same time does not lead to errors due to the base field being // at the same time does not lead to errors due to the base field being
// created twice. // created twice.
try { try {
$this->entityDefinitionUpdateManager->applyUpdates(); $this->entityDefinitionUpdateManager->applyUpdates();
$this->pass('Successfully updated entity schema and created base field at the same time.'); $this->pass($message);
} }
catch (\Exception $e) { catch (\Exception $e) {
$this->fail('Successfully updated entity schema and created base field at the same time.'); $this->fail($message);
throw $e; throw $e;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment