Skip to content

Commit 8b1e40a

Browse files
authored
Merge pull request #6791 from doctrine/3.9.x
Merge 3.9.x up into 3.10.x
2 parents 1eaa36c + 73c7ccd commit 8b1e40a

9 files changed

+215
-7
lines changed

.appveyor.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,8 @@ install:
7878
$destination = "c:\tools\php\ext\php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc15-x64.zip"
7979
Invoke-WebRequest $source -OutFile $destination
8080
7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc15-x64.zip > $null
81-
82-
# Pin the version until https://github.com/krakjoe/pcov/issues/117 is resolved
83-
$DLLVersion = "1.0.11"
84-
Invoke-WebRequest https://windows.php.net/downloads/pecl/releases/pcov/$($DLLVersion)/php_pcov-$($DLLVersion)-$($env:php)-nts-vc15-$($env:platform).zip -OutFile pcov.zip
81+
$DLLVersion = (Invoke-WebRequest "https://pecl.php.net/rest/r/pcov/stable.txt").Content
82+
Invoke-WebRequest https://downloads.php.net/~windows/pecl/releases/pcov/$($DLLVersion)/php_pcov-$($DLLVersion)-$($env:php)-nts-vc15-$($env:platform).zip -OutFile pcov.zip
8583
7z x -y pcov.zip > $null
8684
Remove-Item c:\tools\php\* -include .zip
8785
cd c:\tools\php

.github/workflows/coding-standards.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ on:
2525
jobs:
2626
coding-standards:
2727
name: "Coding Standards"
28-
uses: "doctrine/.github/.github/workflows/coding-standards.yml@7.1.0"
28+
uses: "doctrine/.github/.github/workflows/coding-standards.yml@7.2.1"

.github/workflows/documentation.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ on:
1717
jobs:
1818
documentation:
1919
name: "Documentation"
20-
uses: "doctrine/.github/.github/workflows/documentation.yml@7.1.0"
20+
uses: "doctrine/.github/.github/workflows/documentation.yml@7.2.1"

.github/workflows/static-analysis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ on:
2525
jobs:
2626
static-analysis-phpstan:
2727
name: "Static Analysis"
28-
uses: "doctrine/.github/.github/workflows/phpstan.yml@7.1.0"
28+
uses: "doctrine/.github/.github/workflows/phpstan.yml@7.2.1"

src/Platforms/PostgreSQLPlatform.php

+10
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,16 @@ public function getDropIndexSQL($index, $table = null)
833833
return $this->getDropConstraintSQL($constraintName, $table);
834834
}
835835

836+
if ($table !== null) {
837+
$indexName = $index instanceof Index ? $index->getQuotedName($this) : $index;
838+
$tableName = $table instanceof Table ? $table->getQuotedName($this) : $table;
839+
840+
if (strpos($tableName, '.') !== false) {
841+
[$schema] = explode('.', $tableName);
842+
$index = $schema . '.' . $indexName;
843+
}
844+
}
845+
836846
return parent::getDropIndexSQL($index, $table);
837847
}
838848

src/Schema/ForeignKeyConstraint.php

+4
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ public function getUnqualifiedForeignTableName()
251251
$name = substr($name, $position + 1);
252252
}
253253

254+
if ($this->isIdentifierQuoted($name)) {
255+
$name = $this->trimQuotes($name);
256+
}
257+
254258
return strtolower($name);
255259
}
256260

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema;
6+
7+
use Doctrine\DBAL\Exception;
8+
use Doctrine\DBAL\Schema\AbstractSchemaManager;
9+
use Doctrine\DBAL\Schema\Comparator;
10+
use Doctrine\DBAL\Schema\Table;
11+
use Doctrine\DBAL\Tests\FunctionalTestCase;
12+
use Doctrine\DBAL\Types\Types;
13+
14+
use function array_merge;
15+
16+
final class SchemaManagerTest extends FunctionalTestCase
17+
{
18+
private AbstractSchemaManager $schemaManager;
19+
20+
/** @throws Exception */
21+
protected function setUp(): void
22+
{
23+
$this->schemaManager = $this->connection->createSchemaManager();
24+
}
25+
26+
/**
27+
* @param callable(AbstractSchemaManager):Comparator $comparatorFactory
28+
*
29+
* @dataProvider dataEmptyDiffRegardlessOfForeignTableQuotes
30+
*/
31+
public function testEmptyDiffRegardlessOfForeignTableQuotes(
32+
callable $comparatorFactory,
33+
string $foreignTableName
34+
): void {
35+
if (! $this->connection->getDatabasePlatform()->supportsSchemas()) {
36+
self::markTestSkipped('Platform does not support schemas.');
37+
}
38+
39+
$this->dropAndCreateSchema('other_schema');
40+
41+
$tableForeign = new Table($foreignTableName);
42+
$tableForeign->addColumn('id', 'integer');
43+
$tableForeign->setPrimaryKey(['id']);
44+
$this->dropAndCreateTable($tableForeign);
45+
46+
$tableTo = new Table('other_schema.other_table');
47+
$tableTo->addColumn('id', 'integer');
48+
$tableTo->addColumn('user_id', 'integer');
49+
$tableTo->setPrimaryKey(['id']);
50+
$tableTo->addForeignKeyConstraint($tableForeign, ['user_id'], ['id']);
51+
$this->dropAndCreateTable($tableTo);
52+
53+
$schemaFrom = $this->schemaManager->introspectSchema();
54+
$tableFrom = $schemaFrom->getTable('other_schema.other_table');
55+
56+
$diff = $comparatorFactory($this->schemaManager)->compareTables($tableFrom, $tableTo);
57+
self::assertTrue($diff->isEmpty());
58+
}
59+
60+
/** @return iterable<mixed[]> */
61+
public static function dataEmptyDiffRegardlessOfForeignTableQuotes(): iterable
62+
{
63+
foreach (ComparatorTestUtils::comparatorProvider() as $comparatorArguments) {
64+
foreach (
65+
[
66+
'unquoted' => ['other_schema.user'],
67+
'partially quoted' => ['other_schema."user"'],
68+
'fully quoted' => ['"other_schema"."user"'],
69+
] as $testArguments
70+
) {
71+
yield array_merge($comparatorArguments, $testArguments);
72+
}
73+
}
74+
}
75+
76+
/**
77+
* @param callable(AbstractSchemaManager):Comparator $comparatorFactory
78+
*
79+
* @dataProvider dataDropIndexInAnotherSchema
80+
*/
81+
public function testDropIndexInAnotherSchema(callable $comparatorFactory, string $tableName): void
82+
{
83+
if (! $this->connection->getDatabasePlatform()->supportsSchemas()) {
84+
self::markTestSkipped('Platform does not support schemas.');
85+
}
86+
87+
$this->dropAndCreateSchema('other_schema');
88+
$this->dropAndCreateSchema('case');
89+
90+
$tableFrom = new Table($tableName);
91+
$tableFrom->addColumn('id', Types::INTEGER);
92+
$tableFrom->addColumn('name', Types::STRING);
93+
$tableFrom->addUniqueIndex(['name'], 'some_table_name_unique_index');
94+
$this->dropAndCreateTable($tableFrom);
95+
96+
$tableTo = clone $tableFrom;
97+
$tableTo->dropIndex('some_table_name_unique_index');
98+
99+
$diff = $comparatorFactory($this->schemaManager)->compareTables($tableFrom, $tableTo);
100+
self::assertNotFalse($diff);
101+
102+
$this->schemaManager->alterTable($diff);
103+
$tableFinal = $this->schemaManager->introspectTable($tableName);
104+
self::assertEmpty($tableFinal->getIndexes());
105+
}
106+
107+
/** @return iterable<mixed[]> */
108+
public static function dataDropIndexInAnotherSchema(): iterable
109+
{
110+
foreach (ComparatorTestUtils::comparatorProvider() as $comparatorScenario => $comparatorArguments) {
111+
foreach (
112+
[
113+
'default schema' => ['some_table'],
114+
'unquoted schema' => ['other_schema.some_table'],
115+
'quoted schema' => ['"other_schema".some_table'],
116+
'reserved schema' => ['case.some_table'],
117+
] as $testScenario => $testArguments
118+
) {
119+
yield $comparatorScenario . ' - ' . $testScenario => array_merge($comparatorArguments, $testArguments);
120+
}
121+
}
122+
}
123+
}

tests/FunctionalTestCase.php

+69
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55
use Doctrine\DBAL\Connection;
66
use Doctrine\DBAL\Exception;
77
use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
8+
use Doctrine\DBAL\Schema\Identifier;
9+
use Doctrine\DBAL\Schema\Schema;
810
use Doctrine\DBAL\Schema\Table;
911
use PHPUnit\Framework\TestCase;
1012

13+
use function count;
14+
1115
abstract class FunctionalTestCase extends TestCase
1216
{
1317
/**
@@ -98,4 +102,69 @@ public function dropAndCreateTable(Table $table): void
98102
$this->dropTableIfExists($tableName);
99103
$schemaManager->createTable($table);
100104
}
105+
106+
/**
107+
* Drops the schema with the specified name, if it exists.
108+
*
109+
* @throws Exception
110+
*/
111+
public function dropSchemaIfExists(string $schemaName): void
112+
{
113+
$platform = $this->connection->getDatabasePlatform();
114+
if (! $platform->supportsSchemas()) {
115+
throw Exception::notSupported(__METHOD__);
116+
}
117+
118+
$schemaName = (new Identifier($schemaName))->getName();
119+
$schemaManager = $this->connection->createSchemaManager();
120+
$databaseSchema = $schemaManager->introspectSchema();
121+
122+
$sequencesToDrop = [];
123+
foreach ($databaseSchema->getSequences() as $sequence) {
124+
if ($sequence->getNamespaceName() !== $schemaName) {
125+
continue;
126+
}
127+
128+
$sequencesToDrop[] = $sequence;
129+
}
130+
131+
$tablesToDrop = [];
132+
foreach ($databaseSchema->getTables() as $table) {
133+
if ($table->getNamespaceName() !== $schemaName) {
134+
continue;
135+
}
136+
137+
$tablesToDrop[] = $table;
138+
}
139+
140+
if (count($sequencesToDrop) > 0 || count($tablesToDrop) > 0) {
141+
$schemaManager->dropSchemaObjects(new Schema($tablesToDrop, $sequencesToDrop));
142+
}
143+
144+
try {
145+
$quotedSchemaName = (new Identifier($schemaName))->getQuotedName($platform);
146+
$schemaManager->dropSchema($quotedSchemaName);
147+
} catch (DatabaseObjectNotFoundException $e) {
148+
}
149+
}
150+
151+
/**
152+
* Drops and creates a new schema.
153+
*
154+
* @throws Exception
155+
*/
156+
public function dropAndCreateSchema(string $schemaName): void
157+
{
158+
$platform = $this->connection->getDatabasePlatform();
159+
if (! $platform->supportsSchemas()) {
160+
throw Exception::notSupported(__METHOD__);
161+
}
162+
163+
$schemaManager = $this->connection->createSchemaManager();
164+
$quotedSchemaName = (new Identifier($schemaName))->getQuotedName($platform);
165+
$schemaToCreate = new Schema([], [], null, [$quotedSchemaName]);
166+
167+
$this->dropSchemaIfExists($quotedSchemaName);
168+
$schemaManager->createSchemaObjects($schemaToCreate);
169+
}
101170
}

tests/Schema/ForeignKeyConstraintTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,12 @@ public static function getUnqualifiedForeignTableNameData(): iterable
7272
{
7373
return [
7474
['schema.foreign_table', 'foreign_table'],
75+
['schema."foreign_table"', 'foreign_table'],
76+
['"schema"."foreign_table"', 'foreign_table'],
7577
['foreign_table', 'foreign_table'],
7678
[new Table('schema.foreign_table'), 'foreign_table'],
79+
[new Table('schema."foreign_table"'), 'foreign_table'],
80+
[new Table('"schema"."foreign_table"'), 'foreign_table'],
7781
[new Table('foreign_table'), 'foreign_table'],
7882
];
7983
}

0 commit comments

Comments
 (0)