Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor column PHP type #354

Merged
merged 3 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Enh #349: Add method chaining for column classes (@Tigrov)
- Enh #350: Add array overlaps and JSON overlaps condition builders (@Tigrov)
- Enh #353: Update `bit` type according to main PR yiisoft/db#860 (@Tigrov)
- Enh #354: Refactor PHP type of `ColumnSchemaInterface` instances (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
36 changes: 21 additions & 15 deletions src/Column/ArrayColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Db\Pgsql\Column;

use Traversable;
use Yiisoft\Db\Constant\PhpType;
use Yiisoft\Db\Expression\ArrayExpression;
use Yiisoft\Db\Expression\ExpressionInterface;
use Yiisoft\Db\Pgsql\ArrayParser;
Expand Down Expand Up @@ -37,9 +38,8 @@ final class ArrayColumnSchema extends AbstractColumnSchema

public function __construct(
string $type = Schema::TYPE_ARRAY,
string|null $phpType = SchemaInterface::PHP_TYPE_ARRAY,
) {
parent::__construct($type, $phpType);
parent::__construct($type);
}

/**
Expand All @@ -58,22 +58,23 @@ public function getColumn(): ColumnSchemaInterface
{
if ($this->column === null) {
$type = $this->getType();
$phpType = $this->getPhpType();

$this->column = match ($type) {
SchemaInterface::TYPE_BIT => new BitColumnSchema($type, $phpType),
Schema::TYPE_STRUCTURED => new StructuredColumnSchema($type, $phpType),
SchemaInterface::TYPE_BOOLEAN => new BooleanColumnSchema($type),
SchemaInterface::TYPE_BIT => new BitColumnSchema($type),
SchemaInterface::TYPE_TINYINT => new IntegerColumnSchema($type),
SchemaInterface::TYPE_SMALLINT => new IntegerColumnSchema($type),
SchemaInterface::TYPE_INTEGER => new IntegerColumnSchema($type),
SchemaInterface::TYPE_BIGINT => PHP_INT_SIZE !== 8
? new BigIntColumnSchema($type, $phpType)
: new IntegerColumnSchema($type, $phpType),
default => match ($phpType) {
SchemaInterface::PHP_TYPE_INTEGER => new IntegerColumnSchema($type, $phpType),
SchemaInterface::PHP_TYPE_DOUBLE => new DoubleColumnSchema($type, $phpType),
SchemaInterface::PHP_TYPE_BOOLEAN => new BooleanColumnSchema($type, $phpType),
SchemaInterface::PHP_TYPE_RESOURCE => new BinaryColumnSchema($type, $phpType),
SchemaInterface::PHP_TYPE_ARRAY => new JsonColumnSchema($type, $phpType),
default => new StringColumnSchema($type, $phpType),
},
? new BigIntColumnSchema($type)
: new IntegerColumnSchema($type),
SchemaInterface::TYPE_DECIMAL => new DoubleColumnSchema($type),
SchemaInterface::TYPE_FLOAT => new DoubleColumnSchema($type),
SchemaInterface::TYPE_DOUBLE => new DoubleColumnSchema($type),
SchemaInterface::TYPE_BINARY => new BinaryColumnSchema($type),
SchemaInterface::TYPE_JSON => new JsonColumnSchema($type),
Schema::TYPE_STRUCTURED => new StructuredColumnSchema($type),
default => new StringColumnSchema($type),
};

$this->column->dbType($this->getDbType());
Expand Down Expand Up @@ -103,6 +104,11 @@ public function getDimension(): int
return $this->dimension;
}

public function getPhpType(): string
{
return PhpType::ARRAY;
}

public function dbTypecast(mixed $value): ExpressionInterface|null
{
if ($value === null || $value instanceof ExpressionInterface) {
Expand Down
10 changes: 7 additions & 3 deletions src/Column/StructuredColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
namespace Yiisoft\Db\Pgsql\Column;

use Traversable;
use Yiisoft\Db\Constant\PhpType;
use Yiisoft\Db\Expression\ExpressionInterface;
use Yiisoft\Db\Pgsql\Schema;
use Yiisoft\Db\Pgsql\StructuredExpression;
use Yiisoft\Db\Pgsql\StructuredParser;
use Yiisoft\Db\Schema\Column\AbstractColumnSchema;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
use Yiisoft\Db\Schema\SchemaInterface;

use function array_keys;
use function is_iterable;
Expand All @@ -28,9 +28,8 @@ final class StructuredColumnSchema extends AbstractColumnSchema implements Struc

public function __construct(
string $type = Schema::TYPE_STRUCTURED,
string|null $phpType = SchemaInterface::PHP_TYPE_ARRAY,
) {
parent::__construct($type, $phpType);
parent::__construct($type);
}

public function columns(array $columns): static
Expand All @@ -44,6 +43,11 @@ public function getColumns(): array
return $this->columns;
}

public function getPhpType(): string
{
return PhpType::ARRAY;
}

public function dbTypecast(mixed $value): mixed
{
if ($value === null || $value instanceof ExpressionInterface) {
Expand Down
45 changes: 18 additions & 27 deletions src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
use Yiisoft\Db\Pgsql\Column\StructuredColumnSchemaInterface;
use Yiisoft\Db\Schema\Builder\ColumnInterface;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
use Yiisoft\Db\Schema\Column\StringColumnSchema;
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Schema\TableSchemaInterface;

Expand Down Expand Up @@ -876,25 +875,20 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
return $column;
}

protected function getColumnPhpType(string $type, bool $isUnsigned = false): string
protected function createColumnSchemaFromType(string $type, bool $isUnsigned = false): ColumnSchemaInterface
{
return match ($type) {
self::TYPE_BIT => self::PHP_TYPE_INTEGER,
self::TYPE_STRUCTURED => self::PHP_TYPE_ARRAY,
default => parent::getColumnPhpType($type, $isUnsigned),
};
}

protected function createColumnSchemaFromPhpType(string $phpType, string $type): ColumnSchemaInterface
{
return match ($phpType) {
self::PHP_TYPE_STRING => $type === SchemaInterface::TYPE_BIGINT
? new BigIntColumnSchema($type, $phpType)
: new StringColumnSchema($type, $phpType),
self::PHP_TYPE_INTEGER => new IntegerColumnSchema($type, $phpType),
self::PHP_TYPE_BOOLEAN => new BooleanColumnSchema($type, $phpType),
self::PHP_TYPE_RESOURCE => new BinaryColumnSchema($type, $phpType),
default => parent::createColumnSchemaFromPhpType($phpType, $type),
SchemaInterface::TYPE_BOOLEAN => new BooleanColumnSchema($type),
SchemaInterface::TYPE_BIT => new BitColumnSchema($type),
SchemaInterface::TYPE_TINYINT => new IntegerColumnSchema($type),
SchemaInterface::TYPE_SMALLINT => new IntegerColumnSchema($type),
SchemaInterface::TYPE_INTEGER => new IntegerColumnSchema($type),
SchemaInterface::TYPE_BIGINT => PHP_INT_SIZE !== 8
? new BigIntColumnSchema($type)
: new IntegerColumnSchema($type),
SchemaInterface::TYPE_BINARY => new BinaryColumnSchema($type),
self::TYPE_STRUCTURED => new StructuredColumnSchema($type),
default => parent::createColumnSchemaFromType($type),
};
}

Expand Down Expand Up @@ -1092,16 +1086,13 @@ protected function createColumnSchema(string $type, mixed ...$info): ColumnSchem
return $column;
}

$phpType = $this->getColumnPhpType($type);
$column = $this->createColumnSchemaFromType($type);

return match ($type) {
self::TYPE_BIT => new BitColumnSchema($type, $phpType),
self::TYPE_STRUCTURED => (new StructuredColumnSchema($type, $phpType))->columns($info['columns'] ?? []),
self::TYPE_BIGINT => PHP_INT_SIZE !== 8
? new BigIntColumnSchema($type, $phpType)
: new IntegerColumnSchema($type, $phpType),
default => parent::createColumnSchema($type),
};
if ($column instanceof StructuredColumnSchemaInterface) {
$column->columns($info['columns'] ?? []);
}

return $column;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/ColumnSchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public function testArrayColumnSchema()

public function testArrayColumnSchemaColumn(): void
{
$arrayCol = new ArrayColumnSchema(SchemaInterface::TYPE_STRING, SchemaInterface::PHP_TYPE_STRING);
$arrayCol = new ArrayColumnSchema(SchemaInterface::TYPE_STRING);
$intCol = new IntegerColumnSchema();

$this->assertInstanceOf(StringColumnSchema::class, $arrayCol->getColumn());
Expand Down
39 changes: 20 additions & 19 deletions tests/Provider/ColumnSchemaProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PDO;
use Yiisoft\Db\Command\Param;
use Yiisoft\Db\Constant\PhpType;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Expression\JsonExpression;
use Yiisoft\Db\Pgsql\Column\BigIntColumnSchema;
Expand All @@ -28,7 +29,7 @@ public static function predefinedTypes(): array
$values['bigint'][0] = BigIntColumnSchema::class;
$values['binary'][0] = BinaryColumnSchema::class;
$values['boolean'][0] = BooleanColumnSchema::class;
$values['bit'] = [BitColumnSchema::class, Schema::TYPE_BIT, SchemaInterface::PHP_TYPE_INTEGER];
$values['bit'][0] = BitColumnSchema::class;

return $values;
}
Expand Down Expand Up @@ -97,7 +98,7 @@ public static function dbTypecastArrayColumns()
[
'int4',
SchemaInterface::TYPE_INTEGER,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
// [dimension, expected, typecast value]
[1, [1, 2, 3, null], [1, 2.0, '3', null]],
Expand All @@ -108,7 +109,7 @@ public static function dbTypecastArrayColumns()
[
'int8',
SchemaInterface::TYPE_BIGINT,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
[1, [1, 2, 3, $bigInt], [1, 2.0, '3', '9223372036854775807']],
[2, [[1, 2], [3], [$bigInt]], [[1, 2.0], ['3'], ['9223372036854775807']]],
Expand All @@ -117,7 +118,7 @@ public static function dbTypecastArrayColumns()
[
'float8',
SchemaInterface::TYPE_DOUBLE,
SchemaInterface::PHP_TYPE_DOUBLE,
PhpType::FLOAT,
[
[1, [1.0, 2.2, 3.3, null], [1, 2.2, '3.3', null]],
[2, [[1.0, 2.2], [3.3, null]], [[1, 2.2], ['3.3', null]]],
Expand All @@ -126,7 +127,7 @@ public static function dbTypecastArrayColumns()
[
'bool',
SchemaInterface::TYPE_BOOLEAN,
SchemaInterface::PHP_TYPE_BOOLEAN,
PhpType::BOOL,
[
[1, [true, true, true, false, false, false, null], [true, 1, '1', false, 0, '0', null]],
[2, [[true, true, true, false, false, false, null]], [[true, 1, '1', false, 0, '0', null]]],
Expand All @@ -135,7 +136,7 @@ public static function dbTypecastArrayColumns()
[
'varchar',
SchemaInterface::TYPE_STRING,
SchemaInterface::PHP_TYPE_STRING,
PhpType::STRING,
[
[1, ['1', '2', '1', '0', '', null], [1, '2', true, false, '', null]],
[2, [['1', '2', '1', '0'], [''], [null]], [[1, '2', true, false], [''], [null]]],
Expand All @@ -144,7 +145,7 @@ public static function dbTypecastArrayColumns()
[
'bytea',
SchemaInterface::TYPE_BINARY,
SchemaInterface::PHP_TYPE_RESOURCE,
PhpType::MIXED,
[
[1, [
'1',
Expand All @@ -163,7 +164,7 @@ public static function dbTypecastArrayColumns()
[
'jsonb',
SchemaInterface::TYPE_JSON,
SchemaInterface::PHP_TYPE_ARRAY,
PhpType::MIXED,
[
[1, [
new JsonExpression([1, 2, 3], 'jsonb'),
Expand All @@ -185,7 +186,7 @@ public static function dbTypecastArrayColumns()
[
'varbit',
Schema::TYPE_BIT,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
[1, ['1011', '1001', null], [0b1011, '1001', null]],
[2, [['1011', '1001', null]], [[0b1011, '1001', null]]],
Expand All @@ -194,7 +195,7 @@ public static function dbTypecastArrayColumns()
[
'price_composite',
Schema::TYPE_STRUCTURED,
SchemaInterface::PHP_TYPE_ARRAY,
PhpType::ARRAY,
[
[
1,
Expand Down Expand Up @@ -232,7 +233,7 @@ public static function phpTypecastArrayColumns()
[
'int4',
SchemaInterface::TYPE_INTEGER,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
// [dimension, expected, typecast value]
[1, [1, 2, 3, null], '{1,2,3,}'],
Expand All @@ -242,7 +243,7 @@ public static function phpTypecastArrayColumns()
[
'int8',
SchemaInterface::TYPE_BIGINT,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
[1, [1, 2, $bigInt], '{1,2,9223372036854775807}'],
[2, [[1, 2], [$bigInt]], '{{1,2},{9223372036854775807}}'],
Expand All @@ -251,7 +252,7 @@ public static function phpTypecastArrayColumns()
[
'float8',
SchemaInterface::TYPE_DOUBLE,
SchemaInterface::PHP_TYPE_DOUBLE,
PhpType::FLOAT,
[
[1, [1.0, 2.2, null], '{1,2.2,}'],
[2, [[1.0], [2.2, null]], '{{1},{2.2,}}'],
Expand All @@ -260,7 +261,7 @@ public static function phpTypecastArrayColumns()
[
'bool',
SchemaInterface::TYPE_BOOLEAN,
SchemaInterface::PHP_TYPE_BOOLEAN,
PhpType::BOOL,
[
[1, [true, false, null], '{t,f,}'],
[2, [[true, false, null]], '{{t,f,}}'],
Expand All @@ -269,7 +270,7 @@ public static function phpTypecastArrayColumns()
[
'varchar',
SchemaInterface::TYPE_STRING,
SchemaInterface::PHP_TYPE_STRING,
PhpType::STRING,
[
[1, ['1', '2', '', null], '{1,2,"",}'],
[2, [['1', '2'], [''], [null]], '{{1,2},{""},{NULL}}'],
Expand All @@ -278,7 +279,7 @@ public static function phpTypecastArrayColumns()
[
'bytea',
SchemaInterface::TYPE_BINARY,
SchemaInterface::PHP_TYPE_RESOURCE,
PhpType::MIXED,
[
[1, ["\x10\x11", '', null], '{\x1011,"",}'],
[2, [["\x10\x11"], ['', null]], '{{\x1011},{"",}}'],
Expand All @@ -287,7 +288,7 @@ public static function phpTypecastArrayColumns()
[
'jsonb',
SchemaInterface::TYPE_JSON,
SchemaInterface::PHP_TYPE_ARRAY,
PhpType::MIXED,
[
[1, [[1, 2, 3], null], '{"[1,2,3]",}'],
[1, [[1, 2, 3]], '{{1,2,3}}'],
Expand All @@ -297,7 +298,7 @@ public static function phpTypecastArrayColumns()
[
'varbit',
Schema::TYPE_BIT,
SchemaInterface::PHP_TYPE_INTEGER,
PhpType::INT,
[
[1, [0b1011, 0b1001, null], '{1011,1001,}'],
[2, [[0b1011, 0b1001, null]], '{{1011,1001,}}'],
Expand All @@ -306,7 +307,7 @@ public static function phpTypecastArrayColumns()
[
'price_structured',
Schema::TYPE_STRUCTURED,
SchemaInterface::PHP_TYPE_ARRAY,
PhpType::ARRAY,
[
[1, [['10', 'USD'], null], '{"(10,USD)",}'],
[2, [[['10', 'USD'], null]], '{{"(10,USD)",}}'],
Expand Down
Loading