From 61393c73e931622f5f61ce57270275694fad4223 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sat, 2 Nov 2024 16:26:51 +0700 Subject: [PATCH 1/2] Refactor `AbstractColumnFactory` --- src/Schema/Column/AbstractColumnFactory.php | 134 ++++++++++++-------- tests/Common/CommonSchemaTest.php | 33 ----- tests/Provider/SchemaProvider.php | 9 -- 3 files changed, 80 insertions(+), 96 deletions(-) diff --git a/src/Schema/Column/AbstractColumnFactory.php b/src/Schema/Column/AbstractColumnFactory.php index a58789c1c..ed44bd898 100644 --- a/src/Schema/Column/AbstractColumnFactory.php +++ b/src/Schema/Column/AbstractColumnFactory.php @@ -18,29 +18,18 @@ abstract class AbstractColumnFactory implements ColumnFactoryInterface { /** - * Get the abstract database type for a database column type. - * - * @param string $dbType The database column type. - * @param array $info The column information. + * The mapping from physical column types (keys) to abstract column types (values). * - * @return string The abstract database type. + * @var string[] * - * @psalm-param ColumnInfo $info - * @psalm-return ColumnType::* + * @psalm-var array */ - abstract protected function getType(string $dbType, array $info = []): string; - - /** - * Checks if the column type is a database type. - */ - abstract protected function isDbType(string $dbType): bool; + protected const TYPE_MAP = []; public function fromDbType(string $dbType, array $info = []): ColumnSchemaInterface { - unset($info['dbType']); - $type = $info['type'] ?? $this->getType($dbType, $info); - unset($info['type']); $info['dbType'] = $dbType; + $type = $info['type'] ?? $this->getType($dbType, $info); return $this->fromType($type, $info); } @@ -60,12 +49,10 @@ public function fromDefinition(string $definition, array $info = []): ColumnSche $info += $definitionInfo; if ($this->isDbType($type)) { - unset($info['dbType']); return $this->fromDbType($type, $info); } if ($this->isType($type)) { - unset($info['type']); return $this->fromType($type, $info); } @@ -73,64 +60,103 @@ public function fromDefinition(string $definition, array $info = []): ColumnSche return $this->fromPseudoType($type, $info); } - unset($info['dbType']); return $this->fromDbType($type, $info); } - /** - * @psalm-suppress MixedArgument - * @psalm-suppress InvalidArgument - * @psalm-suppress InvalidNamedArgument - */ public function fromPseudoType(string $pseudoType, array $info = []): ColumnSchemaInterface { $info['primaryKey'] = true; $info['autoIncrement'] = true; - return match ($pseudoType) { - PseudoType::PK => new IntegerColumnSchema(ColumnType::INTEGER, ...$info), - PseudoType::UPK => new IntegerColumnSchema(ColumnType::INTEGER, ...[...$info, 'unsigned' => true]), - PseudoType::BIGPK => PHP_INT_SIZE !== 8 - ? new BigIntColumnSchema(ColumnType::BIGINT, ...$info) - : new IntegerColumnSchema(ColumnType::BIGINT, ...$info), - PseudoType::UBIGPK => new BigIntColumnSchema(ColumnType::BIGINT, ...[...$info, 'unsigned' => true]), - PseudoType::UUID_PK => new StringColumnSchema(ColumnType::UUID, ...$info), - PseudoType::UUID_PK_SEQ => new StringColumnSchema(ColumnType::UUID, ...$info), + if ($pseudoType === PseudoType::UPK || $pseudoType === PseudoType::UBIGPK) { + $info['unsigned'] = true; + } + + $type = match ($pseudoType) { + PseudoType::PK => ColumnType::INTEGER, + PseudoType::UPK => ColumnType::INTEGER, + PseudoType::BIGPK => ColumnType::BIGINT, + PseudoType::UBIGPK => ColumnType::BIGINT, + PseudoType::UUID_PK => ColumnType::UUID, + PseudoType::UUID_PK_SEQ => ColumnType::UUID, }; + + return $this->fromType($type, $info); + } + + public function fromType(string $type, array $info = []): ColumnSchemaInterface + { + unset($info['type']); + + if ($type === ColumnType::ARRAY && empty($info['column']) && !empty($info['dbType'])) { + $info['column'] = $this->fromDbType($info['dbType'], $info); + } + + $columnClass = $this->getColumnClass($type, $info); + + return new $columnClass($type, ...$info); } /** - * @psalm-suppress InvalidNamedArgument + * Returns the column definition parser. */ - public function fromType(string $type, array $info = []): ColumnSchemaInterface + protected function columnDefinitionParser(): ColumnDefinitionParser { - return match ($type) { - ColumnType::BOOLEAN => new BooleanColumnSchema($type, ...$info), - ColumnType::BIT => new BitColumnSchema($type, ...$info), - ColumnType::TINYINT => new IntegerColumnSchema($type, ...$info), - ColumnType::SMALLINT => new IntegerColumnSchema($type, ...$info), + return new ColumnDefinitionParser(); + } + + /** + * @psalm-param ColumnType::* $type + * @param ColumnInfo $info + * + * @psalm-return class-string + */ + protected function getColumnClass(string $type, array $info = []): string + { + return match($type) { + ColumnType::BOOLEAN => BooleanColumnSchema::class, + ColumnType::BIT => BitColumnSchema::class, + ColumnType::TINYINT => IntegerColumnSchema::class, + ColumnType::SMALLINT => IntegerColumnSchema::class, ColumnType::INTEGER => PHP_INT_SIZE !== 8 && !empty($info['unsigned']) - ? new BigIntColumnSchema($type, ...$info) - : new IntegerColumnSchema($type, ...$info), + ? BigIntColumnSchema::class + : IntegerColumnSchema::class, ColumnType::BIGINT => PHP_INT_SIZE !== 8 || !empty($info['unsigned']) - ? new BigIntColumnSchema($type, ...$info) - : new IntegerColumnSchema($type, ...$info), - ColumnType::DECIMAL => new DoubleColumnSchema($type, ...$info), - ColumnType::FLOAT => new DoubleColumnSchema($type, ...$info), - ColumnType::DOUBLE => new DoubleColumnSchema($type, ...$info), - ColumnType::BINARY => new BinaryColumnSchema($type, ...$info), - ColumnType::STRUCTURED => new StructuredColumnSchema($type, ...$info), - ColumnType::JSON => new JsonColumnSchema($type, ...$info), - default => new StringColumnSchema($type, ...$info), + ? BigIntColumnSchema::class + : IntegerColumnSchema::class, + ColumnType::DECIMAL => DoubleColumnSchema::class, + ColumnType::FLOAT => DoubleColumnSchema::class, + ColumnType::DOUBLE => DoubleColumnSchema::class, + ColumnType::BINARY => BinaryColumnSchema::class, + ColumnType::ARRAY => ArrayColumnSchema::class, + ColumnType::STRUCTURED => StructuredColumnSchema::class, + ColumnType::JSON => JsonColumnSchema::class, + default => StringColumnSchema::class, }; } /** - * Returns the column definition parser. + * Get the abstract database type for a database column type. + * + * @param string $dbType The database column type. + * @param array $info The column information. + * + * @return string The abstract database type. + * + * @psalm-param ColumnInfo $info + * @psalm-return ColumnType::* */ - protected function columnDefinitionParser(): ColumnDefinitionParser + protected function getType(string $dbType, array $info = []): string { - return new ColumnDefinitionParser(); + return static::TYPE_MAP[$dbType] ?? ColumnType::STRING; + } + + /** + * Checks if the column type is a database type. + */ + protected function isDbType(string $dbType): bool + { + return isset(static::TYPE_MAP[$dbType]); } /** diff --git a/tests/Common/CommonSchemaTest.php b/tests/Common/CommonSchemaTest.php index 3f2ffd6fe..bbf5447da 100644 --- a/tests/Common/CommonSchemaTest.php +++ b/tests/Common/CommonSchemaTest.php @@ -359,39 +359,6 @@ public function testGetSchemaUniques(): void $db->close(); } - /** - * @dataProvider \Yiisoft\Db\Tests\Provider\SchemaProvider::columnsTypeChar - */ - public function testGetStringFieldsSize( - string $columnName, - string $columnType, - int|null $columnSize, - string $columnDbType - ): void { - $db = $this->getConnection(true); - - $schema = $db->getSchema(); - $tableSchema = $schema->getTableSchema('type'); - - $this->assertInstanceOf(TableSchemaInterface::class, $tableSchema); - - $columns = $tableSchema->getColumns(); - - foreach ($columns as $name => $column) { - $type = $column->getType(); - $size = $column->getSize(); - $dbType = $column->getDbType(); - - if ($name === $columnName) { - $this->assertSame($columnType, $type); - $this->assertSame($columnSize, $size); - $this->assertSame($columnDbType, $dbType); - } - } - - $db->close(); - } - public function testGetTableChecks(): void { $db = $this->getConnection(true); diff --git a/tests/Provider/SchemaProvider.php b/tests/Provider/SchemaProvider.php index 1cce996fc..bd451a4d1 100644 --- a/tests/Provider/SchemaProvider.php +++ b/tests/Provider/SchemaProvider.php @@ -19,15 +19,6 @@ public static function columns(): array return []; } - public static function columnsTypeChar(): array - { - return [ - ['char_col', 'char', 100, 'char(100)'], - ['char_col2', 'string', 100, 'varchar(100)'], - ['char_col3', 'text', null, 'text'], - ]; - } - public static function constraints(): array { return [ From 911938827bd401de065979933c0aa1e8e2a221f9 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Sat, 2 Nov 2024 09:27:22 +0000 Subject: [PATCH 2/2] Apply fixes from StyleCI --- src/Schema/Column/AbstractColumnFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Schema/Column/AbstractColumnFactory.php b/src/Schema/Column/AbstractColumnFactory.php index ed44bd898..4fc4627bb 100644 --- a/src/Schema/Column/AbstractColumnFactory.php +++ b/src/Schema/Column/AbstractColumnFactory.php @@ -113,7 +113,7 @@ protected function columnDefinitionParser(): ColumnDefinitionParser */ protected function getColumnClass(string $type, array $info = []): string { - return match($type) { + return match ($type) { ColumnType::BOOLEAN => BooleanColumnSchema::class, ColumnType::BIT => BitColumnSchema::class, ColumnType::TINYINT => IntegerColumnSchema::class,