Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow ColumnInterface as column type #766

Merged
merged 13 commits into from
Apr 7, 2024
2 changes: 1 addition & 1 deletion src/Command/AbstractCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function addCheck(string $table, string $name, string $expression): stati
return $this->setSql($sql)->requireTableSchemaRefresh($table);
}

public function addColumn(string $table, string $column, string $type): static
public function addColumn(string $table, string $column, ColumnInterface|string $type): static
{
$sql = $this->getQueryBuilder()->addColumn($table, $column, $type);
return $this->setSql($sql)->requireTableSchemaRefresh($table);
Expand Down
7 changes: 4 additions & 3 deletions src/Command/CommandInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ public function addCheck(string $table, string $name, string $expression): stati
*
* @param string $table The name of the table to add new column to.
* @param string $column The name of the new column.
* @param string $type The column type. {@see QueryBuilder::getColumnType()} will be called to convert the given
* column type to the database one.
* @param ColumnInterface|string $type The column type. {@see QueryBuilder::getColumnType()} will be called
* to convert the given column type to the database one.
* For example, `string` will be converted to `varchar(255)`, and `string not null` becomes `varchar(255) not null`.
*
* Note: The method will quote the `table` and `column` parameters before using them in the generated SQL.
*/
public function addColumn(string $table, string $column, string $type): static;
public function addColumn(string $table, string $column, ColumnInterface|string $type): static;

/**
* Builds an SQL command for adding a comment to a column.
Expand Down Expand Up @@ -306,6 +306,7 @@ public function createIndex(
*
* @param string $table The name of the table to create.
* @param array $columns The columns (name => definition) in the new table.
* The definition can be `string` or {@see ColumnInterface} instance.
* @param string|null $options More SQL fragments to append to the generated SQL.
*
* @throws Exception
Expand Down
2 changes: 1 addition & 1 deletion src/Debug/CommandInterfaceProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function addCheck(string $table, string $name, string $expression): stati
/**
* @psalm-suppress MixedArgument
*/
public function addColumn(string $table, string $column, string $type): static
public function addColumn(string $table, string $column, ColumnInterface|string $type): static
{
return new self($this->decorated->{__FUNCTION__}(...func_get_args()), $this->collector);
}
Expand Down
5 changes: 3 additions & 2 deletions src/QueryBuilder/AbstractDDLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function addCheck(string $table, string $name, string $expression): strin
. ' CHECK (' . $this->quoter->quoteSql($expression) . ')';
}

public function addColumn(string $table, string $column, string $type): string
public function addColumn(string $table, string $column, ColumnInterface|string $type): string
{
return 'ALTER TABLE '
. $this->quoter->quoteTableName($table)
Expand Down Expand Up @@ -169,14 +169,15 @@ public function createTable(string $table, array $columns, string $options = nul
{
$cols = [];

/** @psalm-var string[] $columns */
/** @psalm-var array<string, ColumnInterface>|string[] $columns */
vjik marked this conversation as resolved.
Show resolved Hide resolved
foreach ($columns as $name => $type) {
if (is_string($name)) {
$cols[] = "\t"
. $this->quoter->quoteColumnName($name)
. ' '
. $this->queryBuilder->getColumnType($type);
} else {
/** @psalm-var string $type */
$cols[] = "\t" . $type;
vjik marked this conversation as resolved.
Show resolved Hide resolved
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/QueryBuilder/AbstractQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function addCheck(string $table, string $name, string $expression): strin
return $this->ddlBuilder->addCheck($table, $name, $expression);
}

public function addColumn(string $table, string $column, string $type): string
public function addColumn(string $table, string $column, ColumnInterface|string $type): string
{
return $this->ddlBuilder->addColumn($table, $column, $type);
}
Expand Down
5 changes: 3 additions & 2 deletions src/QueryBuilder/DDLQueryBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function addCheck(string $table, string $name, string $expression): strin
*
* @param string $table The table to add the new column will to.
* @param string $column The name of the new column.
* @param string $type The column type.
* @param ColumnInterface|string $type The column type.
* {@see getColumnType()} Method will be invoked to convert an abstract column type (if any) into the physical one.
* Anything that isn't recognized as an abstract type will be kept in the generated SQL.
* For example, 'string' will be turned into 'varchar(255)', while 'string not null' will become
Expand All @@ -46,7 +46,7 @@ public function addCheck(string $table, string $name, string $expression): strin
*
* Note: The method will quote the `table` and `column` parameters before using them in the generated SQL.
*/
public function addColumn(string $table, string $column, string $type): string;
public function addColumn(string $table, string $column, ColumnInterface|string $type): string;

/**
* Builds an SQL command for adding comment to column.
Expand Down Expand Up @@ -233,6 +233,7 @@ public function createIndex(
*
* @param string $table The name of the table to create.
* @param array $columns The columns (name => definition) in the new table.
* The definition can be `string` or {@see ColumnInterface} instance.
* @param string|null $options More SQL fragments to append to the generated SQL.
*
* @return string The SQL statement for creating a new DB table.
Expand Down
8 changes: 5 additions & 3 deletions tests/AbstractQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Query\QueryInterface;
use Yiisoft\Db\QueryBuilder\Condition\SimpleCondition;
use Yiisoft\Db\Schema\Builder\ColumnInterface;
use Yiisoft\Db\Schema\QuoterInterface;
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Tests\Support\Assert;
Expand Down Expand Up @@ -52,18 +53,19 @@ public function testAddCheck(): void
);
}

public function testAddColumn(): void
/** @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::columnTypes */
public function testAddColumn(ColumnInterface|string $type): void
{
$db = $this->getConnection();

$qb = $db->getQueryBuilder();
$sql = $qb->addColumn('table', 'column', SchemaInterface::TYPE_STRING);
$sql = $qb->addColumn('table', 'column', $type);

$this->assertSame(
DbHelper::replaceQuotes(
<<<SQL
ALTER TABLE [[table]] ADD [[column]]
SQL . ' ' . $qb->getColumnType(SchemaInterface::TYPE_STRING),
SQL . ' ' . $qb->getColumnType($type),
$db->getDriverName(),
),
$sql,
Expand Down
16 changes: 12 additions & 4 deletions tests/Common/CommonCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Tests\AbstractCommandTest;
use Yiisoft\Db\Tests\Support\Assert;
use Yiisoft\Db\Tests\Support\Stub\Column;
use Yiisoft\Db\Transaction\TransactionInterface;

use function call_user_func_array;
Expand Down Expand Up @@ -544,16 +545,23 @@ public function testCreateTable(): void

$command->createTable(
'{{testCreateTable}}',
['[[id]]' => SchemaInterface::TYPE_PK, '[[bar]]' => SchemaInterface::TYPE_INTEGER],
[
'[[id]]' => SchemaInterface::TYPE_PK,
'[[bar]]' => SchemaInterface::TYPE_INTEGER,
'[[name]]' => (new Column('string(100)'))->notNull(),
],
)->execute();
$command->insert('{{testCreateTable}}', ['[[bar]]' => 1])->execute();
$command->insert('{{testCreateTable}}', ['[[bar]]' => 1, '[[name]]' => 'Lilo'])->execute();
$records = $command->setSql(
<<<SQL
SELECT [[id]], [[bar]] FROM [[testCreateTable]];
SELECT [[id]], [[bar]], [[name]] FROM [[testCreateTable]];
SQL
)->queryAll();

$this->assertEquals([['id' => 1, 'bar' => 1]], $records);
$nameCol = $schema->getTableSchema('{{testCreateTable}}', true)->getColumn('name');

$this->assertFalse($nameCol->isAllowNull());
$this->assertEquals([['id' => 1, 'bar' => 1, 'name' => 'Lilo']], $records);

$db->close();
}
Expand Down
10 changes: 7 additions & 3 deletions tests/Db/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Db\Tests\Db\Command;

use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Schema\Builder\ColumnInterface;
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Tests\AbstractCommandTest;
use Yiisoft\Db\Tests\Support\Assert;
Expand Down Expand Up @@ -39,17 +40,20 @@ public function testAddCheck(): void
);
}

public function testAddColumn(): void
/** @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::columnTypes */
public function testAddColumn(ColumnInterface|string $type): void
{
$db = $this->getConnection();

$command = $db->createCommand();
$sql = $command->addColumn('table', 'column', SchemaInterface::TYPE_INTEGER)->getSql();
$sql = $command->addColumn('table', 'column', $type)->getSql();

$type = $db->getQueryBuilder()->getColumnType($type);
vjik marked this conversation as resolved.
Show resolved Hide resolved

$this->assertSame(
DbHelper::replaceQuotes(
<<<SQL
ALTER TABLE [[table]] ADD [[column]] integer
ALTER TABLE [[table]] ADD [[column]] {$type}
SQL,
$db->getDriverName(),
),
Expand Down
3 changes: 2 additions & 1 deletion tests/Db/QueryBuilder/QueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Yiisoft\Db\Query\QueryInterface;
use Yiisoft\Db\Tests\AbstractQueryBuilderTest;
use Yiisoft\Db\Tests\Support\DbHelper;
use Yiisoft\Db\Tests\Support\Stub\Column;
use Yiisoft\Db\Tests\Support\Stub\QueryBuilder;
use Yiisoft\Db\Tests\Support\Stub\Schema;
use Yiisoft\Db\Tests\Support\TestTrait;
Expand Down Expand Up @@ -115,7 +116,7 @@ public function testCreateTable(): void
[
'id' => 'pk',
'name' => 'string(255) NOT NULL',
'email' => 'string(255) NOT NULL',
'email' => (new Column('string(255)'))->notNull(),
'status' => 'integer NOT NULL',
'created_at' => 'datetime NOT NULL',
'UNIQUE test_email_unique (email)',
Expand Down
9 changes: 9 additions & 0 deletions tests/Provider/CommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Tests\Support\DbHelper;
use Yiisoft\Db\Tests\Support\Stub\Column;
use Yiisoft\Db\Tests\Support\TestTrait;

class CommandProvider
Expand Down Expand Up @@ -842,4 +843,12 @@ public static function upsert(): array
],
];
}

public static function columnTypes(): array
{
return [
[SchemaInterface::TYPE_INTEGER],
[new Column('string(100)')],
];
}
}
9 changes: 9 additions & 0 deletions tests/Provider/QueryBuilderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
use Yiisoft\Db\Schema\SchemaInterface;
use Yiisoft\Db\Tests\Support\DbHelper;
use Yiisoft\Db\Tests\Support\Stub\Column;
use Yiisoft\Db\Tests\Support\TestTrait;
use Yiisoft\Db\Tests\Support\TraversableObject;

Expand Down Expand Up @@ -1260,4 +1261,12 @@ public static function cteAliases(): array
'with extra space' => ['a(b,c,d) ', 'a(b,c,d) '],
];
}

public static function columnTypes(): array
{
return [
[SchemaInterface::TYPE_STRING],
[new Column('string(100)')],
];
}
}
Loading