From 82624c0f86ffd1eeb44507b912c270f5c1a388f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Tue, 6 Feb 2024 17:46:02 +0100 Subject: [PATCH 01/10] Make column and index renaming configurable --- src/Platforms/MySQL/Comparator.php | 4 ++- src/Platforms/SQLServer/Comparator.php | 4 ++- src/Platforms/SQLite/Comparator.php | 4 ++- src/Schema/Comparator.php | 17 ++++++--- src/Schema/ComparatorConfig.php | 32 +++++++++++++++++ tests/Schema/AbstractComparatorTestCase.php | 38 +++++++++++++++++++++ 6 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 src/Schema/ComparatorConfig.php diff --git a/src/Platforms/MySQL/Comparator.php b/src/Platforms/MySQL/Comparator.php index ebe025dc2a9..6be36be67a9 100644 --- a/src/Platforms/MySQL/Comparator.php +++ b/src/Platforms/MySQL/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -30,11 +31,12 @@ public function __construct( parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable): TableDiff + public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff { return parent::compareTables( $this->normalizeTable($oldTable), $this->normalizeTable($newTable), + $config, ); } diff --git a/src/Platforms/SQLServer/Comparator.php b/src/Platforms/SQLServer/Comparator.php index aa8d9fb5b62..5135b508b4f 100644 --- a/src/Platforms/SQLServer/Comparator.php +++ b/src/Platforms/SQLServer/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -22,11 +23,12 @@ public function __construct(SQLServerPlatform $platform, private readonly string parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable): TableDiff + public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff { return parent::compareTables( $this->normalizeColumns($oldTable), $this->normalizeColumns($newTable), + $config, ); } diff --git a/src/Platforms/SQLite/Comparator.php b/src/Platforms/SQLite/Comparator.php index f27e1b4571c..4c1f0475c97 100644 --- a/src/Platforms/SQLite/Comparator.php +++ b/src/Platforms/SQLite/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -24,11 +25,12 @@ public function __construct(SQLitePlatform $platform) parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable): TableDiff + public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff { return parent::compareTables( $this->normalizeColumns($oldTable), $this->normalizeColumns($newTable), + $config, ); } diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 4c60c0770a3..88710f84f6e 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -24,7 +24,7 @@ public function __construct(private readonly AbstractPlatform $platform) /** * Returns the differences between the schemas. */ - public function compareSchemas(Schema $oldSchema, Schema $newSchema): SchemaDiff + public function compareSchemas(Schema $oldSchema, Schema $newSchema, ?ComparatorConfig $config = null): SchemaDiff { $createdSchemas = []; $droppedSchemas = []; @@ -59,6 +59,7 @@ public function compareSchemas(Schema $oldSchema, Schema $newSchema): SchemaDiff $tableDiff = $this->compareTables( $oldSchema->getTable($newTableName), $newSchema->getTable($newTableName), + $config, ); if (! $tableDiff->isEmpty()) { @@ -141,14 +142,18 @@ public function diffSequence(Sequence $sequence1, Sequence $sequence2): bool /** * Compares the tables and returns the difference between them. */ - public function compareTables(Table $oldTable, Table $newTable): TableDiff + public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff { + $config ??= new ComparatorConfig(); + $addedColumns = []; $modifiedColumns = []; $droppedColumns = []; + $renamedColumns = []; $addedIndexes = []; $modifiedIndexes = []; $droppedIndexes = []; + $renamedIndexes = []; $addedForeignKeys = []; $modifiedForeignKeys = []; $droppedForeignKeys = []; @@ -187,7 +192,9 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff $modifiedColumns[] = new ColumnDiff($oldColumn, $newColumn); } - $renamedColumns = $this->detectRenamedColumns($addedColumns, $droppedColumns); + if ($config->getDetectRenamedColumns()) { + $renamedColumns = $this->detectRenamedColumns($addedColumns, $droppedColumns); + } $oldIndexes = $oldTable->getIndexes(); $newIndexes = $newTable->getIndexes(); @@ -224,7 +231,9 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff $modifiedIndexes[] = $newIndex; } - $renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes); + if ($config->getDetectRenamedIndexes()) { + $renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes); + } $oldForeignKeys = $oldTable->getForeignKeys(); $newForeignKeys = $newTable->getForeignKeys(); diff --git a/src/Schema/ComparatorConfig.php b/src/Schema/ComparatorConfig.php new file mode 100644 index 00000000000..a2e6d83f42e --- /dev/null +++ b/src/Schema/ComparatorConfig.php @@ -0,0 +1,32 @@ +detectRenamedColumns = $detectRenamedColumns; + } + + public function getDetectRenamedColumns(): bool + { + return $this->detectRenamedColumns; + } + + public function setDetectRenamedIndexes(bool $detectRenamedIndexes): void + { + $this->detectRenamedIndexes = $detectRenamedIndexes; + } + + public function getDetectRenamedIndexes(): bool + { + return $this->detectRenamedIndexes; + } +} diff --git a/tests/Schema/AbstractComparatorTestCase.php b/tests/Schema/AbstractComparatorTestCase.php index ed9faafb6f0..cdc5740742e 100644 --- a/tests/Schema/AbstractComparatorTestCase.php +++ b/tests/Schema/AbstractComparatorTestCase.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Schema; @@ -395,6 +396,23 @@ public function testDetectRenameColumn(): void self::assertEquals('bar', $renamedColumns['foo']->getName()); } + public function testDetectRenameColumnDisabled(): void + { + $tableA = new Table('foo'); + $tableA->addColumn('foo', Types::INTEGER); + + $tableB = new Table('foo'); + $tableB->addColumn('bar', Types::INTEGER); + + $config = new ComparatorConfig(); + $config->setDetectRenamedColumns(false); + $tableDiff = $this->comparator->compareTables($tableA, $tableB, $config); + + self::assertCount(1, $tableDiff->getAddedColumns()); + self::assertCount(1, $tableDiff->getDroppedColumns()); + self::assertCount(0, $tableDiff->getRenamedColumns()); + } + /** * You can easily have ambiguities in the column renaming. If these * are detected no renaming should take place, instead adding and dropping @@ -437,6 +455,26 @@ public function testDetectRenameIndex(): void self::assertEquals('idx_bar', $renamedIndexes['idx_foo']->getName()); } + public function testDetectRenameIndexDisabled(): void + { + $table1 = new Table('foo'); + $table1->addColumn('foo', Types::INTEGER); + + $table2 = clone $table1; + + $table1->addIndex(['foo'], 'idx_foo'); + + $table2->addIndex(['foo'], 'idx_bar'); + + $config = new ComparatorConfig(); + $config->setDetectRenamedIndexes(false); + $tableDiff = $this->comparator->compareTables($table1, $table2, $config); + + self::assertCount(1, $tableDiff->getAddedIndexes()); + self::assertCount(1, $tableDiff->getDroppedIndexes()); + self::assertCount(0, $tableDiff->getRenamedIndexes()); + } + /** * You can easily have ambiguities in the index renaming. If these * are detected no renaming should take place, instead adding and dropping From d0c8602b4e2ce9fcf5baba7e72d7781e7c4340b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Mon, 11 Mar 2024 14:09:51 +0100 Subject: [PATCH 02/10] Use setter method instead of config parameter --- src/Platforms/MySQL/Comparator.php | 4 +--- src/Platforms/SQLServer/Comparator.php | 4 +--- src/Platforms/SQLite/Comparator.php | 4 +--- src/Schema/Comparator.php | 20 ++++++++++++-------- tests/Schema/AbstractComparatorTestCase.php | 6 ++++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Platforms/MySQL/Comparator.php b/src/Platforms/MySQL/Comparator.php index 6be36be67a9..ebe025dc2a9 100644 --- a/src/Platforms/MySQL/Comparator.php +++ b/src/Platforms/MySQL/Comparator.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; -use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -31,12 +30,11 @@ public function __construct( parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff + public function compareTables(Table $oldTable, Table $newTable): TableDiff { return parent::compareTables( $this->normalizeTable($oldTable), $this->normalizeTable($newTable), - $config, ); } diff --git a/src/Platforms/SQLServer/Comparator.php b/src/Platforms/SQLServer/Comparator.php index 5135b508b4f..aa8d9fb5b62 100644 --- a/src/Platforms/SQLServer/Comparator.php +++ b/src/Platforms/SQLServer/Comparator.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; -use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -23,12 +22,11 @@ public function __construct(SQLServerPlatform $platform, private readonly string parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff + public function compareTables(Table $oldTable, Table $newTable): TableDiff { return parent::compareTables( $this->normalizeColumns($oldTable), $this->normalizeColumns($newTable), - $config, ); } diff --git a/src/Platforms/SQLite/Comparator.php b/src/Platforms/SQLite/Comparator.php index 4c1f0475c97..f27e1b4571c 100644 --- a/src/Platforms/SQLite/Comparator.php +++ b/src/Platforms/SQLite/Comparator.php @@ -6,7 +6,6 @@ use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; -use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -25,12 +24,11 @@ public function __construct(SQLitePlatform $platform) parent::__construct($platform); } - public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff + public function compareTables(Table $oldTable, Table $newTable): TableDiff { return parent::compareTables( $this->normalizeColumns($oldTable), $this->normalizeColumns($newTable), - $config, ); } diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 88710f84f6e..62d7970e2f4 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -17,14 +17,21 @@ class Comparator { /** @internal The comparator can be only instantiated by a schema manager. */ - public function __construct(private readonly AbstractPlatform $platform) + public function __construct( + private readonly AbstractPlatform $platform, + private ComparatorConfig $config = new ComparatorConfig(), + ) { + } + + public function setConfig(ComparatorConfig $config): void { + $this->config = $config; } /** * Returns the differences between the schemas. */ - public function compareSchemas(Schema $oldSchema, Schema $newSchema, ?ComparatorConfig $config = null): SchemaDiff + public function compareSchemas(Schema $oldSchema, Schema $newSchema): SchemaDiff { $createdSchemas = []; $droppedSchemas = []; @@ -59,7 +66,6 @@ public function compareSchemas(Schema $oldSchema, Schema $newSchema, ?Comparator $tableDiff = $this->compareTables( $oldSchema->getTable($newTableName), $newSchema->getTable($newTableName), - $config, ); if (! $tableDiff->isEmpty()) { @@ -142,10 +148,8 @@ public function diffSequence(Sequence $sequence1, Sequence $sequence2): bool /** * Compares the tables and returns the difference between them. */ - public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfig $config = null): TableDiff + public function compareTables(Table $oldTable, Table $newTable): TableDiff { - $config ??= new ComparatorConfig(); - $addedColumns = []; $modifiedColumns = []; $droppedColumns = []; @@ -192,7 +196,7 @@ public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfi $modifiedColumns[] = new ColumnDiff($oldColumn, $newColumn); } - if ($config->getDetectRenamedColumns()) { + if ($this->config->getDetectRenamedColumns()) { $renamedColumns = $this->detectRenamedColumns($addedColumns, $droppedColumns); } @@ -231,7 +235,7 @@ public function compareTables(Table $oldTable, Table $newTable, ?ComparatorConfi $modifiedIndexes[] = $newIndex; } - if ($config->getDetectRenamedIndexes()) { + if ($this->config->getDetectRenamedIndexes()) { $renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes); } diff --git a/tests/Schema/AbstractComparatorTestCase.php b/tests/Schema/AbstractComparatorTestCase.php index cdc5740742e..eb41ba914b7 100644 --- a/tests/Schema/AbstractComparatorTestCase.php +++ b/tests/Schema/AbstractComparatorTestCase.php @@ -406,7 +406,8 @@ public function testDetectRenameColumnDisabled(): void $config = new ComparatorConfig(); $config->setDetectRenamedColumns(false); - $tableDiff = $this->comparator->compareTables($tableA, $tableB, $config); + $this->comparator->setConfig($config); + $tableDiff = $this->comparator->compareTables($tableA, $tableB); self::assertCount(1, $tableDiff->getAddedColumns()); self::assertCount(1, $tableDiff->getDroppedColumns()); @@ -468,7 +469,8 @@ public function testDetectRenameIndexDisabled(): void $config = new ComparatorConfig(); $config->setDetectRenamedIndexes(false); - $tableDiff = $this->comparator->compareTables($table1, $table2, $config); + $this->comparator->setConfig($config); + $tableDiff = $this->comparator->compareTables($table1, $table2); self::assertCount(1, $tableDiff->getAddedIndexes()); self::assertCount(1, $tableDiff->getDroppedIndexes()); From 9180776e1161220c18b1e28422a9d3bbcd62a59e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Fri, 21 Jun 2024 13:35:22 +0200 Subject: [PATCH 03/10] Pass the config to SchemaManager::createComparator() --- src/Platforms/MySQL/Comparator.php | 4 +++- src/Platforms/SQLServer/Comparator.php | 10 +++++--- src/Platforms/SQLite/Comparator.php | 5 ++-- src/Schema/AbstractSchemaManager.php | 7 ++++-- src/Schema/Comparator.php | 7 +----- src/Schema/ComparatorConfig.php | 24 ++++++++++++------- src/Schema/MySQLSchemaManager.php | 11 +++++++-- src/Schema/SQLServerSchemaManager.php | 16 ++++++++++--- src/Schema/SQLiteSchemaManager.php | 7 ++++-- .../AbstractMySQLPlatformTestCase.php | 2 ++ tests/Platforms/AbstractPlatformTestCase.php | 3 ++- tests/Platforms/MySQL/ComparatorTest.php | 6 +++-- .../MySQL/MariaDBJsonComparatorTest.php | 2 ++ tests/Platforms/SQLServer/ComparatorTest.php | 5 ++-- tests/Platforms/SQLServerPlatformTest.php | 3 ++- tests/Platforms/SQLite/ComparatorTest.php | 5 ++-- tests/Platforms/SQLitePlatformTest.php | 3 ++- tests/Schema/AbstractComparatorTestCase.php | 21 +++++++++------- tests/Schema/Platforms/MySQLSchemaTest.php | 2 ++ 19 files changed, 96 insertions(+), 47 deletions(-) diff --git a/src/Platforms/MySQL/Comparator.php b/src/Platforms/MySQL/Comparator.php index ebe025dc2a9..14f02d03564 100644 --- a/src/Platforms/MySQL/Comparator.php +++ b/src/Platforms/MySQL/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -26,8 +27,9 @@ public function __construct( private readonly CharsetMetadataProvider $charsetMetadataProvider, private readonly CollationMetadataProvider $collationMetadataProvider, private readonly DefaultTableOptions $defaultTableOptions, + ComparatorConfig $config, ) { - parent::__construct($platform); + parent::__construct($platform, $config); } public function compareTables(Table $oldTable, Table $newTable): TableDiff diff --git a/src/Platforms/SQLServer/Comparator.php b/src/Platforms/SQLServer/Comparator.php index aa8d9fb5b62..a36fb2d22dd 100644 --- a/src/Platforms/SQLServer/Comparator.php +++ b/src/Platforms/SQLServer/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -17,9 +18,12 @@ class Comparator extends BaseComparator { /** @internal The comparator can be only instantiated by a schema manager. */ - public function __construct(SQLServerPlatform $platform, private readonly string $databaseCollation) - { - parent::__construct($platform); + public function __construct( + SQLServerPlatform $platform, + private readonly string $databaseCollation, + ComparatorConfig $config, + ) { + parent::__construct($platform, $config); } public function compareTables(Table $oldTable, Table $newTable): TableDiff diff --git a/src/Platforms/SQLite/Comparator.php b/src/Platforms/SQLite/Comparator.php index f27e1b4571c..9390e39ea57 100644 --- a/src/Platforms/SQLite/Comparator.php +++ b/src/Platforms/SQLite/Comparator.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Schema\Comparator as BaseComparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; @@ -19,9 +20,9 @@ class Comparator extends BaseComparator { /** @internal The comparator can be only instantiated by a schema manager. */ - public function __construct(SQLitePlatform $platform) + public function __construct(SQLitePlatform $platform, ComparatorConfig $config) { - parent::__construct($platform); + parent::__construct($platform, $config); } public function compareTables(Table $oldTable, Table $newTable): TableDiff diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 88ffdadc9cc..9d534485e59 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -17,6 +17,8 @@ use function array_map; use function array_values; use function count; +use function func_get_arg; +use function func_num_args; use function strtolower; /** @@ -840,9 +842,10 @@ private function getDatabase(string $methodName): string return $database; } - public function createComparator(): Comparator + /** @param ComparatorConfig $config */ + public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { - return new Comparator($this->platform); + return new Comparator($this->platform, func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig()); } /** diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 62d7970e2f4..8bc72644098 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -19,15 +19,10 @@ class Comparator /** @internal The comparator can be only instantiated by a schema manager. */ public function __construct( private readonly AbstractPlatform $platform, - private ComparatorConfig $config = new ComparatorConfig(), + private readonly ComparatorConfig $config, ) { } - public function setConfig(ComparatorConfig $config): void - { - $this->config = $config; - } - /** * Returns the differences between the schemas. */ diff --git a/src/Schema/ComparatorConfig.php b/src/Schema/ComparatorConfig.php index a2e6d83f42e..4f5fa59cc4e 100644 --- a/src/Schema/ComparatorConfig.php +++ b/src/Schema/ComparatorConfig.php @@ -4,15 +4,20 @@ namespace Doctrine\DBAL\Schema; -class ComparatorConfig +final class ComparatorConfig { - protected bool $detectRenamedColumns = true; - - protected bool $detectRenamedIndexes = true; + public function __construct( + private readonly bool $detectRenamedColumns = true, + private readonly bool $detectRenamedIndexes = true, + ) { + } - public function setDetectRenamedColumns(bool $detectRenamedColumns): void + public function withDetectRenamedColumns(bool $detectRenamedColumns): self { - $this->detectRenamedColumns = $detectRenamedColumns; + return new self( + $detectRenamedColumns, + $this->detectRenamedIndexes, + ); } public function getDetectRenamedColumns(): bool @@ -20,9 +25,12 @@ public function getDetectRenamedColumns(): bool return $this->detectRenamedColumns; } - public function setDetectRenamedIndexes(bool $detectRenamedIndexes): void + public function withDetectRenamedIndexes(bool $detectRenamedIndexes): self { - $this->detectRenamedIndexes = $detectRenamedIndexes; + return new self( + $this->detectRenamedColumns, + $detectRenamedIndexes, + ); } public function getDetectRenamedIndexes(): bool diff --git a/src/Schema/MySQLSchemaManager.php b/src/Schema/MySQLSchemaManager.php index fa042d653ce..90ea970fdf6 100644 --- a/src/Schema/MySQLSchemaManager.php +++ b/src/Schema/MySQLSchemaManager.php @@ -19,6 +19,8 @@ use function array_change_key_case; use function assert; use function explode; +use function func_get_arg; +use function func_num_args; use function implode; use function is_string; use function preg_match; @@ -313,8 +315,12 @@ protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey) ); } - /** @throws Exception */ - public function createComparator(): Comparator + /** + * @param ComparatorConfig $config + * + * @throws Exception + */ + public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { return new MySQL\Comparator( $this->platform, @@ -325,6 +331,7 @@ public function createComparator(): Comparator new ConnectionCollationMetadataProvider($this->connection), ), $this->getDefaultTableOptions(), + func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig(), ); } diff --git a/src/Schema/SQLServerSchemaManager.php b/src/Schema/SQLServerSchemaManager.php index e0a74ce2a81..736d0c533ba 100644 --- a/src/Schema/SQLServerSchemaManager.php +++ b/src/Schema/SQLServerSchemaManager.php @@ -13,6 +13,8 @@ use function array_change_key_case; use function assert; use function explode; +use function func_get_arg; +use function func_num_args; use function implode; use function is_string; use function preg_match; @@ -261,10 +263,18 @@ protected function _getPortableViewDefinition(array $view): View return new View($view['name'], $view['definition']); } - /** @throws Exception */ - public function createComparator(): Comparator + /** + * @param ComparatorConfig $config + * + * @throws Exception + */ + public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { - return new SQLServer\Comparator($this->platform, $this->getDatabaseCollation()); + return new SQLServer\Comparator( + $this->platform, + $this->getDatabaseCollation(), + func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig(), + ); } /** @throws Exception */ diff --git a/src/Schema/SQLiteSchemaManager.php b/src/Schema/SQLiteSchemaManager.php index 20dc4fd257d..74a8b006e54 100644 --- a/src/Schema/SQLiteSchemaManager.php +++ b/src/Schema/SQLiteSchemaManager.php @@ -16,6 +16,8 @@ use function array_merge; use function assert; use function count; +use function func_get_arg; +use function func_num_args; use function implode; use function is_string; use function preg_match; @@ -493,9 +495,10 @@ private function getForeignKeyDetails(string $table): array return $details; } - public function createComparator(): Comparator + /** @param ComparatorConfig $config */ + public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { - return new SQLite\Comparator($this->platform); + return new SQLite\Comparator($this->platform, func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig()); } protected function selectTableNames(string $databaseName): Result diff --git a/tests/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Platforms/AbstractMySQLPlatformTestCase.php index 4a48e89f0cf..66d23c2c89c 100644 --- a/tests/Platforms/AbstractMySQLPlatformTestCase.php +++ b/tests/Platforms/AbstractMySQLPlatformTestCase.php @@ -11,6 +11,7 @@ use Doctrine\DBAL\Platforms\MySQL\CollationMetadataProvider; use Doctrine\DBAL\Platforms\MySQL\DefaultTableOptions; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\TransactionIsolationLevel; use Doctrine\DBAL\Types\Types; @@ -678,6 +679,7 @@ protected function createComparator(): Comparator self::createStub(CharsetMetadataProvider::class), self::createStub(CollationMetadataProvider::class), new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'), + new ComparatorConfig(), ); } } diff --git a/tests/Platforms/AbstractPlatformTestCase.php b/tests/Platforms/AbstractPlatformTestCase.php index 9669d277b0f..b40da22e118 100644 --- a/tests/Platforms/AbstractPlatformTestCase.php +++ b/tests/Platforms/AbstractPlatformTestCase.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Table; @@ -39,7 +40,7 @@ protected function setUp(): void protected function createComparator(): Comparator { - return new Comparator($this->platform); + return new Comparator($this->platform, new ComparatorConfig()); } public function testQuoteIdentifier(): void diff --git a/tests/Platforms/MySQL/ComparatorTest.php b/tests/Platforms/MySQL/ComparatorTest.php index d2d8a25ad21..f69f8ab844a 100644 --- a/tests/Platforms/MySQL/ComparatorTest.php +++ b/tests/Platforms/MySQL/ComparatorTest.php @@ -9,17 +9,19 @@ use Doctrine\DBAL\Platforms\MySQL\Comparator; use Doctrine\DBAL\Platforms\MySQL\DefaultTableOptions; use Doctrine\DBAL\Platforms\MySQLPlatform; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Tests\Schema\AbstractComparatorTestCase; class ComparatorTest extends AbstractComparatorTestCase { - protected function setUp(): void + protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator { - $this->comparator = new Comparator( + return new Comparator( new MySQLPlatform(), self::createStub(CharsetMetadataProvider::class), self::createStub(CollationMetadataProvider::class), new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'), + $config, ); } } diff --git a/tests/Platforms/MySQL/MariaDBJsonComparatorTest.php b/tests/Platforms/MySQL/MariaDBJsonComparatorTest.php index 274edf99492..155ea813391 100644 --- a/tests/Platforms/MySQL/MariaDBJsonComparatorTest.php +++ b/tests/Platforms/MySQL/MariaDBJsonComparatorTest.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Platforms\MySQL\CollationMetadataProvider; use Doctrine\DBAL\Platforms\MySQL\Comparator; use Doctrine\DBAL\Platforms\MySQL\DefaultTableOptions; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Types; use PHPUnit\Framework\TestCase; @@ -39,6 +40,7 @@ public function getCollationCharset(string $collation): ?string } }, new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'), + new ComparatorConfig(), ); // TableA has collation set at table level and various column collations diff --git a/tests/Platforms/SQLServer/ComparatorTest.php b/tests/Platforms/SQLServer/ComparatorTest.php index d93bfcf021a..5392afe2332 100644 --- a/tests/Platforms/SQLServer/ComparatorTest.php +++ b/tests/Platforms/SQLServer/ComparatorTest.php @@ -6,12 +6,13 @@ use Doctrine\DBAL\Platforms\SQLServer\Comparator; use Doctrine\DBAL\Platforms\SQLServerPlatform; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Tests\Schema\AbstractComparatorTestCase; class ComparatorTest extends AbstractComparatorTestCase { - protected function setUp(): void + protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator { - $this->comparator = new Comparator(new SQLServerPlatform(), ''); + return new Comparator(new SQLServerPlatform(), '', $config); } } diff --git a/tests/Platforms/SQLServerPlatformTest.php b/tests/Platforms/SQLServerPlatformTest.php index 7f2aedf3921..265a0f93133 100644 --- a/tests/Platforms/SQLServerPlatformTest.php +++ b/tests/Platforms/SQLServerPlatformTest.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Sequence; use Doctrine\DBAL\Schema\Table; @@ -31,7 +32,7 @@ public function createPlatform(): AbstractPlatform protected function createComparator(): Comparator { - return new SQLServer\Comparator($this->platform, ''); + return new SQLServer\Comparator($this->platform, '', new ComparatorConfig()); } public function getGenerateTableSql(): string diff --git a/tests/Platforms/SQLite/ComparatorTest.php b/tests/Platforms/SQLite/ComparatorTest.php index 4ed8911b91c..3cd41348f21 100644 --- a/tests/Platforms/SQLite/ComparatorTest.php +++ b/tests/Platforms/SQLite/ComparatorTest.php @@ -6,13 +6,14 @@ use Doctrine\DBAL\Platforms\SQLite\Comparator; use Doctrine\DBAL\Platforms\SQLitePlatform; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Tests\Schema\AbstractComparatorTestCase; class ComparatorTest extends AbstractComparatorTestCase { - protected function setUp(): void + protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator { - $this->comparator = new Comparator(new SQLitePlatform()); + return new Comparator(new SQLitePlatform(), $config); } public function testCompareChangedBinaryColumn(): void diff --git a/tests/Platforms/SQLitePlatformTest.php b/tests/Platforms/SQLitePlatformTest.php index c15b85dcb32..0667803006b 100644 --- a/tests/Platforms/SQLitePlatformTest.php +++ b/tests/Platforms/SQLitePlatformTest.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\TransactionIsolationLevel; @@ -26,7 +27,7 @@ public function createPlatform(): AbstractPlatform protected function createComparator(): Comparator { - return new SQLite\Comparator($this->platform); + return new SQLite\Comparator($this->platform, new ComparatorConfig()); } public function getGenerateTableSql(): string diff --git a/tests/Schema/AbstractComparatorTestCase.php b/tests/Schema/AbstractComparatorTestCase.php index eb41ba914b7..7d4b02e077a 100644 --- a/tests/Schema/AbstractComparatorTestCase.php +++ b/tests/Schema/AbstractComparatorTestCase.php @@ -25,7 +25,14 @@ abstract class AbstractComparatorTestCase extends TestCase { - protected Comparator $comparator; + private Comparator $comparator; + + abstract protected function createComparator(ComparatorConfig $config): Comparator; + + protected function setUp(): void + { + $this->comparator = $this->createComparator(new ComparatorConfig()); + } public function testCompareSame1(): void { @@ -404,10 +411,8 @@ public function testDetectRenameColumnDisabled(): void $tableB = new Table('foo'); $tableB->addColumn('bar', Types::INTEGER); - $config = new ComparatorConfig(); - $config->setDetectRenamedColumns(false); - $this->comparator->setConfig($config); - $tableDiff = $this->comparator->compareTables($tableA, $tableB); + $this->comparator = $this->createComparator((new ComparatorConfig())->withDetectRenamedColumns(false)); + $tableDiff = $this->comparator->compareTables($tableA, $tableB); self::assertCount(1, $tableDiff->getAddedColumns()); self::assertCount(1, $tableDiff->getDroppedColumns()); @@ -467,10 +472,8 @@ public function testDetectRenameIndexDisabled(): void $table2->addIndex(['foo'], 'idx_bar'); - $config = new ComparatorConfig(); - $config->setDetectRenamedIndexes(false); - $this->comparator->setConfig($config); - $tableDiff = $this->comparator->compareTables($table1, $table2); + $this->comparator = $this->createComparator((new ComparatorConfig())->withDetectRenamedIndexes(false)); + $tableDiff = $this->comparator->compareTables($table1, $table2); self::assertCount(1, $tableDiff->getAddedIndexes()); self::assertCount(1, $tableDiff->getDroppedIndexes()); diff --git a/tests/Schema/Platforms/MySQLSchemaTest.php b/tests/Schema/Platforms/MySQLSchemaTest.php index fee785069e2..252808c2a00 100644 --- a/tests/Schema/Platforms/MySQLSchemaTest.php +++ b/tests/Schema/Platforms/MySQLSchemaTest.php @@ -11,6 +11,7 @@ use Doctrine\DBAL\Platforms\MySQL\DefaultTableOptions; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Types; use PHPUnit\Framework\TestCase; @@ -71,6 +72,7 @@ private function createComparator(): Comparator self::createStub(CharsetMetadataProvider::class), self::createStub(CollationMetadataProvider::class), new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'), + new ComparatorConfig(), ); } } From e117bbbfbd9a6968c5d7466d0f12398a279c79e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Fri, 21 Jun 2024 13:53:09 +0200 Subject: [PATCH 04/10] Add documentation --- docs/en/reference/schema-manager.rst | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/docs/en/reference/schema-manager.rst b/docs/en/reference/schema-manager.rst index cb462ca0540..45a6e8071ab 100644 --- a/docs/en/reference/schema-manager.rst +++ b/docs/en/reference/schema-manager.rst @@ -217,7 +217,7 @@ the changes on the database: .. code-block:: php getMigrateToSql($toSchema, $conn->getDatabasePlatform()); + $sql = $sm->createComparator()->compareSchemas($fromSchema, $toSchema)->toSql($conn->getDatabasePlatform()); The ``$sql`` array should give you a SQL query to drop the user table: @@ -233,6 +233,29 @@ table: ) */ +createComparator() +------------------ + +To create a comparator that can be used to compare two schemas use the +``createComparator()`` method which returns an instance of +``Doctrine\DBAL\Schema\Comparator``. + +.. code-block:: php + + createComparator(); + $schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema); + +To change the configuration of the comparator, you can pass as +``Doctrine\DBAL\Schema\ComparatorConfig`` object to the method: + +.. code-block:: php + + withDetectRenamedColumns(false); + $comparator = $sm->createComparator($config); + $schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema); + Overriding the schema manager ----------------------------- From b4195aed7722f5f0dad05ca637f798b1a5792d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Fri, 21 Jun 2024 14:00:09 +0200 Subject: [PATCH 05/10] Fix CI --- src/Schema/AbstractSchemaManager.php | 1 - src/Schema/MySQLSchemaManager.php | 6 +----- src/Schema/SQLServerSchemaManager.php | 6 +----- src/Schema/SQLiteSchemaManager.php | 1 - 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 9d534485e59..f0b6cae4359 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -842,7 +842,6 @@ private function getDatabase(string $methodName): string return $database; } - /** @param ComparatorConfig $config */ public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { return new Comparator($this->platform, func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig()); diff --git a/src/Schema/MySQLSchemaManager.php b/src/Schema/MySQLSchemaManager.php index c84d0e4ebeb..b2f949849d6 100644 --- a/src/Schema/MySQLSchemaManager.php +++ b/src/Schema/MySQLSchemaManager.php @@ -315,11 +315,7 @@ protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey) ); } - /** - * @param ComparatorConfig $config - * - * @throws Exception - */ + /** @throws Exception */ public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { return new MySQL\Comparator( diff --git a/src/Schema/SQLServerSchemaManager.php b/src/Schema/SQLServerSchemaManager.php index 736d0c533ba..f93d99bba6c 100644 --- a/src/Schema/SQLServerSchemaManager.php +++ b/src/Schema/SQLServerSchemaManager.php @@ -263,11 +263,7 @@ protected function _getPortableViewDefinition(array $view): View return new View($view['name'], $view['definition']); } - /** - * @param ComparatorConfig $config - * - * @throws Exception - */ + /** @throws Exception */ public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { return new SQLServer\Comparator( diff --git a/src/Schema/SQLiteSchemaManager.php b/src/Schema/SQLiteSchemaManager.php index a9fcdf38688..6d69e598854 100644 --- a/src/Schema/SQLiteSchemaManager.php +++ b/src/Schema/SQLiteSchemaManager.php @@ -495,7 +495,6 @@ private function getForeignKeyDetails(string $table): array return $details; } - /** @param ComparatorConfig $config */ public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator { return new SQLite\Comparator($this->platform, func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig()); From 12a347979aa468ae80dcedf81520f7374117ec84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Thu, 15 Aug 2024 10:37:16 +0200 Subject: [PATCH 06/10] Fix test --- tests/Functional/Schema/ComparatorTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Functional/Schema/ComparatorTest.php b/tests/Functional/Schema/ComparatorTest.php index da7244aad9c..17bd048e4ea 100644 --- a/tests/Functional/Schema/ComparatorTest.php +++ b/tests/Functional/Schema/ComparatorTest.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\Platforms\MariaDBPlatform; use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Comparator; +use Doctrine\DBAL\Schema\ComparatorConfig; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Tests\Functional\Platform\RenameColumnTest; use Doctrine\DBAL\Tests\FunctionalTestCase; @@ -53,7 +54,7 @@ public function testDefaultValueComparison(string $type, mixed $value): void public function testRenameColumnComparison(): void { $platform = $this->connection->getDatabasePlatform(); - $comparator = new Comparator($platform); + $comparator = new Comparator($platform, new ComparatorConfig()); $table = new Table('rename_table'); $table->addColumn('test', Types::STRING, ['default' => 'baz', 'length' => 20]); From 05ad0d8fb651830c2171f946cb87919ee2f98e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Thu, 15 Aug 2024 11:02:19 +0200 Subject: [PATCH 07/10] Remove unused variable --- src/Schema/Comparator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 4a5dba711fc..f344c5b5e9e 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -148,7 +148,6 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff $addedColumns = []; $modifiedColumns = []; $droppedColumns = []; - $renamedColumns = []; $addedIndexes = []; $modifiedIndexes = []; $droppedIndexes = []; From 4751bc90f0339abbf1697e2486d76033d283b180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Thu, 10 Oct 2024 15:49:21 +0200 Subject: [PATCH 08/10] Fix backwards compatibility of constructors --- src/Platforms/MySQL/Comparator.php | 2 +- src/Platforms/SQLServer/Comparator.php | 2 +- src/Platforms/SQLite/Comparator.php | 2 +- src/Schema/Comparator.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Platforms/MySQL/Comparator.php b/src/Platforms/MySQL/Comparator.php index 14f02d03564..af2dbe88215 100644 --- a/src/Platforms/MySQL/Comparator.php +++ b/src/Platforms/MySQL/Comparator.php @@ -27,7 +27,7 @@ public function __construct( private readonly CharsetMetadataProvider $charsetMetadataProvider, private readonly CollationMetadataProvider $collationMetadataProvider, private readonly DefaultTableOptions $defaultTableOptions, - ComparatorConfig $config, + ComparatorConfig $config = new ComparatorConfig(), ) { parent::__construct($platform, $config); } diff --git a/src/Platforms/SQLServer/Comparator.php b/src/Platforms/SQLServer/Comparator.php index a36fb2d22dd..079e70eafaf 100644 --- a/src/Platforms/SQLServer/Comparator.php +++ b/src/Platforms/SQLServer/Comparator.php @@ -21,7 +21,7 @@ class Comparator extends BaseComparator public function __construct( SQLServerPlatform $platform, private readonly string $databaseCollation, - ComparatorConfig $config, + ComparatorConfig $config = new ComparatorConfig(), ) { parent::__construct($platform, $config); } diff --git a/src/Platforms/SQLite/Comparator.php b/src/Platforms/SQLite/Comparator.php index 9390e39ea57..d14aefb29b5 100644 --- a/src/Platforms/SQLite/Comparator.php +++ b/src/Platforms/SQLite/Comparator.php @@ -20,7 +20,7 @@ class Comparator extends BaseComparator { /** @internal The comparator can be only instantiated by a schema manager. */ - public function __construct(SQLitePlatform $platform, ComparatorConfig $config) + public function __construct(SQLitePlatform $platform, ComparatorConfig $config = new ComparatorConfig()) { parent::__construct($platform, $config); } diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index f344c5b5e9e..a2b18b802c3 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -19,7 +19,7 @@ class Comparator /** @internal The comparator can be only instantiated by a schema manager. */ public function __construct( private readonly AbstractPlatform $platform, - private readonly ComparatorConfig $config, + private readonly ComparatorConfig $config = new ComparatorConfig(), ) { } From c204fe1dca1d2949544b3e2b443942e2a0f00c6b Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Fri, 11 Oct 2024 13:56:10 +0200 Subject: [PATCH 09/10] Run risky code in finally block (#6543) | Q | A |------------- | ----------- | Type | bug | Fixed issues | https://github.com/doctrine/dbal/pull/4846 #### Summary Let's do the same thing as for ORM in https://github.com/doctrine/orm/pull/11646 This somehow solves issue we tried to resolve in https://github.com/doctrine/dbal/pull/4846 by providing original exception in Previous. --- src/Connection.php | 13 +++++++++---- tests/ConnectionTest.php | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Connection.php b/src/Connection.php index b9756706061..9ca4d74b024 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -1278,15 +1278,20 @@ public function lastInsertId($name = null) public function transactional(Closure $func) { $this->beginTransaction(); + + $successful = false; + try { $res = $func($this); $this->commit(); - return $res; - } catch (Throwable $e) { - $this->rollBack(); + $successful = true; - throw $e; + return $res; + } finally { + if (! $successful) { + $this->rollBack(); + } } } diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index 0a94a129b45..719647989f9 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -1004,6 +1004,27 @@ public function testLegacySchemaManagerFactory(): void $connection = DriverManager::getConnection(['driver' => 'sqlite3', 'memory' => true]); self::assertInstanceOf(SqliteSchemaManager::class, $connection->createSchemaManager()); } + + public function testItPreservesTheOriginalExceptionOnRollbackFailure(): void + { + $connection = new class (['memory' => true], new Driver\SQLite3\Driver()) extends Connection { + public function rollBack(): void + { + throw new Exception('Rollback exception'); + } + }; + + try { + $connection->transactional(static function (): void { + throw new Exception('Original exception'); + }); + self::fail('Exception expected'); + } catch (Exception $e) { + self::assertSame('Rollback exception', $e->getMessage()); + self::assertNotNull($e->getPrevious()); + self::assertSame('Original exception', $e->getPrevious()->getMessage()); + } + } } interface ConnectDispatchEventListener From 92356cff13ff6ced66a217c2e69a9811978ec357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Auswo=CC=88ger?= Date: Fri, 11 Oct 2024 11:12:56 +0200 Subject: [PATCH 10/10] Use child class as return type --- docs/en/reference/schema-manager.rst | 2 +- tests/Platforms/MySQL/ComparatorTest.php | 2 +- tests/Platforms/SQLServer/ComparatorTest.php | 2 +- tests/Platforms/SQLite/ComparatorTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/en/reference/schema-manager.rst b/docs/en/reference/schema-manager.rst index 45a6e8071ab..1eda305ac74 100644 --- a/docs/en/reference/schema-manager.rst +++ b/docs/en/reference/schema-manager.rst @@ -246,7 +246,7 @@ To create a comparator that can be used to compare two schemas use the $comparator = $sm->createComparator(); $schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema); -To change the configuration of the comparator, you can pass as +To change the configuration of the comparator, you can pass a ``Doctrine\DBAL\Schema\ComparatorConfig`` object to the method: .. code-block:: php diff --git a/tests/Platforms/MySQL/ComparatorTest.php b/tests/Platforms/MySQL/ComparatorTest.php index f69f8ab844a..da57a11bf10 100644 --- a/tests/Platforms/MySQL/ComparatorTest.php +++ b/tests/Platforms/MySQL/ComparatorTest.php @@ -14,7 +14,7 @@ class ComparatorTest extends AbstractComparatorTestCase { - protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator + protected function createComparator(ComparatorConfig $config): Comparator { return new Comparator( new MySQLPlatform(), diff --git a/tests/Platforms/SQLServer/ComparatorTest.php b/tests/Platforms/SQLServer/ComparatorTest.php index 5392afe2332..682fc204454 100644 --- a/tests/Platforms/SQLServer/ComparatorTest.php +++ b/tests/Platforms/SQLServer/ComparatorTest.php @@ -11,7 +11,7 @@ class ComparatorTest extends AbstractComparatorTestCase { - protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator + protected function createComparator(ComparatorConfig $config): Comparator { return new Comparator(new SQLServerPlatform(), '', $config); } diff --git a/tests/Platforms/SQLite/ComparatorTest.php b/tests/Platforms/SQLite/ComparatorTest.php index 3cd41348f21..59275581dd5 100644 --- a/tests/Platforms/SQLite/ComparatorTest.php +++ b/tests/Platforms/SQLite/ComparatorTest.php @@ -11,7 +11,7 @@ class ComparatorTest extends AbstractComparatorTestCase { - protected function createComparator(ComparatorConfig $config): \Doctrine\DBAL\Schema\Comparator + protected function createComparator(ComparatorConfig $config): Comparator { return new Comparator(new SQLitePlatform(), $config); }