|
17 | 17 | use Yiisoft\Db\Expression\Expression; |
18 | 18 | use Yiisoft\Db\Helper\DbArrayHelper; |
19 | 19 | use Yiisoft\Db\Schema\Builder\ColumnInterface; |
20 | | -use Yiisoft\Db\Schema\ColumnSchemaInterface; |
| 20 | +use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; |
21 | 21 | use Yiisoft\Db\Schema\TableSchemaInterface; |
22 | 22 |
|
23 | 23 | use function array_column; |
|
67 | 67 | * type:string, |
68 | 68 | * notnull:string, |
69 | 69 | * dflt_value:string|null, |
70 | | - * pk:string |
| 70 | + * pk:string, |
| 71 | + * size?: int, |
| 72 | + * precision?: int, |
| 73 | + * scale?: int, |
71 | 74 | * } |
72 | 75 | */ |
73 | 76 | final class Schema extends AbstractPdoSchema |
@@ -370,10 +373,10 @@ protected function findColumns(TableSchemaInterface $table): bool |
370 | 373 | } |
371 | 374 |
|
372 | 375 | $column = $this->loadColumnSchema($info); |
373 | | - $table->column($column->getName(), $column); |
| 376 | + $table->column($info['name'], $column); |
374 | 377 |
|
375 | 378 | if ($column->isPrimaryKey()) { |
376 | | - $table->primaryKey($column->getName()); |
| 379 | + $table->primaryKey($info['name']); |
377 | 380 | } |
378 | 381 | } |
379 | 382 |
|
@@ -469,49 +472,63 @@ public function getSchemaDefaultValues(string $schema = '', bool $refresh = fals |
469 | 472 | * |
470 | 473 | * @return ColumnSchemaInterface The column schema object. |
471 | 474 | * |
472 | | - * @psalm-param array{cid:string, name:string, type:string, notnull:string, dflt_value:string|null, pk:string} $info |
| 475 | + * @psalm-param ColumnInfo $info |
473 | 476 | */ |
474 | | - protected function loadColumnSchema(array $info): ColumnSchemaInterface |
| 477 | + private function loadColumnSchema(array $info): ColumnSchemaInterface |
475 | 478 | { |
476 | | - $column = $this->createColumnSchema($info['name']); |
| 479 | + $dbType = strtolower($info['type']); |
| 480 | + $type = $this->getColumnType($dbType, $info); |
| 481 | + $isUnsigned = str_contains($dbType, 'unsigned'); |
| 482 | + /** @psalm-var ColumnInfo $info */ |
| 483 | + $column = $this->createColumnSchema($type, unsigned: $isUnsigned); |
| 484 | + $column->name($info['name']); |
| 485 | + $column->size($info['size'] ?? null); |
| 486 | + $column->precision($info['precision'] ?? null); |
| 487 | + $column->scale($info['scale'] ?? null); |
477 | 488 | $column->allowNull(!$info['notnull']); |
478 | | - $column->primaryKey($info['pk'] != '0'); |
479 | | - $column->dbType(strtolower($info['type'])); |
480 | | - $column->unsigned(str_contains($column->getDbType() ?? '', 'unsigned')); |
481 | | - $column->type(self::TYPE_STRING); |
| 489 | + $column->primaryKey((bool) $info['pk']); |
| 490 | + $column->dbType($dbType); |
| 491 | + $column->defaultValue($this->normalizeDefaultValue($info['dflt_value'], $column)); |
482 | 492 |
|
483 | | - if (preg_match('/^(\w+)(?:\(([^)]+)\))?/', $column->getDbType() ?? '', $matches)) { |
484 | | - $type = strtolower($matches[1]); |
| 493 | + return $column; |
| 494 | + } |
485 | 495 |
|
486 | | - if (isset(self::TYPE_MAP[$type])) { |
487 | | - $column->type(self::TYPE_MAP[$type]); |
488 | | - } |
| 496 | + /** |
| 497 | + * Get the abstract data type for the database data type. |
| 498 | + * |
| 499 | + * @param string $dbType The database data type |
| 500 | + * @param array $info Column information. |
| 501 | + * |
| 502 | + * @return string The abstract data type. |
| 503 | + */ |
| 504 | + private function getColumnType(string $dbType, array &$info): string |
| 505 | + { |
| 506 | + preg_match('/^(\w*)(?:\(([^)]+)\))?/', $dbType, $matches); |
| 507 | + $dbType = strtolower($matches[1]); |
489 | 508 |
|
490 | | - if (!empty($matches[2])) { |
491 | | - $values = explode(',', $matches[2]); |
492 | | - $column->precision((int) $values[0]); |
493 | | - $column->size((int) $values[0]); |
| 509 | + if (!empty($matches[2])) { |
| 510 | + $values = explode(',', $matches[2], 2); |
| 511 | + $info['size'] = (int) $values[0]; |
| 512 | + $info['precision'] = (int) $values[0]; |
494 | 513 |
|
495 | | - if (isset($values[1])) { |
496 | | - $column->scale((int) $values[1]); |
497 | | - } |
| 514 | + if (isset($values[1])) { |
| 515 | + $info['scale'] = (int) $values[1]; |
| 516 | + } |
498 | 517 |
|
499 | | - if (($type === 'tinyint' || $type === 'bit') && $column->getSize() === 1) { |
500 | | - $column->type(self::TYPE_BOOLEAN); |
501 | | - } elseif ($type === 'bit') { |
502 | | - if ($column->getSize() > 32) { |
503 | | - $column->type(self::TYPE_BIGINT); |
504 | | - } elseif ($column->getSize() === 32) { |
505 | | - $column->type(self::TYPE_INTEGER); |
506 | | - } |
507 | | - } |
| 518 | + if (($dbType === 'tinyint' || $dbType === 'bit') && $info['size'] === 1) { |
| 519 | + return self::TYPE_BOOLEAN; |
508 | 520 | } |
509 | | - } |
510 | 521 |
|
511 | | - $column->phpType($this->getColumnPhpType($column)); |
512 | | - $column->defaultValue($this->normalizeDefaultValue($info['dflt_value'], $column)); |
| 522 | + if ($dbType === 'bit') { |
| 523 | + return match (true) { |
| 524 | + $info['size'] === 32 => self::TYPE_INTEGER, |
| 525 | + $info['size'] > 32 => self::TYPE_BIGINT, |
| 526 | + default => self::TYPE_SMALLINT, |
| 527 | + }; |
| 528 | + } |
| 529 | + } |
513 | 530 |
|
514 | | - return $column; |
| 531 | + return self::TYPE_MAP[$dbType] ?? self::TYPE_STRING; |
515 | 532 | } |
516 | 533 |
|
517 | 534 | /** |
@@ -627,18 +644,6 @@ private function loadTableConstraints(string $tableName, string $returnType): Co |
627 | 644 | return $result[$returnType]; |
628 | 645 | } |
629 | 646 |
|
630 | | - /** |
631 | | - * Creates a column schema for the database. |
632 | | - * |
633 | | - * This method may be overridden by child classes to create a DBMS-specific column schema. |
634 | | - * |
635 | | - * @param string $name Name of the column. |
636 | | - */ |
637 | | - private function createColumnSchema(string $name): ColumnSchemaInterface |
638 | | - { |
639 | | - return new ColumnSchema($name); |
640 | | - } |
641 | | - |
642 | 647 | /** |
643 | 648 | * @throws Exception |
644 | 649 | * @throws InvalidConfigException |
|
0 commit comments