diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f6bba6a..9604c6584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ - Enh #378: Improve loading schemas of views (@Tigrov) - Enh #379: Remove `ColumnInterface` (@Tigrov) - Enh #380: Rename `ColumnSchemaInterface` to `ColumnInterface` (@Tigrov) -- Enh #381: Add `ColumnDefinitionParser` class (@Tigrov) +- Enh #381, #383: Add `ColumnDefinitionParser` class (@Tigrov) - Enh #382: Replace `DbArrayHelper::getColumn()` with `array_column()` (@Tigrov) ## 1.3.0 March 21, 2024 diff --git a/src/Column/ColumnDefinitionParser.php b/src/Column/ColumnDefinitionParser.php index f55e65d08..b9dee5986 100644 --- a/src/Column/ColumnDefinitionParser.php +++ b/src/Column/ColumnDefinitionParser.php @@ -9,19 +9,20 @@ use function strlen; use function strtolower; use function substr; +use function substr_count; /** * Parses column definition string. For example, `string(255)` or `int unsigned`. */ final class ColumnDefinitionParser extends \Yiisoft\Db\Syntax\ColumnDefinitionParser { - private const TYPE_PATTERN = '/^(' + private const TYPE_PATTERN = '/^(?:(' . 'time(?:stamp)?\s*(?:\((\d+)\))? with(?:out)? time zone' . ')|(' . '(?:character|bit) varying' . '|double precision' . '|\w*' - . ')(?:\(([^)]+)\))?\s*/i'; + . ')(?:\(([^)]+)\))?)(\[[\d\[\]]*\])?\s*/i'; public function parse(string $definition): array { @@ -40,6 +41,11 @@ public function parse(string $definition): array } } + if (isset($matches[5])) { + /** @psalm-var positive-int */ + $info['dimension'] = substr_count($matches[5], '['); + } + $extra = substr($definition, strlen($matches[0])); return $info + $this->extraInfo($extra); diff --git a/src/Column/ColumnFactory.php b/src/Column/ColumnFactory.php index b2641c60c..8261f8989 100644 --- a/src/Column/ColumnFactory.php +++ b/src/Column/ColumnFactory.php @@ -162,6 +162,15 @@ protected function getColumnClass(string $type, array $info = []): string }; } + protected function getType(string $dbType, array $info = []): string + { + if (!empty($info['dimension'])) { + return ColumnType::ARRAY; + } + + return self::TYPE_MAP[$dbType] ?? ColumnType::STRING; + } + protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnInterface $column): mixed { $value = preg_replace("/::[^:']+$/", '$1', $defaultValue); diff --git a/tests/Provider/ColumnDefinitionParserProvider.php b/tests/Provider/ColumnDefinitionParserProvider.php index 327723dbb..fb3df9cf9 100644 --- a/tests/Provider/ColumnDefinitionParserProvider.php +++ b/tests/Provider/ColumnDefinitionParserProvider.php @@ -17,6 +17,8 @@ public static function parse(): array ['timestamp(3) with time zone', ['type' => 'timestamp with time zone', 'size' => 3]], ['time without time zone', ['type' => 'time without time zone']], ['time (3) with time zone', ['type' => 'time with time zone', 'size' => 3]], + ['int[]', ['type' => 'int', 'dimension' => 1]], + ['character varying(126)[][]', ['type' => 'character varying', 'size' => 126, 'dimension' => 2]], ]; } } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index f8117eb21..ed44567c6 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -638,7 +638,9 @@ public static function buildColumnDefinition(): array return [ ...$values, + ['int[]', 'int[]'], ['character varying(255)', 'character varying(255)'], + ['character varying(255)[][]', 'character varying(255)[][]'], ['timestamp(5)', 'timestamp (5) without time zone'], ['timestamptz', 'timestamp with time zone'], ['time(3)', 'time(3) without time zone'],