Skip to content

Commit 5530ff5

Browse files
authored
Merge branch 'master' into ease-local-testing
2 parents d262091 + c74a84b commit 5530ff5

28 files changed

+431
-354
lines changed

CHANGELOG.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,22 @@
1515
- Enh #279: Separate column type constants (@Tigrov)
1616
- New #280, #291: Realize `ColumnBuilder` class (@Tigrov)
1717
- Enh #281: Update according changes in `ColumnSchemaInterface` (@Tigrov)
18-
- New #282, #291: Add `ColumnDefinitionBuilder` class (@Tigrov)
18+
- New #282, #291, #299, #302: Add `ColumnDefinitionBuilder` class (@Tigrov)
1919
- Bug #285: Fix `DMLQueryBuilder::insertBatch()` method (@Tigrov)
2020
- Enh #283: Refactor `Dsn` class (@Tigrov)
2121
- Enh #286: Use constructor to create columns and initialize properties (@Tigrov)
2222
- Enh #288: Refactor `Schema::findColumns()` method (@Tigrov)
2323
- Enh #289: Refactor `Schema::normalizeDefaultValue()` method and move it to `ColumnFactory` class (@Tigrov)
2424
- New #292: Override `QueryBuilder::prepareBinary()` method (@Tigrov)
2525
- Chg #294: Update `QueryBuilder` constructor (@Tigrov)
26+
- Enh #293: Use `ColumnDefinitionBuilder` to generate table column SQL representation (@Tigrov)
27+
- Enh #296: Remove `ColumnInterface` (@Tigrov)
28+
- Enh #298: Rename `ColumnSchemaInterface` to `ColumnInterface` (@Tigrov)
29+
- Enh #298: Refactor `DMLQueryBuilder::prepareInsertValues()` method (@Tigrov)
30+
- Enh #299: Add `ColumnDefinitionParser` class (@Tigrov)
31+
- Enh #299: Convert database types to lower case (@Tigrov)
32+
- Enh #300: Replace `DbArrayHelper::getColumn()` with `array_column()` (@Tigrov)
33+
- New #301: Add `IndexType` class (@Tigrov)
2634

2735
## 1.3.0 March 21, 2024
2836

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"require-dev": {
3838
"maglnet/composer-require-checker": "^4.2",
3939
"phpunit/phpunit": "^10.0",
40-
"rector/rector": "^1.0",
40+
"rector/rector": "^2.0",
4141
"roave/infection-static-analysis-plugin": "^1.16",
4242
"spatie/phpunit-watcher": "^1.23",
4343
"vimeo/psalm": "^5.25",

src/Column.php

-51
This file was deleted.

src/Column/BinaryColumnSchema.php src/Column/BinaryColumn.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66

77
use Yiisoft\Db\Command\ParamInterface;
88
use Yiisoft\Db\Expression\Expression;
9-
use Yiisoft\Db\Schema\Column\BinaryColumnSchema as BaseBinaryColumnSchema;
9+
use Yiisoft\Db\Schema\Column\BinaryColumn as BaseBinaryColumn;
1010

1111
use function is_string;
1212

13-
final class BinaryColumnSchema extends BaseBinaryColumnSchema
13+
final class BinaryColumn extends BaseBinaryColumn
1414
{
1515
public function dbTypecast(mixed $value): mixed
1616
{
17-
if ($this->getDbType() === 'BLOB') {
17+
if ($this->getDbType() === 'blob') {
1818
if ($value instanceof ParamInterface && is_string($value->getValue())) {
1919
/** @var string */
2020
$value = $value->getValue();

src/Column/ColumnBuilder.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
namespace Yiisoft\Db\Oracle\Column;
66

77
use Yiisoft\Db\Constant\ColumnType;
8-
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
8+
use Yiisoft\Db\Schema\Column\ColumnInterface;
99

1010
final class ColumnBuilder extends \Yiisoft\Db\Schema\Column\ColumnBuilder
1111
{
12-
public static function binary(int|null $size = null): ColumnSchemaInterface
12+
public static function binary(int|null $size = null): ColumnInterface
1313
{
14-
return new BinaryColumnSchema(ColumnType::BINARY, size: $size);
14+
return new BinaryColumn(ColumnType::BINARY, size: $size);
1515
}
1616
}

src/Column/ColumnDefinitionBuilder.php

+47-34
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
namespace Yiisoft\Db\Oracle\Column;
66

77
use Yiisoft\Db\Constant\ColumnType;
8+
use Yiisoft\Db\Constant\ReferentialAction;
89
use Yiisoft\Db\QueryBuilder\AbstractColumnDefinitionBuilder;
9-
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
10+
use Yiisoft\Db\Schema\Column\ColumnInterface;
1011

1112
use function ceil;
1213
use function log10;
@@ -16,8 +17,6 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder
1617
{
1718
protected const AUTO_INCREMENT_KEYWORD = 'GENERATED BY DEFAULT AS IDENTITY';
1819

19-
protected const GENERATE_UUID_EXPRESSION = 'sys_guid()';
20-
2120
protected const TYPES_WITH_SIZE = [
2221
'char',
2322
'nchar',
@@ -37,7 +36,7 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder
3736
'number',
3837
];
3938

40-
public function build(ColumnSchemaInterface $column): string
39+
public function build(ColumnInterface $column): string
4140
{
4241
return $this->buildType($column)
4342
. $this->buildAutoIncrement($column)
@@ -53,8 +52,8 @@ public function build(ColumnSchemaInterface $column): string
5352
protected function buildOnDelete(string $onDelete): string
5453
{
5554
return match ($onDelete = strtoupper($onDelete)) {
56-
'CASCADE',
57-
'SET NULL' => " ON DELETE $onDelete",
55+
ReferentialAction::CASCADE,
56+
ReferentialAction::SET_NULL => " ON DELETE $onDelete",
5857
default => '',
5958
};
6059
}
@@ -64,39 +63,53 @@ protected function buildOnUpdate(string $onUpdate): string
6463
return '';
6564
}
6665

67-
protected function getDbType(ColumnSchemaInterface $column): string
66+
protected function getDbType(ColumnInterface $column): string
6867
{
68+
$dbType = $column->getDbType();
6969
$size = $column->getSize();
70+
$scale = $column->getScale();
7071

7172
/** @psalm-suppress DocblockTypeContradiction */
72-
return $column->getDbType() ?? match ($column->getType()) {
73-
ColumnType::BOOLEAN => 'number(1)',
74-
ColumnType::BIT => match (true) {
75-
$size === null => 'number(38)',
76-
$size <= 126 => 'number(' . ceil(log10(2 ** $size)) . ')',
77-
default => 'raw(' . ceil($size / 8) . ')',
73+
return match ($dbType) {
74+
default => $dbType,
75+
null => match ($column->getType()) {
76+
ColumnType::BOOLEAN => 'number(1)',
77+
ColumnType::BIT => match (true) {
78+
$size === null => 'number(38)',
79+
$size <= 126 => 'number(' . ceil(log10(2 ** $size)) . ')',
80+
default => 'raw(' . ceil($size / 8) . ')',
81+
},
82+
ColumnType::TINYINT => 'number(' . ($size ?? 3) . ')',
83+
ColumnType::SMALLINT => 'number(' . ($size ?? 5) . ')',
84+
ColumnType::INTEGER => 'number(' . ($size ?? 10) . ')',
85+
ColumnType::BIGINT => 'number(' . ($size ?? 20) . ')',
86+
ColumnType::FLOAT => 'binary_float',
87+
ColumnType::DOUBLE => 'binary_double',
88+
ColumnType::DECIMAL => 'number(' . ($size ?? 10) . ',' . ($scale ?? 0) . ')',
89+
ColumnType::MONEY => 'number(' . ($size ?? 19) . ',' . ($scale ?? 4) . ')',
90+
ColumnType::CHAR => 'char',
91+
ColumnType::STRING => 'varchar2(' . ($size ?? 255) . ')',
92+
ColumnType::TEXT => 'clob',
93+
ColumnType::BINARY => 'blob',
94+
ColumnType::UUID => 'raw(16)',
95+
ColumnType::DATETIME => 'timestamp',
96+
ColumnType::TIMESTAMP => 'timestamp',
97+
ColumnType::DATE => 'date',
98+
ColumnType::TIME => 'interval day(0) to second',
99+
ColumnType::ARRAY => 'clob',
100+
ColumnType::STRUCTURED => 'clob',
101+
ColumnType::JSON => 'clob',
102+
default => 'varchar2',
78103
},
79-
ColumnType::TINYINT => 'number(' . ($size ?? 3) . ')',
80-
ColumnType::SMALLINT => 'number(' . ($size ?? 5) . ')',
81-
ColumnType::INTEGER => 'number(' . ($size ?? 10) . ')',
82-
ColumnType::BIGINT => 'number(' . ($size ?? 20) . ')',
83-
ColumnType::FLOAT => 'binary_float',
84-
ColumnType::DOUBLE => 'binary_double',
85-
ColumnType::DECIMAL => 'number(' . ($size ?? 10) . ',' . ($column->getScale() ?? 0) . ')',
86-
ColumnType::MONEY => 'number(' . ($size ?? 19) . ',' . ($column->getScale() ?? 4) . ')',
87-
ColumnType::CHAR => 'char',
88-
ColumnType::STRING => 'varchar2(' . ($size ?? 255) . ')',
89-
ColumnType::TEXT => 'clob',
90-
ColumnType::BINARY => 'blob',
91-
ColumnType::UUID => 'raw(16)',
92-
ColumnType::DATETIME => 'timestamp',
93-
ColumnType::TIMESTAMP => 'timestamp',
94-
ColumnType::DATE => 'date',
95-
ColumnType::TIME => 'interval day(0) to second',
96-
ColumnType::ARRAY => 'clob',
97-
ColumnType::STRUCTURED => 'clob',
98-
ColumnType::JSON => 'clob',
99-
default => 'varchar2',
104+
'timestamp with time zone' => 'timestamp' . ($size !== null ? "($size)" : '') . ' with time zone',
105+
'timestamp with local time zone' => 'timestamp' . ($size !== null ? "($size)" : '') . ' with local time zone',
106+
'interval day to second' => 'interval day' . ($scale !== null ? "($scale)" : '') . ' to second' . ($size !== null ? "($size)" : ''),
107+
'interval year to month' => 'interval year' . ($scale !== null ? "($scale)" : '') . ' to month',
100108
};
101109
}
110+
111+
protected function getDefaultUuidExpression(): string
112+
{
113+
return 'sys_guid()';
114+
}
102115
}

src/Column/ColumnDefinitionParser.php

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Db\Oracle\Column;
6+
7+
use function preg_match;
8+
use function preg_replace;
9+
use function strlen;
10+
use function strtolower;
11+
use function substr;
12+
13+
/**
14+
* Parses column definition string. For example, `string(255)` or `int unsigned`.
15+
*/
16+
final class ColumnDefinitionParser extends \Yiisoft\Db\Syntax\ColumnDefinitionParser
17+
{
18+
private const TYPE_PATTERN = '/^('
19+
. 'timestamp\s*(?:\((\d+)\))? with(?: local)? time zone'
20+
. '|interval year\s*(?:\((\d+)\))? to month'
21+
. ')|('
22+
. 'interval day\s*(?:\((\d+)\))? to second'
23+
. '|long raw'
24+
. '|\w*'
25+
. ')\s*(?:\(([^)]+)\))?\s*'
26+
. '/i';
27+
28+
public function parse(string $definition): array
29+
{
30+
preg_match(self::TYPE_PATTERN, $definition, $matches);
31+
32+
$type = strtolower(preg_replace('/\s*\(\d+\)/', '', $matches[4] ?? $matches[1]));
33+
$info = ['type' => $type];
34+
35+
$typeDetails = $matches[6] ?? $matches[2] ?? '';
36+
37+
if ($typeDetails !== '') {
38+
if ($type === 'enum') {
39+
$info += $this->enumInfo($typeDetails);
40+
} else {
41+
$info += $this->sizeInfo($typeDetails);
42+
}
43+
}
44+
45+
$scale = $matches[5] ?? $matches[3] ?? '';
46+
47+
if ($scale !== '') {
48+
$info += ['scale' => (int) $scale];
49+
}
50+
51+
$extra = substr($definition, strlen($matches[0]));
52+
53+
return $info + $this->extraInfo($extra);
54+
}
55+
}

src/Column/ColumnFactory.php

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66

77
use Yiisoft\Db\Constant\ColumnType;
88
use Yiisoft\Db\Schema\Column\AbstractColumnFactory;
9-
use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
9+
use Yiisoft\Db\Schema\Column\ColumnInterface;
1010

11-
use function preg_replace;
1211
use function rtrim;
13-
use function strtolower;
1412

1513
final class ColumnFactory extends AbstractColumnFactory
1614
{
@@ -40,19 +38,23 @@ final class ColumnFactory extends AbstractColumnFactory
4038
'binary_double' => ColumnType::DOUBLE, // 64 bit
4139
'float' => ColumnType::DOUBLE, // 126 bit
4240
'date' => ColumnType::DATE,
43-
'interval day to second' => ColumnType::TIME,
4441
'timestamp' => ColumnType::TIMESTAMP,
4542
'timestamp with time zone' => ColumnType::TIMESTAMP,
4643
'timestamp with local time zone' => ColumnType::TIMESTAMP,
44+
'interval day to second' => ColumnType::STRING,
45+
'interval year to month' => ColumnType::STRING,
4746

4847
/** Deprecated */
4948
'long' => ColumnType::TEXT,
5049
];
5150

52-
protected function getType(string $dbType, array $info = []): string
51+
protected function columnDefinitionParser(): ColumnDefinitionParser
5352
{
54-
$dbType = strtolower($dbType);
53+
return new ColumnDefinitionParser();
54+
}
5555

56+
protected function getType(string $dbType, array $info = []): string
57+
{
5658
if ($dbType === 'number') {
5759
return match ($info['scale'] ?? null) {
5860
null => ColumnType::DOUBLE,
@@ -61,10 +63,8 @@ protected function getType(string $dbType, array $info = []): string
6163
};
6264
}
6365

64-
$dbType = preg_replace('/\([^)]+\)/', '', $dbType);
65-
66-
if ($dbType === 'interval day to second' && isset($info['size']) && $info['size'] > 0) {
67-
return ColumnType::STRING;
66+
if ($dbType === 'interval day to second' && isset($info['scale']) && $info['scale'] === 0) {
67+
return ColumnType::TIME;
6868
}
6969

7070
return parent::getType($dbType, $info);
@@ -73,13 +73,13 @@ protected function getType(string $dbType, array $info = []): string
7373
protected function getColumnClass(string $type, array $info = []): string
7474
{
7575
if ($type === ColumnType::BINARY) {
76-
return BinaryColumnSchema::class;
76+
return BinaryColumn::class;
7777
}
7878

7979
return parent::getColumnClass($type, $info);
8080
}
8181

82-
protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnSchemaInterface $column): mixed
82+
protected function normalizeNotNullDefaultValue(string $defaultValue, ColumnInterface $column): mixed
8383
{
8484
return parent::normalizeNotNullDefaultValue(rtrim($defaultValue), $column);
8585
}

0 commit comments

Comments
 (0)