Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@
- Enh #919: Replace `name()` with immutable `withName()` method in `ColumnInterface` interface (@Tigrov)
- Enh #921: Move `DataType` class to `Yiisoft\Db\Constant` namespace (@Tigrov)
- Enh #926: Refactor `DbArrayHelper` (@Tigrov)
- Enh #920: Move index constants to the appropriate DBMS driver's `IndexType` and `IndexMethod` classes (@Tigrov)
- Enh #920: Move index constants to the appropriate DBMS driver's `IndexType` and `IndexMethod` classes (@Tigrov)
- New #928: Add `ReferentialAction` class with constants of possible values of referential actions (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
3 changes: 2 additions & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ and the following changes were made:
- `Yiisoft\Db\Constant\GettypeResult` with `gettype()` function results constants;
- `Yiisoft\Db\Constant\ColumnType` with abstract column types constants;
- `Yiisoft\Db\Constant\PseudoType` with column pseudo-types constants;
- `Yiisoft\Db\Constant\IndexType` with table index types.
- `Yiisoft\Db\Constant\IndexType` with table index types;
- `Yiisoft\Db\Constant\ReferentialAction` with possible values of referential actions.

### New classes for table columns

Expand Down
5 changes: 3 additions & 2 deletions docs/guide/en/command/ddl.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ method:

```php
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Constant\ReferentialAction;

/** @var ConnectionInterface $db */
$db->createCommand()->addForeignKey(
Expand All @@ -189,8 +190,8 @@ $db->createCommand()->addForeignKey(
'profile_id',
'{{%profile}}',
'id',
'CASCADE',
'CASCADE'
ReferentialAction::CASCADE,
ReferentialAction::CASCADE
)->execute();
```

Expand Down
5 changes: 3 additions & 2 deletions docs/guide/pt-BR/command/ddl.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ Para adicionar uma chave estrangeira a uma tabela existente, você pode usar o m

```php
use Yiisoft\Db\Connection\ConnectionInterface;
use Yiisoft\Db\Constant\ReferentialAction;

/** @var ConnectionInterface $db */
$db->createCommand()->addForeignKey(
Expand All @@ -185,8 +186,8 @@ $db->createCommand()->addForeignKey(
'profile_id',
'{{%profile}}',
'id',
'CASCADE',
'CASCADE'
ReferentialAction::CASCADE,
ReferentialAction::CASCADE
)->execute();
```

Expand Down
18 changes: 8 additions & 10 deletions src/Command/CommandInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Yiisoft\Db\Constant\DataType;
use Yiisoft\Db\Constant\IndexType;
use Yiisoft\Db\Constant\PseudoType;
use Yiisoft\Db\Constant\ReferentialAction;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidArgumentException;
use Yiisoft\Db\Exception\InvalidCallException;
Expand Down Expand Up @@ -99,8 +100,7 @@ public function addDefaultValue(string $table, string $name, string $column, mix

/**
* Creates an SQL command for adding a foreign key constraint to an existing table.
*
* The method will quote the table and column names.
* The method will quote the `name`, `table`, `referenceTable` parameters before using them in the generated SQL.
*
* @param string $table The name of the table to add foreign key constraint to.
* @param string $name The name of the foreign key constraint.
Expand All @@ -109,25 +109,23 @@ public function addDefaultValue(string $table, string $name, string $column, mix
* @param string $referenceTable The name of the table that the foreign key references to.
* @param array|string $referenceColumns The name of the column that the foreign key references to. If there are
* many columns, separate them with commas.
* @param string|null $delete The `ON DELETE` option. Most DBMS support these options: `RESTRICT`, `CASCADE`, `NO ACTION`,
* `SET DEFAULT`, `SET NULL`.
* @param string|null $update The `ON UPDATE` option. Most DBMS support these options: `RESTRICT`, `CASCADE`, `NO ACTION`,
* `SET DEFAULT`, `SET NULL`.
* @param string|null $delete The `ON DELETE` option. See {@see ReferentialAction} class for possible values.
* @param string|null $update The `ON UPDATE` option. See {@see ReferentialAction} class for possible values.
*
* @throws Exception
* @throws InvalidArgumentException
*
* Note: The method will quote the `name`, `table`, `referenceTable` parameters before using them in the generated
* SQL.
* @psalm-param ReferentialAction::*|null $delete
* @psalm-param ReferentialAction::*|null $update
*/
public function addForeignKey(
string $table,
string $name,
array|string $columns,
string $referenceTable,
array|string $referenceColumns,
string $delete = null,
string $update = null
string|null $delete = null,
string|null $update = null
): static;

/**
Expand Down
46 changes: 46 additions & 0 deletions src/Constant/ReferentialAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Constant;

/**
* `ReferentialAction` represents the possible foreign key actions that can be performed on the referenced table.
*
* The constants are used to specify `ON DELETE` and `ON UPDATE` actions by {@see ForeignKeyConstraint::onDelete()},
* {@see ForeignKeyConstraint::onUpdate()}, {@see DDLQueryBuilderInterface::addForeignKey()}
* and {@see CommandInterface::addForeignKey()}.
*
* MSSQL does not support `RESTRICT` keyword but uses this behavior by default (if no action is specified).
*
* Oracle supports only `CASCADE` and `SET NULL` key worlds and only `ON DELETE` clause.
* `NO ACTION` is used by default for `ON DELETE` and `ON UPDATE` (if no action is specified).
*/
final class ReferentialAction
{
/**
* @var string Used when the referenced rows are not deleted or updated. If rows of the referenced table are used
* by rows of the referencing table, an error is thrown. This is the default behavior.
*/
public const NO_ACTION = 'NO ACTION';
/**
* @var string Used when the referenced rows cannot be deleted or updated. For example, if rows of the referenced
* table are used by rows of the referencing table, it is not permitted to delete those rows from the referenced table.
* This is similar to {@see NO_ACTION}, but is not used by some DBMSs.
*/
public const RESTRICT = 'RESTRICT';
/**
* @var string Used when the referenced row is deleted or updated and all rows that reference it are deleted
* or updated accordingly.
*/
public const CASCADE = 'CASCADE';
/**
* @var string Used when the rows that refer to the deleted or updated row are set to `NULL`.
* If columns are defined as `NOT NULL`, an error is thrown.
*/
public const SET_NULL = 'SET NULL';
/**
* @var string Used when the rows that refer to the deleted or updated row are set to their default values.
*/
public const SET_DEFAULT = 'SET DEFAULT';
}
14 changes: 14 additions & 0 deletions src/Constraint/ForeignKeyConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Yiisoft\Db\Constraint;

use Yiisoft\Db\Constant\ReferentialAction;

/**
* Represents a foreign key constraint in a database.
*
Expand All @@ -17,7 +19,9 @@ final class ForeignKeyConstraint extends Constraint
private string|null $foreignSchemaName = null;
private string|null $foreignTableName = null;
private array $foreignColumnNames = [];
/** @psalm-var ReferentialAction::*|null */
private string|null $onUpdate = null;
/** @psalm-var ReferentialAction::*|null */
private string|null $onDelete = null;

/**
Expand Down Expand Up @@ -46,6 +50,8 @@ public function getForeignColumnNames(): array

/**
* @return string|null The referential action if rows in a referenced table are to be updated.
*
* @psalm-return ReferentialAction::*|null
*/
public function getOnUpdate(): string|null
{
Expand All @@ -54,6 +60,8 @@ public function getOnUpdate(): string|null

/**
* @return string|null The referential action if rows in a referenced table are to be deleted.
*
* @psalm-return ReferentialAction::*|null
*/
public function getOnDelete(): string|null
{
Expand Down Expand Up @@ -97,6 +105,9 @@ public function foreignColumnNames(array $value): self
* Set the referential action if rows in a referenced table are to be updated.
*
* @param string|null $value The referential action if rows in a referenced table are to be updated.
* See {@see ReferentialAction} class for possible values.
*
* @psalm-param ReferentialAction::*|null $value
*/
public function onUpdate(string|null $value): self
{
Expand All @@ -108,6 +119,9 @@ public function onUpdate(string|null $value): self
* Set the referential action if rows in a referenced table are to be deleted.
*
* @param string|null $value The referential action if rows in a referenced table are to be deleted.
* See {@see ReferentialAction} class for possible values.
*
* @psalm-param ReferentialAction::*|null $value
*/
public function onDelete(string|null $value): self
{
Expand Down
5 changes: 5 additions & 0 deletions src/QueryBuilder/AbstractColumnDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Db\QueryBuilder;

use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\Constant\ReferentialAction;
use Yiisoft\Db\Schema\Column\ColumnInterface;

use function in_array;
Expand Down Expand Up @@ -231,6 +232,8 @@ protected function buildReferenceDefinition(ColumnInterface $column): string|nul

/**
* Builds the ON DELETE clause for the column reference.
*
* @psalm-param ReferentialAction::* $onDelete
*/
protected function buildOnDelete(string $onDelete): string
{
Expand All @@ -239,6 +242,8 @@ protected function buildOnDelete(string $onDelete): string

/**
* Builds the ON UPDATE clause for the column reference.
*
* @psalm-param ReferentialAction::* $onUpdate
*/
protected function buildOnUpdate(string $onUpdate): string
{
Expand Down
11 changes: 6 additions & 5 deletions src/QueryBuilder/DDLQueryBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Db\QueryBuilder;

use Yiisoft\Db\Constant\IndexType;
use Yiisoft\Db\Constant\ReferentialAction;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\InvalidArgumentException;
use Yiisoft\Db\Exception\InvalidConfigException;
Expand Down Expand Up @@ -103,6 +104,7 @@ public function addDefaultValue(string $table, string $name, string $column, mix

/**
* Builds an SQL statement for adding a foreign key constraint to an existing table.
* The method will quote the `name`, `table`, `referenceTable` parameters before using them in the generated SQL.
*
* @param string $table The table to add the foreign key constraint will to.
* @param string $name The name of the foreign key constraint.
Expand All @@ -111,17 +113,16 @@ public function addDefaultValue(string $table, string $name, string $column, mix
* @param string $referenceTable The table that the foreign key references to.
* @param array|string $referenceColumns The name of the column that the foreign key references to.
* If there are many columns, separate them with commas or use an array to represent them.
* @param string|null $delete The `ON DELETE` option. Most DBMS support these options: `RESTRICT`, `CASCADE`, `NO ACTION`,
* `SET DEFAULT`, `SET NULL`.
* @param string|null $update The `ON UPDATE` option. Most DBMS support these options: `RESTRICT`, `CASCADE`, `NO ACTION`,
* `SET DEFAULT`, `SET NULL`.
* @param string|null $delete The `ON DELETE` option. See {@see ReferentialAction} class for possible values.
* @param string|null $update The `ON UPDATE` option. See {@see ReferentialAction} class for possible values.
*
* @throws Exception
* @throws InvalidArgumentException
*
* @return string The SQL statement for adding a foreign key constraint to an existing table.
*
* Note: The method will quote the `name`, `table`, `referenceTable` parameters before using them in the generated SQL.
* @psalm-param ReferentialAction::*|null $delete
* @psalm-param ReferentialAction::*|null $update
*/
public function addForeignKey(
string $table,
Expand Down
14 changes: 8 additions & 6 deletions tests/Db/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,20 @@ public function testAddDefaultValue(): void
* @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::addForeignKeySql
*/
public function testAddForeignKeySql(
string $name,
string $tableName,
array|string $column1,
array|string $column2,
array|string $columns,
array|string $referenceColumns,
string|null $delete,
string|null $update,
string $expected
): void {
$db = $this->getConnection();

$command = $db->createCommand();
$sql = $command->addForeignKey($tableName, $name, $column1, $tableName, $column2, $delete, $update)->getSql();

$name = '{{fk_constraint}}';
$tableName = '{{fk_table}}';
$referenceTable = '{{fk_referenced_table}}';

$sql = $command->addForeignKey($tableName, $name, $columns, $referenceTable, $referenceColumns, $delete, $update)->getSql();

$this->assertSame($expected, $sql);
}
Expand Down
Loading