Skip to content

Commit 72da3f3

Browse files
authored
Realize ColumnBuilder (#360)
1 parent 80b32d6 commit 72da3f3

13 files changed

+235
-53
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- Enh #355: Implement `ColumnFactory` class (@Tigrov)
1515
- Enh #359: Separate column type constants (@Tigrov)
1616
- Enh #359: Remove `Schema::TYPE_ARRAY` and `Schema::TYPE_STRUCTURED` constants (@Tigrov)
17+
- Enh #360: Realize `ColumnBuilder` class (@Tigrov)
1718

1819
## 1.3.0 March 21, 2024
1920

src/Column/ArrayColumnSchema.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ public function column(ColumnSchemaInterface|null $column): static
5656
public function getColumn(): ColumnSchemaInterface
5757
{
5858
if ($this->column === null) {
59-
$this->column = (new ColumnFactory())->fromType($this->getType());
60-
$this->column->dbType($this->getDbType());
59+
$this->column = (new ColumnFactory())->fromDbType($this->getDbType() ?? '');
6160
$this->column->enumValues($this->getEnumValues());
6261
$this->column->precision($this->getPrecision());
6362
$this->column->scale($this->getScale());
@@ -101,7 +100,7 @@ public function dbTypecast(mixed $value): ExpressionInterface|null
101100
$value = $this->dbTypecastArray($value, $this->dimension);
102101
}
103102

104-
return new ArrayExpression($value, $this->getDbType(), $this->dimension);
103+
return new ArrayExpression($value, $this->getDbType() ?? $this->getColumn()->getDbType(), $this->dimension);
105104
}
106105

107106
public function phpTypecast(mixed $value): array|null

src/Column/ColumnBuilder.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Db\Pgsql\Column;
6+
7+
use Yiisoft\Db\Constant\ColumnType;
8+
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
9+
10+
final class ColumnBuilder extends \Yiisoft\Db\Schema\Column\ColumnBuilder
11+
{
12+
public static function boolean(): ColumnSchemaInterface
13+
{
14+
return new BooleanColumnSchema(ColumnType::BOOLEAN);
15+
}
16+
17+
public static function bit(int|null $size = null): ColumnSchemaInterface
18+
{
19+
return (new BitColumnSchema(ColumnType::BIT))
20+
->size($size);
21+
}
22+
23+
public static function tinyint(int|null $size = null): ColumnSchemaInterface
24+
{
25+
return (new IntegerColumnSchema(ColumnType::TINYINT))
26+
->size($size);
27+
}
28+
29+
public static function smallint(int|null $size = null): ColumnSchemaInterface
30+
{
31+
return (new IntegerColumnSchema(ColumnType::SMALLINT))
32+
->size($size);
33+
}
34+
35+
public static function integer(int|null $size = null): ColumnSchemaInterface
36+
{
37+
return (new IntegerColumnSchema(ColumnType::INTEGER))
38+
->size($size);
39+
}
40+
41+
public static function bigint(int|null $size = null): ColumnSchemaInterface
42+
{
43+
return (new IntegerColumnSchema(ColumnType::BIGINT))
44+
->size($size);
45+
}
46+
47+
public static function binary(int|null $size = null): ColumnSchemaInterface
48+
{
49+
return (new BinaryColumnSchema(ColumnType::BINARY))
50+
->size($size);
51+
}
52+
53+
public static function array(ColumnSchemaInterface|null $column = null): ColumnSchemaInterface
54+
{
55+
return (new ArrayColumnSchema(ColumnType::ARRAY))
56+
->column($column);
57+
}
58+
59+
/**
60+
* @param string|null $dbType The DB type of the column.
61+
* @param ColumnSchemaInterface[] $columns The columns (name -> instance) that the structured column should contain.
62+
*
63+
* @psalm-param array<string, ColumnSchemaInterface> $columns
64+
*/
65+
public static function structured(string|null $dbType = null, array $columns = []): ColumnSchemaInterface
66+
{
67+
return (new StructuredColumnSchema(ColumnType::STRUCTURED))
68+
->dbType($dbType)
69+
->columns($columns);
70+
}
71+
}

src/Column/ColumnFactory.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ final class ColumnFactory extends AbstractColumnFactory
114114
* @psalm-param ColumnType::* $type
115115
* @psalm-param ColumnInfo $info
116116
* @psalm-suppress MoreSpecificImplementedParamType
117+
* @psalm-suppress ArgumentTypeCoercion
117118
*/
118119
public function fromType(string $type, array $info = []): ColumnSchemaInterface
119120
{
@@ -125,7 +126,6 @@ public function fromType(string $type, array $info = []): ColumnSchemaInterface
125126
->dimension($dimension)
126127
->column($this->fromType($type, $info));
127128
} else {
128-
/** @psalm-suppress ArgumentTypeCoercion */
129129
$column = match ($type) {
130130
ColumnType::BOOLEAN => new BooleanColumnSchema($type),
131131
ColumnType::BIT => new BitColumnSchema($type),
@@ -141,11 +141,16 @@ public function fromType(string $type, array $info = []): ColumnSchemaInterface
141141
};
142142
}
143143

144-
return $column;
144+
return $column->load($info);
145145
}
146146

147147
protected function getType(string $dbType, array $info = []): string
148148
{
149149
return self::TYPE_MAP[$dbType] ?? ColumnType::STRING;
150150
}
151+
152+
protected function isDbType(string $dbType): bool
153+
{
154+
return isset(self::TYPE_MAP[$dbType]);
155+
}
151156
}

src/Connection.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use Yiisoft\Db\Driver\Pdo\AbstractPdoConnection;
88
use Yiisoft\Db\Driver\Pdo\PdoCommandInterface;
99
use Yiisoft\Db\Exception\InvalidArgumentException;
10+
use Yiisoft\Db\Pgsql\Column\ColumnFactory;
1011
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
12+
use Yiisoft\Db\Schema\Column\ColumnFactoryInterface;
1113
use Yiisoft\Db\Schema\Quoter;
1214
use Yiisoft\Db\Schema\QuoterInterface;
1315
use Yiisoft\Db\Schema\SchemaInterface;
@@ -44,6 +46,11 @@ public function createTransaction(): TransactionInterface
4446
return new Transaction($this);
4547
}
4648

49+
public function getColumnFactory(): ColumnFactoryInterface
50+
{
51+
return new ColumnFactory();
52+
}
53+
4754
public function getLastInsertID(string $sequenceName = null): string
4855
{
4956
if ($sequenceName === null) {

src/Schema.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@
1919
use Yiisoft\Db\Expression\Expression;
2020
use Yiisoft\Db\Helper\DbArrayHelper;
2121
use Yiisoft\Db\Pgsql\Column\ArrayColumnSchema;
22-
use Yiisoft\Db\Pgsql\Column\ColumnFactory;
2322
use Yiisoft\Db\Pgsql\Column\SequenceColumnSchemaInterface;
2423
use Yiisoft\Db\Pgsql\Column\StructuredColumnSchemaInterface;
2524
use Yiisoft\Db\Schema\Builder\ColumnInterface;
26-
use Yiisoft\Db\Schema\Column\ColumnFactoryInterface;
2725
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
2826
use Yiisoft\Db\Schema\TableSchemaInterface;
2927

@@ -111,11 +109,6 @@ public function createColumn(string $type, array|int|string $length = null): Col
111109
return new Column($type, $length);
112110
}
113111

114-
public function getColumnFactory(): ColumnFactoryInterface
115-
{
116-
return new ColumnFactory();
117-
}
118-
119112
/**
120113
* Resolves the table name and schema name (if any).
121114
*
@@ -722,6 +715,7 @@ protected function findColumns(TableSchemaInterface $table): bool
722715
*/
723716
private function loadColumnSchema(array $info): ColumnSchemaInterface
724717
{
718+
$columnFactory = $this->db->getColumnFactory();
725719
$dbType = $info['data_type'];
726720

727721
if (!in_array($info['type_scheme'], [$this->defaultSchema, 'pg_catalog'], true)) {
@@ -737,10 +731,10 @@ private function loadColumnSchema(array $info): ColumnSchemaInterface
737731
$columns = $structured->getColumns();
738732
}
739733

740-
$column = $this->getColumnFactory()
734+
$column = $columnFactory
741735
->fromType(ColumnType::STRUCTURED, ['dimension' => $info['dimension'], 'columns' => $columns]);
742736
} else {
743-
$column = $this->getColumnFactory()
737+
$column = $columnFactory
744738
->fromDbType($dbType, ['dimension' => $info['dimension']]);
745739
}
746740

tests/ColumnBuilderTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Db\Pgsql\Tests;
6+
7+
use Yiisoft\Db\Pgsql\Column\ColumnBuilder;
8+
use Yiisoft\Db\Pgsql\Tests\Support\TestTrait;
9+
use Yiisoft\Db\Tests\AbstractColumnBuilderTest;
10+
11+
/**
12+
* @group pgsql
13+
*/
14+
final class ColumnBuilderTest extends AbstractColumnBuilderTest
15+
{
16+
use TestTrait;
17+
18+
public function getColumnBuilderClass(): string
19+
{
20+
return ColumnBuilder::class;
21+
}
22+
23+
/**
24+
* @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnBuilderProvider::buildingMethods
25+
*/
26+
public function testBuildingMethods(
27+
string $buildingMethod,
28+
array $args,
29+
string $expectedInstanceOf,
30+
string $expectedType,
31+
array $expectedMethodResults = [],
32+
): void {
33+
parent::testBuildingMethods($buildingMethod, $args, $expectedInstanceOf, $expectedType, $expectedMethodResults);
34+
}
35+
}

tests/ColumnFactoryTest.php

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,23 @@ public function testFromDbType(string $dbType, string $expectedType, string $exp
2121
}
2222

2323
/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnFactoryProvider::definitions */
24-
public function testFromDefinition(string $definition, string $expectedType, string $expectedInstanceOf, array $expectedInfo = []): void
25-
{
26-
parent::testFromDefinition($definition, $expectedType, $expectedInstanceOf, $expectedInfo);
24+
public function testFromDefinition(
25+
string $definition,
26+
string $expectedType,
27+
string $expectedInstanceOf,
28+
array $expectedMethodResults = []
29+
): void {
30+
parent::testFromDefinition($definition, $expectedType, $expectedInstanceOf, $expectedMethodResults);
31+
}
32+
33+
/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnFactoryProvider::pseudoTypes */
34+
public function testFromPseudoType(
35+
string $pseudoType,
36+
string $expectedType,
37+
string $expectedInstanceOf,
38+
array $expectedMethodResults = []
39+
): void {
40+
parent::testFromPseudoType($pseudoType, $expectedType, $expectedInstanceOf, $expectedMethodResults);
2741
}
2842

2943
/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnFactoryProvider::types */

tests/ColumnSchemaTest.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -311,10 +311,12 @@ public function testPhpTypecastColumns(string $className, array $values)
311311
}
312312

313313
/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnSchemaProvider::dbTypecastArrayColumns */
314-
public function testDbTypecastArrayColumnSchema(string $dbType, string $type, string $phpType, array $values): void
314+
public function testDbTypecastArrayColumnSchema(string $dbType, string $type, array $values): void
315315
{
316-
$arrayCol = new ArrayColumnSchema($type, $phpType);
317-
$arrayCol->dbType($dbType);
316+
$db = $this->getConnection();
317+
$columnFactory = $db->getColumnFactory();
318+
319+
$arrayCol = (new ArrayColumnSchema())->column($columnFactory->fromType($type)->dbType($dbType));
318320

319321
foreach ($values as [$dimension, $expected, $value]) {
320322
$arrayCol->dimension($dimension);
@@ -331,10 +333,12 @@ public function testDbTypecastArrayColumnSchema(string $dbType, string $type, st
331333
}
332334

333335
/** @dataProvider \Yiisoft\Db\Pgsql\Tests\Provider\ColumnSchemaProvider::phpTypecastArrayColumns */
334-
public function testPhpTypecastArrayColumnSchema(string $dbType, string $type, string $phpType, array $values): void
336+
public function testPhpTypecastArrayColumnSchema(string $dbType, string $type, array $values): void
335337
{
336-
$arrayCol = new ArrayColumnSchema($type, $phpType);
337-
$arrayCol->dbType($dbType);
338+
$db = $this->getConnection();
339+
$columnFactory = $db->getColumnFactory();
340+
341+
$arrayCol = (new ArrayColumnSchema())->column($columnFactory->fromType($type)->dbType($dbType));
338342

339343
foreach ($values as [$dimension, $expected, $value]) {
340344
$arrayCol->dimension($dimension);

tests/ConnectionTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Yiisoft\Db\Exception\Exception;
1111
use Yiisoft\Db\Exception\InvalidConfigException;
1212
use Yiisoft\Db\Exception\NotSupportedException;
13+
use Yiisoft\Db\Pgsql\Column\ColumnFactory;
1314
use Yiisoft\Db\Pgsql\Tests\Support\TestTrait;
1415
use Yiisoft\Db\Tests\Common\CommonConnectionTest;
1516
use Yiisoft\Db\Transaction\TransactionInterface;
@@ -133,4 +134,11 @@ static function (ConnectionInterface $db) {
133134

134135
$db->close();
135136
}
137+
138+
public function testGetColumnFactory(): void
139+
{
140+
$db = $this->getConnection();
141+
142+
$this->assertInstanceOf(ColumnFactory::class, $db->getColumnFactory());
143+
}
136144
}

0 commit comments

Comments
 (0)