Skip to content

Commit

Permalink
Merge branch 'master' into ease-local-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
arogachev committed Dec 2, 2024
2 parents 78eb952 + 3b65eae commit 8fd7a65
Show file tree
Hide file tree
Showing 14 changed files with 197 additions and 178 deletions.
File renamed without changes.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
- 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: Implement `ColumnFactory` class (@Tigrov)
- New #355, #368, #370: 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)
- Enh #362: Update according changes in `ColumnSchemaInterface` (@Tigrov)
- New #364: Add `ColumnDefinitionBuilder` class (@Tigrov)
- New #364, #372: Add `ColumnDefinitionBuilder` class (@Tigrov)
- Enh #365: Refactor `Dsn` class (@Tigrov)
- Enh #366: Use constructor to create columns and initialize properties (@Tigrov)
- Enh #370: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov)
- New #373: Override `QueryBuilder::prepareBinary()` method (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
4 changes: 2 additions & 2 deletions src/Column/ColumnDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ protected function buildType(ColumnSchemaInterface $column): string
protected function getDbType(ColumnSchemaInterface $column): string
{
/** @psalm-suppress DocblockTypeContradiction */
return match ($column->getType()) {
return $column->getDbType() ?? match ($column->getType()) {
ColumnType::BOOLEAN => 'boolean',
ColumnType::BIT => 'varbit',
ColumnType::TINYINT => $column->isAutoIncrement() ? 'smallserial' : 'smallint',
Expand All @@ -71,7 +71,7 @@ protected function getDbType(ColumnSchemaInterface $column): string
ColumnType::DECIMAL => 'numeric',
ColumnType::MONEY => 'money',
ColumnType::CHAR => 'char',
ColumnType::STRING => 'varchar',
ColumnType::STRING => 'varchar(' . ($column->getSize() ?? 255) . ')',
ColumnType::TEXT => 'text',
ColumnType::BINARY => 'bytea',
ColumnType::UUID => 'uuid',
Expand Down
80 changes: 48 additions & 32 deletions src/Column/ColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constraint\ForeignKeyConstraint;
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Schema\Column\AbstractColumnFactory;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;

use function preg_replace;
use function str_starts_with;
use function substr;

use const PHP_INT_SIZE;

/**
Expand Down Expand Up @@ -45,10 +50,9 @@ final class ColumnFactory extends AbstractColumnFactory
* @link https://www.postgresql.org/docs/current/datatype.html#DATATYPE-TABLE
*
* @var string[]
*
* @psalm-suppress MissingClassConstType
* @psalm-var array<string, ColumnType::*>
*/
private const TYPE_MAP = [
protected const TYPE_MAP = [
'bool' => ColumnType::BOOLEAN,
'boolean' => ColumnType::BOOLEAN,
'bit' => ColumnType::BIT,
Expand Down Expand Up @@ -115,46 +119,58 @@ final class ColumnFactory extends AbstractColumnFactory
'jsonb' => ColumnType::JSON,
];

/**
* @psalm-param ColumnType::* $type
* @psalm-param ColumnInfo $info
* @psalm-suppress MoreSpecificImplementedParamType
* @psalm-suppress ArgumentTypeCoercion
* @psalm-suppress InvalidNamedArgument
* @psalm-suppress PossiblyInvalidArgument
*/
public function fromType(string $type, array $info = []): ColumnSchemaInterface
{
$dimension = $info['dimension'] ?? 0;
unset($info['dimension']);
$column = parent::fromType($type, $info);

if ($dimension > 0) {
$info['column'] ??= $this->fromType($type, $info);
return new ArrayColumnSchema(...$info, dimension: $dimension);
if ($column instanceof StructuredColumnSchema) {
/** @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]);
}
}
}
}

return $column;
}

protected function getColumnClass(string $type, array $info = []): string
{
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 => new IntegerColumnSchema($type, ...$info),
ColumnType::BOOLEAN => BooleanColumnSchema::class,
ColumnType::BIT => BitColumnSchema::class,
ColumnType::TINYINT => IntegerColumnSchema::class,
ColumnType::SMALLINT => IntegerColumnSchema::class,
ColumnType::INTEGER => IntegerColumnSchema::class,
ColumnType::BIGINT => PHP_INT_SIZE !== 8
? new BigIntColumnSchema($type, ...$info)
: new IntegerColumnSchema($type, ...$info),
ColumnType::BINARY => new BinaryColumnSchema($type, ...$info),
ColumnType::STRUCTURED => new StructuredColumnSchema($type, ...$info),
default => parent::fromType($type, $info),
? BigIntColumnSchema::class
: IntegerColumnSchema::class,
ColumnType::BINARY => BinaryColumnSchema::class,
ColumnType::ARRAY => ArrayColumnSchema::class,
ColumnType::STRUCTURED => StructuredColumnSchema::class,
default => parent::getColumnClass($type, $info),
};
}

protected function getType(string $dbType, array $info = []): string
protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnSchemaInterface $column): mixed
{
return self::TYPE_MAP[$dbType] ?? ColumnType::STRING;
}
$value = preg_replace("/::[^:']+$/", '$1', $defaultValue);

protected function isDbType(string $dbType): bool
{
return isset(self::TYPE_MAP[$dbType]);
if (str_starts_with($value, "B'") && $value[-1] === "'") {
return $column->phpTypecast(substr($value, 2, -1));
}

$value = parent::normalizeNotNullDefaultValue($value, $column);

if ($value instanceof Expression) {
return new Expression($defaultValue);
}

return $value;
}
}
4 changes: 3 additions & 1 deletion src/Column/SequenceColumnSchemaInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
interface SequenceColumnSchemaInterface extends ColumnSchemaInterface
{
/**
* @return string|null name of an associated sequence if column is auto incremental.
* Returns name of an associated sequence if column is auto incremental.
*
* @psalm-mutation-free
*/
public function getSequenceName(): string|null;

Expand Down
5 changes: 4 additions & 1 deletion src/Column/SequenceColumnSchemaTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ trait SequenceColumnSchemaTrait
/**
* @var string|null Name of an associated sequence if column is auto incremental.
*/
private string|null $sequenceName = null;
protected string|null $sequenceName = null;

/**
* @psalm-mutation-free
*/
public function getSequenceName(): string|null
{
return $this->sequenceName;
Expand Down
7 changes: 7 additions & 0 deletions src/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
use Yiisoft\Db\Schema\QuoterInterface;
use Yiisoft\Db\Schema\SchemaInterface;

use function bin2hex;

/**
* Implements the PostgreSQL Server specific query builder.
*/
Expand Down Expand Up @@ -57,4 +59,9 @@ public function __construct(QuoterInterface $quoter, SchemaInterface $schema)

parent::__construct($quoter, $schema, $ddlBuilder, $dmlBuilder, $dqlBuilder, $columnDefinitionBuilder);
}

protected function prepareBinary(string $binary): string
{
return "'\x" . bin2hex($binary) . "'::bytea";
}
}
Loading

0 comments on commit 8fd7a65

Please sign in to comment.