diff --git a/psalm.xml b/psalm.xml
index 5001d0a7..fc577119 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -15,6 +15,7 @@
+
diff --git a/src/Column.php b/src/Column.php
index 1ce3b73e..d408ec7e 100644
--- a/src/Column.php
+++ b/src/Column.php
@@ -6,6 +6,7 @@
use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\Schema\Builder\AbstractColumn;
+use Yiisoft\Db\Schema\Column\StringColumnSchema;
/**
* Provides a convenient way to create column schema for use with {@see Schema} for MSSQL Server.
@@ -21,6 +22,10 @@
*
* Provides a fluent interface, which means that the methods can be chained together to create a column schema with
* many properties in a single line of code.
+ *
+ * @psalm-suppress DeprecatedClass
+ *
+ * @deprecated Use {@see StringColumnSchema} or other column classes instead. Will be removed in 2.0.0.
*/
final class Column extends AbstractColumn
{
diff --git a/src/Column/ColumnDefinitionBuilder.php b/src/Column/ColumnDefinitionBuilder.php
index 82698f69..737bc161 100644
--- a/src/Column/ColumnDefinitionBuilder.php
+++ b/src/Column/ColumnDefinitionBuilder.php
@@ -49,6 +49,13 @@ public function build(ColumnSchemaInterface $column): string
. $this->buildExtra($column);
}
+ public function buildAlter(ColumnSchemaInterface $column): string
+ {
+ return $this->buildType($column)
+ . $this->buildNotNull($column)
+ . $this->buildExtra($column);
+ }
+
protected function getDbType(ColumnSchemaInterface $column): string
{
$size = $column->getSize();
diff --git a/src/DDLQueryBuilder.php b/src/DDLQueryBuilder.php
index a9f2685f..87b9ee3a 100644
--- a/src/DDLQueryBuilder.php
+++ b/src/DDLQueryBuilder.php
@@ -8,11 +8,13 @@
use Throwable;
use Yiisoft\Db\Exception\InvalidArgumentException;
use Yiisoft\Db\Exception\NotSupportedException;
-use Yiisoft\Db\Expression\Expression;
use Yiisoft\Db\QueryBuilder\AbstractDDLQueryBuilder;
use Yiisoft\Db\Schema\Builder\ColumnInterface;
+use Yiisoft\Db\Schema\Column\ColumnSchemaInterface;
use function array_diff;
+use function implode;
+use function preg_replace;
/**
* Implements a (Data Definition Language) SQL statements for MSSQL Server.
@@ -51,45 +53,45 @@ public function addDefaultValue(string $table, string $name, string $column, mix
/**
* @throws Exception
*/
- public function alterColumn(string $table, string $column, ColumnInterface|string $type): string
+ public function alterColumn(string $table, string $column, ColumnInterface|ColumnSchemaInterface|string $type): string
{
- $sqlAfter = [];
$columnName = $this->quoter->quoteColumnName($column);
$tableName = $this->quoter->quoteTableName($table);
- $constraintBase = preg_replace('/[^a-z0-9_]/i', '', $table . '_' . $column);
+ $constraintBase = preg_replace('/\W/', '', $table . '_' . $column);
if ($type instanceof ColumnInterface) {
- $type->setFormat('{type}{length}{notnull}{append}');
-
- /** @psalm-var mixed $defaultValue */
- $defaultValue = $type->getDefault();
- if ($defaultValue !== null || $type->isNotNull() === false) {
- $sqlAfter[] = $this->addDefaultValue(
- $table,
- "DF_{$constraintBase}",
- $column,
- $defaultValue instanceof Expression ? $defaultValue : new Expression((string)$defaultValue)
- );
- }
-
- $checkValue = $type->getCheck();
- if ($checkValue !== null) {
- $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " .
- $this->quoter->quoteColumnName("CK_{$constraintBase}") .
- ' CHECK (' . ($defaultValue instanceof Expression ? $checkValue : new Expression($checkValue)) . ')';
- }
-
- if ($type->isUnique()) {
- $sqlAfter[] = "ALTER TABLE {$tableName} ADD CONSTRAINT " . $this->quoter->quoteColumnName("UQ_{$constraintBase}") . " UNIQUE ({$columnName})";
- }
+ $type = $type->asString();
}
- /** @psalm-suppress DeprecatedMethod */
- return implode("\n", [
+ if (is_string($type)) {
+ $type = $this->schema->getColumnFactory()->fromDefinition($type);
+ }
+
+ $columnDefinitionBuilder = $this->queryBuilder->getColumnDefinitionBuilder();
+ $statements = [
$this->dropConstraintsForColumn($table, $column, 'D'),
- "ALTER TABLE $tableName ALTER COLUMN $columnName {$this->queryBuilder->getColumnType($type)}",
- ...$sqlAfter,
- ]);
+ "ALTER TABLE $tableName ALTER COLUMN $columnName " . $columnDefinitionBuilder->buildAlter($type),
+ ];
+
+ if ($type->hasDefaultValue()) {
+ $defaultValue = $type->dbTypecast($type->getDefaultValue());
+ $statements[] = $this->addDefaultValue($table, "DF_$constraintBase", $column, $defaultValue);
+ }
+
+ $checkValue = $type->getCheck();
+ if (!empty($checkValue)) {
+ $statements[] = "ALTER TABLE $tableName ADD CONSTRAINT "
+ . $this->quoter->quoteColumnName("CK_$constraintBase")
+ . " CHECK ($checkValue)";
+ }
+
+ if ($type->isUnique()) {
+ $statements[] = "ALTER TABLE $tableName ADD CONSTRAINT "
+ . $this->quoter->quoteColumnName("UQ_$constraintBase")
+ . " UNIQUE ($columnName)";
+ }
+
+ return implode("\n", $statements);
}
/**
diff --git a/src/Schema.php b/src/Schema.php
index 06bc0686..53e1e77a 100644
--- a/src/Schema.php
+++ b/src/Schema.php
@@ -71,6 +71,7 @@ final class Schema extends AbstractPdoSchema
/** @deprecated Use {@see ColumnBuilder} instead. Will be removed in 2.0. */
public function createColumn(string $type, array|int|string|null $length = null): ColumnInterface
{
+ /** @psalm-suppress DeprecatedClass */
return new Column($type, $length);
}
@@ -229,7 +230,6 @@ protected function loadTableSchema(string $name): TableSchemaInterface|null
*/
protected function loadTablePrimaryKey(string $tableName): Constraint|null
{
- /** @psalm-var mixed $tablePrimaryKey */
$tablePrimaryKey = $this->loadTableConstraints($tableName, self::PRIMARY_KEY);
return $tablePrimaryKey instanceof Constraint ? $tablePrimaryKey : null;
}
@@ -247,7 +247,6 @@ protected function loadTablePrimaryKey(string $tableName): Constraint|null
*/
protected function loadTableForeignKeys(string $tableName): array
{
- /** @psalm-var mixed $tableForeignKeys */
$tableForeignKeys = $this->loadTableConstraints($tableName, self::FOREIGN_KEYS);
return is_array($tableForeignKeys) ? $tableForeignKeys : [];
}
@@ -320,7 +319,6 @@ protected function loadTableIndexes(string $tableName): array
*/
protected function loadTableUniques(string $tableName): array
{
- /** @psalm-var mixed $tableUniques */
$tableUniques = $this->loadTableConstraints($tableName, self::UNIQUES);
return is_array($tableUniques) ? $tableUniques : [];
}
@@ -338,7 +336,6 @@ protected function loadTableUniques(string $tableName): array
*/
protected function loadTableChecks(string $tableName): array
{
- /** @psalm-var mixed $tableCheck */
$tableCheck = $this->loadTableConstraints($tableName, self::CHECKS);
return is_array($tableCheck) ? $tableCheck : [];
}
@@ -356,7 +353,6 @@ protected function loadTableChecks(string $tableName): array
*/
protected function loadTableDefaultValues(string $tableName): array
{
- /** @psalm-var mixed $tableDefault */
$tableDefault = $this->loadTableConstraints($tableName, self::DEFAULTS);
return is_array($tableDefault) ? $tableDefault : [];
}
diff --git a/tests/ColumnSchemaBuilderTest.php b/tests/ColumnSchemaBuilderTest.php
index fe1c5a0e..da490b0d 100644
--- a/tests/ColumnSchemaBuilderTest.php
+++ b/tests/ColumnSchemaBuilderTest.php
@@ -15,12 +15,4 @@
final class ColumnSchemaBuilderTest extends CommonColumnSchemaBuilderTest
{
use TestTrait;
-
- /**
- * @dataProvider \Yiisoft\Db\Mssql\Tests\Provider\ColumnSchemaBuilderProvider::createColumnTypes()
- */
- public function testCreateColumnTypes(string $expected, string $type, ?int $length, array $calls): void
- {
- parent::testCreateColumnTypes($expected, $type, $length, $calls);
- }
}
diff --git a/tests/Provider/ColumnSchemaBuilderProvider.php b/tests/Provider/ColumnSchemaBuilderProvider.php
deleted file mode 100644
index 5f7b2d18..00000000
--- a/tests/Provider/ColumnSchemaBuilderProvider.php
+++ /dev/null
@@ -1,29 +0,0 @@
- '[\\]',
];
+ public static function alterColumn(): array
+ {
+ return [
+ [
+ 'varchar(255)',
+ <<notNull(),
+ <<check('LEN(bar) > 5'),
+ << 5)
+ SQL,
+ ], [
+ ColumnBuilder::string()->defaultValue(''),
+ <<defaultValue('AbCdE'),
+ <<defaultValue(new Expression('CURRENT_TIMESTAMP')),
+ <<unique(),
+ <<assertSame($testData, $resultData['blob_col']);
}
- /**
- * @throws Exception
- * @throws InvalidConfigException
- */
- public function testAlterColumn(): void
+ #[DataProviderExternal(QueryBuilderProvider::class, 'alterColumn')]
+ public function testAlterColumn(string|ColumnSchemaInterface $type, string $expected): void
{
- $db = $this->getConnection(true);
-
- $qb = $db->getQueryBuilder();
-
- $expected = <<alterColumn('foo1', 'bar', 'varchar(255)');
- $this->assertEquals($expected, $sql);
-
- $expected = <<alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::STRING, 255))->notNull()
- );
- $this->assertEquals($expected, $sql);
-
- $expected = << 5)
- SQL;
- $sql = $qb->alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::STRING, 255))->check('LEN(bar) > 5')
- );
- $this->assertEquals($expected, $sql);
-
- $expected = <<alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::STRING, 255))->defaultValue('')
- );
- $this->assertEquals($expected, $sql);
-
- $expected = <<alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::STRING, 255))->defaultValue('AbCdE')
- );
- $this->assertEquals($expected, $sql);
-
- $expected = <<alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::TIMESTAMP))->defaultExpression('CURRENT_TIMESTAMP')
- );
- $this->assertEquals($expected, $sql);
-
- $expected = <<alterColumn(
- 'foo1',
- 'bar',
- (new Column(ColumnType::STRING, 30))->unique()
- );
- $this->assertEquals($expected, $sql);
+ parent::testAlterColumn($type, $expected);
}
/**
@@ -856,7 +637,7 @@ public function testAlterColumnOnDb(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::STRING, 128))->notNull()
+ ColumnBuilder::string(128)->notNull()
);
$db->createCommand($sql)->execute();
$schema = $db->getTableSchema('[foo1]', true);
@@ -868,11 +649,11 @@ public function testAlterColumnOnDb(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::TIMESTAMP))->defaultExpression('CURRENT_TIMESTAMP')
+ ColumnBuilder::timestamp()->defaultValue(new Expression('CURRENT_TIMESTAMP'))
);
$db->createCommand($sql)->execute();
$schema = $db->getTableSchema('[foo1]', true);
- $this->assertSame(ColumnType::DATETIME, $schema?->getColumn('bar')->getDbType());
+ $this->assertSame('datetime2', $schema?->getColumn('bar')->getDbType());
$this->assertEquals(new Expression('getdate()'), $schema?->getColumn('bar')->getDefaultValue());
}
@@ -888,7 +669,7 @@ public function testAlterColumnWithCheckConstraintOnDb(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::STRING, 128))->null()->check('LEN(bar) > 5')
+ ColumnBuilder::string(128)->null()->check('LEN(bar) > 5')
);
$db->createCommand($sql)->execute();
$schema = $db->getTableSchema('[foo1]', true);
@@ -912,7 +693,7 @@ public function testAlterColumnWithCheckConstraintOnDbWithException(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::STRING, 64))->check('LEN(bar) > 5')
+ ColumnBuilder::string(64)->check('LEN(bar) > 5')
);
$db->createCommand($sql)->execute();
@@ -933,7 +714,7 @@ public function testAlterColumnWithUniqueConstraintOnDbWithException(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::STRING, 64))->unique()
+ ColumnBuilder::string(64)->unique()
);
$db->createCommand($sql)->execute();
@@ -1017,7 +798,7 @@ public function testDropColumnOnDb(): void
$sql = $db->getQueryBuilder()->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::STRING, 64))
+ ColumnBuilder::string(64)
->defaultValue('')
->check('LEN(bar) < 5')
->unique()
@@ -1067,7 +848,7 @@ public function testAlterColumnWithNull(): void
$sql = $qb->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::INTEGER))->null()->defaultValue(null)
+ ColumnBuilder::integer()->null()->defaultValue(null)
);
$this->assertEquals($expected, $sql);
@@ -1093,13 +874,13 @@ public function testAlterColumnWithNull(): void
IF @constraintName IS NULL BREAK
EXEC (N'ALTER TABLE ' + @tableName + ' DROP CONSTRAINT [' + @constraintName + ']')
END
- ALTER TABLE [foo1] ALTER COLUMN [bar] int NULL
+ ALTER TABLE [foo1] ALTER COLUMN [bar] int
ALTER TABLE [foo1] ADD CONSTRAINT [DF_foo1_bar] DEFAULT NULL FOR [bar]
SQL;
$sql = $qb->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::INTEGER))->defaultValue(null)
+ ColumnBuilder::integer()->defaultValue(null)
);
$this->assertEquals($expected, $sql);
}
@@ -1140,7 +921,7 @@ public function testAlterColumnWithExpression(): void
$sql = $qb->alterColumn(
'foo1',
'bar',
- (new Column(ColumnType::INTEGER))
+ ColumnBuilder::integer()
->null()
->defaultValue(new Expression('CAST(GETDATE() AS INT)'))
);