Skip to content

Commit

Permalink
Separate column type constants (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov authored Sep 13, 2024
1 parent 2402d7d commit 80b32d6
Show file tree
Hide file tree
Showing 14 changed files with 225 additions and 221 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- Enh #354: Refactor PHP type of `ColumnSchemaInterface` instances (@Tigrov)
- Enh #356: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov)
- Enh #355: Implement `ColumnFactory` class (@Tigrov)
- Enh #359: Separate column type constants (@Tigrov)
- Enh #359: Remove `Schema::TYPE_ARRAY` and `Schema::TYPE_STRUCTURED` constants (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
2 changes: 1 addition & 1 deletion src/Column.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* For example, the following code creates a column schema for an integer column:
*
* ```php
* $column = (new Column(SchemaInterface::TYPE_INTEGER))->notNull()->defaultValue(0);
* $column = (new Column(ColumnType::INTEGER))->notNull()->defaultValue(0);
* ```
*
* Provides a fluent interface, which means that the methods can be chained together to create a column schema with
Expand Down
12 changes: 7 additions & 5 deletions src/Column/ArrayColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
namespace Yiisoft\Db\Pgsql\Column;

use Traversable;
use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constant\PhpType;
use Yiisoft\Db\Expression\ArrayExpression;
use Yiisoft\Db\Expression\ExpressionInterface;
use Yiisoft\Db\Pgsql\ArrayParser;
use Yiisoft\Db\Pgsql\Schema;
use Yiisoft\Db\Schema\Column\AbstractColumnSchema;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
use Yiisoft\Db\Schema\SchemaInterface;

use function array_map;
use function array_walk_recursive;
Expand All @@ -33,8 +32,11 @@ final class ArrayColumnSchema extends AbstractColumnSchema
*/
private int $dimension = 1;

/**
* @psalm-param ColumnType::* $type
*/
public function __construct(
string $type = Schema::TYPE_ARRAY,
string $type = ColumnType::ARRAY,
) {
parent::__construct($type);
}
Expand Down Expand Up @@ -112,13 +114,13 @@ public function phpTypecast(mixed $value): array|null
return null;
}

if ($this->getType() === SchemaInterface::TYPE_STRING) {
if ($this->getType() === ColumnType::STRING) {
return $value;
}

$column = $this->getColumn();

if ($this->dimension === 1 && $column->getType() !== SchemaInterface::TYPE_JSON) {
if ($this->dimension === 1 && $column->getType() !== ColumnType::JSON) {
return array_map($column->phpTypecast(...), $value);
}

Expand Down
149 changes: 75 additions & 74 deletions src/Column/ColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

namespace Yiisoft\Db\Pgsql\Column;

use Yiisoft\Db\Pgsql\Schema;
use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Schema\Column\AbstractColumnFactory;
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
use Yiisoft\Db\Schema\SchemaInterface;

use const PHP_INT_SIZE;

Expand Down Expand Up @@ -46,72 +45,73 @@ final class ColumnFactory extends AbstractColumnFactory
* @psalm-suppress MissingClassConstType
*/
private const TYPE_MAP = [
'bool' => SchemaInterface::TYPE_BOOLEAN,
'boolean' => SchemaInterface::TYPE_BOOLEAN,
'bit' => SchemaInterface::TYPE_BIT,
'bit varying' => SchemaInterface::TYPE_BIT,
'varbit' => SchemaInterface::TYPE_BIT,
'smallint' => SchemaInterface::TYPE_SMALLINT,
'int2' => SchemaInterface::TYPE_SMALLINT,
'smallserial' => SchemaInterface::TYPE_SMALLINT,
'serial2' => SchemaInterface::TYPE_SMALLINT,
'int4' => SchemaInterface::TYPE_INTEGER,
'int' => SchemaInterface::TYPE_INTEGER,
'integer' => SchemaInterface::TYPE_INTEGER,
'serial' => SchemaInterface::TYPE_INTEGER,
'serial4' => SchemaInterface::TYPE_INTEGER,
'bigint' => SchemaInterface::TYPE_BIGINT,
'int8' => SchemaInterface::TYPE_BIGINT,
'bigserial' => SchemaInterface::TYPE_BIGINT,
'serial8' => SchemaInterface::TYPE_BIGINT,
'oid' => SchemaInterface::TYPE_BIGINT, // shouldn't be used. it's pg internal!
'pg_lsn' => SchemaInterface::TYPE_BIGINT,
'real' => SchemaInterface::TYPE_FLOAT,
'float4' => SchemaInterface::TYPE_FLOAT,
'float8' => SchemaInterface::TYPE_DOUBLE,
'double precision' => SchemaInterface::TYPE_DOUBLE,
'decimal' => SchemaInterface::TYPE_DECIMAL,
'numeric' => SchemaInterface::TYPE_DECIMAL,
'money' => SchemaInterface::TYPE_MONEY,
'char' => SchemaInterface::TYPE_CHAR,
'character' => SchemaInterface::TYPE_CHAR,
'bpchar' => SchemaInterface::TYPE_CHAR,
'character varying' => SchemaInterface::TYPE_STRING,
'varchar' => SchemaInterface::TYPE_STRING,
'text' => SchemaInterface::TYPE_TEXT,
'bytea' => SchemaInterface::TYPE_BINARY,
'date' => SchemaInterface::TYPE_DATE,
'time' => SchemaInterface::TYPE_TIME,
'time without time zone' => SchemaInterface::TYPE_TIME,
'time with time zone' => SchemaInterface::TYPE_TIME,
'timetz' => SchemaInterface::TYPE_TIME,
'timestamp' => SchemaInterface::TYPE_TIMESTAMP,
'timestamp without time zone' => SchemaInterface::TYPE_TIMESTAMP,
'timestamp with time zone' => SchemaInterface::TYPE_TIMESTAMP,
'timestamptz' => SchemaInterface::TYPE_TIMESTAMP,
'abstime' => SchemaInterface::TYPE_TIMESTAMP,
'interval' => SchemaInterface::TYPE_STRING,
'box' => SchemaInterface::TYPE_STRING,
'circle' => SchemaInterface::TYPE_STRING,
'point' => SchemaInterface::TYPE_STRING,
'line' => SchemaInterface::TYPE_STRING,
'lseg' => SchemaInterface::TYPE_STRING,
'polygon' => SchemaInterface::TYPE_STRING,
'path' => SchemaInterface::TYPE_STRING,
'cidr' => SchemaInterface::TYPE_STRING,
'inet' => SchemaInterface::TYPE_STRING,
'macaddr' => SchemaInterface::TYPE_STRING,
'tsquery' => SchemaInterface::TYPE_STRING,
'tsvector' => SchemaInterface::TYPE_STRING,
'txid_snapshot' => SchemaInterface::TYPE_STRING,
'unknown' => SchemaInterface::TYPE_STRING,
'uuid' => SchemaInterface::TYPE_STRING,
'xml' => SchemaInterface::TYPE_STRING,
'json' => SchemaInterface::TYPE_JSON,
'jsonb' => SchemaInterface::TYPE_JSON,
'bool' => ColumnType::BOOLEAN,
'boolean' => ColumnType::BOOLEAN,
'bit' => ColumnType::BIT,
'bit varying' => ColumnType::BIT,
'varbit' => ColumnType::BIT,
'smallint' => ColumnType::SMALLINT,
'int2' => ColumnType::SMALLINT,
'smallserial' => ColumnType::SMALLINT,
'serial2' => ColumnType::SMALLINT,
'int4' => ColumnType::INTEGER,
'int' => ColumnType::INTEGER,
'integer' => ColumnType::INTEGER,
'serial' => ColumnType::INTEGER,
'serial4' => ColumnType::INTEGER,
'bigint' => ColumnType::BIGINT,
'int8' => ColumnType::BIGINT,
'bigserial' => ColumnType::BIGINT,
'serial8' => ColumnType::BIGINT,
'oid' => ColumnType::BIGINT, // shouldn't be used. it's pg internal!
'pg_lsn' => ColumnType::BIGINT,
'real' => ColumnType::FLOAT,
'float4' => ColumnType::FLOAT,
'float8' => ColumnType::DOUBLE,
'double precision' => ColumnType::DOUBLE,
'decimal' => ColumnType::DECIMAL,
'numeric' => ColumnType::DECIMAL,
'money' => ColumnType::MONEY,
'char' => ColumnType::CHAR,
'character' => ColumnType::CHAR,
'bpchar' => ColumnType::CHAR,
'character varying' => ColumnType::STRING,
'varchar' => ColumnType::STRING,
'text' => ColumnType::TEXT,
'bytea' => ColumnType::BINARY,
'date' => ColumnType::DATE,
'time' => ColumnType::TIME,
'time without time zone' => ColumnType::TIME,
'time with time zone' => ColumnType::TIME,
'timetz' => ColumnType::TIME,
'timestamp' => ColumnType::TIMESTAMP,
'timestamp without time zone' => ColumnType::TIMESTAMP,
'timestamp with time zone' => ColumnType::TIMESTAMP,
'timestamptz' => ColumnType::TIMESTAMP,
'abstime' => ColumnType::TIMESTAMP,
'interval' => ColumnType::STRING,
'box' => ColumnType::STRING,
'circle' => ColumnType::STRING,
'point' => ColumnType::STRING,
'line' => ColumnType::STRING,
'lseg' => ColumnType::STRING,
'polygon' => ColumnType::STRING,
'path' => ColumnType::STRING,
'cidr' => ColumnType::STRING,
'inet' => ColumnType::STRING,
'macaddr' => ColumnType::STRING,
'tsquery' => ColumnType::STRING,
'tsvector' => ColumnType::STRING,
'txid_snapshot' => ColumnType::STRING,
'unknown' => ColumnType::STRING,
'uuid' => ColumnType::STRING,
'xml' => ColumnType::STRING,
'json' => ColumnType::JSON,
'jsonb' => ColumnType::JSON,
];

/**
* @psalm-param ColumnType::* $type
* @psalm-param ColumnInfo $info
* @psalm-suppress MoreSpecificImplementedParamType
*/
Expand All @@ -125,17 +125,18 @@ public function fromType(string $type, array $info = []): ColumnSchemaInterface
->dimension($dimension)
->column($this->fromType($type, $info));
} else {
/** @psalm-suppress ArgumentTypeCoercion */
$column = match ($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
ColumnType::BOOLEAN => new BooleanColumnSchema($type),
ColumnType::BIT => new BitColumnSchema($type),
ColumnType::TINYINT => new IntegerColumnSchema($type),
ColumnType::SMALLINT => new IntegerColumnSchema($type),
ColumnType::INTEGER => new IntegerColumnSchema($type),
ColumnType::BIGINT => PHP_INT_SIZE !== 8
? new BigIntColumnSchema($type)
: new IntegerColumnSchema($type),
SchemaInterface::TYPE_BINARY => new BinaryColumnSchema($type),
Schema::TYPE_STRUCTURED => (new StructuredColumnSchema($type))->columns($info['columns'] ?? []),
ColumnType::BINARY => new BinaryColumnSchema($type),
ColumnType::STRUCTURED => (new StructuredColumnSchema($type))->columns($info['columns'] ?? []),
default => parent::fromType($type, $info),
};
}
Expand All @@ -145,6 +146,6 @@ public function fromType(string $type, array $info = []): ColumnSchemaInterface

protected function getType(string $dbType, array $info = []): string
{
return self::TYPE_MAP[$dbType] ?? SchemaInterface::TYPE_STRING;
return self::TYPE_MAP[$dbType] ?? ColumnType::STRING;
}
}
7 changes: 5 additions & 2 deletions src/Column/StructuredColumnSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Db\Pgsql\Column;

use Traversable;
use Yiisoft\Db\Constant\ColumnType;
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;
Expand All @@ -26,8 +26,11 @@ final class StructuredColumnSchema extends AbstractColumnSchema implements Struc
*/
private array $columns = [];

/**
* @psalm-param ColumnType::* $type
*/
public function __construct(
string $type = Schema::TYPE_STRUCTURED,
string $type = ColumnType::STRUCTURED,
) {
parent::__construct($type);
}
Expand Down
50 changes: 26 additions & 24 deletions src/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Yiisoft\Db\Pgsql;

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constant\PseudoType;
use Yiisoft\Db\QueryBuilder\AbstractQueryBuilder;
use Yiisoft\Db\Schema\QuoterInterface;
use Yiisoft\Db\Schema\SchemaInterface;
Expand All @@ -19,30 +21,30 @@ final class QueryBuilder extends AbstractQueryBuilder
* @psalm-var string[]
*/
protected array $typeMap = [
SchemaInterface::TYPE_PK => 'serial NOT NULL PRIMARY KEY',
SchemaInterface::TYPE_UPK => 'serial NOT NULL PRIMARY KEY',
SchemaInterface::TYPE_BIGPK => 'bigserial NOT NULL PRIMARY KEY',
SchemaInterface::TYPE_UBIGPK => 'bigserial NOT NULL PRIMARY KEY',
SchemaInterface::TYPE_CHAR => 'char(1)',
SchemaInterface::TYPE_STRING => 'varchar(255)',
SchemaInterface::TYPE_TEXT => 'text',
SchemaInterface::TYPE_TINYINT => 'smallint',
SchemaInterface::TYPE_SMALLINT => 'smallint',
SchemaInterface::TYPE_INTEGER => 'integer',
SchemaInterface::TYPE_BIGINT => 'bigint',
SchemaInterface::TYPE_FLOAT => 'double precision',
SchemaInterface::TYPE_DOUBLE => 'double precision',
SchemaInterface::TYPE_DECIMAL => 'numeric(10,0)',
SchemaInterface::TYPE_DATETIME => 'timestamp(0)',
SchemaInterface::TYPE_TIMESTAMP => 'timestamp(0)',
SchemaInterface::TYPE_TIME => 'time(0)',
SchemaInterface::TYPE_DATE => 'date',
SchemaInterface::TYPE_BINARY => 'bytea',
SchemaInterface::TYPE_BOOLEAN => 'boolean',
SchemaInterface::TYPE_MONEY => 'numeric(19,4)',
SchemaInterface::TYPE_JSON => 'jsonb',
SchemaInterface::TYPE_UUID => 'uuid',
SchemaInterface::TYPE_UUID_PK => 'uuid PRIMARY KEY',
PseudoType::PK => 'serial NOT NULL PRIMARY KEY',
PseudoType::UPK => 'serial NOT NULL PRIMARY KEY',
PseudoType::BIGPK => 'bigserial NOT NULL PRIMARY KEY',
PseudoType::UBIGPK => 'bigserial NOT NULL PRIMARY KEY',
ColumnType::CHAR => 'char(1)',
ColumnType::STRING => 'varchar(255)',
ColumnType::TEXT => 'text',
ColumnType::TINYINT => 'smallint',
ColumnType::SMALLINT => 'smallint',
ColumnType::INTEGER => 'integer',
ColumnType::BIGINT => 'bigint',
ColumnType::FLOAT => 'double precision',
ColumnType::DOUBLE => 'double precision',
ColumnType::DECIMAL => 'numeric(10,0)',
ColumnType::DATETIME => 'timestamp(0)',
ColumnType::TIMESTAMP => 'timestamp(0)',
ColumnType::TIME => 'time(0)',
ColumnType::DATE => 'date',
ColumnType::BINARY => 'bytea',
ColumnType::BOOLEAN => 'boolean',
ColumnType::MONEY => 'numeric(19,4)',
ColumnType::JSON => 'jsonb',
ColumnType::UUID => 'uuid',
PseudoType::UUID_PK => 'uuid PRIMARY KEY',
];

public function __construct(QuoterInterface $quoter, SchemaInterface $schema)
Expand Down
19 changes: 6 additions & 13 deletions src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use JsonException;
use Throwable;
use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constraint\CheckConstraint;
use Yiisoft\Db\Constraint\Constraint;
use Yiisoft\Db\Constraint\DefaultValueConstraint;
Expand All @@ -31,6 +32,7 @@
use function array_unique;
use function array_values;
use function explode;
use function in_array;
use function is_string;
use function preg_match;
use function preg_replace;
Expand Down Expand Up @@ -92,15 +94,6 @@
*/
final class Schema extends AbstractPdoSchema
{
/**
* Define the abstract column type as `array`.
*/
public const TYPE_ARRAY = 'array';
/**
* Define the abstract column type as `structured`.
*/
public const TYPE_STRUCTURED = 'structured';

/**
* @var string|null The default schema used for the current session.
*/
Expand Down Expand Up @@ -745,7 +738,7 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
}

$column = $this->getColumnFactory()
->fromType(self::TYPE_STRUCTURED, ['dimension' => $info['dimension'], 'columns' => $columns]);
->fromType(ColumnType::STRUCTURED, ['dimension' => $info['dimension'], 'columns' => $columns]);
} else {
$column = $this->getColumnFactory()
->fromDbType($dbType, ['dimension' => $info['dimension']]);
Expand Down Expand Up @@ -823,12 +816,12 @@ private function normalizeDefaultValue(string|null $defaultValue, ColumnSchemaIn
return null;
}

if ($column->getType() === self::TYPE_BOOLEAN && in_array($defaultValue, ['true', 'false'], true)) {
if ($column->getType() === ColumnType::BOOLEAN && in_array($defaultValue, ['true', 'false'], true)) {
return $defaultValue === 'true';
}

if (
in_array($column->getType(), [self::TYPE_TIMESTAMP, self::TYPE_DATE, self::TYPE_TIME], true)
in_array($column->getType(), [ColumnType::TIMESTAMP, ColumnType::DATE, ColumnType::TIME], true)
&& in_array(strtoupper($defaultValue), ['NOW()', 'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'], true)
) {
return new Expression($defaultValue);
Expand All @@ -837,7 +830,7 @@ private function normalizeDefaultValue(string|null $defaultValue, ColumnSchemaIn
$value = preg_replace("/^B?['(](.*?)[)'](?:::[^:]+)?$/s", '$1', $defaultValue);
$value = str_replace("''", "'", $value);

if ($column->getType() === self::TYPE_BINARY && str_starts_with($value, '\\x')) {
if ($column->getType() === ColumnType::BINARY && str_starts_with($value, '\\x')) {
return hex2bin(substr($value, 2));
}

Expand Down
Loading

0 comments on commit 80b32d6

Please sign in to comment.