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() {
*/
public function applyUpdates() {
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.
if (!empty($change_list['field_storage_definitions'])) {
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
......@@ -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
protected function createDedicatedTableSchema(FieldStorageDefinitionInterface $storage_definition) {
$schema = $this->getDedicatedTableSchema($storage_definition);
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);
}
......@@ -1109,11 +1113,19 @@ protected function createSharedTableSchema(FieldStorageDefinitionInterface $stor
$schema[$table_name] = $this->getSharedTableFieldSchema($storage_definition, $table_name, $column_names);
if (!$only_save) {
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'])) {
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'])) {
......
......@@ -100,6 +100,21 @@ protected function addBaseField($type = 'string') {
$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'.
*/
......
......@@ -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() {
$this->updateEntityTypeToRevisionable();
$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
// at the same time does not lead to errors due to the base field being
// created twice.
try {
$this->entityDefinitionUpdateManager->applyUpdates();
$this->pass('Successfully updated entity schema and created base field at the same time.');
$this->pass($message);
}
catch (\Exception $e) {
$this->fail('Successfully updated entity schema and created base field at the same time.');
$this->fail($message);
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