[BUGFIX] Respect SQL table names max length in install tool 83/50583/5
authorMarkus Hoelzle <typo3@markus-hoelzle.de>
Thu, 10 Nov 2016 19:47:14 +0000 (20:47 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 2 Dec 2016 16:29:39 +0000 (17:29 +0100)
Respect the max length of 64 chars in sql if removing (renaming)
an SQL table. Add unit test.

Resolves: #78636
Releases: master
Change-Id: I5f5d4b239f467a205edfdceeac97da5625631a83
Reviewed-on: https://review.typo3.org/50583
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Alexander Rothmund <alexander@rothmund.ch>
Tested-by: Alexander Rothmund <alexander@rothmund.ch>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php
typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php [new file with mode: 0644]

index 9b097a0..c74d39a 100644 (file)
@@ -42,6 +42,11 @@ class ConnectionMigrator
     protected $deletedPrefix = 'zzz_deleted_';
 
     /**
+     * @var int
+     */
+    protected $maxTableNameLength = 64;
+
+    /**
      * @var Connection
      */
     protected $connection;
@@ -876,6 +881,13 @@ class ConnectionMigrator
             );
 
             $tableDiff->newName = $this->deletedPrefix . $removedTable->getName();
+            if (strlen($tableDiff->newName) > $this->maxTableNameLength) {
+                $shortTableName = substr(
+                    $removedTable->getName(),
+                    strlen($removedTable->getName()) + strlen($this->deletedPrefix) - $this->maxTableNameLength
+                );
+                $tableDiff->newName = $this->deletedPrefix . $shortTableName;
+            }
             $schemaDiff->changedTables[$index] = $tableDiff;
             unset($schemaDiff->removedTables[$index]);
         }
diff --git a/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php b/typo3/sysext/core/Tests/Unit/Database/Schema/ConnectionMigratorTest.php
new file mode 100644 (file)
index 0000000..207b320
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+declare(strict_types=1);
+
+namespace TYPO3\CMS\Core\Tests\Unit\Database;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Doctrine\DBAL\Schema\SchemaDiff;
+use Doctrine\DBAL\Schema\Table;
+use TYPO3\CMS\Core\Database\Connection;
+use TYPO3\CMS\Core\Database\Schema\ConnectionMigrator;
+use TYPO3\CMS\Core\Tests\UnitTestCase;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Tests for ConnectionMigrator
+ */
+class ConnectionMigratorTest extends UnitTestCase
+{
+
+    /**
+     * @test
+     */
+    public function tableNamesStickToTheMaximumCharactersWhenPrefixedForRemoval()
+    {
+        $ridiculouslyLongTableName = 'table_name_that_is_ridiculously_long_' . random_bytes(200);
+        $tableMock = $this->getAccessibleMock(Table::class, ['getQuotedName'], [$ridiculouslyLongTableName]);
+        $tableMock->expects($this->any())->method('getQuotedName')->withAnyParameters()->will($this->returnValue($ridiculouslyLongTableName));
+
+        $platform = $this->getMockBuilder(\Doctrine\DBAL\Platforms\AbstractPlatform::class)->disableOriginalConstructor()->getMock();
+
+        $connectionMock = $this->getMockBuilder(Connection::class)->setMethods(['getDatabasePlatform'])->disableOriginalConstructor()->getMock();
+        $connectionMock->method('getDatabasePlatform')->willReturn($platform);
+
+        $connectionMigrator = $this->getAccessibleMock(ConnectionMigrator::class, null, [], '', false);
+        $connectionMigrator->_set('connection', $connectionMock);
+
+        $originalSchemaDiff = GeneralUtility::makeInstance(SchemaDiff::class, null, null, [$tableMock]);
+
+        $renamedSchemaDiff = $connectionMigrator->_call('migrateUnprefixedRemovedTablesToRenames', $originalSchemaDiff);
+
+        $this->assertStringStartsWith('zzz_deleted_', $renamedSchemaDiff->changedTables[0]->newName);
+        $this->assertLessThanOrEqual(
+            strlen($renamedSchemaDiff->changedTables[0]->newName),
+            $this->maxTableNameLength
+        );
+    }
+}