From 7e69c2f1ee46df75aaec92468ae70d4d0c52555a Mon Sep 17 00:00:00 2001 From: Tigrov Date: Mon, 7 Oct 2024 12:47:45 +0700 Subject: [PATCH 1/9] Add `ColumnDefinitionBuilder` --- src/Column/ColumnBuilder.php | 20 +++++ src/Column/ColumnDefinitionBuilder.php | 93 ++++++++++++++++++++++++ src/Connection.php | 7 -- src/DDLQueryBuilder.php | 1 + src/QueryBuilder.php | 5 +- src/Schema.php | 10 ++- tests/ConnectionTest.php | 8 -- tests/Provider/ColumnBuilderProvider.php | 23 ++++-- tests/Provider/QueryBuilderProvider.php | 87 ++++++++++++++++++++++ tests/QueryBuilderTest.php | 7 ++ tests/SchemaTest.php | 8 ++ 11 files changed, 245 insertions(+), 24 deletions(-) create mode 100644 src/Column/ColumnDefinitionBuilder.php diff --git a/src/Column/ColumnBuilder.php b/src/Column/ColumnBuilder.php index a0dcd28e..fda13e46 100644 --- a/src/Column/ColumnBuilder.php +++ b/src/Column/ColumnBuilder.php @@ -9,6 +9,26 @@ final class ColumnBuilder extends \Yiisoft\Db\Schema\Column\ColumnBuilder { + public static function tinyint(int|null $size = 3): ColumnSchemaInterface + { + return parent::tinyint($size); + } + + public static function smallint(int|null $size = 5): ColumnSchemaInterface + { + return parent::smallint($size); + } + + public static function integer(int|null $size = 10): ColumnSchemaInterface + { + return parent::integer($size); + } + + public static function bigint(int|null $size = 20): ColumnSchemaInterface + { + return parent::bigint($size); + } + public static function binary(int|null $size = null): ColumnSchemaInterface { return (new BinaryColumnSchema(ColumnType::BINARY)) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php new file mode 100644 index 00000000..fd53aac4 --- /dev/null +++ b/src/Column/ColumnDefinitionBuilder.php @@ -0,0 +1,93 @@ +getSize(); + + /** @psalm-suppress DocblockTypeContradiction */ + return match ($column->getType()) { + ColumnType::BOOLEAN => 'number(1)', + ColumnType::BIT => match (true) { + $size === null => 'number(38)', + $size <= 126 => 'number(' . ceil(log10(2 ** $size)) . ')', + default => 'raw(' . ceil($size / 8) . ')', + }, + ColumnType::TINYINT => 'number(' . ($size ?? 3) . ')', + ColumnType::SMALLINT => 'number(' . ($size ?? 5) . ')', + ColumnType::INTEGER => 'number(' . ($size ?? 10) . ')', + ColumnType::BIGINT => 'number(' . ($size ?? 20) . ')', + ColumnType::FLOAT => 'binary_float', + ColumnType::DOUBLE => 'binary_double', + ColumnType::DECIMAL => 'number(' . ($size ?? 10) . ',' . ($column->getScale() ?? 0) . ')', + ColumnType::MONEY => 'number(' . ($size ?? 19) . ',' . ($column->getScale() ?? 0) . ')', + ColumnType::CHAR => 'char', + ColumnType::STRING => 'varchar2', + ColumnType::TEXT => 'clob', + ColumnType::BINARY => 'blob', + ColumnType::UUID => 'raw(16)', + ColumnType::DATETIME => 'timestamp', + ColumnType::TIMESTAMP => 'timestamp', + ColumnType::DATE => 'date', + ColumnType::TIME => 'interval day(0) to second', + ColumnType::ARRAY => 'json', + ColumnType::STRUCTURED => 'json', + ColumnType::JSON => 'json', + default => 'varchar2', + }; + } +} diff --git a/src/Connection.php b/src/Connection.php index bed8d20c..144dd7dc 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -11,9 +11,7 @@ use Yiisoft\Db\Exception\InvalidArgumentException; use Yiisoft\Db\Exception\InvalidCallException; use Yiisoft\Db\Exception\InvalidConfigException; -use Yiisoft\Db\Oracle\Column\ColumnFactory; use Yiisoft\Db\QueryBuilder\QueryBuilderInterface; -use Yiisoft\Db\Schema\Column\ColumnFactoryInterface; use Yiisoft\Db\Schema\QuoterInterface; use Yiisoft\Db\Schema\SchemaInterface; use Yiisoft\Db\Transaction\TransactionInterface; @@ -49,11 +47,6 @@ public function createTransaction(): TransactionInterface return new Transaction($this); } - public function getColumnFactory(): ColumnFactoryInterface - { - return new ColumnFactory(); - } - /** * Override base behaviour to support Oracle sequences. * diff --git a/src/DDLQueryBuilder.php b/src/DDLQueryBuilder.php index 972c0dc0..972dcd3c 100644 --- a/src/DDLQueryBuilder.php +++ b/src/DDLQueryBuilder.php @@ -47,6 +47,7 @@ public function addForeignKey( public function alterColumn(string $table, string $column, ColumnInterface|string $type): string { + /** @psalm-suppress DeprecatedMethod */ return 'ALTER TABLE ' . $this->quoter->quoteTableName($table) . ' MODIFY ' diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index f82d8eaa..8965a363 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -6,6 +6,7 @@ use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; +use Yiisoft\Db\Oracle\Column\ColumnDefinitionBuilder; use Yiisoft\Db\QueryBuilder\AbstractQueryBuilder; use Yiisoft\Db\Schema\QuoterInterface; use Yiisoft\Db\Schema\SchemaInterface; @@ -49,6 +50,8 @@ public function __construct(QuoterInterface $quoter, SchemaInterface $schema) $ddlBuilder = new DDLQueryBuilder($this, $quoter, $schema); $dmlBuilder = new DMLQueryBuilder($this, $quoter, $schema); $dqlBuilder = new DQLQueryBuilder($this, $quoter); - parent::__construct($quoter, $schema, $ddlBuilder, $dmlBuilder, $dqlBuilder); + $columnDefinitionBuilder = new ColumnDefinitionBuilder($this); + + parent::__construct($quoter, $schema, $ddlBuilder, $dmlBuilder, $dqlBuilder, $columnDefinitionBuilder); } } diff --git a/src/Schema.php b/src/Schema.php index b5d1f711..7f6771c2 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -18,7 +18,9 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Helper\DbArrayHelper; +use Yiisoft\Db\Oracle\Column\ColumnFactory; use Yiisoft\Db\Schema\Builder\ColumnInterface; +use Yiisoft\Db\Schema\Column\ColumnFactoryInterface; use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; use Yiisoft\Db\Schema\TableSchemaInterface; @@ -71,11 +73,17 @@ public function __construct(protected ConnectionInterface $db, SchemaCache $sche parent::__construct($db, $schemaCache); } + /** @deprecated Use {@see ColumnBuilder} instead. Will be removed in 2.0. */ public function createColumn(string $type, array|int|string $length = null): ColumnInterface { return new Column($type, $length); } + public function getColumnFactory(): ColumnFactoryInterface + { + return new ColumnFactory(); + } + protected function resolveTableName(string $name): TableSchemaInterface { $resolvedName = new TableSchema(); @@ -418,7 +426,7 @@ protected function getTableSequenceName(string $tableName): string|null */ private function loadColumnSchema(array $info): ColumnSchemaInterface { - $columnFactory = $this->db->getColumnFactory(); + $columnFactory = $this->db->getSchema()->getColumnFactory(); $dbType = $info['data_type']; $column = $columnFactory->fromDbType($dbType, [ diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php index 233f1107..fe853afd 100644 --- a/tests/ConnectionTest.php +++ b/tests/ConnectionTest.php @@ -11,7 +11,6 @@ use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\InvalidConfigException; use Yiisoft\Db\Exception\NotSupportedException; -use Yiisoft\Db\Oracle\Column\ColumnFactory; use Yiisoft\Db\Oracle\Tests\Support\TestTrait; use Yiisoft\Db\Tests\Common\CommonConnectionTest; use Yiisoft\Db\Transaction\TransactionInterface; @@ -131,11 +130,4 @@ public function testSerialized(): void $this->assertEquals(123, $unserialized->createCommand('SELECT 123 FROM DUAL')->queryScalar()); $this->assertNotNull($connection->getPDO()); } - - public function testGetColumnFactory(): void - { - $db = $this->getConnection(); - - $this->assertInstanceOf(ColumnFactory::class, $db->getColumnFactory()); - } } diff --git a/tests/Provider/ColumnBuilderProvider.php b/tests/Provider/ColumnBuilderProvider.php index bc6bd1f7..41bbb5e2 100644 --- a/tests/Provider/ColumnBuilderProvider.php +++ b/tests/Provider/ColumnBuilderProvider.php @@ -4,18 +4,27 @@ namespace Yiisoft\Db\Oracle\Tests\Provider; -use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Oracle\Column\BinaryColumnSchema; class ColumnBuilderProvider extends \Yiisoft\Db\Tests\Provider\ColumnBuilderProvider { public static function buildingMethods(): array { - return [ - // building method, args, expected instance of, expected type, expected column method results - ...parent::buildingMethods(), - ['binary', [], BinaryColumnSchema::class, ColumnType::BINARY], - ['binary', [8], BinaryColumnSchema::class, ColumnType::BINARY, ['getSize' => 8]], - ]; + $values = parent::buildingMethods(); + + $values['primaryKey()'][4]['getSize'] = 10; + $values['primaryKey(false)'][4]['getSize'] = 10; + $values['smallPrimaryKey()'][4]['getSize'] = 5; + $values['smallPrimaryKey(false)'][4]['getSize'] = 5; + $values['bigPrimaryKey()'][4]['getSize'] = 20; + $values['bigPrimaryKey(false)'][4]['getSize'] = 20; + $values['tinyint()'][4]['getSize'] = 3; + $values['smallint()'][4]['getSize'] = 5; + $values['integer()'][4]['getSize'] = 10; + $values['bigint()'][4]['getSize'] = 20; + $values['binary()'][2] = BinaryColumnSchema::class; + $values['binary(8)'][2] = BinaryColumnSchema::class; + + return $values; } } diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 94e73323..5ccbc011 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -5,6 +5,7 @@ namespace Yiisoft\Db\Oracle\Tests\Provider; use Exception; +use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Expression\Expression; use Yiisoft\Db\Oracle\Tests\Support\TestTrait; use Yiisoft\Db\Query\Query; @@ -235,4 +236,90 @@ public static function upsert(): array return $upsert; } + + public static function buildColumnDefinition(): array + { + $values = parent::buildColumnDefinition(); + + $values[PseudoType::PK][0] = 'number(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values[PseudoType::UPK][0] = 'number(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values[PseudoType::BIGPK][0] = 'number(20) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values[PseudoType::UBIGPK][0] = 'number(20) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values[PseudoType::UUID_PK][0] = 'raw(16) DEFAULT sys_guid() PRIMARY KEY'; + $values[PseudoType::UUID_PK_SEQ][0] = 'raw(16) DEFAULT sys_guid() PRIMARY KEY'; + $values['STRING'][0] = 'varchar2'; + $values['STRING(100)'][0] = 'varchar2(100)'; + $values['primaryKey()'][0] = 'number(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values['primaryKey(false)'][0] = 'number(10) PRIMARY KEY'; + $values['smallPrimaryKey()'][0] = 'number(5) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values['smallPrimaryKey(false)'][0] = 'number(5) PRIMARY KEY'; + $values['bigPrimaryKey()'][0] = 'number(20) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; + $values['bigPrimaryKey(false)'][0] = 'number(20) PRIMARY KEY'; + $values['uuidPrimaryKey()'][0] = 'raw(16) DEFAULT sys_guid() PRIMARY KEY'; + $values['uuidPrimaryKey(false)'][0] = 'raw(16) PRIMARY KEY'; + $values['boolean()'][0] = 'number(1)'; + $values['boolean(100)'][0] = 'number(1)'; + $values['bit()'][0] = 'number(38)'; + $values['bit(1)'][0] = 'number(1)'; + $values['bit(8)'][0] = 'number(3)'; + $values['bit(1000)'][0] = 'raw(125)'; + $values['tinyint()'][0] = 'number(3)'; + $values['tinyint(2)'][0] = 'number(2)'; + $values['smallint()'][0] = 'number(5)'; + $values['smallint(4)'][0] = 'number(4)'; + $values['integer()'][0] = 'number(10)'; + $values['integer(8)'][0] = 'number(8)'; + $values['bigint()'][0] = 'number(20)'; + $values['bigint(15)'][0] = 'number(15)'; + $values['float()'][0] = 'binary_float'; + $values['float(10)'][0] = 'binary_float'; + $values['float(10,2)'][0] = 'binary_float'; + $values['double()'][0] = 'binary_double'; + $values['double(10)'][0] = 'binary_double'; + $values['double(10,2)'][0] = 'binary_double'; + $values['decimal()'][0] = 'number(10,0)'; + $values['decimal(5)'][0] = 'number(5,0)'; + $values['decimal(5,2)'][0] = 'number(5,2)'; + $values['decimal(null)'][0] = 'number(10,0)'; + $values['money()'][0] = 'number(19,4)'; + $values['money(10)'][0] = 'number(10,4)'; + $values['money(10,2)'][0] = 'number(10,2)'; + $values['money(null)'][0] = 'number(19,4)'; + $values['string()'][0] = 'varchar2(255)'; + $values['string(100)'][0] = 'varchar2(100)'; + $values['string(null)'][0] = 'varchar2'; + $values['text()'][0] = 'clob'; + $values['text(1000)'][0] = 'clob'; + $values['binary()'][0] = 'blob'; + $values['binary(1000)'][0] = 'blob'; + $values['uuid()'][0] = 'raw(16)'; + $values['datetime()'][0] = 'timestamp(0)'; + $values['datetime(6)'][0] = 'timestamp(6)'; + $values['datetime(null)'][0] = 'timestamp'; + $values['time()'][0] = 'interval day(0) to second(0)'; + $values['time(6)'][0] = 'interval day(0) to second(6)'; + $values['time(null)'][0] = 'interval day(0) to second'; + $values["comment('comment')"][0] = 'varchar2(255)'; + $values["comment('')"][0] = 'varchar2(255)'; + $values['comment(null)'][0] = 'varchar2(255)'; + $values["extra('bar')"][0] = 'varchar2(255) bar'; + $values["extra('')"][0] = 'varchar2(255)'; + $values["check('value > 5')"][0] = 'varchar2(255) CHECK (value > 5)'; + $values["check('')"][0] = 'varchar2(255)'; + $values['check(null)'][0] = 'varchar2(255)'; + $values["defaultValue('value')"][0] = "varchar2(255) DEFAULT 'value'"; + $values["defaultValue('')"][0] = "varchar2(255) DEFAULT ''"; + $values['defaultValue(null)'][0] = 'varchar2(255)'; + $values['defaultValue($expression)'][0] = 'varchar2(255) DEFAULT expression'; + $values['notNull()'][0] = 'varchar2(255) NOT NULL'; + $values['integer()->primaryKey()'][0] = 'number(10) PRIMARY KEY'; + $values['size(10)'][0] = 'varchar2(10)'; + $values['unique()'][0] = 'varchar2(255) UNIQUE'; + $values['unsigned()'][0] = 'number(10)'; + $values['scale(2)'][0] = 'number(10,2)'; + $values['integer(8)->scale(2)'][0] = 'number(8)'; + $values['reference($reference)'][0] = 'number(10) REFERENCES "ref_table" ("id") ON DELETE CASCADE ON UPDATE CASCADE'; + + return $values; + } } diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index bec761e8..e8c23a38 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -14,6 +14,7 @@ use Yiisoft\Db\Oracle\Tests\Support\TestTrait; use Yiisoft\Db\Query\Query; use Yiisoft\Db\Query\QueryInterface; +use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; use Yiisoft\Db\Tests\Common\CommonQueryBuilderTest; /** @@ -670,4 +671,10 @@ public function testSelectScalar(array|bool|float|int|string $columns, string $e { parent::testSelectScalar($columns, $expected); } + + /** @dataProvider \Yiisoft\Db\Oracle\Tests\Provider\QueryBuilderProvider::buildColumnDefinition() */ + public function testBuildColumnDefinition(string $expected, ColumnSchemaInterface|string $column): void + { + parent::testBuildColumnDefinition($expected, $column); + } } diff --git a/tests/SchemaTest.php b/tests/SchemaTest.php index 2fb6f0fe..40e909d5 100644 --- a/tests/SchemaTest.php +++ b/tests/SchemaTest.php @@ -10,6 +10,7 @@ use Yiisoft\Db\Exception\Exception; use Yiisoft\Db\Exception\InvalidConfigException; use Yiisoft\Db\Exception\NotSupportedException; +use Yiisoft\Db\Oracle\Column\ColumnFactory; use Yiisoft\Db\Oracle\Schema; use Yiisoft\Db\Oracle\Tests\Support\TestTrait; use Yiisoft\Db\Tests\Common\CommonSchemaTest; @@ -295,4 +296,11 @@ public function testNotConnectionPDO(): void $schema->refresh(); } + + public function testGetColumnFactory(): void + { + $db = $this->getConnection(); + + $this->assertInstanceOf(ColumnFactory::class, $db->getSchema()->getColumnFactory()); + } } From ac696342e2e921cfd3950ebd27d81af123122513 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 09:36:21 +0700 Subject: [PATCH 2/9] Remove code comments --- src/Column/ColumnDefinitionBuilder.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index fd53aac4..6a13107c 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -8,8 +8,6 @@ use Yiisoft\Db\QueryBuilder\AbstractColumnDefinitionBuilder; use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; -use function strcasecmp; - final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder { protected const AUTO_INCREMENT_KEYWORD = 'GENERATED BY DEFAULT AS IDENTITY'; @@ -39,16 +37,6 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder 'urowid', 'char', 'nchar', - -// 'clob', -// 'nclob', -// 'blob', -// 'bfile', -// 'long raw', -// 'binary_float', -// 'binary_double', -// 'date', -// 'long', ]; protected const TYPES_WITH_SCALE = [ From 92bae70e2a81c9226f09b504869ac7ccf94fdc8a Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 10:03:13 +0700 Subject: [PATCH 3/9] Add FQNs --- src/Column/ColumnDefinitionBuilder.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index 6a13107c..43d85e9a 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -8,6 +8,9 @@ use Yiisoft\Db\QueryBuilder\AbstractColumnDefinitionBuilder; use Yiisoft\Db\Schema\Column\ColumnSchemaInterface; +use function ceil; +use function log10; + final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder { protected const AUTO_INCREMENT_KEYWORD = 'GENERATED BY DEFAULT AS IDENTITY'; From 03c49fb95766e1536cd8a9414e73b700cb9d2bb6 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 10:18:09 +0700 Subject: [PATCH 4/9] Update according changes in main PR --- tests/Provider/QueryBuilderProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index 5ccbc011..afcc4ff5 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -313,6 +313,7 @@ public static function buildColumnDefinition(): array $values['defaultValue($expression)'][0] = 'varchar2(255) DEFAULT expression'; $values['notNull()'][0] = 'varchar2(255) NOT NULL'; $values['integer()->primaryKey()'][0] = 'number(10) PRIMARY KEY'; + $values["integer()->defaultValue('')"][0] = 'number(10)'; $values['size(10)'][0] = 'varchar2(10)'; $values['unique()'][0] = 'varchar2(255) UNIQUE'; $values['unsigned()'][0] = 'number(10)'; From 1d46ee696b8e4075949c7c9bba1e3386fbb66e11 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 10:36:10 +0700 Subject: [PATCH 5/9] Fix money scale --- src/Column/ColumnDefinitionBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index 43d85e9a..47e43bd7 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -65,7 +65,7 @@ protected function getDbType(ColumnSchemaInterface $column): string ColumnType::FLOAT => 'binary_float', ColumnType::DOUBLE => 'binary_double', ColumnType::DECIMAL => 'number(' . ($size ?? 10) . ',' . ($column->getScale() ?? 0) . ')', - ColumnType::MONEY => 'number(' . ($size ?? 19) . ',' . ($column->getScale() ?? 0) . ')', + ColumnType::MONEY => 'number(' . ($size ?? 19) . ',' . ($column->getScale() ?? 4) . ')', ColumnType::CHAR => 'char', ColumnType::STRING => 'varchar2', ColumnType::TEXT => 'clob', From 508f9475c620e082a119d7733879f602d12a2ce3 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 11:14:11 +0700 Subject: [PATCH 6/9] Improve --- src/Column/ColumnDefinitionBuilder.php | 15 +++++++++++++++ tests/Provider/QueryBuilderProvider.php | 20 ++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index 47e43bd7..312a1cbd 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -10,6 +10,7 @@ use function ceil; use function log10; +use function strtoupper; final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder { @@ -46,6 +47,20 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder 'number', ]; + protected function buildOnDeleteClause(string $onDelete): string + { + return match ($onDelete = strtoupper($onDelete)) { + 'CASCADE', + 'SET NULL' => " ON DELETE $onDelete", + default => '', + }; + } + + protected function buildOnUpdateClause(string $onUpdate): string + { + return ''; + } + protected function getDbType(ColumnSchemaInterface $column): string { $size = $column->getSize(); diff --git a/tests/Provider/QueryBuilderProvider.php b/tests/Provider/QueryBuilderProvider.php index afcc4ff5..bb9a6a0e 100644 --- a/tests/Provider/QueryBuilderProvider.php +++ b/tests/Provider/QueryBuilderProvider.php @@ -6,7 +6,9 @@ use Exception; use Yiisoft\Db\Constant\PseudoType; +use Yiisoft\Db\Constraint\ForeignKeyConstraint; use Yiisoft\Db\Expression\Expression; +use Yiisoft\Db\Oracle\Column\ColumnBuilder; use Yiisoft\Db\Oracle\Tests\Support\TestTrait; use Yiisoft\Db\Query\Query; use Yiisoft\Db\Tests\Support\DbHelper; @@ -239,6 +241,14 @@ public static function upsert(): array public static function buildColumnDefinition(): array { + $referenceRestrict = new ForeignKeyConstraint(); + $referenceRestrict->foreignColumnNames(['id']); + $referenceRestrict->foreignTableName('ref_table'); + $referenceRestrict->onDelete('restrict'); + + $referenceSetNull = clone $referenceRestrict; + $referenceSetNull->onDelete('set null'); + $values = parent::buildColumnDefinition(); $values[PseudoType::PK][0] = 'number(10) GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'; @@ -319,8 +329,14 @@ public static function buildColumnDefinition(): array $values['unsigned()'][0] = 'number(10)'; $values['scale(2)'][0] = 'number(10,2)'; $values['integer(8)->scale(2)'][0] = 'number(8)'; - $values['reference($reference)'][0] = 'number(10) REFERENCES "ref_table" ("id") ON DELETE CASCADE ON UPDATE CASCADE'; + $values['reference($reference)'][0] = 'number(10) REFERENCES "ref_table" ("id") ON DELETE CASCADE'; + $values['reference($referenceWithSchema)'][0] = 'number(10) REFERENCES "ref_schema"."ref_table" ("id") ON DELETE CASCADE'; - return $values; + return [ + ...$values, + + ['number(10) REFERENCES "ref_table" ("id")', ColumnBuilder::integer()->reference($referenceRestrict)], + ['number(10) REFERENCES "ref_table" ("id") ON DELETE SET NULL', ColumnBuilder::integer()->reference($referenceSetNull)], + ]; } } From eb2ada138307e0b34a4442900fb676891cbcb5c3 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 11:48:02 +0700 Subject: [PATCH 7/9] Update according changes in main PR --- src/Column/ColumnDefinitionBuilder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index 312a1cbd..0c99744d 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -47,7 +47,7 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder 'number', ]; - protected function buildOnDeleteClause(string $onDelete): string + protected function buildOnDelete(string $onDelete): string { return match ($onDelete = strtoupper($onDelete)) { 'CASCADE', @@ -56,7 +56,7 @@ protected function buildOnDeleteClause(string $onDelete): string }; } - protected function buildOnUpdateClause(string $onUpdate): string + protected function buildOnUpdate(string $onUpdate): string { return ''; } From dc638f429745da36a746a0a79afb6d101e91d3a4 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 9 Oct 2024 12:05:34 +0700 Subject: [PATCH 8/9] Remove `CLAUSES` constant --- src/Column/ColumnDefinitionBuilder.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php index 0c99744d..baad5036 100644 --- a/src/Column/ColumnDefinitionBuilder.php +++ b/src/Column/ColumnDefinitionBuilder.php @@ -16,18 +16,6 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder { protected const AUTO_INCREMENT_KEYWORD = 'GENERATED BY DEFAULT AS IDENTITY'; - protected const CLAUSES = [ - 'type', - 'auto_increment', - 'default', - 'primary_key', - 'unique', - 'not_null', - 'check', - 'references', - 'extra', - ]; - protected const GENERATE_UUID_EXPRESSION = 'sys_guid()'; protected const TYPES_WITH_SIZE = [ @@ -47,6 +35,19 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder 'number', ]; + public function build(ColumnSchemaInterface $column): string + { + return $this->buildType($column) + . $this->buildAutoIncrement($column) + . $this->buildDefault($column) + . $this->buildPrimaryKey($column) + . $this->buildUnique($column) + . $this->buildNotNull($column) + . $this->buildCheck($column) + . $this->buildReferences($column) + . $this->buildExtra($column); + } + protected function buildOnDelete(string $onDelete): string { return match ($onDelete = strtoupper($onDelete)) { From 40fbdd6e949aee8cf39a6b9b0cff9fb109a0e7fe Mon Sep 17 00:00:00 2001 From: Tigrov Date: Fri, 11 Oct 2024 09:53:29 +0700 Subject: [PATCH 9/9] Add line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f542228..ddb324cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,16 @@ from `$table, $columns, $rows` to `$table, $rows, $columns = []` (@Tigrov) - Enh #260: Support `Traversable` values for `DMLQueryBuilder::batchInsert()` method with empty columns (@Tigrov) - Enh #255: Implement `SqlParser` and `ExpressionBuilder` driver classes (@Tigrov) -- Enh #236: Implement `ColumnSchemaInterface` classes according to the data type of database table columns +- New #236: Implement `ColumnSchemaInterface` classes according to the data type of database table columns for type casting performance. Related with yiisoft/db#752 (@Tigrov) - Chg #272: Replace call of `SchemaInterface::getRawTableName()` to `QuoterInterface::getRawTableName()` (@Tigrov) - Enh #275: Refactor PHP type of `ColumnSchemaInterface` instances (@Tigrov) - Enh #277: Raise minimum PHP version to `^8.1` with minor refactoring (@Tigrov) -- Enh #276: Implement `ColumnFactory` class (@Tigrov) +- New #276: Implement `ColumnFactory` class (@Tigrov) - Enh #279: Separate column type constants (@Tigrov) -- Enh #280: Realize `ColumnBuilder` class (@Tigrov) +- New #280: Realize `ColumnBuilder` class (@Tigrov) - Enh #281: Update according changes in `ColumnSchemaInterface` (@Tigrov) +- New #282: Add `ColumnDefinitionBuilder` class (@Tigrov) ## 1.3.0 March 21, 2024