Skip to content

Commit

Permalink
Merge branch '4.3.x' into 5.0.x
Browse files Browse the repository at this point in the history
* 4.3.x:
  Use child class as return type
  Run risky code in finally block (#6543)
  Fix backwards compatibility of constructors
  Remove unused variable
  Fix test
  Fix CI
  Add documentation
  Pass the config to SchemaManager::createComparator()
  Use setter method instead of config parameter
  Make column and index renaming configurable
  • Loading branch information
derrabus committed Oct 12, 2024
2 parents 4d93661 + 5746c89 commit c6d139a
Show file tree
Hide file tree
Showing 23 changed files with 206 additions and 33 deletions.
25 changes: 24 additions & 1 deletion docs/en/reference/schema-manager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ the changes on the database:
.. code-block:: php
<?php
$sql = $fromSchema->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:
Expand All @@ -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
<?php
$comparator = $sm->createComparator();
$schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema);
To change the configuration of the comparator, you can pass a
``Doctrine\DBAL\Schema\ComparatorConfig`` object to the method:

.. code-block:: php
<?php
$config = (new ComparatorConfig())->withDetectRenamedColumns(false);
$comparator = $sm->createComparator($config);
$schemaDiff = $comparator->compareSchemas($fromSchema, $toSchema);
Overriding the schema manager
-----------------------------

Expand Down
13 changes: 9 additions & 4 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -926,15 +926,20 @@ public function lastInsertId(): int|string
public function transactional(Closure $func): mixed
{
$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();
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/Platforms/MySQL/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -26,8 +27,9 @@ public function __construct(
private readonly CharsetMetadataProvider $charsetMetadataProvider,
private readonly CollationMetadataProvider $collationMetadataProvider,
private readonly DefaultTableOptions $defaultTableOptions,
ComparatorConfig $config = new ComparatorConfig(),
) {
parent::__construct($platform);
parent::__construct($platform, $config);
}

public function compareTables(Table $oldTable, Table $newTable): TableDiff
Expand Down
10 changes: 7 additions & 3 deletions src/Platforms/SQLServer/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 = new ComparatorConfig(),
) {
parent::__construct($platform, $config);
}

public function compareTables(Table $oldTable, Table $newTable): TableDiff
Expand Down
5 changes: 3 additions & 2 deletions src/Platforms/SQLite/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 = new ComparatorConfig())
{
parent::__construct($platform);
parent::__construct($platform, $config);
}

public function compareTables(Table $oldTable, Table $newTable): TableDiff
Expand Down
6 changes: 4 additions & 2 deletions src/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -840,9 +842,9 @@ private function getDatabase(string $methodName): string
return $database;
}

public function createComparator(): Comparator
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());
}

/**
Expand Down
15 changes: 11 additions & 4 deletions src/Schema/Comparator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
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 readonly ComparatorConfig $config = new ComparatorConfig(),
) {
}

/**
Expand Down Expand Up @@ -149,6 +151,7 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff
$addedIndexes = [];
$modifiedIndexes = [];
$droppedIndexes = [];
$renamedIndexes = [];
$addedForeignKeys = [];
$modifiedForeignKeys = [];
$droppedForeignKeys = [];
Expand Down Expand Up @@ -207,7 +210,9 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff
);
}

$this->detectRenamedColumns($modifiedColumns, $addedColumns, $droppedColumns);
if ($this->config->getDetectRenamedColumns()) {
$this->detectRenamedColumns($modifiedColumns, $addedColumns, $droppedColumns);
}

$oldIndexes = $oldTable->getIndexes();
$newIndexes = $newTable->getIndexes();
Expand Down Expand Up @@ -244,7 +249,9 @@ public function compareTables(Table $oldTable, Table $newTable): TableDiff
$modifiedIndexes[] = $newIndex;
}

$renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes);
if ($this->config->getDetectRenamedIndexes()) {
$renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes);
}

$oldForeignKeys = $oldTable->getForeignKeys();
$newForeignKeys = $newTable->getForeignKeys();
Expand Down
40 changes: 40 additions & 0 deletions src/Schema/ComparatorConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Schema;

final class ComparatorConfig
{
public function __construct(
private readonly bool $detectRenamedColumns = true,
private readonly bool $detectRenamedIndexes = true,
) {
}

public function withDetectRenamedColumns(bool $detectRenamedColumns): self
{
return new self(
$detectRenamedColumns,
$this->detectRenamedIndexes,
);
}

public function getDetectRenamedColumns(): bool
{
return $this->detectRenamedColumns;
}

public function withDetectRenamedIndexes(bool $detectRenamedIndexes): self
{
return new self(
$this->detectRenamedColumns,
$detectRenamedIndexes,
);
}

public function getDetectRenamedIndexes(): bool
{
return $this->detectRenamedIndexes;
}
}
5 changes: 4 additions & 1 deletion src/Schema/MySQLSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use function array_map;
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;
Expand Down Expand Up @@ -335,7 +337,7 @@ protected function _getPortableTableForeignKeyDefinition(array $tableForeignKey)
}

/** @throws Exception */
public function createComparator(): Comparator
public function createComparator(/* ComparatorConfig $config = new ComparatorConfig() */): Comparator
{
return new MySQL\Comparator(
$this->platform,
Expand All @@ -346,6 +348,7 @@ public function createComparator(): Comparator
new ConnectionCollationMetadataProvider($this->connection),
),
$this->getDefaultTableOptions(),
func_num_args() > 0 ? func_get_arg(0) : new ComparatorConfig(),
);
}

Expand Down
10 changes: 8 additions & 2 deletions src/Schema/SQLServerSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -262,9 +264,13 @@ protected function _getPortableViewDefinition(array $view): View
}

/** @throws Exception */
public function createComparator(): Comparator
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 */
Expand Down
6 changes: 4 additions & 2 deletions src/Schema/SQLiteSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -494,9 +496,9 @@ private function getForeignKeyDetails(string $table): array
return $details;
}

public function createComparator(): Comparator
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
Expand Down
21 changes: 21 additions & 0 deletions tests/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -623,4 +623,25 @@ public function testDefaultSchemaManagerFactory(): 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 ConnectionException('Rollback exception');
}
};

try {
$connection->transactional(static function (): void {
throw new ConnectionException('Original exception');
});
self::fail('Exception expected'); // @phpstan-ignore deadCode.unreachable
} catch (ConnectionException $e) {
self::assertSame('Rollback exception', $e->getMessage());
self::assertNotNull($e->getPrevious());
self::assertSame('Original exception', $e->getPrevious()->getMessage());
}
}
}
3 changes: 2 additions & 1 deletion tests/Functional/Schema/ComparatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]);
Expand Down
2 changes: 2 additions & 0 deletions tests/Platforms/AbstractMySQLPlatformTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -692,6 +693,7 @@ protected function createComparator(): Comparator
self::createStub(CharsetMetadataProvider::class),
self::createStub(CollationMetadataProvider::class),
new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'),
new ComparatorConfig(),
);
}
}
3 changes: 2 additions & 1 deletion tests/Platforms/AbstractPlatformTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -40,7 +41,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
Expand Down
Loading

0 comments on commit c6d139a

Please sign in to comment.