From b62f06256982a2647f18b963f40ff0ca067cdb2b Mon Sep 17 00:00:00 2001 From: Thomas Hohn <thomas@hohn.dk> Date: Thu, 23 Feb 2017 18:54:21 +0100 Subject: [PATCH] [BUGFIX] Detect TEXT/BLOB changes in schema analyzer Length changes of TEXT/BLOB type are not analyzed by the Doctrine schema analyzer as only MySQL has different length version of these fields. Add a custom column comparator that compares the different fields length on MySQL to properly detect changes in field type. Resolves: #79722 Releases: master Change-Id: I2e448dcde02c3fa370496b4920dfad536fbafcd6 Reviewed-on: https://review.typo3.org/51807 Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de> Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de> Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Classes/Database/Schema/Comparator.php | 53 +++++++++++++++++++ .../Database/Schema/ConnectionMigrator.php | 5 +- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/typo3/sysext/core/Classes/Database/Schema/Comparator.php b/typo3/sysext/core/Classes/Database/Schema/Comparator.php index 8a09ef9491db..f21f255702b6 100644 --- a/typo3/sysext/core/Classes/Database/Schema/Comparator.php +++ b/typo3/sysext/core/Classes/Database/Schema/Comparator.php @@ -15,7 +15,11 @@ namespace TYPO3\CMS\Core\Database\Schema; * The TYPO3 project - inspiring people to share! */ +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Platforms\MySqlPlatform; +use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Table; +use Doctrine\DBAL\Types; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -25,6 +29,21 @@ use TYPO3\CMS\Core\Utility\GeneralUtility; */ class Comparator extends \Doctrine\DBAL\Schema\Comparator { + /** + * @var AbstractPlatform + */ + protected $databasePlatform; + + /** + * Comparator constructor. + * + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + */ + public function __construct(AbstractPlatform $platform = null) + { + $this->databasePlatform = $platform; + } + /** * Returns the difference between the tables $fromTable and $toTable. * @@ -69,4 +88,38 @@ class Comparator extends \Doctrine\DBAL\Schema\Comparator return $tableDifferences; } + + /** + * Returns the difference between the columns $column1 and $column2 + * by first checking the doctrine diffColumn. Extend the Doctrine + * method by taking into account MySQL TINY/MEDIUM/LONG type variants. + * + * @param \Doctrine\DBAL\Schema\Column $column1 + * @param \Doctrine\DBAL\Schema\Column $column2 + * @return array + */ + public function diffColumn(Column $column1, Column $column2) + { + $changedProperties = parent::diffColumn($column1, $column2); + + // Only MySQL has variable length versions of TEXT/BLOB + if (!$this->databasePlatform instanceof MySqlPlatform) { + return $changedProperties; + } + + $properties1 = $column1->toArray(); + $properties2 = $column2->toArray(); + + if ($properties1['type'] instanceof Types\BlobType || $properties1['type'] instanceof Types\TextType) { + // Doctrine does not provide a length for LONGTEXT/LONGBLOB columns + $length1 = $properties1['length'] ?: 2147483647; + $length2 = $properties2['length'] ?: 2147483647; + + if ($length1 !== $length2) { + $changedProperties[] = 'length'; + } + } + + return array_unique($changedProperties); + } } diff --git a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php index 46f63bc5e790..d2ebdcc826c5 100644 --- a/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php +++ b/typo3/sysext/core/Classes/Database/Schema/ConnectionMigrator.php @@ -224,8 +224,9 @@ class ConnectionMigrator * for tables that are in the database but have no direct relation to the TYPO3 instance. * * @param bool $renameUnused - * @return \Doctrine\DBAL\Schema\SchemaDiff * @throws \Doctrine\DBAL\DBALException + * @return \Doctrine\DBAL\Schema\SchemaDiff + * @throws \Doctrine\DBAL\Schema\SchemaException * @throws \InvalidArgumentException */ protected function buildSchemaDiff(bool $renameUnused = true): SchemaDiff @@ -247,7 +248,7 @@ class ConnectionMigrator } // Build SchemaDiff and handle renames of tables and colums - $comparator = GeneralUtility::makeInstance(Comparator::class); + $comparator = GeneralUtility::makeInstance(Comparator::class, $this->connection->getDatabasePlatform()); $schemaDiff = $comparator->compare($fromSchema, $toSchema); $schemaDiff = $this->migrateColumnRenamesToDistinctActions($schemaDiff); -- GitLab