diff --git a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php b/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php index 3fc26b0..2e8abc9 100644 --- a/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php +++ b/core/lib/Drupal/Core/Entity/RevisionableSchemaConverter.php @@ -75,7 +75,7 @@ public function convertSchema($entity_type_id, $options = []) { ]; $options = array_merge($default_options, $options); $this->updateEntityType($entity_type_id, $options); - $this->createTables($entity_type_id, $options); + //$this->createTables($entity_type_id, $options); $this->installRevisionableFields($entity_type_id, $options); } @@ -151,72 +151,13 @@ public function copyData(EntityTypeInterface $entity_type, array &$sandbox) { * Options to update the entity type with. */ protected function updateEntityType($entity_type_id, $options) { - $last_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id); - $keys = $last_entity_type->getKeys(); - $keys['revision'] = $options['revision']; - $last_entity_type->set('entity_keys', $keys); - $last_entity_type->set('revision_table', $options['revision_table']); - $last_entity_type->set('revision_data_table', $options['revision_data_table']); - $this->lastInstalledSchemaRepository->setLastInstalledDefinition($last_entity_type); - } - - /** - * Creates missing tables. - * - * @param string $entity_type_id - * ID of the entity type to update. - * @param array $options - * Options to update the entity type with. - */ - protected function createTables($entity_type_id, $options) { $entity_type = $this->entityDefinitionUpdateManager->getEntityType($entity_type_id); - $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($entity_type_id); - $table_mapping = $this->entityTypeManager->getStorage($entity_type_id)->getTableMapping($field_definitions); - $id_key = $entity_type->getKey('id'); - $revision_key = $entity_type->getKey('revision'); - - $revision_table_schema = [ - 'description' => "The revision table for $entity_type_id entities.", - 'primary key' => [$revision_key], - 'unique keys' => [], - 'indexes' => [$entity_type_id . '__' . $id_key => [$id_key]], - 'foreign keys' => [ - $entity_type_id . '__revisioned' => [ - 'table' => $entity_type->getBaseTable(), - 'columns' => [$id_key => $id_key], - ], - ], - 'fields' => [], - ]; - foreach ($table_mapping->getFieldNames($options['revision_table']) as $field) { - $revision_table_schema['fields'][$field] = $field_definitions[$field]->getSchema(); - } - $this->database->schema()->createTable($options['revision_table'], $revision_table_schema); - - $revision_data_table_schema = [ - 'description' => "The revision data table for $entity_type_id entities.", - 'primary key' => [$revision_key, $entity_type->getKey('langcode')], - 'unique keys' => [], - 'indexes' => [ - $entity_type_id . '__id__default_langcode__langcode' => [$id_key, $entity_type->getKey('default_langcode'), $entity_type->getKey('langcode')], - ], - 'foreign keys' => [ - $entity_type_id . '__revisioned' => [ - 'table' => $entity_type->getBaseTable(), - 'columns' => [$id_key => $id_key], - ], - $entity_type_id . '__revision' => [ - 'table' => $entity_type->getRevisionTable(), - 'columns' => [$revision_key => $revision_key], - ] - ], - 'fields' => [], - ]; - foreach ($table_mapping->getFieldNames($options['revision_data_table']) as $field) { - $revision_data_table_schema['fields'][$field] = $field_definitions[$field]->getSchema(); - } - $this->database->schema()->createTable($options['revision_data_table'], $revision_data_table_schema); - + $keys = $entity_type->getKeys(); + $keys['revision'] = $options['revision']; + $entity_type->set('entity_keys', $keys); + $entity_type->set('revision_table', $options['revision_table']); + $entity_type->set('revision_data_table', $options['revision_data_table']); + $this->entityDefinitionUpdateManager->updateEntityType($entity_type); } /** diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php index a12f773..475d706 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php @@ -300,19 +300,52 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI // If a migration is required, we can't proceed. if ($this->requiresEntityDataMigration($entity_type, $original)) { - throw new EntityStorageException('The SQL storage cannot change the schema for an existing entity type (' . $entity_type->id() . ') with data.'); + //throw new EntityStorageException('The SQL storage cannot change the schema for an existing entity type (' . $entity_type->id() . ') with data.'); } - // If we have no data just recreate the entity schema from scratch. - if ($this->isTableEmpty($this->storage->getBaseTable())) { 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 { - $this->onEntityTypeDelete($original); - $this->onEntityTypeCreate($entity_type); + if ($this->isTableEmpty($this->storage->getBaseTable())) { + $this->onEntityTypeDelete($original); + } + $this->checkEntityType($entity_type); + $schema_handler = $this->database->schema(); + + // Create entity tables. + $schema = $this->getEntitySchema($entity_type, TRUE); + foreach ($schema as $table_name => $table_schema) { + if (!$schema_handler->tableExists($table_name)) { + $schema_handler->createTable($table_name, $table_schema); + } + } + + // Create dedicated field tables. + $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type->id()); + $table_mapping = $this->storage->getTableMapping($field_storage_definitions); + foreach ($field_storage_definitions as $field_storage_definition) { + if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) { + $this->createDedicatedTableSchema($field_storage_definition); + } + elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) { + // The shared tables are already fully created, but we need to save the + // per-field schema definitions for later use. + $this->createSharedTableSchema($field_storage_definition, TRUE); + } + } + + // Drop original indexes and unique keys. + $this->deleteEntitySchemaIndexes($this->loadEntitySchemaData($entity_type)); + + // Create new indexes and unique keys. + $entity_schema = $this->getEntitySchema($entity_type, TRUE); + $this->createEntitySchemaIndexes($entity_schema); + + // Store the updated entity schema. + $this->saveEntitySchemaData($entity_type, $entity_schema); } catch (\Exception $e) { if ($this->database->supportsTransactionalDDL()) { @@ -324,18 +357,6 @@ public function onEntityTypeUpdate(EntityTypeInterface $entity_type, EntityTypeI } throw $e; } - } - else { - // Drop original indexes and unique keys. - $this->deleteEntitySchemaIndexes($this->loadEntitySchemaData($entity_type)); - - // Create new indexes and unique keys. - $entity_schema = $this->getEntitySchema($entity_type, TRUE); - $this->createEntitySchemaIndexes($entity_schema); - - // Store the updated entity schema. - $this->saveEntitySchemaData($entity_type, $entity_schema); - } } /**