Skip to content

Commit e50ade1

Browse files
committed
Migrate to schema and column editor APIs
1 parent 2f396b8 commit e50ade1

2 files changed

Lines changed: 108 additions & 13 deletions

File tree

phpstan-dbal3.neon

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,32 @@ parameters:
164164
-
165165
message: '~inferType.*never returns~'
166166
path: src/Query/ParameterTypeInferer.php
167+
168+
# DBAL 4/5 Schema Editor API compatibility
169+
-
170+
message: '~^Class Doctrine\\DBAL\\Schema\\Table constructor invoked with 7 parameters, 1-6 required\.$~'
171+
path: src/Tools/SchemaTool.php
172+
173+
-
174+
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\SchemaConfig::toTableConfiguration\(\)\.$~'
175+
path: src/Tools/SchemaTool.php
176+
177+
-
178+
message: '~^Call to method setAutoincrement\(\) on an unknown class Doctrine\\DBAL\\Schema\\ColumnEditor\.$~'
179+
path: src/Tools/SchemaTool.php
180+
181+
-
182+
message: '~^Parameter \$column of anonymous function has invalid type Doctrine\\DBAL\\Schema\\ColumnEditor\.$~'
183+
path: src/Tools/SchemaTool.php
184+
185+
-
186+
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::edit\(\)\.$~'
187+
path: src/Tools/SchemaTool.php
188+
189+
-
190+
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::modifyColumnByUnquotedName\(\)\.$~'
191+
path: src/Tools/SchemaTool.php
192+
193+
-
194+
message: '~^Instantiated class Doctrine\\DBAL\\Schema\\ColumnEditor not found\.$~'
195+
path: src/Tools/SchemaTool.php

src/Tools/SchemaTool.php

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Doctrine\DBAL\Platforms\AbstractPlatform;
99
use Doctrine\DBAL\Schema\AbstractAsset;
1010
use Doctrine\DBAL\Schema\AbstractSchemaManager;
11+
use Doctrine\DBAL\Schema\ColumnEditor;
1112
use Doctrine\DBAL\Schema\ComparatorConfig;
1213
use Doctrine\DBAL\Schema\DefaultExpression;
1314
use Doctrine\DBAL\Schema\DefaultExpression\CurrentDate;
@@ -21,6 +22,7 @@
2122
use Doctrine\DBAL\Schema\NamedObject;
2223
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
2324
use Doctrine\DBAL\Schema\Schema;
25+
use Doctrine\DBAL\Schema\SchemaConfig;
2426
use Doctrine\DBAL\Schema\Table;
2527
use Doctrine\DBAL\Types\Types;
2628
use Doctrine\Deprecations\Deprecation;
@@ -204,11 +206,29 @@ public function getSchemaFromMetadata(array $classes): Schema
204206
continue;
205207
}
206208

207-
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
209+
// Create table object
210+
// @phpstan-ignore function.impossibleType (Using unreleased Schema::edit() API)
211+
if (method_exists(Schema::class, 'edit')) {
212+
$table = new Table(
213+
$this->quoteStrategy->getTableName($class, $this->platform),
214+
[],
215+
[],
216+
[],
217+
[],
218+
[],
219+
$metadataSchemaConfig->toTableConfiguration(),
220+
);
221+
// Add default table options (charset, collation, engine, etc.)
222+
foreach ($metadataSchemaConfig->getDefaultTableOptions() as $option => $value) {
223+
$table->addOption($option, $value);
224+
}
225+
} else {
226+
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
227+
}
208228

209229
if ($class->isInheritanceTypeSingleTable()) {
210230
$this->gatherColumns($class, $table);
211-
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
231+
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks, $metadataSchemaConfig);
212232

213233
// Add the discriminator column
214234
$this->addDiscriminatorColumnDefinition($class, $table);
@@ -222,7 +242,7 @@ public function getSchemaFromMetadata(array $classes): Schema
222242
foreach ($class->subClasses as $subClassName) {
223243
$subClass = $this->em->getClassMetadata($subClassName);
224244
$this->gatherColumns($subClass, $table);
225-
$this->gatherRelationsSql($subClass, $table, $schema, $addedFks, $blacklistedFks);
245+
$this->gatherRelationsSql($subClass, $table, $schema, $addedFks, $blacklistedFks, $metadataSchemaConfig);
226246
$processedClasses[$subClassName] = true;
227247
}
228248
} elseif ($class->isInheritanceTypeJoined()) {
@@ -233,7 +253,7 @@ public function getSchemaFromMetadata(array $classes): Schema
233253
}
234254
}
235255

236-
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
256+
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks, $metadataSchemaConfig);
237257

238258
// Add the discriminator column only to the root table
239259
if ($class->name === $class->rootEntityName) {
@@ -253,7 +273,18 @@ public function getSchemaFromMetadata(array $classes): Schema
253273
$this->platform,
254274
);
255275
// TODO: This seems rather hackish, can we optimize it?
256-
$table->getColumn($columnName)->setAutoincrement(false);
276+
// Use new column editor API only when new schema editor API is available (DBAL 4.5+)
277+
// @phpstan-ignore function.impossibleType (Using unreleased Schema::edit() API for version detection)
278+
if (method_exists(Schema::class, 'edit')) {
279+
// New API: modify column using table editor (creates new table object)
280+
// This is safe because we'll add the table to schema later after all modifications
281+
$table = $table->edit()->modifyColumnByUnquotedName(
282+
$columnName,
283+
static fn (ColumnEditor $column) => $column->setAutoincrement(false),
284+
)->create();
285+
} else {
286+
$table->getColumn($columnName)->setAutoincrement(false);
287+
}
257288

258289
$pkColumns[] = $columnName;
259290
$inheritedKeyColumns[] = $columnName;
@@ -306,7 +337,7 @@ public function getSchemaFromMetadata(array $classes): Schema
306337
}
307338
} else {
308339
$this->gatherColumns($class, $table);
309-
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
340+
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks, $metadataSchemaConfig);
310341
}
311342

312343
$pkColumns = [];
@@ -377,6 +408,15 @@ public function getSchemaFromMetadata(array $classes): Schema
377408

378409
$processedClasses[$class->name] = true;
379410

411+
// Add the fully populated table to the schema
412+
// @phpstan-ignore function.impossibleType (Using unreleased Schema::edit() API)
413+
if (method_exists(Schema::class, 'edit')) {
414+
// @phpstan-ignore method.notFound (Using unreleased Schema::edit() API)
415+
$schemaEditor = $schema->edit();
416+
$schemaEditor->addTable($table);
417+
$schema = $schemaEditor->create();
418+
}
419+
380420
if ($class->isIdGeneratorSequence() && $class->name === $class->rootEntityName) {
381421
$seqDef = $class->sequenceGeneratorDefinition;
382422
$quotedName = $this->quoteStrategy->getSequenceName($seqDef, $class, $this->platform);
@@ -620,9 +660,10 @@ private function gatherColumn(
620660
private function gatherRelationsSql(
621661
ClassMetadata $class,
622662
Table $table,
623-
Schema $schema,
663+
Schema &$schema,
624664
array &$addedFks,
625665
array &$blacklistedFks,
666+
SchemaConfig $schemaConfig,
626667
): void {
627668
foreach ($class->associationMappings as $id => $mapping) {
628669
if (isset($mapping->inherited) && ! in_array($id, $class->identifier, true)) {
@@ -647,12 +688,29 @@ private function gatherRelationsSql(
647688
// create join table
648689
$joinTable = $mapping->joinTable;
649690

650-
$theJoinTable = $schema->createTable(
651-
$this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform),
652-
);
653-
654-
foreach ($joinTable->options as $key => $val) {
655-
$theJoinTable->addOption($key, $val);
691+
$tableName = $this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform);
692+
693+
// Create the join table object
694+
// @phpstan-ignore function.impossibleType (Using unreleased Schema::edit() API)
695+
if (method_exists(Schema::class, 'edit')) {
696+
$theJoinTable = new Table(
697+
$tableName,
698+
[],
699+
[],
700+
[],
701+
[],
702+
$joinTable->options,
703+
$schemaConfig->toTableConfiguration(),
704+
);
705+
// Add default table options (charset, collation, engine, etc.)
706+
foreach ($schemaConfig->getDefaultTableOptions() as $option => $value) {
707+
$theJoinTable->addOption($option, $value);
708+
}
709+
} else {
710+
$theJoinTable = $schema->createTable($tableName);
711+
foreach ($joinTable->options as $key => $val) {
712+
$theJoinTable->addOption($key, $val);
713+
}
656714
}
657715

658716
$primaryKeyColumns = [];
@@ -680,6 +738,14 @@ private function gatherRelationsSql(
680738
);
681739

682740
self::addPrimaryKeyConstraint($theJoinTable, $primaryKeyColumns);
741+
742+
// Add the fully populated join table to the schema
743+
// @phpstan-ignore function.impossibleType (Using unreleased Schema::edit() API)
744+
if (method_exists(Schema::class, 'edit')) {
745+
$schemaEditor = $schema->edit();
746+
$schemaEditor->addTable($theJoinTable);
747+
$schema = $schemaEditor->create();
748+
}
683749
}
684750
}
685751
}

0 commit comments

Comments
 (0)