Skip to content

Commit 5ca4f26

Browse files
committed
Refactor ColumnFactory
1 parent 4f85a22 commit 5ca4f26

File tree

6 files changed

+70
-107
lines changed

6 files changed

+70
-107
lines changed

src/Column/ColumnFactory.php

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,17 @@
3737
* unique?: bool|string,
3838
* }
3939
*/
40-
final class ColumnFactory extends AbstractColumnFactory
40+
class ColumnFactory extends AbstractColumnFactory
4141
{
4242
/**
4343
* The mapping from physical column types (keys) to abstract column types (values).
4444
*
4545
* @link https://www.postgresql.org/docs/current/datatype.html#DATATYPE-TABLE
4646
*
4747
* @var string[]
48-
*
49-
* @psalm-suppress MissingClassConstType
48+
* @psalm-var array<string, ColumnType::*>
5049
*/
51-
private const TYPE_MAP = [
50+
protected const TYPE_MAP = [
5251
'bool' => ColumnType::BOOLEAN,
5352
'boolean' => ColumnType::BOOLEAN,
5453
'bit' => ColumnType::BIT,
@@ -115,46 +114,21 @@ final class ColumnFactory extends AbstractColumnFactory
115114
'jsonb' => ColumnType::JSON,
116115
];
117116

118-
/**
119-
* @psalm-param ColumnType::* $type
120-
* @psalm-param ColumnInfo $info
121-
* @psalm-suppress MoreSpecificImplementedParamType
122-
* @psalm-suppress ArgumentTypeCoercion
123-
* @psalm-suppress InvalidNamedArgument
124-
* @psalm-suppress PossiblyInvalidArgument
125-
*/
126-
public function fromType(string $type, array $info = []): ColumnSchemaInterface
117+
protected function getColumnClass(string $type, array $info = []): string
127118
{
128-
$dimension = $info['dimension'] ?? 0;
129-
unset($info['dimension']);
130-
131-
if ($dimension > 0) {
132-
$info['column'] ??= $this->fromType($type, $info);
133-
return new ArrayColumnSchema(...$info, dimension: $dimension);
134-
}
135-
136119
return match ($type) {
137-
ColumnType::BOOLEAN => new BooleanColumnSchema($type, ...$info),
138-
ColumnType::BIT => new BitColumnSchema($type, ...$info),
139-
ColumnType::TINYINT => new IntegerColumnSchema($type, ...$info),
140-
ColumnType::SMALLINT => new IntegerColumnSchema($type, ...$info),
141-
ColumnType::INTEGER => new IntegerColumnSchema($type, ...$info),
120+
ColumnType::BOOLEAN => BooleanColumnSchema::class,
121+
ColumnType::BIT => BitColumnSchema::class,
122+
ColumnType::TINYINT => IntegerColumnSchema::class,
123+
ColumnType::SMALLINT => IntegerColumnSchema::class,
124+
ColumnType::INTEGER => IntegerColumnSchema::class,
142125
ColumnType::BIGINT => PHP_INT_SIZE !== 8
143-
? new BigIntColumnSchema($type, ...$info)
144-
: new IntegerColumnSchema($type, ...$info),
145-
ColumnType::BINARY => new BinaryColumnSchema($type, ...$info),
146-
ColumnType::STRUCTURED => new StructuredColumnSchema($type, ...$info),
147-
default => parent::fromType($type, $info),
126+
? BigIntColumnSchema::class
127+
: IntegerColumnSchema::class,
128+
ColumnType::BINARY => BinaryColumnSchema::class,
129+
ColumnType::ARRAY => ArrayColumnSchema::class,
130+
ColumnType::STRUCTURED => StructuredColumnSchema::class,
131+
default => parent::getColumnClass($type, $info),
148132
};
149133
}
150-
151-
protected function getType(string $dbType, array $info = []): string
152-
{
153-
return self::TYPE_MAP[$dbType] ?? ColumnType::STRING;
154-
}
155-
156-
protected function isDbType(string $dbType): bool
157-
{
158-
return isset(self::TYPE_MAP[$dbType]);
159-
}
160134
}

src/Schema.php

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Yiisoft\Db\Exception\NotSupportedException;
1919
use Yiisoft\Db\Expression\Expression;
2020
use Yiisoft\Db\Helper\DbArrayHelper;
21-
use Yiisoft\Db\Pgsql\Column\ArrayColumnSchema;
2221
use Yiisoft\Db\Pgsql\Column\ColumnFactory;
2322
use Yiisoft\Db\Pgsql\Column\SequenceColumnSchemaInterface;
2423
use Yiisoft\Db\Schema\Builder\ColumnInterface;
@@ -44,8 +43,6 @@
4443
* Implements the PostgreSQL Server specific schema, supporting PostgreSQL Server version 9.6 and above.
4544
*
4645
* @psalm-type ColumnArray = array{
47-
* table_schema: string,
48-
* table_name: string,
4946
* column_name: string,
5047
* data_type: string,
5148
* type_type: string|null,
@@ -60,7 +57,9 @@
6057
* size: int|string|null,
6158
* scale: int|string|null,
6259
* contype: string|null,
63-
* dimension: int|string
60+
* dimension: int|string,
61+
* schema: string,
62+
* table: string
6463
* }
6564
* @psalm-type ConstraintArray = array<
6665
* array-key,
@@ -621,8 +620,6 @@ protected function findColumns(TableSchemaInterface $table): bool
621620

622621
$sql = <<<SQL
623622
SELECT
624-
d.nspname AS table_schema,
625-
c.relname AS table_name,
626623
a.attname AS column_name,
627624
COALESCE(td.typname, tb.typname, t.typname) AS data_type,
628625
COALESCE(td.typtype, tb.typtype, t.typtype) AS type_type,
@@ -687,9 +684,12 @@ protected function findColumns(TableSchemaInterface $table): bool
687684
a.attnum;
688685
SQL;
689686

687+
$schemaName = $table->getSchemaName();
688+
$tableName = $table->getName();
689+
690690
$columns = $this->db->createCommand($sql, [
691-
':schemaName' => $table->getSchemaName(),
692-
':tableName' => $table->getName(),
691+
':schemaName' => $schemaName,
692+
':tableName' => $tableName,
693693
])->queryAll();
694694

695695
if (empty($columns)) {
@@ -698,9 +698,12 @@ protected function findColumns(TableSchemaInterface $table): bool
698698

699699
/** @psalm-var ColumnArray $info */
700700
foreach ($columns as $info) {
701-
/** @psalm-var ColumnArray $info */
702701
$info = array_change_key_case($info);
703702

703+
$info['schema'] = $schemaName;
704+
$info['table'] = $tableName;
705+
706+
/** @psalm-var ColumnArray $info */
704707
$column = $this->loadColumnSchema($info);
705708

706709
$table->column($info['column_name'], $column);
@@ -733,40 +736,43 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
733736
$dbType = $info['type_scheme'] . '.' . $dbType;
734737
}
735738

736-
$columns = [];
739+
$columnInfo = [
740+
'autoIncrement' => (bool) $info['is_autoinc'],
741+
'comment' => $info['column_comment'],
742+
'dbType' => $dbType,
743+
'enumValues' => $info['enum_values'] !== null
744+
? explode(',', str_replace(["''"], ["'"], $info['enum_values']))
745+
: null,
746+
'name' => $info['column_name'],
747+
'notNull' => !$info['is_nullable'],
748+
'primaryKey' => $info['contype'] === 'p',
749+
'scale' => $info['scale'] !== null ? (int) $info['scale'] : null,
750+
'schema' => $info['schema'],
751+
'size' => $info['size'] !== null ? (int) $info['size'] : null,
752+
'table' => $info['table'],
753+
'unique' => $info['contype'] === 'u',
754+
];
737755

738756
if ($info['type_type'] === 'c') {
739757
$structured = $this->resolveTableName($dbType);
740758

741759
if ($this->findColumns($structured)) {
742-
$columns = $structured->getColumns();
760+
$columnInfo['columns'] = $structured->getColumns();
743761
}
744762

745-
/** @psalm-suppress ArgumentTypeCoercion */
746-
$column = $columnFactory
747-
->fromType(ColumnType::STRUCTURED, [
748-
'columns' => $columns,
749-
'dbType' => $dbType,
750-
'dimension' => (int) $info['dimension'],
751-
]);
763+
$column = $columnFactory->fromType(ColumnType::STRUCTURED, $columnInfo);
752764
} else {
753-
/** @psalm-suppress ArgumentTypeCoercion */
754-
$column = $columnFactory
755-
->fromDbType($dbType, ['dimension' => (int) $info['dimension']]);
765+
$column = $columnFactory->fromDbType($dbType, $columnInfo);
756766
}
757767

758-
/** @psalm-suppress DeprecatedMethod */
759-
$column->name($info['column_name']);
760-
$column->notNull(!$info['is_nullable']);
761-
$column->autoIncrement((bool) $info['is_autoinc']);
762-
$column->comment($info['column_comment']);
763-
$column->enumValues($info['enum_values'] !== null
764-
? explode(',', str_replace(["''"], ["'"], $info['enum_values']))
765-
: null);
766-
$column->primaryKey($info['contype'] === 'p');
767-
$column->unique($info['contype'] === 'u');
768-
$column->scale($info['scale'] !== null ? (int) $info['scale'] : null);
769-
$column->size($info['size'] !== null ? (int) $info['size'] : null);
768+
$dimension = (int) $info['dimension'];
769+
770+
if ($dimension > 0) {
771+
$columnInfo['column'] = $column;
772+
$columnInfo['dimension'] = $dimension;
773+
774+
$column = $columnFactory->fromType(ColumnType::ARRAY, $columnInfo);
775+
}
770776

771777
/**
772778
* pg_get_serial_sequence() doesn't track DEFAULT value change.
@@ -783,12 +789,6 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
783789
} elseif ($info['sequence_name'] !== null) {
784790
$column->sequenceName($this->resolveTableName($info['sequence_name'])->getFullName());
785791
}
786-
} elseif ($column instanceof ArrayColumnSchema) {
787-
/** @var ColumnSchemaInterface $arrayColumn */
788-
$arrayColumn = $column->getColumn();
789-
$arrayColumn->enumValues($column->getEnumValues());
790-
$arrayColumn->scale($column->getScale());
791-
$arrayColumn->size($column->getSize());
792792
}
793793

794794
$column->defaultValue($this->normalizeDefaultValue($defaultValue, $column));
@@ -799,7 +799,9 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
799799

800800
if (is_array($defaultValue)) {
801801
foreach ($column->getColumns() as $structuredColumnName => $structuredColumn) {
802-
$structuredColumn->defaultValue($defaultValue[$structuredColumnName] ?? null);
802+
if (isset($defaultValue[$structuredColumnName])) {
803+
$structuredColumn->defaultValue($defaultValue[$structuredColumnName]);
804+
}
803805
}
804806
}
805807
}

tests/ColumnFactoryTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Yiisoft\Db\Pgsql\Tests;
66

7+
use Yiisoft\Db\Constant\ColumnType;
78
use Yiisoft\Db\Pgsql\Column\ArrayColumnSchema;
89
use Yiisoft\Db\Pgsql\Tests\Support\TestTrait;
910
use Yiisoft\Db\Tests\AbstractColumnFactoryTest;
@@ -23,8 +24,8 @@ public function testFromDbType(string $dbType, string $expectedType, string $exp
2324
$db = $this->getConnection();
2425
$columnFactory = $db->getSchema()->getColumnFactory();
2526

26-
// With dimension
27-
$column = $columnFactory->fromDbType($dbType, ['dimension' => 1]);
27+
// For array type
28+
$column = $columnFactory->fromType(ColumnType::ARRAY, ['dbType' => $dbType]);
2829

2930
$this->assertInstanceOf(ArrayColumnSchema::class, $column);
3031
$this->assertInstanceOf($expectedInstanceOf, $column->getColumn());
@@ -62,8 +63,8 @@ public function testFromType(string $type, string $expectedType, string $expecte
6263
$db = $this->getConnection();
6364
$columnFactory = $db->getSchema()->getColumnFactory();
6465

65-
// With dimension
66-
$column = $columnFactory->fromType($type, ['dimension' => 1]);
66+
// For array type
67+
$column = $columnFactory->fromType(ColumnType::ARRAY, ['column' => $columnFactory->fromType($type)]);
6768

6869
$this->assertInstanceOf(ArrayColumnSchema::class, $column);
6970
$this->assertInstanceOf($expectedInstanceOf, $column->getColumn());

tests/Provider/ColumnFactoryProvider.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,12 @@ public static function definitions(): array
9292

9393
return $definitions;
9494
}
95+
96+
public static function pseudoTypes(): array
97+
{
98+
$result = parent::pseudoTypes();
99+
$result['ubigpk'][2] = IntegerColumnSchema::class;
100+
101+
return $result;
102+
}
95103
}

tests/Provider/SchemaProvider.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -504,16 +504,6 @@ public static function columns(): array
504504
];
505505
}
506506

507-
public static function columnsTypeChar(): array
508-
{
509-
$columnsTypeChar = parent::columnsTypeChar();
510-
511-
$columnsTypeChar[0][3] = 'bpchar';
512-
$columnsTypeChar[1][3] = 'varchar';
513-
514-
return $columnsTypeChar;
515-
}
516-
517507
public static function constraints(): array
518508
{
519509
$constraints = parent::constraints();

tests/SchemaTest.php

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -182,18 +182,6 @@ public function testGetSchemaNames(): void
182182
$db->close();
183183
}
184184

185-
/**
186-
* @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\SchemaProvider::columnsTypeChar
187-
*/
188-
public function testGetStringFieldsSize(
189-
string $columnName,
190-
string $columnType,
191-
int|null $columnSize,
192-
string $columnDbType
193-
): void {
194-
parent::testGetStringFieldsSize($columnName, $columnType, $columnSize, $columnDbType);
195-
}
196-
197185
/**
198186
* @throws Exception
199187
* @throws InvalidConfigException

0 commit comments

Comments
 (0)