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

Remove ColumnSchemaInterface::load(), add properties to constructor #890

Merged
merged 3 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 1 addition & 2 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ and the following changes were made:
- `isNotNull()` method is added;
- `unique(bool $unique = true)` method is added;
- `isUnique()` method is added;
- `load(array $info)` method is added;
- constructor of `AbstractColumnSchema` class is changed to `__construct(string $type, string|null $phpType = null)`;
- all `AbstractColumnSchema` class properties moved to constructor;
- added method chaining.

### New classes with constants
Expand Down
2 changes: 1 addition & 1 deletion src/Connection/AbstractDsn.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ abstract class AbstractDsn implements DsnInterface, Stringable
*/
public function __construct(
private readonly string $driver,
private readonly string $host,
private readonly string $host = '127.0.0.1',
private readonly string|null $databaseName = null,
private readonly string|null $port = null,
private readonly array $options = []
Expand Down
89 changes: 52 additions & 37 deletions src/Schema/Column/AbstractColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
/**
* The default implementation of the {@see ColumnFactoryInterface}.
*
* @psalm-import-type ColumnInfo from ColumnSchemaInterface
* @psalm-suppress MixedArgumentTypeCoercion
* @psalm-import-type ColumnInfo from ColumnFactoryInterface
*/
abstract class AbstractColumnFactory implements ColumnFactoryInterface
{
Expand All @@ -38,8 +37,10 @@

public function fromDbType(string $dbType, array $info = []): ColumnSchemaInterface
{
$info['db_type'] = $dbType;
unset($info['dbType']);
$type = $info['type'] ?? $this->getType($dbType, $info);
unset($info['type']);
$info['dbType'] = $dbType;

return $this->fromType($type, $info);
}
Expand All @@ -52,62 +53,76 @@
$info['extra'] = $definitionInfo['extra'] . ' ' . $info['extra'];
}

/** @var string $dbType */
$dbType = $definitionInfo['db_type'] ?? '';
unset($definitionInfo['db_type']);
/** @var string $type */
$type = $definitionInfo['type'] ?? '';
unset($definitionInfo['type']);

$info += $definitionInfo;

if ($this->isDbType($dbType)) {
return $this->fromDbType($dbType, $info);
if ($this->isDbType($type)) {
unset($info['dbType']);
return $this->fromDbType($type, $info);
}

if ($this->isType($dbType)) {
return $this->fromType($dbType, $info);
if ($this->isType($type)) {
unset($info['type']);
return $this->fromType($type, $info);
}

if ($this->isPseudoType($dbType)) {
return $this->fromPseudoType($dbType, $info);
if ($this->isPseudoType($type)) {
return $this->fromPseudoType($type, $info);
}

return $this->fromDbType($dbType, $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 => ColumnBuilder::primaryKey()->load($info),
PseudoType::UPK => ColumnBuilder::primaryKey()->unsigned()->load($info),
PseudoType::BIGPK => ColumnBuilder::bigPrimaryKey()->load($info),
PseudoType::UBIGPK => ColumnBuilder::bigPrimaryKey()->unsigned()->load($info),
PseudoType::UUID_PK => ColumnBuilder::uuidPrimaryKey()->load($info),
PseudoType::UUID_PK_SEQ => ColumnBuilder::uuidPrimaryKey()->load($info),
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)

Check warning on line 94 in src/Schema/Column/AbstractColumnFactory.php

View check run for this annotation

Codecov / codecov/patch

src/Schema/Column/AbstractColumnFactory.php#L94

Added line #L94 was not covered by tests
: 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),
};
}

/**
* @psalm-suppress InvalidNamedArgument
*/
public function fromType(string $type, array $info = []): ColumnSchemaInterface
{
$column = match ($type) {
ColumnType::BOOLEAN => new BooleanColumnSchema($type),
ColumnType::BIT => new BitColumnSchema($type),
ColumnType::TINYINT => new IntegerColumnSchema($type),
ColumnType::SMALLINT => new IntegerColumnSchema($type),
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),
ColumnType::INTEGER => PHP_INT_SIZE !== 8 && !empty($info['unsigned'])
? new BigIntColumnSchema($type)
: new IntegerColumnSchema($type),
? new BigIntColumnSchema($type, ...$info)

Check warning on line 113 in src/Schema/Column/AbstractColumnFactory.php

View check run for this annotation

Codecov / codecov/patch

src/Schema/Column/AbstractColumnFactory.php#L113

Added line #L113 was not covered by tests
: new IntegerColumnSchema($type, ...$info),
ColumnType::BIGINT => PHP_INT_SIZE !== 8 || !empty($info['unsigned'])
? new BigIntColumnSchema($type)
: new IntegerColumnSchema($type),
ColumnType::DECIMAL => new DoubleColumnSchema($type),
ColumnType::FLOAT => new DoubleColumnSchema($type),
ColumnType::DOUBLE => new DoubleColumnSchema($type),
ColumnType::BINARY => new BinaryColumnSchema($type),
ColumnType::STRUCTURED => new StructuredColumnSchema($type),
ColumnType::JSON => new JsonColumnSchema($type),
default => new StringColumnSchema($type),
? 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),
};

return $column->load($info);
}

/**
Expand Down
116 changes: 61 additions & 55 deletions src/Schema/Column/AbstractColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

use Yiisoft\Db\Constraint\ForeignKeyConstraint;

use function is_array;
use function property_exists;

/**
* Represents the metadata of a column in a database table.
Expand Down Expand Up @@ -37,29 +37,69 @@
*/
abstract class AbstractColumnSchema implements ColumnSchemaInterface
{
private bool $autoIncrement = false;
private string|null $check = null;
private string|null $comment = null;
private bool $computed = false;
private string|null $dbType = null;
private mixed $defaultValue = null;
private array|null $enumValues = null;
private string|null $extra = null;
private bool $isPrimaryKey = false;
private string|null $name = null;
private bool $notNull = false;
private ForeignKeyConstraint|null $reference = null;
private int|null $scale = null;
private int|null $size = null;
private bool $unique = false;
private bool $unsigned = false;
/**
* @var string The default column abstract type
* @psalm-var ColumnType::*
*/
protected const DEFAULT_TYPE = ColumnType::STRING;

/**
* @var string The column abstract type
* @psalm-var ColumnType::*
*/
private string $type;

/**
* @param string|null $type The column's abstract type.
* @param bool $autoIncrement Whether the column is auto-incremental.
* @param string|null $check The check constraint for the column.
* @param string|null $comment The column's comment.
* @param bool $computed Whether the column is a computed column.
* @param string|null $dbType The column's database type.
* @param mixed $defaultValue The default value of the column.
* @param array|null $enumValues The list of possible values for an ENUM column.
* @param string|null $extra Any extra information that needs to be appended to the column's definition.
* @param bool $primaryKey Whether the column is a primary key.
* @param string|null $name The column's name.
* @param bool $notNull Whether the column is not nullable.
* @param ForeignKeyConstraint|null $reference The foreign key constraint.
* @param int|null $scale The number of digits to the right of the decimal point.
* @param int|null $size The column's size.
* @param bool $unique Whether the column is unique.
* @param bool $unsigned Whether the column is unsigned.
* @param mixed ...$args Additional arguments to be passed to the constructor.
*
* @psalm-param ColumnType::* $type
* @psalm-param array<string, mixed> $args
*/
public function __construct(
private string $type,
string|null $type = null,
private bool $autoIncrement = false,
private string|null $check = null,
private string|null $comment = null,
private bool $computed = false,
private string|null $dbType = null,
private mixed $defaultValue = null,
private array|null $enumValues = null,
private string|null $extra = null,
private bool $primaryKey = false,
private string|null $name = null,
private bool $notNull = false,
private ForeignKeyConstraint|null $reference = null,
private int|null $scale = null,
private int|null $size = null,
private bool $unique = false,
private bool $unsigned = false,
mixed ...$args,
) {
$this->type = $type ?? static::DEFAULT_TYPE;

/** @var array<string, mixed> $args */
foreach ($args as $property => $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
}
}
}

/**
Expand Down Expand Up @@ -215,7 +255,7 @@ public function isNotNull(): bool

public function isPrimaryKey(): bool
{
return $this->isPrimaryKey;
return $this->primaryKey;
}

public function isUnique(): bool
Expand All @@ -228,40 +268,6 @@ public function isUnsigned(): bool
return $this->unsigned;
}

public function load(array $info): static
{
foreach ($info as $key => $value) {
/**
* @psalm-suppress PossiblyInvalidCast
* @psalm-suppress InvalidCast
* @psalm-suppress DeprecatedMethod
*/
match ($key) {
'allow_null' => $this->allowNull((bool) $value),
'auto_increment' => $this->autoIncrement((bool) $value),
'check' => $this->check($value !== null ? (string) $value : null),
'comment' => $this->comment($value !== null ? (string) $value : null),
'computed' => $this->computed((bool) $value),
'db_type' => $this->dbType($value !== null ? (string) $value : null),
'default_value' => $this->defaultValue($value),
'enum_values' => $this->enumValues(is_array($value) ? $value : null),
'extra' => $this->extra($value !== null ? (string) $value : null),
'name' => $this->name($value !== null ? (string) $value : null),
'not_null' => $this->notNull((bool) $value),
'primary_key' => $this->primaryKey((bool) $value),
'precision' => $this->precision($value !== null ? (int) $value : null),
'reference' => $this->reference($value instanceof ForeignKeyConstraint ? $value : null),
'scale' => $this->scale($value !== null ? (int) $value : null),
'size' => $this->size($value !== null ? (int) $value : null),
'unique' => $this->unique((bool) $value),
'unsigned' => $this->unsigned((bool) $value),
default => null,
};
}

return $this;
}

/**
* @deprecated Will be removed in version 2.0.
*/
Expand All @@ -285,9 +291,9 @@ public function precision(int|null $precision): static
return $this->size($precision);
}

public function primaryKey(bool $isPrimaryKey = true): static
public function primaryKey(bool $primaryKey = true): static
{
$this->isPrimaryKey = $isPrimaryKey;
$this->primaryKey = $primaryKey;
return $this;
}

Expand Down
27 changes: 15 additions & 12 deletions src/Schema/Column/ArrayColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,23 @@
use function is_string;
use function iterator_to_array;

/**
* Represents the schema for an array column.
*/
class ArrayColumnSchema extends AbstractColumnSchema
{
protected const DEFAULT_TYPE = ColumnType::ARRAY;

/**
* @var ColumnSchemaInterface|null The column of an array item.
*/
private ColumnSchemaInterface|null $column = null;
protected ColumnSchemaInterface|null $column = null;

/**
* @var int The dimension of array, must be greater than 0.
* @psalm-var positive-int
*/
private int $dimension = 1;
protected int $dimension = 1;

/**
* Returns the parser for the column value.
Expand All @@ -39,15 +45,6 @@ protected function getParser(): ParserToArrayInterface
throw new NotSupportedException(__METHOD__ . '() is not supported. Use concrete DBMS implementation.');
}

/**
* @psalm-param ColumnType::* $type
*/
public function __construct(
string $type = ColumnType::ARRAY,
) {
parent::__construct($type);
}

/**
* Set column of an array item.
*/
Expand All @@ -74,7 +71,9 @@ public function getColumn(): ColumnSchemaInterface
}

/**
* Set dimension of an array, must be greater than 0.
* Set dimension of an array, must be greater than
*
* @psalm-param positive-int $dimension
*/
public function dimension(int $dimension): static
{
Expand All @@ -84,6 +83,8 @@ public function dimension(int $dimension): static

/**
* @return int the dimension of the array.
*
* @psalm-return positive-int
*/
public function getDimension(): int
{
Expand Down Expand Up @@ -143,6 +144,8 @@ public function phpTypecast(mixed $value): array|null
* @param mixed $value The array or iterable object.
* @param int $dimension The array dimension. Should be more than 0.
*
* @psalm-param positive-int $dimension
*
* @return array|null Converted values.
*/
protected function dbTypecastArray(mixed $value, int $dimension): array|null
Expand Down
Loading
Loading