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/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index c38baff0ffe..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: @@ -390,7 +379,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" 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 }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 48799043831..875477846ae 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -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/UPGRADE.md b/UPGRADE.md index 895f991b362..18927edfa0f 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -321,6 +321,17 @@ The following methods have been removed. # 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/composer.json b/composer.json index 26edd74da54..d2bdcf8f951 100644 --- a/composer.json +++ b/composer.json @@ -39,7 +39,7 @@ }, "require-dev": { "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2020.2", + "jetbrains/phpstorm-stubs": "2021.1", "phpstan/phpstan": "0.12.81", "phpstan/phpstan-phpunit": "0.12.18", "phpstan/phpstan-strict-rules": "0.12.2", @@ -48,7 +48,7 @@ "squizlabs/php_codesniffer": "3.6.0", "symfony/cache": "^5.2|^6.0", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.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/phpcs.xml.dist b/phpcs.xml.dist index 45a67c13ac0..6e49ea563fc 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -12,6 +12,8 @@ + + bin src tests @@ -36,13 +38,6 @@ */lib/Doctrine/DBAL/Driver/PDOStatementImplementations.php - - - - - - - */src/Configuration.php */src/Connection.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f82076114c4..69a860a80cf 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -17,6 +17,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\.~' # Requires a release of https://github.com/JetBrains/phpstorm-stubs/pull/553 - @@ -123,6 +124,15 @@ parameters: message: '~^Instanceof between Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList and Doctrine\\DBAL\\Platforms\\Keywords\\KeywordList will always evaluate to true\.~' 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 includes: - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon diff --git a/psalm.xml.dist b/psalm.xml.dist index 925faa20b5d..7fbdb676373 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -60,6 +60,13 @@ --> + + + + @@ -85,6 +92,8 @@ See https://github.com/vimeo/psalm/issues/5325 --> + + @@ -117,6 +126,12 @@ + + + + + + @@ -174,24 +189,11 @@ - - - - - - @@ -215,6 +217,12 @@ + + + + + + @@ -231,6 +239,9 @@ + + + diff --git a/src/Driver/OCI8/Connection.php b/src/Driver/OCI8/Connection.php index 87d4dc7c4eb..001e5bc2d37 100644 --- a/src/Driver/OCI8/Connection.php +++ b/src/Driver/OCI8/Connection.php @@ -85,9 +85,9 @@ public function query(string $sql): ResultInterface return $this->prepare($sql)->execute(); } - public function quote(string $input): string + public function quote(string $value): string { - return "'" . addcslashes(str_replace("'", "''", $input), "\000\n\r\\\032") . "'"; + return "'" . addcslashes(str_replace("'", "''", $value), "\000\n\r\\\032") . "'"; } public function exec(string $sql): int diff --git a/src/Driver/SQLSrv/Connection.php b/src/Driver/SQLSrv/Connection.php index a6be6eabb8a..9f0230dcaf2 100644 --- a/src/Driver/SQLSrv/Connection.php +++ b/src/Driver/SQLSrv/Connection.php @@ -64,9 +64,9 @@ public function query(string $sql): ResultInterface return $this->prepare($sql)->execute(); } - public function quote(string $input): string + public function quote(string $value): string { - return "'" . str_replace("'", "''", $input) . "'"; + return "'" . str_replace("'", "''", $value) . "'"; } public function exec(string $sql): int diff --git a/src/Platforms/AbstractPlatform.php b/src/Platforms/AbstractPlatform.php index 181ed0cd518..e5f7d36ff20 100644 --- a/src/Platforms/AbstractPlatform.php +++ b/src/Platforms/AbstractPlatform.php @@ -1189,11 +1189,11 @@ public function getWriteLockSQL(): string /** * 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. */ - public function getDropDatabaseSQL(string $database): string + public function getDropDatabaseSQL(string $name): string { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } /** @@ -2620,11 +2620,11 @@ public function getSequenceNextValSQL(string $sequence): string /** * 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. * * @throws Exception If not supported on this platform. */ - public function getCreateDatabaseSQL(string $database): string + public function getCreateDatabaseSQL(string $name): string { throw NotSupported::new(__METHOD__); } diff --git a/src/Platforms/DB2Platform.php b/src/Platforms/DB2Platform.php index ff1e420b6da..c922bf3eb33 100644 --- a/src/Platforms/DB2Platform.php +++ b/src/Platforms/DB2Platform.php @@ -328,14 +328,14 @@ public function getDropViewSQL(string $name): string return 'DROP VIEW ' . $name; } - public function getCreateDatabaseSQL(string $database): string + public function getCreateDatabaseSQL(string $name): string { - return 'CREATE DATABASE ' . $database; + return 'CREATE DATABASE ' . $name; } - public function getDropDatabaseSQL(string $database): string + public function getDropDatabaseSQL(string $name): string { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } public function supportsCreateDropDatabase(): bool diff --git a/src/Platforms/MySQLPlatform.php b/src/Platforms/MySQLPlatform.php index 148861de4c9..6809f1a7f87 100644 --- a/src/Platforms/MySQLPlatform.php +++ b/src/Platforms/MySQLPlatform.php @@ -300,14 +300,14 @@ public function getListTableMetadataSQL(string $table, ?string $database = null) ); } - public function getCreateDatabaseSQL(string $database): string + public function getCreateDatabaseSQL(string $name): string { - return 'CREATE DATABASE ' . $database; + return 'CREATE DATABASE ' . $name; } - public function getDropDatabaseSQL(string $database): string + public function getDropDatabaseSQL(string $name): string { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } /** diff --git a/src/Platforms/OraclePlatform.php b/src/Platforms/OraclePlatform.php index 1fa5c92d66f..1f73506cfa1 100644 --- a/src/Platforms/OraclePlatform.php +++ b/src/Platforms/OraclePlatform.php @@ -703,9 +703,9 @@ public function getForeignKeyReferentialActionSQL(string $action): string } } - public function getDropDatabaseSQL(string $database): string + public function getDropDatabaseSQL(string $name): string { - return 'DROP USER ' . $database . ' CASCADE'; + return 'DROP USER ' . $name . ' CASCADE'; } /** diff --git a/src/Platforms/PostgreSQL94Platform.php b/src/Platforms/PostgreSQL94Platform.php index 07d40681b1a..9dafcd0cb0c 100644 --- a/src/Platforms/PostgreSQL94Platform.php +++ b/src/Platforms/PostgreSQL94Platform.php @@ -324,9 +324,9 @@ public function getListTableColumnsSQL(string $table, ?string $database = null): ORDER BY a.attnum'; } - public function getCreateDatabaseSQL(string $database): string + public function getCreateDatabaseSQL(string $name): string { - return 'CREATE DATABASE ' . $database; + return 'CREATE DATABASE ' . $name; } public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey): string @@ -641,6 +641,12 @@ protected function _getCreateTableSQL(string $name, array $columns, array $optio } } + 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/src/Platforms/SQLServer2012Platform.php b/src/Platforms/SQLServer2012Platform.php index 7ca53110259..1b80cfc2da6 100644 --- a/src/Platforms/SQLServer2012Platform.php +++ b/src/Platforms/SQLServer2012Platform.php @@ -182,14 +182,14 @@ public function hasNativeGuidType(): bool return true; } - public function getCreateDatabaseSQL(string $database): string + public function getCreateDatabaseSQL(string $name): string { - return 'CREATE DATABASE ' . $database; + return 'CREATE DATABASE ' . $name; } - public function getDropDatabaseSQL(string $database): string + public function getDropDatabaseSQL(string $name): string { - return 'DROP DATABASE ' . $database; + return 'DROP DATABASE ' . $name; } public function supportsCreateDropDatabase(): bool 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); diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index ac194b2241e..3959a6ae80b 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -571,6 +571,28 @@ public function dropAndCreateView(View $view): void $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 + { + $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 d18b4a8201a..e5ed353d521 100644 --- a/src/Schema/Comparator.php +++ b/src/Schema/Comparator.php @@ -5,6 +5,7 @@ namespace Doctrine\DBAL\Schema; use Doctrine\DBAL\Types; +use Doctrine\Deprecations\Deprecation; use function array_intersect_key; use function array_key_exists; @@ -22,27 +23,16 @@ */ class Comparator { - /** - * @throws SchemaException - */ - public static function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff - { - $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. * * @throws SchemaException */ - public function compare(Schema $fromSchema, Schema $toSchema): SchemaDiff + public static function compareSchemas(Schema $fromSchema, Schema $toSchema): SchemaDiff { + $comparator = new self(); $diff = new SchemaDiff(); $diff->fromSchema = $fromSchema; @@ -69,7 +59,7 @@ public function compare(Schema $fromSchema, Schema $toSchema): SchemaDiff if (! $fromSchema->hasTable($tableName)) { $diff->newTables[$tableName] = $toSchema->getTable($tableName); } else { - $tableDifferences = $this->diffTable( + $tableDifferences = $comparator->diffTable( $fromSchema->getTable($tableName), $toSchema->getTable($tableName) ); @@ -130,18 +120,18 @@ public function compare(Schema $fromSchema, Schema $toSchema): SchemaDiff 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; } @@ -157,6 +147,24 @@ public function compare(Schema $fromSchema, Schema $toSchema): SchemaDiff 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); + } + private function isAutoIncrementSequenceInSchema(Schema $schema, Sequence $sequence): bool { foreach ($schema->getTables() as $table) { diff --git a/src/Schema/Schema.php b/src/Schema/Schema.php index 8290f762565..45821df1a3b 100644 --- a/src/Schema/Schema.php +++ b/src/Schema/Schema.php @@ -388,8 +388,7 @@ public function toDropSql(AbstractPlatform $platform): array */ public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform): array { - $comparator = new Comparator(); - $schemaDiff = $comparator->compare($this, $toSchema); + $schemaDiff = (new Comparator())->compareSchemas($this, $toSchema); return $schemaDiff->toSql($platform); } @@ -401,8 +400,7 @@ public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform): a */ public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform): array { - $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 970fe188a8f..3d9b771c574 100644 --- a/src/Schema/SchemaDiff.php +++ b/src/Schema/SchemaDiff.php @@ -9,7 +9,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 { diff --git a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php index f332de445a8..fad685ad2e3 100644 --- a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -461,6 +461,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()) { diff --git a/tests/Platforms/PostgreSQL94PlatformTest.php b/tests/Platforms/PostgreSQL94PlatformTest.php index 4aa793f8717..419b2e0cd1f 100644 --- a/tests/Platforms/PostgreSQL94PlatformTest.php +++ b/tests/Platforms/PostgreSQL94PlatformTest.php @@ -21,6 +21,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 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');