diff --git a/CHANGELOG.md b/CHANGELOG.md index f0fe8660f..d85daff14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - Enh #905: Use `AbstractColumnDefinitionBuilder` to generate table column SQL representation (@Tigrov) - Enh #915: Remove `ColumnInterface` (@Tigrov) - Enh #917: Rename `ColumnSchemaInterface` to `ColumnInterface` (@Tigrov) +- Enh #919: Replace `name()` with immutable `withName()` method in `ColumnInterface` interface (@Tigrov) ## 1.3.0 March 21, 2024 diff --git a/UPGRADE.md b/UPGRADE.md index 2856ed75d..da8e9c863 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -75,7 +75,7 @@ and the following changes were made: - `getName()` method can return `string` or `null`; - `getPhpType()` method must return `string` PHP type of the column which used for generating related model properties; -- `name(string|null $name)` method is added; +- `withName(string|null $name)` method is added; - `check(string|null $check)` method is added; - `getCheck()` method is added; - `reference(ForeignKeyConstraint|null $reference)` method is added; diff --git a/src/QueryBuilder/AbstractDDLQueryBuilder.php b/src/QueryBuilder/AbstractDDLQueryBuilder.php index 57892c681..9d1667dc3 100644 --- a/src/QueryBuilder/AbstractDDLQueryBuilder.php +++ b/src/QueryBuilder/AbstractDDLQueryBuilder.php @@ -171,9 +171,13 @@ public function createTable(string $table, array $columns, string $options = nul $cols[] = "\t" . $this->quoter->quoteColumnName($name) . ' ' - . $this->queryBuilder->buildColumnDefinition($type); + . $this->queryBuilder->buildColumnDefinition( + $type instanceof ColumnInterface + ? $type->withName($name) + : $type + ); } else { - /** @psalm-var string $type */ + /** @var string $type */ $cols[] = "\t" . $type; } } diff --git a/src/Schema/Column/AbstractColumn.php b/src/Schema/Column/AbstractColumn.php index c873ebd23..5876136ab 100644 --- a/src/Schema/Column/AbstractColumn.php +++ b/src/Schema/Column/AbstractColumn.php @@ -203,10 +203,7 @@ public function getExtra(): string|null return $this->extra; } - /** - * @deprecated Will be removed in version 2.0. - * @psalm-mutation-free - */ + /** @psalm-mutation-free */ public function getName(): string|null { return $this->name; @@ -372,4 +369,11 @@ public function unsigned(bool $unsigned = true): static $this->unsigned = $unsigned; return $this; } + + public function withName(string|null $name): static + { + $new = clone $this; + $new->name = $name; + return $new; + } } diff --git a/src/Schema/Column/ColumnInterface.php b/src/Schema/Column/ColumnInterface.php index 7bee7cd00..96cea7c7e 100644 --- a/src/Schema/Column/ColumnInterface.php +++ b/src/Schema/Column/ColumnInterface.php @@ -198,7 +198,6 @@ public function getExtra(): string|null; /** * @return string|null The name of the column. * - * @deprecated Will be removed in version 2.0. * @psalm-mutation-free */ public function getName(): string|null; @@ -319,19 +318,6 @@ public function isUnique(): bool; */ public function isUnsigned(): bool; - /** - * Sets a name of the column. - * - * ```php - * $columns = [ - * 'id' => ColumnBuilder::primaryKey()->name('id'), - * ]; - * ``` - * - * @deprecated Will be removed in version 2.0. - */ - public function name(string|null $name): static; - /** * Whether the column is not nullable. * @@ -453,4 +439,15 @@ public function unique(bool $unique = true): static; * ``` */ public function unsigned(bool $unsigned = true): static; + + /** + * Returns a new instance with the specified name of the column. + * + * ```php + * $columns = [ + * 'id' => ColumnBuilder::primaryKey()->withName('id'), + * ]; + * ``` + */ + public function withName(string|null $name): static; } diff --git a/tests/Db/Command/CommandTest.php b/tests/Db/Command/CommandTest.php index d5a3f1797..c0d60227f 100644 --- a/tests/Db/Command/CommandTest.php +++ b/tests/Db/Command/CommandTest.php @@ -7,6 +7,7 @@ use Yiisoft\Db\Constant\ColumnType; use Yiisoft\Db\Constant\PseudoType; use Yiisoft\Db\Exception\NotSupportedException; +use Yiisoft\Db\Schema\Column\ColumnBuilder; use Yiisoft\Db\Schema\Column\ColumnInterface; use Yiisoft\Db\Tests\AbstractCommandTest; use Yiisoft\Db\Tests\Support\Assert; @@ -239,6 +240,7 @@ public function testCreateTable(): void \t[address] varchar(255) NOT NULL, \t[status] integer NOT NULL, \t[profile_id] integer NOT NULL, + \t[data] json CHECK (json_valid([data])), \t[created_at] timestamp NOT NULL, \t[updated_at] timestamp NOT NULL ) CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB @@ -250,6 +252,7 @@ public function testCreateTable(): void 'address' => ColumnType::STRING . '(255) NOT NULL', 'status' => ColumnType::INTEGER . ' NOT NULL', 'profile_id' => ColumnType::INTEGER . ' NOT NULL', + 'data' => ColumnBuilder::json(), 'created_at' => ColumnType::TIMESTAMP . ' NOT NULL', 'updated_at' => ColumnType::TIMESTAMP . ' NOT NULL', ]; diff --git a/tests/Db/Schema/Column/ColumnTest.php b/tests/Db/Schema/Column/ColumnTest.php index 4c89c73eb..68409aeb6 100644 --- a/tests/Db/Schema/Column/ColumnTest.php +++ b/tests/Db/Schema/Column/ColumnTest.php @@ -171,12 +171,15 @@ public function testName(): void $column = new Column(); $this->assertNull($column->getName()); - $this->assertSame($column, $column->name('test')); - $this->assertSame('test', $column->getName()); - $column->name(''); + $newColumn = $column->withName('test'); - $this->assertSame('', $column->getName()); + $this->assertNotSame($column, $newColumn); + $this->assertSame('test', $newColumn->getName()); + + $newColumn = $newColumn->withName(''); + + $this->assertSame('', $newColumn->getName()); } public function testNotNull(): void diff --git a/tests/Support/Stub/ColumnDefinitionBuilder.php b/tests/Support/Stub/ColumnDefinitionBuilder.php index 7cbe3c53d..b7446b640 100644 --- a/tests/Support/Stub/ColumnDefinitionBuilder.php +++ b/tests/Support/Stub/ColumnDefinitionBuilder.php @@ -36,6 +36,23 @@ final class ColumnDefinitionBuilder extends AbstractColumnDefinitionBuilder 'decimal', ]; + protected function buildCheck(ColumnInterface $column): string + { + $check = $column->getCheck(); + + if (empty($check)) { + $columnName = $column->getName(); + + if (!empty($columnName) && $column->getType() === ColumnType::JSON) { + return ' CHECK (json_valid(' . $this->queryBuilder->quoter()->quoteColumnName($columnName) . '))'; + } + + return ''; + } + + return " CHECK ($check)"; + } + protected function getDbType(ColumnInterface $column): string { return $column->getDbType() ?? match ($column->getType()) {