Skip to content

Commit ad6943a

Browse files
pl-githubtemp
authored andcommitted
feat: Support Doctrine DBAL 4.x
1 parent 959bf8d commit ad6943a

14 files changed

+363
-107
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"brainbits/phpcs-standard": "^8.0.0",
1717
"brainbits/phpstan-rules": "^4.0",
1818
"dama/doctrine-test-bundle": "^8.2",
19-
"doctrine/dbal": "^3.9",
19+
"doctrine/dbal": "^4.2",
2020
"ergebnis/phpstan-rules": "^2.8",
2121
"gemorroj/archive7z": "^5.7",
2222
"mikey179/vfsstream": "^1.6.12",

src/Schema/Strategy/MysqlBasedSchemaStrategy.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function applySchema(SchemaBuilder $schemaBuilder, Connection $connection
3131
{
3232
$platform = $connection->getDatabasePlatform();
3333

34-
$existingTables = $connection->executeQuery($platform->getListTablesSQL())->fetchFirstColumn();
34+
$existingTables = $connection->createSchemaManager()->listTableNames();
3535

3636
if (count($existingTables) > 0) {
3737
if (count(self::$executedStatements) === 0) {
@@ -107,25 +107,20 @@ public function applyData(DataBuilder $dataBuilder, Connection $connection): voi
107107
}
108108
}
109109

110-
/** @param list<string> $tables */
111-
private function dropTables(array $tables, Connection $connection): void
110+
/** @param list<string> $tableNames */
111+
private function dropTables(array $tableNames, Connection $connection): void
112112
{
113-
$platform = $connection->getDatabasePlatform();
113+
$schemaManager = $connection->createSchemaManager();
114114

115115
try {
116116
$connection->executeStatement('SET foreign_key_checks = 0');
117117

118-
foreach ($tables as $table) {
119-
$listForeignKeysSql = $platform->getListTableForeignKeysSQL($table);
120-
$foreignKeys = $connection->executeQuery($listForeignKeysSql)->fetchFirstColumn();
121-
122-
foreach ($foreignKeys as $foreignKey) {
123-
$dropForeignKeySQL = $platform->getDropForeignKeySQL($foreignKey, $table);
124-
$connection->executeStatement($dropForeignKeySQL);
118+
foreach ($tableNames as $tableName) {
119+
foreach ($schemaManager->listTableForeignKeys($tableName) as $foreignKey) {
120+
$schemaManager->dropForeignKey($foreignKey->getName(), $tableName);
125121
}
126122

127-
$dropTableSQL = $platform->getDropTableSQL($table);
128-
$connection->executeStatement($dropTableSQL);
123+
$schemaManager->dropTable($tableName);
129124
}
130125
} finally {
131126
$connection->executeStatement('SET foreign_key_checks = 1');

src/Schema/Strategy/MysqlDamaBasedSchemaStrategy.php

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public function applySchema(SchemaBuilder $schemaBuilder, Connection $connection
3232
{
3333
$platform = $connection->getDatabasePlatform();
3434

35-
$existingTables = $connection->executeQuery($platform->getListTablesSQL())->fetchFirstColumn();
35+
$existingTables = $connection->createSchemaManager()->listTableNames();
3636

3737
StaticDriver::rollBack();
3838

@@ -101,25 +101,20 @@ public function applyData(DataBuilder $dataBuilder, Connection $connection): voi
101101
}
102102
}
103103

104-
/** @param list<string> $tables */
105-
private function dropTables(array $tables, Connection $connection): void
104+
/** @param list<string> $tableNames */
105+
private function dropTables(array $tableNames, Connection $connection): void
106106
{
107-
$platform = $connection->getDatabasePlatform();
107+
$schemaManager = $connection->createSchemaManager();
108108

109109
try {
110110
$connection->executeStatement('SET foreign_key_checks = 0');
111111

112-
foreach ($tables as $table) {
113-
$listForeignKeysSql = $platform->getListTableForeignKeysSQL($table);
114-
$foreignKeys = $connection->executeQuery($listForeignKeysSql)->fetchFirstColumn();
115-
116-
foreach ($foreignKeys as $foreignKey) {
117-
$dropForeignKeySQL = $platform->getDropForeignKeySQL($foreignKey, $table);
118-
$connection->executeStatement($dropForeignKeySQL);
112+
foreach ($tableNames as $tableName) {
113+
foreach ($schemaManager->listTableForeignKeys($tableName) as $foreignKey) {
114+
$schemaManager->dropForeignKey($foreignKey->getName(), $tableName);
119115
}
120116

121-
$dropTableSQL = $platform->getDropTableSQL($table);
122-
$connection->executeStatement($dropTableSQL);
117+
$schemaManager->dropTable($tableName);
123118
}
124119
} finally {
125120
$connection->executeStatement('SET foreign_key_checks = 1');

tests/Schema/Strategy/MysqlBasedSchemaStrategyTest.php

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
use Doctrine\DBAL\Connection;
1313
use Doctrine\DBAL\Platforms\MySQLPlatform;
1414
use Doctrine\DBAL\Result;
15+
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
16+
use Doctrine\DBAL\Schema\MySQLSchemaManager;
1517
use Doctrine\DBAL\Schema\Schema;
1618
use PHPUnit\Framework\Attributes\CoversClass;
19+
use PHPUnit\Framework\MockObject\MockObject;
1720
use PHPUnit\Framework\TestCase;
1821

22+
use function array_keys;
23+
use function array_map;
24+
use function array_values;
1925
use function func_get_arg;
26+
use function func_get_args;
2027
use function Safe\preg_match;
2128
use function str_starts_with;
2229

@@ -26,11 +33,13 @@ final class MysqlBasedSchemaStrategyTest extends TestCase
2633
use SnapshotTrait;
2734

2835
private MySQLPlatform $platform;
36+
private MySQLSchemaManager&MockObject $schemaManager;
2937
private SchemaBuilder $schemaBuilder;
3038

3139
protected function setUp(): void
3240
{
3341
$this->platform = new MySQLPlatform();
42+
$this->schemaManager = $this->createMock(MySQLSchemaManager::class);
3443

3544
$this->schemaBuilder = $this->createSchemaBuilder();
3645
$this->schemaBuilder->foo();
@@ -41,6 +50,22 @@ public function testApplySchema(): void
4150
/** @phpstan-var ArrayObject<string, mixed[]> $queryLog */
4251
$queryLog = new ArrayObject();
4352

53+
$this->schemaManager->expects($this->any())
54+
->method('listTableNames')
55+
->willReturnCallback(
56+
static function () use ($queryLog) {
57+
$result = [];
58+
59+
$queryLog[] = [
60+
'function' => 'listTableNames()',
61+
'parameters' => func_get_args(),
62+
'result' => $result,
63+
];
64+
65+
return $result;
66+
},
67+
);
68+
4469
$connection = $this->createMock(Connection::class);
4570
$connection->expects($this->any())
4671
->method('quoteIdentifier')
@@ -51,11 +76,16 @@ public function testApplySchema(): void
5176
$connection->expects($this->any())
5277
->method('getDatabasePlatform')
5378
->willReturn($this->platform);
79+
$connection->expects($this->any())
80+
->method('createSchemaManager')
81+
->willReturn($this->schemaManager);
5482
$connection->expects($this->any())
5583
->method('executeStatement')
5684
->willReturnCallback(
57-
static function () use ($queryLog): void {
85+
static function () use ($queryLog): int {
5886
$queryLog[] = ['statement' => func_get_arg(0)];
87+
88+
return 0;
5989
},
6090
);
6191
$connection->expects($this->any())
@@ -68,7 +98,7 @@ static function () use ($queryLog, $connection) {
6898

6999
$queryLog[] = ['query' => $query, 'parameters' => $parameters, 'result' => $result];
70100

71-
return new Result(new ArrayResult($result), $connection);
101+
return new Result(self::createArrayResult($result), $connection);
72102
},
73103
);
74104

@@ -83,6 +113,57 @@ public function testExistingTablesAreDroppedBeforeCreatingFreshSchema(): void
83113
/** @phpstan-var ArrayObject<string, mixed[]> $queryLog */
84114
$queryLog = new ArrayObject();
85115

116+
$this->schemaManager->expects($this->once())
117+
->method('listTableNames')
118+
->willReturnCallback(static function () use ($queryLog) {
119+
$result = ['old_table_1', 'old_table_2'];
120+
121+
$queryLog[] = ['function' => 'listTableNames()', 'parameters' => func_get_args(), 'result' => $result];
122+
123+
return $result;
124+
});
125+
126+
$this->schemaManager->expects($this->exactly(2))
127+
->method('listTableForeignKeys')
128+
->willReturnCallback(static function ($tableName) use ($queryLog) {
129+
$result = [];
130+
131+
if ($tableName === 'old_table_1') {
132+
$result = [
133+
new ForeignKeyConstraint([], '', [], 'constraint_1'),
134+
new ForeignKeyConstraint([], '', [], 'constraint_2'),
135+
];
136+
}
137+
138+
$queryLog[] = [
139+
'function' => 'listTableForeignKeys()',
140+
'parameters' => func_get_args(),
141+
'result' => array_map(static fn ($fk) => $fk->getName(), $result),
142+
];
143+
144+
return $result;
145+
});
146+
147+
$this->schemaManager->expects($this->any())
148+
->method('dropForeignKey')
149+
->willReturnCallback(static function ($tableName) use ($queryLog) {
150+
$result = [];
151+
152+
$queryLog[] = ['function' => 'dropForeignKey()', 'parameters' => func_get_args(), 'result' => $result];
153+
154+
return $result;
155+
});
156+
157+
$this->schemaManager->expects($this->any())
158+
->method('dropTable')
159+
->willReturnCallback(static function ($tableName) use ($queryLog) {
160+
$result = [];
161+
162+
$queryLog[] = ['function' => 'dropTable()', 'parameters' => func_get_args(), 'result' => $result];
163+
164+
return $result;
165+
});
166+
86167
$connection = $this->createMock(Connection::class);
87168
$connection->expects($this->any())
88169
->method('quoteIdentifier')
@@ -93,11 +174,16 @@ public function testExistingTablesAreDroppedBeforeCreatingFreshSchema(): void
93174
$connection->expects($this->any())
94175
->method('getDatabasePlatform')
95176
->willReturn($this->platform);
177+
$connection->expects($this->any())
178+
->method('createSchemaManager')
179+
->willReturn($this->schemaManager);
96180
$connection->expects($this->any())
97181
->method('executeStatement')
98182
->willReturnCallback(
99-
static function () use ($queryLog): void {
183+
static function () use ($queryLog): int {
100184
$queryLog[] = ['statement' => func_get_arg(0)];
185+
186+
return 0;
101187
},
102188
);
103189
$connection->expects($this->any())
@@ -118,7 +204,7 @@ static function () use ($queryLog, $connection) {
118204

119205
$queryLog[] = ['query' => $query, 'parameters' => $parameters, 'result' => $result];
120206

121-
return new Result(new ArrayResult($result), $connection);
207+
return new Result(self::createArrayResult($result), $connection);
122208
},
123209
);
124210

@@ -133,6 +219,22 @@ public function testSchemaIsReadFromCacheIfDatabaseAndCacheExists(): void
133219
/** @phpstan-var ArrayObject<string, mixed[]> $queryLog */
134220
$queryLog = new ArrayObject();
135221

222+
$this->schemaManager->expects($this->any())
223+
->method('listTableNames')
224+
->willReturnCallback(
225+
static function () use ($queryLog) {
226+
$result = [];
227+
228+
$queryLog[] = [
229+
'function' => 'listTableNames()',
230+
'parameters' => func_get_args(),
231+
'result' => $result,
232+
];
233+
234+
return $result;
235+
},
236+
);
237+
136238
$connection = $this->createMock(Connection::class);
137239
$connection->expects($this->any())
138240
->method('quoteIdentifier')
@@ -143,11 +245,16 @@ public function testSchemaIsReadFromCacheIfDatabaseAndCacheExists(): void
143245
$connection->expects($this->any())
144246
->method('getDatabasePlatform')
145247
->willReturn(new MySQLPlatform());
248+
$connection->expects($this->any())
249+
->method('createSchemaManager')
250+
->willReturn($this->schemaManager);
146251
$connection->expects($this->any())
147252
->method('executeStatement')
148253
->willReturnCallback(
149-
static function () use ($queryLog): void {
254+
static function () use ($queryLog): int {
150255
$queryLog[] = ['statement' => func_get_arg(0)];
256+
257+
return 0;
151258
},
152259
);
153260
$connection->expects($this->any())
@@ -160,7 +267,7 @@ static function () use ($queryLog, $connection) {
160267

161268
$queryLog[] = ['query' => $query, 'parameters' => $parameters, 'result' => $result];
162269

163-
return new Result(new ArrayResult($result), $connection);
270+
return new Result(self::createArrayResult($result), $connection);
164271
},
165272
);
166273

@@ -194,8 +301,10 @@ public function testDeleteData(): void
194301
$connection->expects($this->any())
195302
->method('executeStatement')
196303
->willReturnCallback(
197-
static function () use ($queryLog): void {
304+
static function () use ($queryLog): int {
198305
$queryLog[] = ['statement' => func_get_arg(0)];
306+
307+
return 0;
199308
},
200309
);
201310
$connection->expects($this->any())
@@ -213,7 +322,7 @@ static function () use ($queryLog, $connection) {
213322

214323
$queryLog[] = ['query' => $query, 'parameters' => $parameters, 'result' => $result];
215324

216-
return new Result(new ArrayResult($result), $connection);
325+
return new Result(self::createArrayResult($result), $connection);
217326
},
218327
);
219328

@@ -244,8 +353,10 @@ public function testResetSequences(): void
244353
$connection->expects($this->any())
245354
->method('executeStatement')
246355
->willReturnCallback(
247-
static function () use ($queryLog): void {
356+
static function () use ($queryLog): int {
248357
$queryLog[] = ['statement' => func_get_arg(0)];
358+
359+
return 0;
249360
},
250361
);
251362
$connection->expects($this->any())
@@ -264,7 +375,7 @@ static function () use ($queryLog, $connection) {
264375

265376
$queryLog[] = ['query' => $query, 'parameters' => $parameters, 'result' => $result];
266377

267-
return new Result(new ArrayResult($result), $connection);
378+
return new Result(self::createArrayResult($result), $connection);
268379
},
269380
);
270381

@@ -298,7 +409,7 @@ public function foo(): void
298409
{
299410
$table = $this->schema->createTable('foo');
300411
$table->addColumn('id', 'integer', ['autoincrement' => true]);
301-
$table->addColumn('bar', 'string');
412+
$table->addColumn('bar', 'string', ['length' => 255]);
302413
}
303414
};
304415
}
@@ -307,4 +418,13 @@ private function snapshotPath(): string
307418
{
308419
return __DIR__;
309420
}
421+
422+
/** @param mixed[] $result */
423+
private static function createArrayResult(array $result): ArrayResult
424+
{
425+
$columnNames = array_keys($result[0] ?? []);
426+
$rows = array_map(array_values(...), $result);
427+
428+
return new ArrayResult($columnNames, $rows);
429+
}
310430
}

0 commit comments

Comments
 (0)