diff --git a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php index 920adc1..8c9d9f4 100644 --- a/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php +++ b/core/lib/Drupal/Core/Entity/Sql/DefaultTableMapping.php @@ -620,11 +620,14 @@ protected function generateFieldTableName(FieldStorageDefinitionInterface $stora $table_name = $this->prefix . $entity_type_id . $separator . $field_hash; - // If the resulting table name is still longer than 48 characters, use a - // simple "prefix + field_hash" name instead. + // If the resulting table name is still longer than 48 characters, use the + // following pattern: + // - prefix: max 34 chars; + // - separator: max 4 chars; + // - field_hash: max 10 chars. if (strlen($table_name) > 48) { - $prefix = substr($this->prefix, 0, 38); - $table_name = $prefix . $field_hash; + $prefix = substr($this->prefix, 0, 34); + $table_name = $prefix . $separator . $field_hash; } } return $table_name; diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php index fc1874c..7d8f53b 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php @@ -149,8 +149,8 @@ public function convertToRevisionable(array &$sandbox, array $fields_to_update = // Rename the original tables so we can put them back in place in case // anything goes wrong. - $backup_table_name_mapping = array_combine($sandbox['original_table_mapping']->getTableNames(), $sandbox['backup_table_mapping']->getTableNames()); - foreach ($backup_table_name_mapping as $original_table_name => $backup_table_name) { + $backup_table_names = array_combine($sandbox['original_table_mapping']->getTableNames(), $sandbox['backup_table_mapping']->getTableNames()); + foreach ($backup_table_names as $original_table_name => $backup_table_name) { $this->database->schema()->renameTable($original_table_name, $backup_table_name); } @@ -197,7 +197,7 @@ public function convertToRevisionable(array &$sandbox, array $fields_to_update = } catch (\Exception $e) { // Something went wrong, bring back the original tables. - foreach ($backup_table_name_mapping as $original_table_name => $backup_table_name) { + foreach ($backup_table_names as $original_table_name => $backup_table_name) { // We are in the 'original data recovery' phase, so we need to be sure // that the initial tables can be properly restored. if ($this->database->schema()->tableExists($original_table_name)) { @@ -214,7 +214,7 @@ public function convertToRevisionable(array &$sandbox, array $fields_to_update = // At this point the update process either finished successfully or any // error has been handled already, so we can drop the backup entity // tables. - foreach ($backup_table_name_mapping as $original_table_name => $backup_table_name) { + foreach ($backup_table_names as $original_table_name => $backup_table_name) { $this->database->schema()->dropTable($backup_table_name); } } diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/DefaultTableMappingTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/DefaultTableMappingTest.php index e9a306d..b3f317c 100644 --- a/core/tests/Drupal/Tests/Core/Entity/Sql/DefaultTableMappingTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/Sql/DefaultTableMappingTest.php @@ -4,6 +4,7 @@ use Drupal\Core\Entity\Sql\DefaultTableMapping; use Drupal\Core\Entity\Sql\SqlContentEntityStorageException; +use Drupal\Core\Entity\Sql\TemporaryTableMapping; use Drupal\Tests\UnitTestCase; /** @@ -445,6 +446,142 @@ public function testGetFieldTableNameInvalid() { } /** + * @covers ::getDedicatedDataTableName + * @covers ::getDedicatedRevisionTableName + * + * @dataProvider providerTestGetDedicatedTableName + */ + public function testGetDedicatedTableName($info, $expected_data_table, $expected_revision_table) { + $entity_type_id = $info['entity_type_id']; + $field_name = $info['field_name']; + + $definition = $this->setUpDefinition($field_name, []); + $definition->expects($this->any()) + ->method('getTargetEntityTypeId') + ->will($this->returnValue($entity_type_id)); + $definition->expects($this->any()) + ->method('getUniqueStorageIdentifier') + ->will($this->returnValue($entity_type_id . '-' . $field_name)); + + $this->entityType + ->expects($this->any()) + ->method('getBaseTable') + ->willReturn($info['entity_type_id']); + $this->entityType + ->expects($this->any()) + ->method('isTranslatable') + ->willReturn(FALSE); + $this->entityType + ->expects($this->any()) + ->method('isRevisionable') + ->willReturn(FALSE); + + $table_mapping = new DefaultTableMapping($this->entityType, [], $info['prefix']); + + $this->assertSame($expected_data_table, $table_mapping->getDedicatedDataTableName($definition)); + $this->assertSame($expected_revision_table, $table_mapping->getDedicatedRevisionTableName($definition)); + } + + /** + * Provides test data for testGetDedicatedTableName(). + * + * @return array[] + * A nested array where each inner array has the following values: an array + * consisting of the entity type ID, field name and a table prefix, followed + * by the expected data table name and the revision table name. + */ + public function providerTestGetDedicatedTableName() { + $data = []; + + $data['short entity type; short field name; no prefix'] = [ + [ + 'entity_type_id' => 'short_entity_type', + 'field_name' => 'short_field_name', + 'prefix' => '', + ], + 'short_entity_type__short_field_name', + 'short_entity_type_revision__short_field_name', + ]; + $data['short entity type; long field name; no prefix'] = [ + [ + 'entity_type_id' => 'short_entity_type', + 'field_name' => 'long_field_name_abcdefghijklmnopqrstuvwxyz', + 'prefix' => '', + ], + 'short_entity_type__28a01c7777', + 'short_entity_type_r__28a01c7777', + ]; + $data['long entity type; short field name; no prefix'] = [ + [ + 'entity_type_id' => 'long_entity_type_abcdefghijklmnopqrstuvwxyz', + 'field_name' => 'short_field_name', + 'prefix' => '', + ], + 'long_entity_type_abcdefghijklmno__a526e4e042', + 'long_entity_type_abcdefghijklmno_r__a526e4e042', + ]; + $data['long entity type; long field name; no prefix'] = [ + [ + 'entity_type_id' => 'long_entity_type_abcdefghijklmnopqrstuvwxyz', + 'field_name' => 'long_field_name_abcdefghijklmnopqrstuvwxyz', + 'prefix' => '', + ], + 'long_entity_type_abcdefghijklmno__7705d52d75', + 'long_entity_type_abcdefghijklmno_r__7705d52d75', + ]; + + $data['short entity type; short field name; with prefix'] = [ + [ + 'entity_type_id' => 'short_entity_type', + 'field_name' => 'short_field_name', + 'prefix' => 'prefix_', + ], + 'prefix_short_entity_type__short_field_name', + 'prefix_short_entity_type_r__a133cc765a', + ]; + $data['short entity type; long field name; with prefix'] = [ + [ + 'entity_type_id' => 'short_entity_type', + 'field_name' => 'long_field_name_abcdefghijklmnopqrstuvwxyz', + 'prefix' => 'prefix_', + ], + 'prefix_short_entity_type__28a01c7777', + 'prefix_short_entity_type_r__28a01c7777', + ]; + $data['long entity type; short field name; with prefix'] = [ + [ + 'entity_type_id' => 'long_entity_type_abcdefghijklmnopqrstuvwxyz', + 'field_name' => 'short_field_name', + 'prefix' => 'prefix_', + ], + 'prefix___a526e4e042', + 'prefix__r__a526e4e042', + ]; + $data['long entity type; long field name; with prefix'] = [ + [ + 'entity_type_id' => 'long_entity_type_abcdefghijklmnopqrstuvwxyz', + 'field_name' => 'long_field_name_abcdefghijklmnopqrstuvwxyz', + 'prefix' => 'prefix_', + ], + 'prefix___7705d52d75', + 'prefix__r__7705d52d75', + ]; + + return $data; + } + + /** + * @coversDefaultClass \Drupal\Core\Entity\Sql\TemporaryTableMapping + * + * @expectedDeprecation Drupal\Core\Entity\Sql\TemporaryTableMapping is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Use the default table mapping with a prefix instead. + * @group legacy + */ + public function testTemporaryTableMapping() { + $table_mapping = new TemporaryTableMapping($this->entityType, [], ''); + $this->assertTrue($table_mapping instanceof DefaultTableMapping); + } + + /** * Sets up a field storage definition for the test. * * @param string $name