|
20 | 20 | use Yiisoft\Db\Schema\ColumnSchemaInterface; |
21 | 21 | use Yiisoft\Db\Schema\TableSchemaInterface; |
22 | 22 |
|
| 23 | +use function array_column; |
23 | 24 | use function array_merge; |
24 | 25 | use function count; |
25 | 26 | use function explode; |
|
39 | 40 | * seq:string, |
40 | 41 | * table:string, |
41 | 42 | * from:string, |
42 | | - * to:string, |
| 43 | + * to:string|null, |
43 | 44 | * on_update:string, |
44 | 45 | * on_delete:string |
45 | 46 | * } |
@@ -204,15 +205,35 @@ protected function loadTableForeignKeys(string $tableName): array |
204 | 205 | DbArrayHelper::multisort($foreignKeysList, 'seq'); |
205 | 206 |
|
206 | 207 | /** @psalm-var GroupedForeignKeyInfo $foreignKeysList */ |
207 | | - foreach ($foreignKeysList as $table => $foreignKey) { |
208 | | - $fk = (new ForeignKeyConstraint()) |
209 | | - ->columnNames(DbArrayHelper::getColumn($foreignKey, 'from')) |
210 | | - ->foreignTableName($table) |
211 | | - ->foreignColumnNames(DbArrayHelper::getColumn($foreignKey, 'to')) |
212 | | - ->onDelete($foreignKey[0]['on_delete'] ?? null) |
213 | | - ->onUpdate($foreignKey[0]['on_update'] ?? null); |
214 | | - |
215 | | - $result[] = $fk; |
| 208 | + foreach ($foreignKeysList as $table => $foreignKeys) { |
| 209 | + $foreignKeysById = DbArrayHelper::index($foreignKeys, null, ['id']); |
| 210 | + |
| 211 | + /** |
| 212 | + * @psalm-var GroupedForeignKeyInfo $foreignKeysById |
| 213 | + * @psalm-var int $id |
| 214 | + */ |
| 215 | + foreach ($foreignKeysById as $id => $foreignKey) { |
| 216 | + if ($foreignKey[0]['to'] === null) { |
| 217 | + $primaryKey = $this->getTablePrimaryKey($table); |
| 218 | + |
| 219 | + if ($primaryKey !== null) { |
| 220 | + /** @psalm-var string $primaryKeyColumnName */ |
| 221 | + foreach ((array) $primaryKey->getColumnNames() as $i => $primaryKeyColumnName) { |
| 222 | + $foreignKey[$i]['to'] = $primaryKeyColumnName; |
| 223 | + } |
| 224 | + } |
| 225 | + } |
| 226 | + |
| 227 | + $fk = (new ForeignKeyConstraint()) |
| 228 | + ->name((string) $id) |
| 229 | + ->columnNames(array_column($foreignKey, 'from')) |
| 230 | + ->foreignTableName($table) |
| 231 | + ->foreignColumnNames(array_column($foreignKey, 'to')) |
| 232 | + ->onDelete($foreignKey[0]['on_delete']) |
| 233 | + ->onUpdate($foreignKey[0]['on_update']); |
| 234 | + |
| 235 | + $result[] = $fk; |
| 236 | + } |
216 | 237 | } |
217 | 238 |
|
218 | 239 | return $result; |
@@ -374,19 +395,18 @@ protected function findColumns(TableSchemaInterface $table): bool |
374 | 395 | */ |
375 | 396 | protected function findConstraints(TableSchemaInterface $table): void |
376 | 397 | { |
377 | | - /** @psalm-var ForeignKeyInfo[] $foreignKeysList */ |
378 | | - $foreignKeysList = $this->getPragmaForeignKeyList($table->getName()); |
| 398 | + /** @psalm-var ForeignKeyConstraint[] $foreignKeysList */ |
| 399 | + $foreignKeysList = $this->getTableForeignKeys($table->getName(), true); |
379 | 400 |
|
380 | 401 | foreach ($foreignKeysList as $foreignKey) { |
381 | | - $id = (int) $foreignKey['id']; |
382 | | - $fk = $table->getForeignKeys(); |
383 | | - |
384 | | - if (!isset($fk[$id])) { |
385 | | - $table->foreignKey($id, [$foreignKey['table'], $foreignKey['from'] => $foreignKey['to']]); |
386 | | - } else { |
387 | | - /** composite FK */ |
388 | | - $table->compositeForeignKey($id, $foreignKey['from'], $foreignKey['to']); |
389 | | - } |
| 402 | + /** @var array<string> $columnNames */ |
| 403 | + $columnNames = (array) $foreignKey->getColumnNames(); |
| 404 | + $columnNames = array_combine($columnNames, $foreignKey->getForeignColumnNames()); |
| 405 | + |
| 406 | + $foreignReference = array_merge([$foreignKey->getForeignTableName()], $columnNames); |
| 407 | + |
| 408 | + /** @psalm-suppress InvalidCast */ |
| 409 | + $table->foreignKey((string) $foreignKey->getName(), $foreignReference); |
390 | 410 | } |
391 | 411 | } |
392 | 412 |
|
|
0 commit comments