From 268e75c09be76c82e3bc7e52f0bae2c667fb8ad5 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 5 Jun 2021 15:02:00 +0200 Subject: [PATCH 01/14] Add ReturnTypeWillChange to PDO implementations Signed-off-by: Alexander M. Turek --- lib/Doctrine/DBAL/Driver/PDOConnection.php | 5 +++++ lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php | 2 ++ lib/Doctrine/DBAL/Driver/PDOStatement.php | 7 +++++++ lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php | 4 ++++ 4 files changed, 18 insertions(+) diff --git a/lib/Doctrine/DBAL/Driver/PDOConnection.php b/lib/Doctrine/DBAL/Driver/PDOConnection.php index 5f8ccbeeb7d..92dba08a7a7 100644 --- a/lib/Doctrine/DBAL/Driver/PDOConnection.php +++ b/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -10,6 +10,7 @@ use PDO; use PDOException; use PDOStatement; +use ReturnTypeWillChange; use function assert; @@ -47,6 +48,7 @@ public function __construct($dsn, $user = null, $password = null, ?array $option /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function exec($sql) { try { @@ -73,6 +75,7 @@ public function getServerVersion() * * @return PDOStatement */ + #[ReturnTypeWillChange] public function prepare($sql, $driverOptions = []) { try { @@ -88,6 +91,7 @@ public function prepare($sql, $driverOptions = []) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function quote($value, $type = ParameterType::STRING) { return parent::quote($value, $type); @@ -96,6 +100,7 @@ public function quote($value, $type = ParameterType::STRING) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function lastInsertId($name = null) { try { diff --git a/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php b/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php index be05bf64601..68003d1702e 100644 --- a/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php +++ b/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php @@ -3,6 +3,7 @@ namespace Doctrine\DBAL\Driver; use PDOStatement; +use ReturnTypeWillChange; use function func_get_args; @@ -17,6 +18,7 @@ trait PDOQueryImplementation /** * @return PDOStatement */ + #[ReturnTypeWillChange] public function query(?string $query = null, ?int $fetchMode = null, mixed ...$fetchModeArgs) { return $this->doQuery($query, $fetchMode, ...$fetchModeArgs); diff --git a/lib/Doctrine/DBAL/Driver/PDOStatement.php b/lib/Doctrine/DBAL/Driver/PDOStatement.php index d0539103566..84f6b81eed0 100644 --- a/lib/Doctrine/DBAL/Driver/PDOStatement.php +++ b/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -9,6 +9,7 @@ use Doctrine\Deprecations\Deprecation; use PDO; use PDOException; +use ReturnTypeWillChange; use function array_slice; use function assert; @@ -56,6 +57,7 @@ protected function __construct() /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function bindValue($param, $value, $type = ParameterType::STRING) { $type = $this->convertParamType($type); @@ -76,6 +78,7 @@ public function bindValue($param, $value, $type = ParameterType::STRING) * * @return bool */ + #[ReturnTypeWillChange] public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) { $type = $this->convertParamType($type); @@ -92,6 +95,7 @@ public function bindParam($param, &$variable, $type = ParameterType::STRING, $le * * @deprecated Use free() instead. */ + #[ReturnTypeWillChange] public function closeCursor() { try { @@ -106,6 +110,7 @@ public function closeCursor() /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function execute($params = null) { try { @@ -120,6 +125,7 @@ public function execute($params = null) * * @deprecated Use fetchNumeric(), fetchAssociative() or fetchOne() instead. */ + #[ReturnTypeWillChange] public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) { $args = func_get_args(); @@ -140,6 +146,7 @@ public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEX * * @deprecated Use fetchOne() instead. */ + #[ReturnTypeWillChange] public function fetchColumn($columnIndex = 0) { try { diff --git a/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php b/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php index ff1a4af504d..a1f9ae616fe 100644 --- a/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php +++ b/lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php @@ -2,6 +2,8 @@ namespace Doctrine\DBAL\Driver; +use ReturnTypeWillChange; + use function func_get_args; use const PHP_VERSION_ID; @@ -20,6 +22,7 @@ trait PDOStatementImplementations * * @return bool */ + #[ReturnTypeWillChange] public function setFetchMode($mode, ...$args) { return $this->doSetFetchMode($mode, ...$args); @@ -33,6 +36,7 @@ public function setFetchMode($mode, ...$args) * * @return mixed[] */ + #[ReturnTypeWillChange] public function fetchAll($mode = null, ...$args) { return $this->doFetchAll($mode, ...$args); From 417c431adb5764f288f4a284abdb4d607a8fa581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 22 Jun 2021 21:44:11 +0200 Subject: [PATCH 02/14] Drop merge up and release branch creation steps They are causing more issues than they are solving for this repository, where manual merges up are frequent, as well as git conflicts, and where the branch setup is a bit more complex than other repositories (more branches maintained at a time, more frequent major releases). --- .../workflows/release-on-milestone-closed.yml | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index 0a8bf324d97..cd88ebdf362 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -23,23 +23,3 @@ jobs: "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - - - name: "Create Merge-Up Pull Request" - uses: "laminas/automatic-releases@1.0.1" - with: - command-name: "laminas:automatic-releases:create-merge-up-pull-request" - env: - "GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }} - "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} - "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} - "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - - - name: "Create and/or Switch to new Release Branch" - uses: "laminas/automatic-releases@v1" - with: - command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor" - env: - "GITHUB_TOKEN": ${{ secrets.ORGANIZATION_ADMIN_TOKEN }} - "SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }} - "GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }} - "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} From 9fe5679f00756e56415f707a070a55f371c0dd12 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 27 Apr 2021 06:06:15 -0600 Subject: [PATCH 03/14] Move fix for user provided pdo connection to Connection class The goal is to apply the fix to all connections, not just connections built using the DriverManager. Fixes #4619 --- lib/Doctrine/DBAL/Connection.php | 13 +++++ lib/Doctrine/DBAL/DriverManager.php | 9 ---- phpstan.neon.dist | 6 +++ tests/Doctrine/Tests/DBAL/ConnectionTest.php | 52 ++++++++++--------- .../Tests/DBAL/Functional/ConnectionTest.php | 18 ++++++- 5 files changed, 64 insertions(+), 34 deletions(-) diff --git a/lib/Doctrine/DBAL/Connection.php b/lib/Doctrine/DBAL/Connection.php index 23c2af2ccc2..d2f5b8a9bba 100644 --- a/lib/Doctrine/DBAL/Connection.php +++ b/lib/Doctrine/DBAL/Connection.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Cache\ResultCacheStatement; use Doctrine\DBAL\Driver\Connection as DriverConnection; +use Doctrine\DBAL\Driver\PDO\Statement as PDODriverStatement; use Doctrine\DBAL\Driver\PingableConnection; use Doctrine\DBAL\Driver\ResultStatement; use Doctrine\DBAL\Driver\ServerInfoAwareConnection; @@ -21,6 +22,7 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Types\Type; use Doctrine\Deprecations\Deprecation; +use PDO; use Throwable; use Traversable; @@ -193,7 +195,18 @@ public function __construct( $this->params = $params; if (isset($params['pdo'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3554', + 'Passing a user provided PDO instance directly to Doctrine is deprecated.' + ); + + if (! $params['pdo'] instanceof PDO) { + throw Exception::invalidPdoInstance(); + } + $this->_conn = $params['pdo']; + $this->_conn->setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDODriverStatement::class, []]); unset($this->params['pdo']); } diff --git a/lib/Doctrine/DBAL/DriverManager.php b/lib/Doctrine/DBAL/DriverManager.php index d084e220340..2ef49c49859 100644 --- a/lib/Doctrine/DBAL/DriverManager.php +++ b/lib/Doctrine/DBAL/DriverManager.php @@ -8,10 +8,8 @@ use Doctrine\DBAL\Driver\Mysqli; use Doctrine\DBAL\Driver\OCI8; use Doctrine\DBAL\Driver\PDO; -use Doctrine\DBAL\Driver\PDO\Statement as PDODriverStatement; use Doctrine\DBAL\Driver\SQLAnywhere; use Doctrine\DBAL\Driver\SQLSrv; -use Doctrine\Deprecations\Deprecation; use function array_keys; use function array_merge; @@ -244,14 +242,7 @@ public static function getConnection( } if (isset($params['pdo'])) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/3554', - 'Passing a user provided PDO instance directly to Doctrine is deprecated.' - ); - $params['pdo']->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - $params['pdo']->setAttribute(\PDO::ATTR_STATEMENT_CLASS, [PDODriverStatement::class, []]); $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(\PDO::ATTR_DRIVER_NAME); } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 587ebe65431..15e2e42aeec 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -114,3 +114,9 @@ parameters: message: '~^Parameter #1 \$scheme of static method Doctrine\\DBAL\\DriverManager::parseDatabaseUrlScheme\(\) expects string\|null, int\|string\|null given\.$~' paths: - %currentWorkingDirectory%/lib/Doctrine/DBAL/DriverManager.php + + # Until 3.x, $_conn does accept PDO + - + message: '~^Property Doctrine\\DBAL\\Connection::\$_conn \(Doctrine\\DBAL\\Driver\\Connection\|null\) does not accept PDO\.$~' + paths: + - %currentWorkingDirectory%/lib/Doctrine/DBAL/Connection.php diff --git a/tests/Doctrine/Tests/DBAL/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/ConnectionTest.php index 3e5440ac552..515e4fc6214 100644 --- a/tests/Doctrine/Tests/DBAL/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/ConnectionTest.php @@ -23,11 +23,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Result; use Doctrine\Tests\DbalTestCase; +use PDO; use PHPUnit\Framework\MockObject\MockObject; use stdClass; -use function call_user_func_array; - /** * @requires extension pdo_mysql */ @@ -646,11 +645,22 @@ public function testFetchAll(): void self::assertSame($result, $conn->fetchAll($statement, $params, $types)); } + public function testConnectionThrowsExceptionWhenInvalidPDOProvided(): void + { + $driverMock = $this->createMock(Driver::class); + $pdo = $this->createMock(stdClass::class); + + $this->expectException(Exception::class); + + new Connection(['pdo' => $pdo], $driverMock); + } + public function testConnectionDoesNotMaintainTwoReferencesToExternalPDO(): void { $driverMock = $this->createMock(Driver::class); + $pdo = $this->createMock(PDO::class); - $conn = new Connection(['pdo' => new stdClass()], $driverMock); + $conn = new Connection(['pdo' => $pdo], $driverMock); self::assertArrayNotHasKey('pdo', $conn->getParams()); } @@ -658,22 +668,17 @@ public function testConnectionDoesNotMaintainTwoReferencesToExternalPDO(): void public function testPassingExternalPDOMeansConnectionIsConnected(): void { $driverMock = $this->createMock(Driver::class); + $pdo = $this->createMock(PDO::class); - $conn = new Connection(['pdo' => new stdClass()], $driverMock); + $conn = new Connection(['pdo' => $pdo], $driverMock); self::assertTrue($conn->isConnected(), 'Connection is not connected after passing external PDO'); } public function testCallingDeleteWithNoDeletionCriteriaResultsInInvalidArgumentException(): void { - $driver = $this->createMock(Driver::class); - $pdoMock = $this->createMock(\Doctrine\DBAL\Driver\Connection::class); - - // should never execute queries with invalid arguments - $pdoMock->expects($this->never())->method('exec'); - $pdoMock->expects($this->never())->method('prepare'); - - $conn = new Connection(['pdo' => $pdoMock], $driver); + $driver = $this->createMock(Driver::class); + $conn = new Connection([], $driver); $this->expectException(InvalidArgumentException::class); $conn->delete('kittens', []); @@ -700,23 +705,22 @@ public static function dataCallConnectOnce(): iterable */ public function testCallConnectOnce(string $method, array $params): void { - $driverMock = $this->createMock(Driver::class); - $pdoMock = $this->createMock(Connection::class); - $platformMock = $this->createMock(AbstractPlatform::class); - $stmtMock = $this->createMock(Statement::class); + $wrappedConnection = $this->createMock(DriverConnection::class); + $driver = $this->createMock(Driver::class); + $stmt = $this->createMock(Statement::class); + $driver->expects(self::once()) + ->method('connect') + ->willReturn($wrappedConnection); - $pdoMock->expects($this->any()) + $wrappedConnection ->method('prepare') - ->will($this->returnValue($stmtMock)); + ->will($this->returnValue($stmt)); - $conn = (new MockBuilderProxy($this->getMockBuilder(Connection::class))) - ->onlyMethods(['connect']) - ->setConstructorArgs([['pdo' => $pdoMock, 'platform' => $platformMock], $driverMock]) - ->getMock(); + $platform = $this->createMock(AbstractPlatform::class); - $conn->expects($this->once())->method('connect'); + $conn = new Connection(['platform' => $platform], $driver); - call_user_func_array([$conn, $method], $params); + $conn->$method(...$params); } public function testPlatformDetectionIsTriggerOnlyOnceOnRetrievingPlatform(): void diff --git a/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php index b1423f353ac..6f1c888bed7 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php +++ b/tests/Doctrine/Tests/DBAL/Functional/ConnectionTest.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\ConnectionException; use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver\Connection as DriverConnection; +use Doctrine\DBAL\Driver\PDOSqlite\Driver as PDODriver; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\ForwardCompatibility; use Doctrine\DBAL\ParameterType; @@ -363,7 +364,22 @@ public function testUserProvidedPDOConnection(): void $result = $connection->executeQuery('SELECT 1'); - self::assertInstanceOf(ForwardCompatibility\Result::class, $result); + self::assertInstanceOf(ForwardCompatibility\DriverResultStatement::class, $result); + } + + /** + * @requires extension pdo_sqlite + */ + public function testUserProvidedPDOConnectionWithoutDriverManager(): void + { + $connection = new Connection( + ['pdo' => new PDO('sqlite::memory:')], + new PDODriver() + ); + + $result = $connection->executeQuery('SELECT 1'); + + self::assertInstanceOf(ForwardCompatibility\DriverResultStatement::class, $result); } public function testResultCompatibilityWhenExecutingQueryWithoutParam(): void From 691d142457b93c47675e5068d54ca3f3e4f60a63 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Mon, 28 Jun 2021 18:57:11 +0200 Subject: [PATCH 04/14] Ignore errors about missing ReturnTypeWillChange class Signed-off-by: Alexander M. Turek --- phpstan.neon.dist | 3 +++ psalm.xml.dist | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 15e2e42aeec..05fb7ded120 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -120,3 +120,6 @@ parameters: message: '~^Property Doctrine\\DBAL\\Connection::\$_conn \(Doctrine\\DBAL\\Driver\\Connection\|null\) does not accept PDO\.$~' paths: - %currentWorkingDirectory%/lib/Doctrine/DBAL/Connection.php + + # The class was added in PHP 8.1 + - '~^Attribute class ReturnTypeWillChange does not exist.$~' diff --git a/psalm.xml.dist b/psalm.xml.dist index 1282a41f0e4..a16f9d4c219 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -374,6 +374,12 @@ + + + + + + From f367e7396c49415367b52e565eeef42d21283977 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Mon, 28 Jun 2021 20:54:39 -0700 Subject: [PATCH 05/14] Update SQL Server image --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 4bf56b51536..d2ce79dba9e 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -407,7 +407,7 @@ jobs: services: mssql: - image: "microsoft/mssql-server-linux:2017-latest" + image: "mcr.microsoft.com/mssql/server:2017-latest" env: ACCEPT_EULA: "Y" SA_PASSWORD: "Doctrine2018" From 1ececdefdb77040c418cfec113f01d37176e048d Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Mon, 28 Jun 2021 13:03:47 -0700 Subject: [PATCH 06/14] Use PHP 8 for static analysis --- .github/workflows/static-analysis.yml | 26 +++++++++++++++----------- phpstan.neon.dist | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 48799043831..ea150f247ba 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.0" steps: - name: "Checkout code" @@ -42,20 +42,24 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.0" steps: - name: Checkout code uses: actions/checkout@v2 - - name: Psalm - uses: docker://vimeo/psalm-github-actions:4.6.4 + - name: Install PHP + uses: shivammathur/setup-php@v2 with: - composer_require_dev: true - args: --shepherd + coverage: none + php-version: ${{ matrix.php-version }} + tools: cs2pr - - name: Psalm type inference tests - uses: docker://vimeo/psalm-github-actions:4.6.4 - with: - composer_require_dev: true - args: --config=psalm-strict.xml + - name: Install dependencies with Composer + uses: ramsey/composer-install@v1 + + - name: Run static analysis with Vimeo Psalm + run: vendor/bin/psalm --shepherd + + - name: Run type inference tests with Vimeo Psalm + run: vendor/bin/psalm --config=psalm-strict.xml --shepherd diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 05fb7ded120..43f0b2e035d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -37,6 +37,7 @@ parameters: # weird class name, represented in stubs as OCI_(Lob|Collection) - '~unknown class OCI-(Lob|Collection)~' + - '~^Call to method writeTemporary\(\) on an unknown class OCILob\.~' # The ReflectionException in the case when the class does not exist is acceptable and does not need to be handled - '~^Parameter #1 \$argument of class ReflectionClass constructor expects class-string\|T of object, string given\.$~' From c861ca829d11f527644ec261128e0fa7e03c18ef Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sun, 27 Jun 2021 23:44:38 -0700 Subject: [PATCH 07/14] Update JetBrains PhpStorm stubs to 2021.1 --- composer.json | 2 +- psalm.xml.dist | 16 +++------------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index a1bf3f6be93..af0f595948a 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ }, "require-dev": { "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2020.2", + "jetbrains/phpstorm-stubs": "2021.1", "phpstan/phpstan": "0.12.81", "phpunit/phpunit": "^7.5.20|^8.5|9.5.5", "squizlabs/php_codesniffer": "3.6.0", diff --git a/psalm.xml.dist b/psalm.xml.dist index a16f9d4c219..656eee1f1cc 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -322,14 +322,6 @@ - - - - - - @@ -457,6 +444,9 @@ + + + From 998284fa6f559682246b083f5ef82ef2d3d528fb Mon Sep 17 00:00:00 2001 From: Holger Schletz Date: Fri, 18 Jun 2021 18:47:17 +0200 Subject: [PATCH 08/14] Create tables with unique constraints on PostgreSQL PostgreSQL94Platform::_getCreateTableSQL() ignored unique constraints. Implementations for other platforms are OK. --- src/Platforms/PostgreSQL94Platform.php | 6 ++++++ tests/Platforms/PostgreSQL94PlatformTest.php | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Platforms/PostgreSQL94Platform.php b/src/Platforms/PostgreSQL94Platform.php index 7de6c66006e..797ae2f5f53 100644 --- a/src/Platforms/PostgreSQL94Platform.php +++ b/src/Platforms/PostgreSQL94Platform.php @@ -785,6 +785,12 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] } } + if (isset($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $uniqueConstraint) { + $sql[] = $this->getCreateConstraintSQL($uniqueConstraint, $name); + } + } + if (isset($options['foreignKeys'])) { foreach ((array) $options['foreignKeys'] as $definition) { $sql[] = $this->getCreateForeignKeySQL($definition, $name); diff --git a/tests/Platforms/PostgreSQL94PlatformTest.php b/tests/Platforms/PostgreSQL94PlatformTest.php index a827c39b3b8..e0cba5e4421 100644 --- a/tests/Platforms/PostgreSQL94PlatformTest.php +++ b/tests/Platforms/PostgreSQL94PlatformTest.php @@ -19,6 +19,21 @@ public function testSupportsPartialIndexes(): void self::assertTrue($this->platform->supportsPartialIndexes()); } + public function testGetCreateTableSQLWithUniqueConstraints(): void + { + $table = new Table('foo'); + $table->addColumn('id', 'string'); + $table->addUniqueConstraint(['id'], 'test_unique_constraint'); + self::assertSame( + [ + 'CREATE TABLE foo (id VARCHAR(255) NOT NULL)', + 'ALTER TABLE foo ADD CONSTRAINT test_unique_constraint UNIQUE (id)', + ], + $this->platform->getCreateTableSQL($table), + 'Unique constraints are added to table.' + ); + } + public function testGetCreateTableSQLWithColumnCollation(): void { $table = new Table('foo'); From 1739071598b17fd1ebcb292feab0a7a82ea403c2 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Thu, 24 Jun 2021 18:05:53 -0700 Subject: [PATCH 09/14] Configure PHP version for PHP_CodeSniffer --- .github/workflows/coding-standards.yml | 2 +- phpcs.xml.dist | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index a5720420006..65c92570643 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.0" steps: - name: "Checkout" diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 43d3af6fe7f..3374e1f07b5 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -12,6 +12,8 @@ + + bin lib tests/Doctrine/Tests @@ -37,13 +39,6 @@ */lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php - - - - - - - */lib/Doctrine/DBAL/Configuration.php */lib/Doctrine/DBAL/Connection.php From 794f71e9f9a88a65ff03c03ac32d021ea8a8c48a Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Fri, 2 Jul 2021 08:56:26 -0700 Subject: [PATCH 10/14] Update Psalm to 4.8.1 --- composer.json | 2 +- .../Connections/PrimaryReadReplicaConnection.php | 8 ++++---- lib/Doctrine/DBAL/Platforms/AbstractPlatform.php | 10 +++++----- lib/Doctrine/DBAL/Platforms/DB2Platform.php | 8 ++++---- lib/Doctrine/DBAL/Platforms/OraclePlatform.php | 4 ++-- lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php | 12 ++++++------ .../Connection/BackwardCompatibility/Connection.php | 4 ++-- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/composer.json b/composer.json index af0f595948a..fe0f3411a99 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "squizlabs/php_codesniffer": "3.6.0", "symfony/cache": "^4.4", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", - "vimeo/psalm": "4.6.4" + "vimeo/psalm": "4.8.1" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." diff --git a/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php b/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php index 2a1fa39dd3c..e2606e7d296 100644 --- a/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php +++ b/lib/Doctrine/DBAL/Connections/PrimaryReadReplicaConnection.php @@ -367,11 +367,11 @@ public function insert($table, array $data, array $types = []) /** * {@inheritDoc} */ - public function exec($statement) + public function exec($sql) { $this->ensureConnectedToPrimary(); - return parent::exec($statement); + return parent::exec($sql); } /** @@ -433,10 +433,10 @@ public function query() /** * {@inheritDoc} */ - public function prepare($statement) + public function prepare($sql) { $this->ensureConnectedToPrimary(); - return parent::prepare($statement); + return parent::prepare($sql); } } diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 7e58d5f351b..9274e1bfdb4 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1411,13 +1411,13 @@ public function getWriteLockSQL() /** * Returns the SQL snippet to drop an existing database. * - * @param string $database The name of the database that should be dropped. + * @param string $name The name of the database that should be dropped. * * @return string */ - public function getDropDatabaseSQL($database) + public function getDropDatabaseSQL($name) { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } /** @@ -2990,13 +2990,13 @@ public function getSequenceNextValSQL($sequence) /** * Returns the SQL to create a new database. * - * @param string $database The name of the database that should be created. + * @param string $name The name of the database that should be created. * * @return string * * @throws Exception If not supported on this platform. */ - public function getCreateDatabaseSQL($database) + public function getCreateDatabaseSQL($name) { throw Exception::notSupported(__METHOD__); } diff --git a/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/lib/Doctrine/DBAL/Platforms/DB2Platform.php index 3d75866e198..28f76ca4c6f 100644 --- a/lib/Doctrine/DBAL/Platforms/DB2Platform.php +++ b/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -414,17 +414,17 @@ public function getDropViewSQL($name) /** * {@inheritDoc} */ - public function getCreateDatabaseSQL($database) + public function getCreateDatabaseSQL($name) { - return 'CREATE DATABASE ' . $database; + return 'CREATE DATABASE ' . $name; } /** * {@inheritDoc} */ - public function getDropDatabaseSQL($database) + public function getDropDatabaseSQL($name) { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } /** diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 88b4325b7ce..46783d8bf8e 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -785,9 +785,9 @@ public function getForeignKeyReferentialActionSQL($action) /** * {@inheritDoc} */ - public function getDropDatabaseSQL($database) + public function getDropDatabaseSQL($name) { - return 'DROP USER ' . $database . ' CASCADE'; + return 'DROP USER ' . $name . ' CASCADE'; } /** diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php index 48a36a77692..591682ca158 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -406,11 +406,11 @@ public function getCreateConstraintSQL(Constraint $constraint, $table) /** * {@inheritdoc} */ - public function getCreateDatabaseSQL($database) + public function getCreateDatabaseSQL($name) { - $database = new Identifier($database); + $name = new Identifier($name); - return "CREATE DATABASE '" . $database->getName() . "'"; + return "CREATE DATABASE '" . $name->getName() . "'"; } /** @@ -540,11 +540,11 @@ public function getDefaultTransactionIsolationLevel() /** * {@inheritdoc} */ - public function getDropDatabaseSQL($database) + public function getDropDatabaseSQL($name) { - $database = new Identifier($database); + $name = new Identifier($name); - return "DROP DATABASE '" . $database->getName() . "'"; + return "DROP DATABASE '" . $name->getName() . "'"; } /** diff --git a/tests/Doctrine/Tests/DBAL/Functional/Connection/BackwardCompatibility/Connection.php b/tests/Doctrine/Tests/DBAL/Functional/Connection/BackwardCompatibility/Connection.php index aa0496fee89..41865c3d493 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Connection/BackwardCompatibility/Connection.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Connection/BackwardCompatibility/Connection.php @@ -26,9 +26,9 @@ public function executeQuery($sql, array $params = [], $types = [], ?QueryCacheP /** * {@inheritdoc} */ - public function prepare($statement) + public function prepare($sql) { - return new Statement(parent::prepare($statement)); + return new Statement(parent::prepare($sql)); } /** From 0b1736e88f666e3efc30703e09aba2cb21b7cc29 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Mon, 5 Jul 2021 15:39:54 -0700 Subject: [PATCH 11/14] Replace closures with private methods where possible --- src/Portability/Converter.php | 101 ++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/src/Portability/Converter.php b/src/Portability/Converter.php index a19d889d2fa..5763c26039d 100644 --- a/src/Portability/Converter.php +++ b/src/Portability/Converter.php @@ -38,29 +38,17 @@ final class Converter */ public function __construct(bool $convertEmptyStringToNull, bool $rightTrimString, ?int $case) { - $id = - /** - * @param T $value - * - * @return T - * - * @template T - */ - static function ($value) { - return $value; - }; - $convertValue = $this->createConvertValue($convertEmptyStringToNull, $rightTrimString); $convertNumeric = $this->createConvertRow($convertValue, null); $convertAssociative = $this->createConvertRow($convertValue, $case); - $this->convertNumeric = $this->createConvert($convertNumeric, $id); - $this->convertAssociative = $this->createConvert($convertAssociative, $id); - $this->convertOne = $this->createConvert($convertValue, $id); + $this->convertNumeric = $this->createConvert($convertNumeric, [self::class, 'id']); + $this->convertAssociative = $this->createConvert($convertAssociative, [self::class, 'id']); + $this->convertOne = $this->createConvert($convertValue, [self::class, 'id']); - $this->convertAllNumeric = $this->createConvertAll($convertNumeric, $id); - $this->convertAllAssociative = $this->createConvertAll($convertAssociative, $id); - $this->convertFirstColumn = $this->createConvertAll($convertValue, $id); + $this->convertAllNumeric = $this->createConvertAll($convertNumeric, [self::class, 'id']); + $this->convertAllAssociative = $this->createConvertAll($convertAssociative, [self::class, 'id']); + $this->convertFirstColumn = $this->createConvertAll($convertValue, [self::class, 'id']); } /** @@ -123,6 +111,51 @@ public function convertFirstColumn(array $data): array return ($this->convertFirstColumn)($data); } + /** + * @param T $value + * + * @return T + * + * @template T + */ + private static function id($value) + { + return $value; + } + + /** + * @param T $value + * + * @return T|null + * + * @template T + */ + private static function convertEmptyStringToNull($value) + { + if ($value === '') { + return null; + } + + return $value; + } + + /** + * @param T $value + * + * @return T|string + * @psalm-return (T is string ? string : T) + * + * @template T + */ + private static function rightTrimString($value) + { + if (! is_string($value)) { + return $value; + } + + return rtrim($value); + } + /** * Creates a function that will convert each individual value retrieved from the database * @@ -136,39 +169,11 @@ private function createConvertValue(bool $convertEmptyStringToNull, bool $rightT $functions = []; if ($convertEmptyStringToNull) { - $functions[] = - /** - * @param T $value - * - * @return T|null - * - * @template T - */ - static function ($value) { - if ($value === '') { - return null; - } - - return $value; - }; + $functions[] = [self::class, 'convertEmptyStringToNull']; } if ($rightTrimString) { - $functions[] = - /** - * @param T $value - * - * @psalm-return (T is string ? string : T) - * - * @template T - */ - static function ($value) { - if (! is_string($value)) { - return $value; - } - - return rtrim($value); - }; + $functions[] = [self::class, 'rightTrimString']; } return $this->compose(...$functions); From e3f8b50872bc5e18faa682f4d29303169737fb40 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Tue, 6 Jul 2021 07:12:11 -0700 Subject: [PATCH 12/14] Temporarily remove PHP 8.1 jobs from CI --- .github/workflows/continuous-integration.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 1e6f7b49e4d..eaa7d607141 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -25,7 +25,6 @@ jobs: - "7.3" - "7.4" - "8.0" - - "8.1" dependencies: - "highest" include: @@ -69,7 +68,6 @@ jobs: php-version: - "7.4" - "8.0" - - "8.1" services: oracle: @@ -113,7 +111,6 @@ jobs: php-version: - "7.4" - "8.0" - - "8.1" services: oracle: @@ -162,8 +159,6 @@ jobs: include: - php-version: "8.0" postgres-version: "13" - - php-version: "8.1" - postgres-version: "13" services: postgres: @@ -225,12 +220,6 @@ jobs: - php-version: "8.0" mariadb-version: "10.5" extension: "pdo_mysql" - - php-version: "8.1" - mariadb-version: "10.5" - extension: "mysqli" - - php-version: "8.1" - mariadb-version: "10.5" - extension: "pdo_mysql" services: mariadb: From 4c538d199c865e6dfc0c44f7bb65b9518bc21d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Merlet?= Date: Thu, 1 Jul 2021 16:16:45 +0200 Subject: [PATCH 13/14] Add alterSchema() methods in AbstractSchemaManager This introduces new convenient methods to apply a schema diff. I followed the same template used in alterTable() methods. --- src/Schema/AbstractSchemaManager.php | 20 +++++++++++++ .../SchemaManagerFunctionalTestCase.php | 28 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 50b9facee52..69ed799e28f 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -677,6 +677,26 @@ public function dropAndCreateView(View $view) $this->createView($view); } + /** + * Alters an existing schema. + * + * @throws Exception + */ + public function alterSchema(SchemaDiff $schemaDiff): void + { + $this->_execSql($schemaDiff->toSql($this->_platform)); + } + + /** + * Migrates an existing schema to a new schema. + * + * @throws Exception + */ + public function migrateSchema(Schema $toSchema): void + { + $this->alterSchema(Comparator::compareSchemas($this->createSchema(), $toSchema)); + } + /* alterTable() Methods */ /** diff --git a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php index e90582918f1..1a61bd713b5 100644 --- a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -496,6 +496,34 @@ public function testCreateSchema(): void self::assertTrue($schema->hasTable('test_table')); } + public function testMigrateSchema(): void + { + $this->createTestTable('table_to_alter'); + $this->createTestTable('table_to_drop'); + + $schema = $this->schemaManager->createSchema(); + + $tableToAlter = $schema->getTable('table_to_alter'); + $tableToAlter->dropColumn('foreign_key_test'); + $tableToAlter->addColumn('number', 'integer'); + + $schema->dropTable('table_to_drop'); + + $tableToCreate = $schema->createTable('table_to_create'); + $tableToCreate->addColumn('id', 'integer', ['notnull' => true]); + $tableToCreate->setPrimaryKey(['id']); + + $this->schemaManager->migrateSchema($schema); + + $schema = $this->schemaManager->createSchema(); + + self::assertTrue($schema->hasTable('table_to_alter')); + self::assertFalse($schema->getTable('table_to_alter')->hasColumn('foreign_key_test')); + self::assertTrue($schema->getTable('table_to_alter')->hasColumn('number')); + self::assertFalse($schema->hasTable('table_to_drop')); + self::assertTrue($schema->hasTable('table_to_create')); + } + public function testAlterTableScenario(): void { if (! $this->schemaManager->getDatabasePlatform()->supportsAlterTable()) { From dda7bf96511df547d3bc658c55894cff878c0cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Merlet?= Date: Tue, 13 Jul 2021 21:18:38 +0200 Subject: [PATCH 14/14] Deprecate inconsistent Comparator API This commit deprecates: - calls to compare(), and - static calls to compareSchemas(). --- UPGRADE.md | 11 +++++++ phpstan.neon.dist | 9 ++++++ psalm.xml.dist | 5 +++ src/Schema/AbstractSchemaManager.php | 4 ++- src/Schema/Comparator.php | 46 ++++++++++++++++------------ src/Schema/Schema.php | 6 ++-- src/Schema/SchemaDiff.php | 5 ++- 7 files changed, 60 insertions(+), 26 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 0d4a4f8461e..6a4ccc28e98 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,17 @@ awareness about deprecated code. # Upgrade to 3.2 +## Deprecated static calls to `Comparator::compareSchemas($fromSchema, $toSchema)` + +The usage of `Comparator::compareSchemas($fromSchema, $toSchema)` statically is +deprecated in order to provide a more consistent API. + +## Deprecated `Comparator::compare($fromSchema, $toSchema)` + +The usage of `Comparator::compare($fromSchema, $toSchema)` is deprecated and +replaced by `Comparator::compareSchemas($fromSchema, $toSchema)` in order to +clarify the purpose of the method. + ## Deprecated `Connection::lastInsertId($name)` The usage of `Connection::lastInsertId()` with a sequence name is deprecated as unsafe in scenarios with multiple diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 13af46643aa..b4b1ab8b8bc 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -108,6 +108,15 @@ parameters: paths: - %currentWorkingDirectory%/src/Platforms/AbstractPlatform.php + # See https://github.com/doctrine/dbal/pull/4707 + # TODO: remove in 4.0.0 + - + message: '~^Dynamic call to static method Doctrine\\DBAL\\Schema\\Comparator::compareSchemas\(\)\.$~' + paths: + - %currentWorkingDirectory%/src/Schema/AbstractSchemaManager.php + - %currentWorkingDirectory%/src/Schema/Comparator.php + - %currentWorkingDirectory%/src/Schema/Schema.php + # We're checking for invalid invalid input - message: "#^Strict comparison using \\!\\=\\= between null and null will always evaluate to false\\.$#" diff --git a/psalm.xml.dist b/psalm.xml.dist index c2057a2db89..2a5c70d97ee 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -87,6 +87,11 @@ --> + + diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 69ed799e28f..22f07e963f1 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -694,7 +694,9 @@ public function alterSchema(SchemaDiff $schemaDiff): void */ public function migrateSchema(Schema $toSchema): void { - $this->alterSchema(Comparator::compareSchemas($this->createSchema(), $toSchema)); + $schemaDiff = (new Comparator())->compareSchemas($this->createSchema(), $toSchema); + + $this->alterSchema($schemaDiff); } /* alterTable() Methods */ diff --git a/src/Schema/Comparator.php b/src/Schema/Comparator.php index 7ddf5238d16..14154b58634 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -3,6 +3,7 @@ namespace Doctrine\DBAL\Schema; use Doctrine\DBAL\Types; +use Doctrine\Deprecations\Deprecation; use function array_intersect_key; use function array_key_exists; @@ -20,31 +21,18 @@ */ class Comparator { - /** - * @return SchemaDiff - * - * @throws SchemaException - */ - public static function compareSchemas(Schema $fromSchema, Schema $toSchema) - { - $c = new self(); - - return $c->compare($fromSchema, $toSchema); - } - /** * Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema. * - * The returned differences are returned in such a way that they contain the - * operations to change the schema stored in $fromSchema to the schema that is - * stored in $toSchema. + * This method should be called non-statically since it will be declared as non-static in the next major release. * * @return SchemaDiff * * @throws SchemaException */ - public function compare(Schema $fromSchema, Schema $toSchema) + public static function compareSchemas(Schema $fromSchema, Schema $toSchema) { + $comparator = new self(); $diff = new SchemaDiff(); $diff->fromSchema = $fromSchema; @@ -71,7 +59,7 @@ public function compare(Schema $fromSchema, Schema $toSchema) if (! $fromSchema->hasTable($tableName)) { $diff->newTables[$tableName] = $toSchema->getTable($tableName); } else { - $tableDifferences = $this->diffTable( + $tableDifferences = $comparator->diffTable( $fromSchema->getTable($tableName), $toSchema->getTable($tableName) ); @@ -134,18 +122,18 @@ public function compare(Schema $fromSchema, Schema $toSchema) foreach ($toSchema->getSequences() as $sequence) { $sequenceName = $sequence->getShortestName($toSchema->getName()); if (! $fromSchema->hasSequence($sequenceName)) { - if (! $this->isAutoIncrementSequenceInSchema($fromSchema, $sequence)) { + if (! $comparator->isAutoIncrementSequenceInSchema($fromSchema, $sequence)) { $diff->newSequences[] = $sequence; } } else { - if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) { + if ($comparator->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) { $diff->changedSequences[] = $toSchema->getSequence($sequenceName); } } } foreach ($fromSchema->getSequences() as $sequence) { - if ($this->isAutoIncrementSequenceInSchema($toSchema, $sequence)) { + if ($comparator->isAutoIncrementSequenceInSchema($toSchema, $sequence)) { continue; } @@ -161,6 +149,24 @@ public function compare(Schema $fromSchema, Schema $toSchema) return $diff; } + /** + * @deprecated Use non-static call to {@link compareSchemas()} instead. + * + * @return SchemaDiff + * + * @throws SchemaException + */ + public function compare(Schema $fromSchema, Schema $toSchema) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4707', + 'Method compare() is deprecated. Use a non-static call to compareSchemas() instead.' + ); + + return $this->compareSchemas($fromSchema, $toSchema); + } + /** * @param Schema $schema * @param Sequence $sequence diff --git a/src/Schema/Schema.php b/src/Schema/Schema.php index 08eb268331c..ec164cfc21e 100644 --- a/src/Schema/Schema.php +++ b/src/Schema/Schema.php @@ -437,8 +437,7 @@ public function toDropSql(AbstractPlatform $platform) */ public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform) { - $comparator = new Comparator(); - $schemaDiff = $comparator->compare($this, $toSchema); + $schemaDiff = (new Comparator())->compareSchemas($this, $toSchema); return $schemaDiff->toSql($platform); } @@ -450,8 +449,7 @@ public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform) */ public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform) { - $comparator = new Comparator(); - $schemaDiff = $comparator->compare($fromSchema, $this); + $schemaDiff = (new Comparator())->compareSchemas($fromSchema, $this); return $schemaDiff->toSql($platform); } diff --git a/src/Schema/SchemaDiff.php b/src/Schema/SchemaDiff.php index 67fb9bb9daa..50d0d12fcd5 100644 --- a/src/Schema/SchemaDiff.php +++ b/src/Schema/SchemaDiff.php @@ -7,7 +7,10 @@ use function array_merge; /** - * Schema Diff. + * Differences between two schemas. + * + * The object contains the operations to change the schema stored in $fromSchema + * to a target schema. */ class SchemaDiff {