diff --git a/CHANGELOG.md b/CHANGELOG.md index 7506eda89..9d5ea0c3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ - Enh #353: Update `bit` type according to main PR yiisoft/db#860 (@Tigrov) - Enh #354: Refactor PHP type of `ColumnSchemaInterface` instances (@Tigrov) - Enh #356: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov) -- New #355, #368, #370: Implement `ColumnFactory` class (@Tigrov) +- New #355, #368, #370, #399: Implement `ColumnFactory` class (@Tigrov) - Enh #359: Separate column type constants (@Tigrov) - Enh #359: Remove `Schema::TYPE_ARRAY` and `Schema::TYPE_STRUCTURED` constants (@Tigrov) - New #360: Realize `ColumnBuilder` class (@Tigrov) diff --git a/src/Column/ColumnFactory.php b/src/Column/ColumnFactory.php index 1ce3c433c..5af7570f3 100644 --- a/src/Column/ColumnFactory.php +++ b/src/Column/ColumnFactory.php @@ -124,16 +124,7 @@ public function fromType(string $type, array $info = []): ColumnInterface $column = parent::fromType($type, $info); if ($column instanceof StructuredColumn) { - /** @psalm-var array|null $defaultValue */ - $defaultValue = $column->getDefaultValue(); - - if (is_array($defaultValue)) { - foreach ($column->getColumns() as $structuredColumnName => $structuredColumn) { - if (isset($defaultValue[$structuredColumnName])) { - $structuredColumn->defaultValue($defaultValue[$structuredColumnName]); - } - } - } + $this->initializeStructuredDefaultValue($column); } return $column; @@ -179,4 +170,25 @@ protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnInte return $value; } + + /** + * Initializes the default value for structured columns. + */ + private function initializeStructuredDefaultValue(StructuredColumn $column): void + { + /** @psalm-var array|null $defaultValue */ + $defaultValue = $column->getDefaultValue(); + + if (is_array($defaultValue)) { + foreach ($column->getColumns() as $structuredColumnName => $structuredColumn) { + if (isset($defaultValue[$structuredColumnName])) { + $structuredColumn->defaultValue($defaultValue[$structuredColumnName]); + + if ($structuredColumn instanceof StructuredColumn) { + $this->initializeStructuredDefaultValue($structuredColumn); + } + } + } + } + } } diff --git a/tests/ColumnTest.php b/tests/ColumnTest.php index 4535b6440..fe183859f 100644 --- a/tests/ColumnTest.php +++ b/tests/ColumnTest.php @@ -277,10 +277,11 @@ public function testStructuredType(): void name: 'price_array2', notNull: false, columns: [ - 'value' => new DoubleColumn(ColumnType::DECIMAL, dbType: 'numeric', name: 'value', notNull: false, scale: 2, size: 10), - 'currency_code' => new StringColumn(ColumnType::CHAR, dbType: 'bpchar', name: 'currency_code', notNull: false, size: 3), + 'value' => new DoubleColumn(ColumnType::DECIMAL, dbType: 'numeric', name: 'value', notNull: false, scale: 2, size: 10, defaultValue: null), + 'currency_code' => new StringColumn(ColumnType::CHAR, dbType: 'bpchar', name: 'currency_code', notNull: false, size: 3, defaultValue: null), ], ), + defaultValue: null, ), ), $priceArray2->dbTypecast([null, null]), diff --git a/tests/Provider/SchemaProvider.php b/tests/Provider/SchemaProvider.php index d2f9ceadd..f809d5daa 100644 --- a/tests/Provider/SchemaProvider.php +++ b/tests/Provider/SchemaProvider.php @@ -4,7 +4,16 @@ namespace Yiisoft\Db\Pgsql\Tests\Provider; +use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Expression\Expression; +use Yiisoft\Db\Pgsql\Column\ArrayColumn; +use Yiisoft\Db\Pgsql\Column\BinaryColumn; +use Yiisoft\Db\Pgsql\Column\BitColumn; +use Yiisoft\Db\Pgsql\Column\BooleanColumn; +use Yiisoft\Db\Pgsql\Column\IntegerColumn; +use Yiisoft\Db\Schema\Column\DoubleColumn; +use Yiisoft\Db\Schema\Column\JsonColumn; +use Yiisoft\Db\Schema\Column\StringColumn; final class SchemaProvider extends \Yiisoft\Db\Tests\Provider\SchemaProvider { @@ -13,491 +22,230 @@ public static function columns(): array return [ [ [ - 'int_col' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - ], - 'int_col2' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => 1, - ], - 'tinyint_col' => [ - 'type' => 'smallint', - 'dbType' => 'int2', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => 1, - ], - 'smallint_col' => [ - 'type' => 'smallint', - 'dbType' => 'int2', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => 1, - ], - 'char_col' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 100, - 'scale' => null, - 'defaultValue' => null, - ], - 'char_col2' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 100, - 'scale' => null, - 'defaultValue' => 'some\'thing', - ], - 'char_col3' => [ - 'type' => 'text', - 'dbType' => 'text', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - ], - 'char_col4' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => "first line\nsecond line", - ], - 'float_col' => [ - 'type' => 'double', - 'dbType' => 'float8', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - ], - 'float_col2' => [ - 'type' => 'double', - 'dbType' => 'float8', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => 1.23, - ], - 'blob_col' => [ - 'type' => 'binary', - 'dbType' => 'bytea', - 'phpType' => 'mixed', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => 'a binary value', - ], - 'numeric_col' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 5, - 'scale' => 2, - 'defaultValue' => 33.22, - ], - 'time' => [ - 'type' => 'timestamp', - 'dbType' => 'timestamp', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 6, - 'scale' => null, - 'defaultValue' => '2002-01-01 00:00:00', - ], - 'bool_col' => [ - 'type' => 'boolean', - 'dbType' => 'bool', - 'phpType' => 'bool', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - ], - 'bool_col2' => [ - 'type' => 'boolean', - 'dbType' => 'bool', - 'phpType' => 'bool', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => true, - ], - 'ts_default' => [ - 'type' => 'timestamp', - 'dbType' => 'timestamp', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 6, - 'scale' => null, - 'defaultValue' => new Expression('now()'), - ], - 'bit_col' => [ - 'type' => 'bit', - 'dbType' => 'bit', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 8, - 'scale' => null, - 'defaultValue' => 0b1000_0010, // 130 - ], - 'varbit_col' => [ - 'type' => 'bit', - 'dbType' => 'varbit', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => 0b100, // 4 - ], - 'bigint_col' => [ - 'type' => 'bigint', - 'dbType' => 'int8', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - ], - 'intarray_col' => [ - 'type' => 'array', - 'dbType' => 'int4', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - 'dimension' => 1, - 'column' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - ], - ], - 'numericarray_col' => [ - 'type' => 'array', - 'dbType' => 'numeric', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 5, - 'scale' => 2, - 'defaultValue' => null, - 'dimension' => 1, - 'column' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'enumValues' => null, - 'size' => 5, - 'scale' => 2, - ], - ], - 'varchararray_col' => [ - 'type' => 'array', - 'dbType' => 'varchar', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 100, - 'scale' => null, - 'defaultValue' => null, - 'dimension' => 1, - 'column' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'enumValues' => null, - 'size' => 100, - 'scale' => null, - ], - ], - 'textarray2_col' => [ - 'type' => 'array', - 'dbType' => 'text', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'dimension' => 2, - 'column' => [ - 'type' => 'text', - 'dbType' => 'text', - 'phpType' => 'string', - 'enumValues' => null, - 'size' => null, - 'scale' => null, - ], - ], - 'json_col' => [ - 'type' => 'json', - 'dbType' => 'json', - 'phpType' => 'mixed', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => ['a' => 1], - ], - 'jsonb_col' => [ - 'type' => 'json', - 'dbType' => 'jsonb', - 'phpType' => 'mixed', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - ], - 'jsonarray_col' => [ - 'type' => 'array', - 'dbType' => 'json', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'dimension' => 1, - 'column' => [ - 'type' => 'json', - 'dbType' => 'json', - 'phpType' => 'mixed', - 'enumValues' => null, - 'size' => null, - 'scale' => null, - ], - ], + 'int_col' => new IntegerColumn( + dbType: 'int4', + notNull: true, + scale: 0, + ), + 'int_col2' => new IntegerColumn( + dbType: 'int4', + scale: 0, + defaultValue: 1, + ), + 'tinyint_col' => new IntegerColumn( + ColumnType::SMALLINT, + dbType: 'int2', + scale: 0, + defaultValue: 1, + ), + 'smallint_col' => new IntegerColumn( + ColumnType::SMALLINT, + dbType: 'int2', + scale: 0, + defaultValue: 1, + ), + 'char_col' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + notNull: true, + size: 100, + ), + 'char_col2' => new StringColumn( + dbType: 'varchar', + size: 100, + defaultValue: 'some\'thing', + ), + 'char_col3' => new StringColumn( + ColumnType::TEXT, + dbType: 'text', + ), + 'char_col4' => new StringColumn( + dbType: 'varchar', + defaultValue: "first line\nsecond line", + ), + 'float_col' => new DoubleColumn( + dbType: 'float8', + notNull: true, + ), + 'float_col2' => new DoubleColumn( + dbType: 'float8', + defaultValue: 1.23, + ), + 'blob_col' => new BinaryColumn( + dbType: 'bytea', + defaultValue: 'a binary value', + ), + 'numeric_col' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + size: 5, + scale: 2, + defaultValue: 33.22, + ), + 'time' => new StringColumn( + ColumnType::TIMESTAMP, + dbType: 'timestamp', + notNull: true, + size: 6, + defaultValue: '2002-01-01 00:00:00', + ), + 'bool_col' => new BooleanColumn( + dbType: 'bool', + notNull: true, + ), + 'bool_col2' => new BooleanColumn( + dbType: 'bool', + defaultValue: true, + ), + 'ts_default' => new StringColumn( + ColumnType::TIMESTAMP, + dbType: 'timestamp', + notNull: true, + size: 6, + defaultValue: new Expression('now()'), + ), + 'bit_col' => new BitColumn( + dbType: 'bit', + notNull: true, + size: 8, + defaultValue: 0b1000_0010, // 130 + ), + 'varbit_col' => new BitColumn( + dbType: 'varbit', + notNull: true, + defaultValue: 0b100, // 4 + ), + 'bigint_col' => new IntegerColumn( + ColumnType::BIGINT, + dbType: 'int8', + scale: 0, + ), + 'intarray_col' => new ArrayColumn( + dbType: 'int4', + scale: 0, + dimension: 1, + column: new IntegerColumn( + dbType: 'int4', + name: 'intarray_col', + notNull: false, + scale: 0, + ), + ), + 'numericarray_col' => new ArrayColumn( + dbType: 'numeric', + size: 5, + scale: 2, + dimension: 1, + column: new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'numericarray_col', + notNull: false, + size: 5, + scale: 2, + ), + ), + 'varchararray_col' => new ArrayColumn( + dbType: 'varchar', + size: 100, + dimension: 1, + column: new StringColumn( + dbType: 'varchar', + name: 'varchararray_col', + notNull: false, + size: 100, + ), + ), + 'textarray2_col' => new ArrayColumn( + dbType: 'text', + dimension: 2, + column: new StringColumn( + ColumnType::TEXT, + dbType: 'text', + name: 'textarray2_col', + notNull: false, + ), + ), + 'json_col' => new JsonColumn( + dbType: 'json', + defaultValue: ['a' => 1], + ), + 'jsonb_col' => new JsonColumn( + dbType: 'jsonb', + ), + 'jsonarray_col' => new ArrayColumn( + dbType: 'json', + dimension: 1, + column: new JsonColumn( + dbType: 'json', + name: 'jsonarray_col', + notNull: false, + ), + ), ], 'tableName' => 'type', ], [ [ - 'id' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => true, - 'notNull' => true, - 'autoIncrement' => true, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - ], - 'type' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 255, - 'scale' => null, - 'defaultValue' => null, - ], + 'id' => new IntegerColumn( + dbType: 'int4', + primaryKey: true, + notNull: true, + autoIncrement: true, + sequenceName: 'animal_id_seq', + scale: 0, + ), + 'type' => new StringColumn( + dbType: 'varchar', + notNull: true, + size: 255, + ), ], 'animal', ], [ [ - 'uuid' => [ - 'type' => 'string', - 'dbType' => 'uuid', - 'phpType' => 'string', - 'primaryKey' => true, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - ], - 'col' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 16, - 'scale' => null, - 'defaultValue' => null, - ], + 'uuid' => new StringColumn( + dbType: 'uuid', + primaryKey: true, + notNull: true, + ), + 'col' => new StringColumn( + dbType: 'varchar', + size: 16, + ), ], 'table_uuid', ], [ [ - 'C_id' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => true, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - 'unique' => false, - ], - 'C_not_null' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - 'unique' => false, - ], - 'C_check' => [ - 'type' => 'string', - 'dbType' => 'varchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 255, - 'scale' => null, - 'defaultValue' => null, - 'unique' => false, - ], - 'C_unique' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - 'unique' => true, - ], - 'C_default' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => false, - 'notNull' => true, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => 0, - 'unique' => false, - ], + 'C_id' => new IntegerColumn( + dbType: 'int4', + primaryKey: true, + notNull: true, + scale: 0, + ), + 'C_not_null' => new IntegerColumn( + dbType: 'int4', + notNull: true, + scale: 0, + ), + 'C_check' => new StringColumn( + dbType: 'varchar', + size: 255, + ), + 'C_unique' => new IntegerColumn( + dbType: 'int4', + notNull: true, + scale: 0, + unique: true, + ), + 'C_default' => new IntegerColumn( + dbType: 'int4', + notNull: true, + scale: 0, + defaultValue: 0, + ), ], 'T_constraints_1', ], diff --git a/tests/Provider/StructuredTypeProvider.php b/tests/Provider/StructuredTypeProvider.php index a3f853ae9..2a5d77e89 100644 --- a/tests/Provider/StructuredTypeProvider.php +++ b/tests/Provider/StructuredTypeProvider.php @@ -4,6 +4,13 @@ namespace Yiisoft\Db\Pgsql\Tests\Provider; +use Yiisoft\Db\Constant\ColumnType; +use Yiisoft\Db\Pgsql\Column\ArrayColumn; +use Yiisoft\Db\Pgsql\Column\IntegerColumn; +use Yiisoft\Db\Pgsql\Column\StructuredColumn; +use Yiisoft\Db\Schema\Column\DoubleColumn; +use Yiisoft\Db\Schema\Column\StringColumn; + final class StructuredTypeProvider { public static function columns(): array @@ -11,269 +18,180 @@ public static function columns(): array return [ [ [ - 'id' => [ - 'type' => 'integer', - 'dbType' => 'int4', - 'phpType' => 'int', - 'primaryKey' => true, - 'notNull' => true, - 'autoIncrement' => true, - 'enumValues' => null, - 'size' => null, - 'scale' => 0, - 'defaultValue' => null, - ], - 'price_col' => [ - 'type' => 'structured', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, - ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, - ], + 'id' => new IntegerColumn( + dbType: 'int4', + primaryKey: true, + notNull: true, + autoIncrement: true, + sequenceName: 'test_structured_type_id_seq', + scale: 0, + ), + 'price_col' => new StructuredColumn( + dbType: 'currency_money_structured', + defaultValue: null, + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'value', + notNull: false, + size: 10, + scale: 2, + defaultValue: null, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + name: 'currency_code', + notNull: false, + size: 3, + defaultValue: null, + ), ], - ], - 'price_default' => [ - 'type' => 'structured', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => ['value' => 5.0, 'currency_code' => 'USD'], - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, - ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, - ], + ), + 'price_default' => new StructuredColumn( + dbType: 'currency_money_structured', + defaultValue: ['value' => 5.0, 'currency_code' => 'USD'], + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + defaultValue: 5.0, + name: 'value', + notNull: false, + size: 10, + scale: 2, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + defaultValue: 'USD', + name: 'currency_code', + notNull: false, + size: 3, + ), ], - ], - 'price_array' => [ - 'type' => 'array', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => [ + ), + 'price_array' => new ArrayColumn( + dbType: 'currency_money_structured', + defaultValue: [ null, ['value' => 10.55, 'currency_code' => 'USD'], ['value' => -1.0, 'currency_code' => null], ], - 'dimension' => 1, - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, + dimension: 1, + column: new StructuredColumn( + dbType: 'currency_money_structured', + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'value', + notNull: false, + size: 10, + scale: 2, + defaultValue: null, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + name: 'currency_code', + notNull: false, + size: 3, + defaultValue: null, + ), ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, + name: 'price_array', + notNull: false, + ), + ), + 'price_array2' => new ArrayColumn( + dbType: 'currency_money_structured', + dimension: 2, + column: new StructuredColumn( + dbType: 'currency_money_structured', + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'value', + notNull: false, + size: 10, + scale: 2, + defaultValue: null, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + name: 'currency_code', + notNull: false, + size: 3, + defaultValue: null, + ), ], - ], - ], - 'price_array2' => [ - 'type' => 'array', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'dimension' => 2, - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, - ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, - ], - ], - ], - 'range_price_col' => [ - 'type' => 'structured', - 'dbType' => 'range_price_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => [ + name: 'price_array2', + notNull: false, + ), + ), + 'range_price_col' => new StructuredColumn( + dbType: 'range_price_structured', + defaultValue: [ 'price_from' => ['value' => 0.0, 'currency_code' => 'USD'], 'price_to' => ['value' => 100.0, 'currency_code' => 'USD'], ], - 'columns' => [ - 'price_from' => [ - 'type' => 'structured', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, - ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, - ], + columns: [ + 'price_from' => new StructuredColumn( + dbType: 'currency_money_structured', + defaultValue: ['value' => 0.0, 'currency_code' => 'USD'], + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'value', + notNull: false, + size: 10, + scale: 2, + defaultValue: 0.0, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + name: 'currency_code', + notNull: false, + size: 3, + defaultValue: 'USD', + ), ], - ], - 'price_to' => [ - 'type' => 'structured', - 'dbType' => 'currency_money_structured', - 'phpType' => 'array', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => null, - 'scale' => null, - 'defaultValue' => null, - 'columns' => [ - 'value' => [ - 'type' => 'decimal', - 'dbType' => 'numeric', - 'phpType' => 'float', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 10, - 'scale' => 2, - 'defaultValue' => null, - ], - 'currency_code' => [ - 'type' => 'char', - 'dbType' => 'bpchar', - 'phpType' => 'string', - 'primaryKey' => false, - 'notNull' => false, - 'autoIncrement' => false, - 'enumValues' => null, - 'size' => 3, - 'scale' => null, - 'defaultValue' => null, - ], + name: 'price_from', + notNull: false, + ), + 'price_to' => new StructuredColumn( + dbType: 'currency_money_structured', + defaultValue: ['value' => 100.0, 'currency_code' => 'USD'], + columns: [ + 'value' => new DoubleColumn( + ColumnType::DECIMAL, + dbType: 'numeric', + name: 'value', + notNull: false, + size: 10, + scale: 2, + defaultValue: 100.0, + ), + 'currency_code' => new StringColumn( + ColumnType::CHAR, + dbType: 'bpchar', + name: 'currency_code', + notNull: false, + size: 3, + defaultValue: 'USD', + ), ], - ], + name: 'price_to', + notNull: false, + ), ], - ], + ), ], 'test_structured_type', ], diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index f790ed904..5a464cd1f 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -8,7 +8,6 @@ use Throwable; use Yiisoft\Db\Command\CommandInterface; use Yiisoft\Db\Connection\ConnectionInterface; -use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constraint\IndexConstraint; use Yiisoft\Db\Driver\Pdo\PdoConnectionInterface; use Yiisoft\Db\Exception\Exception; @@ -66,7 +65,7 @@ public function testColumns(array $columns, string $tableName): void if (version_compare($db->getServerInfo()->getVersion(), '10', '>')) { if ($tableName === 'type') { - $columns['ts_default']['defaultValue'] = new Expression('CURRENT_TIMESTAMP'); + $columns['ts_default']->defaultValue(new Expression('CURRENT_TIMESTAMP')); } } @@ -574,28 +573,8 @@ public function testGetViewNames(): void /** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\StructuredTypeProvider::columns */ public function testStructuredTypeColumn(array $columns, string $tableName): void - { - $this->testStructuredTypeColumnRecursive($columns, $tableName); - } - - private function testStructuredTypeColumnRecursive(array $columns, string $tableName): void { $this->assertTableColumns($columns, $tableName); - - $db = $this->getConnection(true); - $table = $db->getTableSchema($tableName, true); - - foreach ($table->getColumns() as $name => $column) { - if ($column->getType() === ColumnType::STRUCTURED) { - $this->assertTrue( - isset($columns[$name]['columns']), - "Columns of structured type `$name` do not exist, dbType is `{$column->getDbType()}`." - ); - $this->testStructuredTypeColumnRecursive($columns[$name]['columns'], $column->getDbType()); - } - } - - $db->close(); } public function testTableIndexes(): void