From 449ffd44e8bdc873c1f8ae142573783a3e4a02ee Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Tue, 17 Sep 2024 14:41:27 +0300 Subject: [PATCH 1/7] Add `$ifExists` and `$cascade` to `dropTable()` methods --- CHANGELOG.md | 2 + UPGRADE.md | 2 + src/Command/AbstractCommand.php | 4 +- src/Command/CommandInterface.php | 4 +- src/Debug/CommandInterfaceProxy.php | 2 +- src/QueryBuilder/AbstractDDLQueryBuilder.php | 7 +++- src/QueryBuilder/AbstractQueryBuilder.php | 4 +- src/QueryBuilder/DDLQueryBuilderInterface.php | 4 +- tests/AbstractQueryBuilderTest.php | 40 +++++++++++++----- tests/Common/CommonCommandTest.php | 5 --- tests/Db/Command/CommandTest.php | 41 +++++++++++++------ 11 files changed, 78 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44ce8fb13..71739e15a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,8 @@ - Enh #875: Ignore "Packets out of order..." warnings in `AbstractPdoCommand::internalExecute()` method (@Tigrov) - Enh #877: Separate column type constants (@Tigrov) - Enh #878: Realize `ColumnBuilder` class (@Tigrov) +- New #773: Add parameters `$ifExists` and `$cascade` to `CommandInterface::dropTable()` and + `DDLQueryBuilderInterface::dropTable()` methods (@Tigrov) ## 1.3.0 March 21, 2024 diff --git a/UPGRADE.md b/UPGRADE.md index 6fe3a7c57..df700a693 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -133,3 +133,5 @@ Each table column has its own class in the `Yiisoft\Db\Schema\Column` namespace - Allow `ExpressionInterface` for `$alias` parameter of `QueryPartsInterface::withQuery()` method; - Allow `QueryInterface::one()` to return an object; - Allow `QueryInterface::all()` to return array of objects; +- Add parameters `$ifExists` and `$cascade` to `CommandInterface::dropTable()` and + `DDLQueryBuilderInterface::dropTable()` methods. diff --git a/src/Command/AbstractCommand.php b/src/Command/AbstractCommand.php index 6f97718a8..8774e1637 100644 --- a/src/Command/AbstractCommand.php +++ b/src/Command/AbstractCommand.php @@ -310,9 +310,9 @@ public function dropPrimaryKey(string $table, string $name): static return $this->setSql($sql)->requireTableSchemaRefresh($table); } - public function dropTable(string $table): static + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): static { - $sql = $this->getQueryBuilder()->dropTable($table); + $sql = $this->getQueryBuilder()->dropTable($table, $ifExists, $cascade); return $this->setSql($sql)->requireTableSchemaRefresh($table); } diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index a10748f90..44367e066 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -471,10 +471,12 @@ public function dropPrimaryKey(string $table, string $name): static; * Creates an SQL command for dropping a DB table. * * @param string $table The name of the table to drop. + * @param bool $ifExists Do not throw an error if the table does not exist. + * @param bool $cascade Automatically drop objects that depend on the table. * * Note: The method will quote the `table` parameter before using it in the generated SQL. */ - public function dropTable(string $table): static; + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): static; /** * Creates an SQL command for dropping a unique constraint. diff --git a/src/Debug/CommandInterfaceProxy.php b/src/Debug/CommandInterfaceProxy.php index ddd0fc36f..82cf53ea7 100644 --- a/src/Debug/CommandInterfaceProxy.php +++ b/src/Debug/CommandInterfaceProxy.php @@ -252,7 +252,7 @@ public function dropPrimaryKey(string $table, string $name): static /** * @psalm-suppress MixedArgument */ - public function dropTable(string $table): static + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): static { return new self($this->decorated->{__FUNCTION__}(...func_get_args()), $this->collector); } diff --git a/src/QueryBuilder/AbstractDDLQueryBuilder.php b/src/QueryBuilder/AbstractDDLQueryBuilder.php index ce387a8ae..f3a069555 100644 --- a/src/QueryBuilder/AbstractDDLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDDLQueryBuilder.php @@ -265,9 +265,12 @@ public function dropPrimaryKey(string $table, string $name): string . $this->quoter->quoteColumnName($name); } - public function dropTable(string $table): string + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): string { - return 'DROP TABLE ' . $this->quoter->quoteTableName($table); + return 'DROP TABLE ' + . ($ifExists ? 'IF EXISTS ' : '') + . $this->quoter->quoteTableName($table) + . ($cascade ? ' CASCADE' : ''); } public function dropUnique(string $table, string $name): string diff --git a/src/QueryBuilder/AbstractQueryBuilder.php b/src/QueryBuilder/AbstractQueryBuilder.php index 4123e7cc0..0c6c01c59 100644 --- a/src/QueryBuilder/AbstractQueryBuilder.php +++ b/src/QueryBuilder/AbstractQueryBuilder.php @@ -307,9 +307,9 @@ public function dropPrimaryKey(string $table, string $name): string return $this->ddlBuilder->dropPrimaryKey($table, $name); } - public function dropTable(string $table): string + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): string { - return $this->ddlBuilder->dropTable($table); + return $this->ddlBuilder->dropTable($table, $ifExists, $cascade); } public function dropUnique(string $table, string $name): string diff --git a/src/QueryBuilder/DDLQueryBuilderInterface.php b/src/QueryBuilder/DDLQueryBuilderInterface.php index c6e97fb7d..8b35d5dec 100644 --- a/src/QueryBuilder/DDLQueryBuilderInterface.php +++ b/src/QueryBuilder/DDLQueryBuilderInterface.php @@ -361,12 +361,14 @@ public function dropPrimaryKey(string $table, string $name): string; * Builds an SQL statement for dropping a DB table. * * @param string $table The table to drop. + * @param bool $ifExists Do not throw an error if the table does not exist. + * @param bool $cascade Automatically drop objects that depend on the table. * * @return string The SQL statement for dropping a DB table. * * Note: The method will quote the `table` parameter before using it in the generated SQL. */ - public function dropTable(string $table): string; + public function dropTable(string $table, bool $ifExists = false, bool $cascade = false): string; /** * Creates an SQL command for dropping a unique constraint. diff --git a/tests/AbstractQueryBuilderTest.php b/tests/AbstractQueryBuilderTest.php index c1fc66be9..2ff31be5a 100644 --- a/tests/AbstractQueryBuilderTest.php +++ b/tests/AbstractQueryBuilderTest.php @@ -6,6 +6,7 @@ use Closure; use JsonException; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use stdClass; use Throwable; @@ -1791,21 +1792,38 @@ public function testDropPrimaryKey(): void ); } - public function testDropTable(): void + public static function dataDropTable(): iterable { - $db = $this->getConnection(); + yield ['DROP TABLE [[customer]]', null, null]; + yield ['DROP TABLE IF EXISTS [[customer]]', true, null]; + yield ['DROP TABLE [[customer]]', false, null]; + yield ['DROP TABLE [[customer]] CASCADE', null, true]; + yield ['DROP TABLE [[customer]]', null, false]; + yield ['DROP TABLE [[customer]]', false, false]; + yield ['DROP TABLE IF EXISTS [[customer]] CASCADE', true, true]; + yield ['DROP TABLE IF EXISTS [[customer]]', true, false]; + yield ['DROP TABLE [[customer]] CASCADE', false, true]; + } + #[DataProvider('dataDropTable')] + public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void + { + $db = $this->getConnection(); $qb = $db->getQueryBuilder(); - $this->assertSame( - DbHelper::replaceQuotes( - <<getDriverName(), - ), - $qb->dropTable('customer'), - ); + if ($ifExists === null && $cascade === null) { + $sql = $qb->dropTable('customer'); + } elseif ($ifExists === null) { + $sql = $qb->dropTable('customer', cascade: $cascade); + } elseif ($cascade === null) { + $sql = $qb->dropTable('customer', ifExists: $ifExists); + } else { + $sql = $qb->dropTable('customer', ifExists: $ifExists, cascade: $cascade); + } + + $expectedSql = DbHelper::replaceQuotes($expected, $db->getDriverName()); + + $this->assertSame($expectedSql, $sql); } public function testDropUnique(): void diff --git a/tests/Common/CommonCommandTest.php b/tests/Common/CommonCommandTest.php index 62f0b1dc5..fc97d3785 100644 --- a/tests/Common/CommonCommandTest.php +++ b/tests/Common/CommonCommandTest.php @@ -915,11 +915,6 @@ public function testDropPrimaryKey(): void $db->close(); } - /** - * @throws Exception - * @throws InvalidConfigException - * @throws Throwable - */ public function testDropTable(): void { $db = $this->getConnection(); diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index 0ff505839..463ffcc81 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -4,6 +4,7 @@ namespace Yiisoft\Db\Tests\Db\Command; +use PHPUnit\Framework\Attributes\DataProvider; use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Exception\NotSupportedException; @@ -459,22 +460,38 @@ public function testDropView(): void ); } - public function testDropTable(): void + public static function dataDropTable(): iterable { - $db = $this->getConnection(); + yield ['DROP TABLE [[table]]', null, null]; + yield ['DROP TABLE IF EXISTS [[table]]', true, null]; + yield ['DROP TABLE [[table]]', false, null]; + yield ['DROP TABLE [[table]] CASCADE', null, true]; + yield ['DROP TABLE [[table]]', null, false]; + yield ['DROP TABLE [[table]]', false, false]; + yield ['DROP TABLE IF EXISTS [[table]] CASCADE', true, true]; + yield ['DROP TABLE IF EXISTS [[table]]', true, false]; + yield ['DROP TABLE [[table]] CASCADE', false, true]; + } + #[DataProvider('dataDropTable')] + public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void + { + $db = $this->getConnection(); $command = $db->createCommand(); - $sql = $command->dropTable('table')->getSql(); - $this->assertSame( - DbHelper::replaceQuotes( - <<getDriverName(), - ), - $sql, - ); + if ($ifExists === null && $cascade === null) { + $command = $command->dropTable('table'); + } elseif ($ifExists === null) { + $command = $command->dropTable('table', cascade: $cascade); + } elseif ($cascade === null) { + $command = $command->dropTable('table', ifExists: $ifExists); + } else { + $command = $command->dropTable('table', ifExists: $ifExists, cascade: $cascade); + } + + $expectedSql = DbHelper::replaceQuotes($expected, $db->getDriverName()); + + $this->assertSame($expectedSql, $command->getSql()); } public function testDropUnique(): void From acbff3acadd56a39b4aa686381f26076636335de Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Thu, 19 Sep 2024 08:46:43 +0300 Subject: [PATCH 2/7] Update CHANGELOG.md Co-authored-by: Sergei Tigrov --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71739e15a..4f751f868 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ - Enh #877: Separate column type constants (@Tigrov) - Enh #878: Realize `ColumnBuilder` class (@Tigrov) - New #773: Add parameters `$ifExists` and `$cascade` to `CommandInterface::dropTable()` and - `DDLQueryBuilderInterface::dropTable()` methods (@Tigrov) + `DDLQueryBuilderInterface::dropTable()` methods (@vjik) ## 1.3.0 March 21, 2024 From 21ea40072674b14799792ba39f4e21481cac86b8 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 23 Sep 2024 10:07:11 +0300 Subject: [PATCH 3/7] Move data provider --- tests/Db/Command/CommandTest.php | 16 ++-------------- tests/Provider/CommandProvider.php | 13 +++++++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index 463ffcc81..689d81caf 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -10,6 +10,7 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Schema\Builder\ColumnInterface; use Yiisoft\Db\Tests\AbstractCommandTest; +use Yiisoft\Db\Tests\Provider\CommandProvider; use Yiisoft\Db\Tests\Support\Assert; use Yiisoft\Db\Tests\Support\DbHelper; use Yiisoft\Db\Tests\Support\TestTrait; @@ -460,20 +461,7 @@ public function testDropView(): void ); } - public static function dataDropTable(): iterable - { - yield ['DROP TABLE [[table]]', null, null]; - yield ['DROP TABLE IF EXISTS [[table]]', true, null]; - yield ['DROP TABLE [[table]]', false, null]; - yield ['DROP TABLE [[table]] CASCADE', null, true]; - yield ['DROP TABLE [[table]]', null, false]; - yield ['DROP TABLE [[table]]', false, false]; - yield ['DROP TABLE IF EXISTS [[table]] CASCADE', true, true]; - yield ['DROP TABLE IF EXISTS [[table]]', true, false]; - yield ['DROP TABLE [[table]] CASCADE', false, true]; - } - - #[DataProvider('dataDropTable')] + #[DataProvider(CommandProvider::class.'::dropTable')] public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void { $db = $this->getConnection(); diff --git a/tests/Provider/CommandProvider.php b/tests/Provider/CommandProvider.php index 6c6dfc84a..e2afcdd41 100644 --- a/tests/Provider/CommandProvider.php +++ b/tests/Provider/CommandProvider.php @@ -926,4 +926,17 @@ public static function columnTypes(): array [new Column('string(100)')], ]; } + + public static function dropTable(): iterable + { + yield ['DROP TABLE [[table]]', null, null]; + yield ['DROP TABLE IF EXISTS [[table]]', true, null]; + yield ['DROP TABLE [[table]]', false, null]; + yield ['DROP TABLE [[table]] CASCADE', null, true]; + yield ['DROP TABLE [[table]]', null, false]; + yield ['DROP TABLE [[table]]', false, false]; + yield ['DROP TABLE IF EXISTS [[table]] CASCADE', true, true]; + yield ['DROP TABLE IF EXISTS [[table]]', true, false]; + yield ['DROP TABLE [[table]] CASCADE', false, true]; + } } From d0fbd2ceb566e8c5cfd97323cf5a44f5ca9323d3 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 23 Sep 2024 07:08:02 +0000 Subject: [PATCH 4/7] Apply fixes from StyleCI --- tests/Db/Command/CommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index 689d81caf..d924374ea 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -461,7 +461,7 @@ public function testDropView(): void ); } - #[DataProvider(CommandProvider::class.'::dropTable')] + #[DataProvider(CommandProvider::class . '::dropTable')] public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void { $db = $this->getConnection(); From 93337ccdd2fa98da2143c7bfe03b8efab3dd904a Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 23 Sep 2024 10:12:51 +0300 Subject: [PATCH 5/7] fix --- tests/Db/Command/CommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index d924374ea..7aef735c4 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -461,7 +461,7 @@ public function testDropView(): void ); } - #[DataProvider(CommandProvider::class . '::dropTable')] + #[DataProvider('\Yiisoft\Db\Tests\Provider\CommandProvider::dropTable')] public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void { $db = $this->getConnection(); From e138b9f3769f5a7fe11b784cbcf9e6167c9e8c68 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Mon, 23 Sep 2024 07:13:03 +0000 Subject: [PATCH 6/7] Apply fixes from StyleCI --- tests/Db/Command/CommandTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index 7aef735c4..b1bef6fc9 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -10,7 +10,6 @@ use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Schema\Builder\ColumnInterface; use Yiisoft\Db\Tests\AbstractCommandTest; -use Yiisoft\Db\Tests\Provider\CommandProvider; use Yiisoft\Db\Tests\Support\Assert; use Yiisoft\Db\Tests\Support\DbHelper; use Yiisoft\Db\Tests\Support\TestTrait; From d6acceafc312d56e9fe6d2a0ab64215361bf54c0 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Mon, 23 Sep 2024 10:18:38 +0300 Subject: [PATCH 7/7] fix --- tests/Db/Command/CommandTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index b1bef6fc9..c3205086a 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -4,12 +4,13 @@ namespace Yiisoft\Db\Tests\Db\Command; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\DataProviderExternal; use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Exception\NotSupportedException; use Yiisoft\Db\Schema\Builder\ColumnInterface; use Yiisoft\Db\Tests\AbstractCommandTest; +use Yiisoft\Db\Tests\Provider\CommandProvider; use Yiisoft\Db\Tests\Support\Assert; use Yiisoft\Db\Tests\Support\DbHelper; use Yiisoft\Db\Tests\Support\TestTrait; @@ -460,7 +461,7 @@ public function testDropView(): void ); } - #[DataProvider('\Yiisoft\Db\Tests\Provider\CommandProvider::dropTable')] + #[DataProviderExternal(CommandProvider::class, 'dropTable')] public function testDropTable(string $expected, ?bool $ifExists, ?bool $cascade): void { $db = $this->getConnection();