diff --git a/src/Column/ColumnFactory.php b/src/Column/ColumnFactory.php deleted file mode 100644 index 31de7bc4..00000000 --- a/src/Column/ColumnFactory.php +++ /dev/null @@ -1,73 +0,0 @@ - SchemaInterface::TYPE_BIT, - 'tinyint' => SchemaInterface::TYPE_TINYINT, - 'smallint' => SchemaInterface::TYPE_SMALLINT, - 'mediumint' => SchemaInterface::TYPE_INTEGER, - 'int' => SchemaInterface::TYPE_INTEGER, - 'integer' => SchemaInterface::TYPE_INTEGER, - 'bigint' => SchemaInterface::TYPE_BIGINT, - 'float' => SchemaInterface::TYPE_FLOAT, - 'real' => SchemaInterface::TYPE_FLOAT, - 'double' => SchemaInterface::TYPE_DOUBLE, - 'decimal' => SchemaInterface::TYPE_DECIMAL, - 'numeric' => SchemaInterface::TYPE_DECIMAL, - 'char' => SchemaInterface::TYPE_CHAR, - 'varchar' => SchemaInterface::TYPE_STRING, - 'string' => SchemaInterface::TYPE_STRING, - 'enum' => SchemaInterface::TYPE_STRING, - 'tinytext' => SchemaInterface::TYPE_TEXT, - 'mediumtext' => SchemaInterface::TYPE_TEXT, - 'longtext' => SchemaInterface::TYPE_TEXT, - 'text' => SchemaInterface::TYPE_TEXT, - 'varbinary' => SchemaInterface::TYPE_BINARY, - 'blob' => SchemaInterface::TYPE_BINARY, - 'longblob' => SchemaInterface::TYPE_BINARY, - 'year' => SchemaInterface::TYPE_DATE, - 'date' => SchemaInterface::TYPE_DATE, - 'time' => SchemaInterface::TYPE_TIME, - 'datetime' => SchemaInterface::TYPE_DATETIME, - 'timestamp' => SchemaInterface::TYPE_TIMESTAMP, - 'json' => SchemaInterface::TYPE_JSON, - ]; - - public function fromDefinition(string $definition, array $info = []): ColumnSchemaInterface - { - if (str_starts_with($definition, 'enum(')) { - preg_match('/^enum\(([^)]+)\)\s*/', $definition, $matches); - preg_match_all("/'([^']*)'/", $matches[1], $values); - - $info['enum_values'] = $values[1]; - - return $this->fromDbType('enum', $info); - } - - return parent::fromDefinition($definition, $info); - } - - protected function getType(string $dbType, array $info = []): string - { - $type = self::TYPE_MAP[$dbType] ?? SchemaInterface::TYPE_STRING; - - if ($type === SchemaInterface::TYPE_BIT && isset($info['size']) && $info['size'] === 1) { - return SchemaInterface::TYPE_BOOLEAN; - } - - return $type; - } -} diff --git a/src/Schema.php b/src/Schema.php index 26623418..a1673a0e 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -14,9 +14,7 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Helper\DbArrayHelper; -use Yiisoft\Db\Mysql\Column\ColumnFactory; use Yiisoft\Db\Schema\Builder\ColumnInterface; -use Yiisoft\Db\Schema\Column\ColumnFactoryInterface; use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; use Yiisoft\Db\Schema\TableSchemaInterface; @@ -79,16 +77,48 @@ */ final class Schema extends AbstractPdoSchema { + /** + * Mapping from physical column types (keys) to abstract column types (values). + * + * @var string[] + */ + private const TYPE_MAP = [ + 'tinyint' => self::TYPE_TINYINT, + 'bit' => self::TYPE_BIT, + 'smallint' => self::TYPE_SMALLINT, + 'mediumint' => self::TYPE_INTEGER, + 'int' => self::TYPE_INTEGER, + 'integer' => self::TYPE_INTEGER, + 'bigint' => self::TYPE_BIGINT, + 'float' => self::TYPE_FLOAT, + 'double' => self::TYPE_DOUBLE, + 'real' => self::TYPE_FLOAT, + 'decimal' => self::TYPE_DECIMAL, + 'numeric' => self::TYPE_DECIMAL, + 'tinytext' => self::TYPE_TEXT, + 'mediumtext' => self::TYPE_TEXT, + 'longtext' => self::TYPE_TEXT, + 'longblob' => self::TYPE_BINARY, + 'blob' => self::TYPE_BINARY, + 'text' => self::TYPE_TEXT, + 'varchar' => self::TYPE_STRING, + 'string' => self::TYPE_STRING, + 'char' => self::TYPE_CHAR, + 'datetime' => self::TYPE_DATETIME, + 'year' => self::TYPE_DATE, + 'date' => self::TYPE_DATE, + 'time' => self::TYPE_TIME, + 'timestamp' => self::TYPE_TIMESTAMP, + 'enum' => self::TYPE_STRING, + 'varbinary' => self::TYPE_BINARY, + 'json' => self::TYPE_JSON, + ]; + public function createColumn(string $type, array|int|string $length = null): ColumnInterface { return new Column($type, $length); } - public function getColumnFactory(): ColumnFactoryInterface - { - return new ColumnFactory(); - } - /** * Returns all unique indexes for the given table. * @@ -428,9 +458,15 @@ protected function getCreateTableSql(TableSchemaInterface $table): string private function loadColumnSchema(array $info): ColumnSchemaInterface { $dbType = $info['type']; + $type = $this->getColumnType($dbType, $info); + $isUnsigned = stripos($dbType, 'unsigned') !== false; /** @psalm-var ColumnInfoArray $info */ - $column = $this->getColumnFactory()->fromDefinition($dbType); + $column = $this->createColumnSchema($type, unsigned: $isUnsigned); $column->name($info['field']); + $column->enumValues($info['enum_values'] ?? null); + $column->size($info['size'] ?? null); + $column->precision($info['precision'] ?? null); + $column->scale($info['scale'] ?? null); $column->allowNull($info['null'] === 'YES'); $column->primaryKey(str_contains($info['key'], 'PRI')); $column->autoIncrement(stripos($info['extra'], 'auto_increment') !== false); @@ -443,7 +479,7 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface empty($extra) && !empty($info['extra_default_value']) && !str_starts_with($info['extra_default_value'], '\'') - && in_array($column->getType(), [ + && in_array($type, [ self::TYPE_CHAR, self::TYPE_STRING, self::TYPE_TEXT, self::TYPE_DATETIME, self::TYPE_TIMESTAMP, self::TYPE_TIME, self::TYPE_DATE, ], true) @@ -461,6 +497,41 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface return $column; } + /** + * Get the abstract data type for the database data type. + * + * @param string $dbType The database data type + * @param array $info Column information. + * + * @return string The abstract data type. + */ + private function getColumnType(string $dbType, array &$info): string + { + preg_match('/^(\w*)(?:\(([^)]+)\))?/', $dbType, $matches); + $dbType = strtolower($matches[1]); + + if (!empty($matches[2])) { + if ($dbType === 'enum') { + preg_match_all("/'([^']*)'/", $matches[2], $values); + $info['enum_values'] = $values[1]; + } else { + $values = explode(',', $matches[2], 2); + $info['size'] = (int) $values[0]; + $info['precision'] = (int) $values[0]; + + if (isset($values[1])) { + $info['scale'] = (int) $values[1]; + } + + if ($dbType === 'bit' && $info['size'] === 1) { + return self::TYPE_BOOLEAN; + } + } + } + + return self::TYPE_MAP[$dbType] ?? self::TYPE_STRING; + } + /** * Converts column's default value according to {@see ColumnSchema::phpType} after retrieval from the database. * diff --git a/tests/ColumnFactoryTest.php b/tests/ColumnFactoryTest.php deleted file mode 100644 index bfe58602..00000000 --- a/tests/ColumnFactoryTest.php +++ /dev/null @@ -1,34 +0,0 @@ - 1]]; - - return $definitions; - } -} diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index e1a78588..6e5b0a5c 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -15,7 +15,6 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Mysql\Column; -use Yiisoft\Db\Mysql\Column\ColumnFactory; use Yiisoft\Db\Mysql\Schema; use Yiisoft\Db\Mysql\Tests\Support\TestTrait; use Yiisoft\Db\Query\Query; @@ -563,12 +562,4 @@ public function testInsertDefaultValues() 'numeric_col' => '-33.22', ], $row); } - - public function testGetColumnFactory(): void - { - $db = $this->getConnection(); - $factory = $db->getSchema()->getColumnFactory(); - - $this->assertInstanceOf(ColumnFactory::class, $factory); - } }