88use Doctrine \DBAL \Platforms \AbstractPlatform ;
99use Doctrine \DBAL \Schema \AbstractAsset ;
1010use Doctrine \DBAL \Schema \AbstractSchemaManager ;
11+ use Doctrine \DBAL \Schema \ColumnEditor ;
1112use Doctrine \DBAL \Schema \ComparatorConfig ;
1213use Doctrine \DBAL \Schema \DefaultExpression ;
1314use Doctrine \DBAL \Schema \DefaultExpression \CurrentDate ;
2122use Doctrine \DBAL \Schema \NamedObject ;
2223use Doctrine \DBAL \Schema \PrimaryKeyConstraint ;
2324use Doctrine \DBAL \Schema \Schema ;
25+ use Doctrine \DBAL \Schema \SchemaConfig ;
2426use Doctrine \DBAL \Schema \Table ;
2527use Doctrine \DBAL \Types \Types ;
2628use 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