diff --git a/framework/db/ColumnSchemaBuilder.php b/framework/db/ColumnSchemaBuilder.php index bbf5f14590..510a20ba1b 100644 --- a/framework/db/ColumnSchemaBuilder.php +++ b/framework/db/ColumnSchemaBuilder.php @@ -102,6 +102,12 @@ class ColumnSchemaBuilder extends Object * @since 2.0.8 */ public $db; + /** + * @var mixed comment value of the column. + * @since 2.0.8 + */ + public $comment; + /** * Create a column schema builder instance giving the type and value precision. @@ -161,6 +167,18 @@ class ColumnSchemaBuilder extends Object return $this; } + /** + * Specify the comment for the column. + * @param string $comment the comment + * @return $this + * @since 2.0.8 + */ + public function comment($comment) + { + $this->comment = $comment; + return $this; + } + /** * Marks column as unsigned. * @return $this @@ -228,7 +246,7 @@ class ColumnSchemaBuilder extends Object $format = '{type}{check}'; break; default: - $format = '{type}{length}{notnull}{unique}{default}{check}'; + $format = '{type}{length}{notnull}{unique}{default}{check}{comment}'; } return $this->buildCompleteString($format); } @@ -366,7 +384,17 @@ class ColumnSchemaBuilder extends Object '{pos}' => ($this->isFirst) ? $this->buildFirstString() : $this->buildAfterString(), + '{comment}' => $this->buildCommentString(), ]; return strtr($format, $placeholderValues); } + + /** + * Builds the comment specification for the column. + * @return string with comment. + */ + protected function buildCommentString() + { + return $this->comment !== null ? " COMMENT '{$this->comment}'" : ''; + } } diff --git a/framework/db/Command.php b/framework/db/Command.php index 0e398fe405..10ab75677b 100644 --- a/framework/db/Command.php +++ b/framework/db/Command.php @@ -756,6 +756,62 @@ class Command extends Component return $this->setSql($sql); } + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnColumn($table, $column, $comment) + { + $sql = $this->db->getQueryBuilder()->addCommentOnColumn($table, $column, $comment); + + return $this->setSql($sql); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnTable($table, $comment) + { + $sql = $this->db->getQueryBuilder()->addCommentOnTable($table, $comment); + + return $this->setSql($sql); + } + + /** + * Builds a SQL command for dropping comment from column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromColumn($table, $column) + { + $sql = $this->db->getQueryBuilder()->dropCommentFromColumn($table, $column); + + return $this->setSql($sql); + } + + /** + * Builds a SQL command for dropping comment from table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromTable($table) + { + $sql = $this->db->getQueryBuilder()->dropCommentFromTable($table); + + return $this->setSql($sql); + } + /** * Executes the SQL statement. * This method should only be used for executing non-query SQL statement, such as `INSERT`, `DELETE`, `UPDATE` SQLs. diff --git a/framework/db/Migration.php b/framework/db/Migration.php index d118ce2ece..f840342b9f 100644 --- a/framework/db/Migration.php +++ b/framework/db/Migration.php @@ -259,6 +259,12 @@ class Migration extends Component implements MigrationInterface $time = microtime(true); $this->db->createCommand()->createTable($table, $columns, $options)->execute(); echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + foreach ($columns as $column => $type) { + if ($type instanceof ColumnSchemaBuilder && $type->comment !== null) { + $this->db->createCommand()->addCommentOnColumn($table, $column, $type->comment)->execute(); + } + } + echo " done (time: " . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } /** @@ -311,6 +317,9 @@ class Migration extends Component implements MigrationInterface echo " > add column $column $type to table $table ..."; $time = microtime(true); $this->db->createCommand()->addColumn($table, $column, $type)->execute(); + if ($type instanceof ColumnSchemaBuilder && $type->comment !== null) { + $this->db->createCommand()->addCommentOnColumn($table, $column, $type->comment)->execute(); + } echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } @@ -354,6 +363,10 @@ class Migration extends Component implements MigrationInterface echo " > alter column $column in table $table to $type ..."; $time = microtime(true); $this->db->createCommand()->alterColumn($table, $column, $type)->execute(); + if ($type instanceof ColumnSchemaBuilder && $type->comment !== null) { + $this->db->createCommand()->addCommentOnColumn($table, $column, $type->comment)->execute(); + } + echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } @@ -446,4 +459,68 @@ class Migration extends Component implements MigrationInterface $this->db->createCommand()->dropIndex($name, $table)->execute(); echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; } + + /** + * Builds and execute a SQL statement for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function addCommentOnColumn($table, $column, $comment) + { + echo " > add comment on column $column ..."; + $time = microtime(true); + $this->db->createCommand()->addCommentOnColumn($table, $column, $comment)->execute(); + echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + } + + /** + * Builds a SQL statement for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function addCommentOnTable($table, $comment) + { + echo " > add comment on table $table ..."; + $time = microtime(true); + $this->db->createCommand()->addCommentOnTable($table, $comment)->execute(); + echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + } + + /** + * Builds and execute a SQL statement for dropping comment from column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromColumn($table, $column) + { + echo " > drop comment from column $column ..."; + $time = microtime(true); + $this->db->createCommand()->dropCommentFromColumn($table, $column, $comment)->execute(); + echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + } + + /** + * Builds a SQL statement for dropping comment from table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromTable($table) + { + echo " > drop comment from table $table ..."; + $time = microtime(true); + $this->db->createCommand()->dropCommentFromTable($table, $comment)->execute(); + echo ' done (time: ' . sprintf('%.3f', microtime(true) - $time) . "s)\n"; + } } diff --git a/framework/db/QueryBuilder.php b/framework/db/QueryBuilder.php index 7d3509ebed..eb449c6842 100644 --- a/framework/db/QueryBuilder.php +++ b/framework/db/QueryBuilder.php @@ -568,6 +568,54 @@ class QueryBuilder extends \yii\base\Object throw new NotSupportedException($this->db->getDriverName() . ' does not support enabling/disabling integrity check.'); } + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnColumn($table, $column, $comment) + { + return 'COMMENT ON COLUMN ' . $this->db->quoteTableName($table) . '.' . $this->db->quoteColumnName($column) . ' IS ' . $this->db->quoteValue($comment); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnTable($table, $comment) + { + return 'COMMENT ON TABLE ' . $this->db->quoteTableName($table) . ' IS ' . $this->db->quoteValue($comment); + } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromColumn($table, $column) + { + return 'COMMENT ON COLUMN ' . $this->db->quoteTableName($table) . '.' . $this->db->quoteColumnName($column) . ' IS NULL'; + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromTable($table) + { + return 'COMMENT ON TABLE ' . $this->db->quoteTableName($table) . ' IS NULL'; + } + /** * Converts an abstract column type into a physical column type. * The conversion is done using the type map specified in [[typeMap]]. diff --git a/framework/db/cubrid/QueryBuilder.php b/framework/db/cubrid/QueryBuilder.php index 8d364e2645..e475d6f35c 100644 --- a/framework/db/cubrid/QueryBuilder.php +++ b/framework/db/cubrid/QueryBuilder.php @@ -8,6 +8,7 @@ namespace yii\db\cubrid; use yii\base\InvalidParamException; +use yii\db\Exception; /** * QueryBuilder is the query builder for CUBRID databases (version 9.3.x and higher). @@ -102,4 +103,119 @@ class QueryBuilder extends \yii\db\QueryBuilder { return 'SELECT CASE WHEN EXISTS(' . $rawSql . ') THEN 1 ELSE 0 END'; } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function addCommentOnColumn($table, $column, $comment) + { + $quotedTable = $this->db->quoteTableName($table); + $definition = $this->getColumnDefinition($quotedTable, $column); + $definition = trim(preg_replace("/COMMENT '(.*?)'/i", '', $definition)); + return sprintf( + 'ALTER TABLE %s CHANGE %s %s%s COMMENT %s', + $quotedTable, + $this->db->quoteColumnName($column), + $this->db->quoteColumnName($column), + empty($definition) ? '' : ' ' . $definition, + $this->db->quoteValue($comment) + ); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function addCommentOnTable($table, $comment) + { + $quotedTable = $this->db->quoteTableName($table); + return sprintf( + 'ALTER TABLE %s COMMENT %s', + $quotedTable, + $this->db->quoteValue($comment) + ); + } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromColumn($table, $column) + { + $quotedTable = $this->db->quoteTableName($table); + $definition = $this->getColumnDefinition($quotedTable, $column); + $definition = trim(preg_replace("/COMMENT '(.*?)'/i", '', $definition)); + return sprintf( + 'ALTER TABLE %s CHANGE %s %s%s COMMENT \'\'', + $quotedTable, + $this->db->quoteColumnName($column), + $this->db->quoteColumnName($column), + empty($definition) ? '' : ' ' . $definition + ); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromTable($table) + { + $quotedTable = $this->db->quoteTableName($table); + return sprintf( + "ALTER TABLE %s COMMENT ''", + $quotedTable, + empty($definition) ? '' : ' ' . $definition + ); + } + + + /** + * Gets column definition. + * + * @param string $table table name + * @param string $column column name + * @return null|string the column definition + * @throws Exception in case when table does not contain column + * @since 2.0.8 + */ + private function getColumnDefinition($table, $column) + { + $row = $this->db->createCommand('SHOW CREATE TABLE ' . $table)->queryOne(); + if ($row === false) { + throw new Exception("Unable to find column '$column' in table '$table'."); + } + if (isset($row['Create Table'])) { + $sql = $row['Create Table']; + } else { + $row = array_values($row); + $sql = $row[1]; + } + $sql = preg_replace('/^[^(]+\((.*)\).*$/', '\1', $sql); + $sql = str_replace(', [', ",\n[", $sql); + if (preg_match_all('/^\s*\[(.*?)\]\s+(.*?),?$/m', $sql, $matches)) { + foreach ($matches[1] as $i => $c) { + if ($c === $column) { + return $matches[2][$i]; + } + } + } + return null; + } } diff --git a/framework/db/mssql/ColumnSchemaBuilder.php b/framework/db/mssql/ColumnSchemaBuilder.php new file mode 100644 index 0000000000..1e1ec92354 --- /dev/null +++ b/framework/db/mssql/ColumnSchemaBuilder.php @@ -0,0 +1,28 @@ + + * @since 2.0.6 + */ +class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder +{ + /** + * @inheritdoc + */ + + protected function buildCommentString() + { + return ''; + } +} diff --git a/framework/db/mssql/QueryBuilder.php b/framework/db/mssql/QueryBuilder.php index cf5c6764cc..8adc5a4591 100644 --- a/framework/db/mssql/QueryBuilder.php +++ b/framework/db/mssql/QueryBuilder.php @@ -186,6 +186,53 @@ class QueryBuilder extends \yii\db\QueryBuilder return "ALTER TABLE {$table} {$enable} CONSTRAINT ALL"; } + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnColumn($table, $column, $comment) + { + return "sp_updateextendedproperty @name = N'MS_Description', @value = {$this->db->quoteValue($comment)}, @level1type = N'Table', @level1name = {$this->db->quoteTableName($table)}, @level2type = N'Column', @level2name = {$this->db->quoteColumnName($column)}"; + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnTable($table, $comment) + { + return "sp_updateextendedproperty @name = N'MS_Description', @value = {$this->db->quoteValue($comment)}, @level1type = N'Table', @level1name = {$this->db->quoteTableName($table)}"; + } + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromColumn($table, $column) + { + return "sp_dropextendedproperty @name = N'MS_Description', @level1type = N'Table', @level1name = {$this->db->quoteTableName($table)}, @level2type = N'Column', @level2name = {$this->db->quoteColumnName($column)}"; + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromTable($table) + { + return "sp_dropextendedproperty @name = N'MS_Description', @level1type = N'Table', @level1name = {$this->db->quoteTableName($table)}"; + } + /** * Returns an array of column names given model name * diff --git a/framework/db/mssql/Schema.php b/framework/db/mssql/Schema.php index 2f372a3ef8..45c2e83d94 100644 --- a/framework/db/mssql/Schema.php +++ b/framework/db/mssql/Schema.php @@ -124,6 +124,14 @@ class Schema extends \yii\db\Schema return new QueryBuilder($this->db); } + /** + * @inheritdoc + */ + public function createColumnSchemaBuilder($type, $length = null) + { + return new ColumnSchemaBuilder($type, $length); + } + /** * Loads the metadata for the specified table. * @param string $name table name diff --git a/framework/db/mysql/QueryBuilder.php b/framework/db/mysql/QueryBuilder.php index e1b8de2edf..426eadbe2f 100644 --- a/framework/db/mysql/QueryBuilder.php +++ b/framework/db/mysql/QueryBuilder.php @@ -219,4 +219,112 @@ class QueryBuilder extends \yii\db\QueryBuilder . (!empty($names) ? ' (' . implode(', ', $names) . ')' : '') . (!empty($placeholders) ? ' VALUES (' . implode(', ', $placeholders) . ')' : ' DEFAULT VALUES'); } -} + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnColumn($table, $column, $comment) + { + $quotedTable = $this->db->quoteTableName($table); + $definition = $this->getColumnDefinition($quotedTable, $column); + $definition = trim(preg_replace("/COMMENT '(.*?)'/i", '', $definition)); + return sprintf( + 'ALTER TABLE %s CHANGE %s %s%s COMMENT %s', + $quotedTable, + $this->db->quoteColumnName($column), + $this->db->quoteColumnName($column), + empty($definition) ? '' : ' ' . $definition, + $this->db->quoteValue($comment) + ); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + */ + public function addCommentOnTable($table, $comment) + { + $quotedTable = $this->db->quoteTableName($table); + return sprintf( + 'ALTER TABLE %s COMMENT %s', + $quotedTable, + $this->db->quoteValue($comment) + ); + } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromColumn($table, $column) + { + $quotedTable = $this->db->quoteTableName($table); + $definition = $this->getColumnDefinition($quotedTable, $column); + $definition = trim(preg_replace("/COMMENT '(.*?)'/i", '', $definition)); + return sprintf( + 'ALTER TABLE %s CHANGE %s %s%s COMMENT \'\'', + $quotedTable, + $this->db->quoteColumnName($column), + $this->db->quoteColumnName($column), + empty($definition) ? '' : ' ' . $definition + ); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + */ + public function dropCommentFromTable($table) + { + $quotedTable = $this->db->quoteTableName($table); + return sprintf( + "ALTER TABLE %s COMMENT ''", + $quotedTable, + empty($definition) ? '' : ' ' . $definition + ); + } + + + /** + * Gets column definition. + * + * @param string $table table name + * @param string $column column name + * @return null|string the column definition + * @throws Exception in case when table does not contain column + */ + private function getColumnDefinition($table, $column) + { + $row = $this->db->createCommand('SHOW CREATE TABLE ' . $table)->queryOne(); + if ($row === false) { + throw new Exception("Unable to find column '$column' in table '$table'."); + } + if (isset($row['Create Table'])) { + $sql = $row['Create Table']; + } else { + $row = array_values($row); + $sql = $row[1]; + } + if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) { + foreach ($matches[1] as $i => $c) { + if ($c === $column) { + return $matches[2][$i]; + } + } + } + return null; + } +} \ No newline at end of file diff --git a/framework/db/oci/QueryBuilder.php b/framework/db/oci/QueryBuilder.php index cdede2c3c0..7ceb5cfd88 100644 --- a/framework/db/oci/QueryBuilder.php +++ b/framework/db/oci/QueryBuilder.php @@ -267,4 +267,29 @@ EOD; { return 'SELECT CASE WHEN EXISTS(' . $rawSql . ') THEN 1 ELSE 0 END FROM DUAL'; } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromColumn($table, $column) + { + return 'COMMENT ON COLUMN ' . $this->db->quoteTableName($table) . '.' . $this->db->quoteColumnName($column) . " IS ' '"; + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + * @since 2.0.8 + */ + public function dropCommentFromTable($table) + { + return 'COMMENT ON TABLE ' . $this->db->quoteTableName($table) . " IS ' '"; + } } diff --git a/framework/db/pgsql/ColumnSchemaBuilder.php b/framework/db/pgsql/ColumnSchemaBuilder.php new file mode 100644 index 0000000000..986ce28c4a --- /dev/null +++ b/framework/db/pgsql/ColumnSchemaBuilder.php @@ -0,0 +1,28 @@ + + * @since 2.0.6 + */ +class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder +{ + + /** + * @inheritdoc + */ + protected function buildCommentString() + { + return ''; + } +} diff --git a/framework/db/pgsql/Schema.php b/framework/db/pgsql/Schema.php index b83fdcdf17..320d669726 100644 --- a/framework/db/pgsql/Schema.php +++ b/framework/db/pgsql/Schema.php @@ -118,6 +118,14 @@ class Schema extends \yii\db\Schema return new QueryBuilder($this->db); } + /** + * @inheritdoc + */ + public function createColumnSchemaBuilder($type, $length = null) + { + return new ColumnSchemaBuilder($type, $length); + } + /** * Resolves the table name and schema name (if any). * @param TableSchema $table the table metadata object diff --git a/framework/db/sqlite/ColumnSchemaBuilder.php b/framework/db/sqlite/ColumnSchemaBuilder.php index 15396ba76c..4cc40ae9e9 100644 --- a/framework/db/sqlite/ColumnSchemaBuilder.php +++ b/framework/db/sqlite/ColumnSchemaBuilder.php @@ -43,4 +43,24 @@ class ColumnSchemaBuilder extends AbstractColumnSchemaBuilder } return $this->buildCompleteString($format); } + + /** + * Specify the comment for the column + * + * @param string $comment the comment + * @throws NotSupportedException this is not supported by SQLite + * @since 2.0.8 + */ + public function comment($comment) + { + throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); + } + + /** + * @inheritdoc + */ + protected function buildCommentString() + { + return ''; + } } diff --git a/framework/db/sqlite/QueryBuilder.php b/framework/db/sqlite/QueryBuilder.php index 7c6ad984fb..4768b6d9e2 100644 --- a/framework/db/sqlite/QueryBuilder.php +++ b/framework/db/sqlite/QueryBuilder.php @@ -290,6 +290,58 @@ class QueryBuilder extends \yii\db\QueryBuilder throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); } + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @throws NotSupportedException this is not supported by SQLite + */ + public function addCommentOnColumn($table, $column, $comment) + { + throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $comment the text of the comment to be added. The comment will be properly quoted by the method. + * @return $this the command object itself + * @throws NotSupportedException this is not supported by SQLite + */ + public function addCommentOnTable($table, $comment) + { + throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); + } + + /** + * Builds a SQL command for adding comment to column + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @param string $column the name of the column to be commented. The column name will be properly quoted by the method. + * @return $this the command object itself + * @throws NotSupportedException this is not supported by SQLite + */ + public function dropCommentFromColumn($table, $column) + { + throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); + } + + /** + * Builds a SQL command for adding comment to table + * + * @param string $table the table whose column is to be commented. The table name will be properly quoted by the method. + * @return $this the command object itself + * @throws NotSupportedException this is not supported by SQLite + */ + public function dropCommentFromTable($table) + { + throw new NotSupportedException(__METHOD__ . ' is not supported by SQLite.'); + } + /** * @inheritdoc */ diff --git a/framework/db/sqlite/Schema.php b/framework/db/sqlite/Schema.php index e2cdb4038e..afb8d6c6c5 100644 --- a/framework/db/sqlite/Schema.php +++ b/framework/db/sqlite/Schema.php @@ -91,6 +91,14 @@ class Schema extends \yii\db\Schema return new QueryBuilder($this->db); } + /** + * @inheritdoc + */ + public function createColumnSchemaBuilder($type, $length = null) + { + return new ColumnSchemaBuilder($type, $length); + } + /** * Returns all table names in the database. * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. diff --git a/tests/data/mysql.sql b/tests/data/mysql.sql index 7c1e40bb90..8bdc46df97 100644 --- a/tests/data/mysql.sql +++ b/tests/data/mysql.sql @@ -18,6 +18,7 @@ DROP TABLE IF EXISTS `constraints` CASCADE; DROP TABLE IF EXISTS `animal` CASCADE; DROP TABLE IF EXISTS `default_pk` CASCADE; DROP TABLE IF EXISTS `document` CASCADE; +DROP TABLE IF EXISTS `comment` CASCADE; DROP VIEW IF EXISTS `animal_view`; CREATE TABLE `constraints` @@ -150,6 +151,14 @@ CREATE TABLE `document` ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `comment` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `add_comment` VARCHAR(255) NOT NULL, + `replace_comment` VARCHAR(255) COMMENT 'comment', + `delete_comment` VARCHAR(128) NOT NULL COMMENT 'comment', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE VIEW `animal_view` AS SELECT * FROM `animal`; INSERT INTO `animal` (`type`) VALUES ('yiiunit\data\ar\Cat'); diff --git a/tests/data/postgres.sql b/tests/data/postgres.sql index e37d7351a0..a35c1886d1 100644 --- a/tests/data/postgres.sql +++ b/tests/data/postgres.sql @@ -20,6 +20,7 @@ DROP TABLE IF EXISTS "bool_values" CASCADE; DROP TABLE IF EXISTS "animal" CASCADE; DROP TABLE IF EXISTS "default_pk" CASCADE; DROP TABLE IF EXISTS "document" CASCADE; +DROP TABLE IF EXISTS "comment" CASCADE; DROP VIEW IF EXISTS "animal_view"; DROP SCHEMA IF EXISTS "schema1" CASCADE; DROP SCHEMA IF EXISTS "schema2" CASCADE; @@ -154,6 +155,12 @@ CREATE TABLE "document" ( version integer not null default 0 ); +CREATE TABLE "comment" ( + id serial primary key, + name varchar(255) not null, + message text not null +); + CREATE VIEW "animal_view" AS SELECT * FROM "animal"; INSERT INTO "animal" (type) VALUES ('yiiunit\data\ar\Cat'); diff --git a/tests/framework/db/QueryBuilderTest.php b/tests/framework/db/QueryBuilderTest.php index 3da63c7456..602ac6e29d 100644 --- a/tests/framework/db/QueryBuilderTest.php +++ b/tests/framework/db/QueryBuilderTest.php @@ -915,6 +915,9 @@ abstract class QueryBuilderTest extends DatabaseTestCase 'sqlite' => 'bigint UNSIGNED PRIMARY KEY AUTOINCREMENT NOT NULL', ], ], + [ + + ], ]; foreach ($items as $i => $item) { @@ -1521,4 +1524,34 @@ abstract class QueryBuilderTest extends DatabaseTestCase // // TODO implement // } + + public function testCommentColumn() + { + $qb = $this->getQueryBuilder(); + + $expected = "ALTER TABLE `comment` CHANGE `add_comment` `add_comment` varchar(255) NOT NULL COMMENT 'This is my column.'"; + $sql = $qb->addCommentOnColumn('comment', 'add_comment', 'This is my column.'); + $this->assertEquals($expected, $sql); + + $expected = "ALTER TABLE `comment` CHANGE `replace_comment` `replace_comment` varchar(255) DEFAULT NULL COMMENT 'This is my column.'"; + $sql = $qb->addCommentOnColumn('comment', 'replace_comment', 'This is my column.'); + $this->assertEquals($expected, $sql); + + $expected = "ALTER TABLE `comment` CHANGE `delete_comment` `delete_comment` varchar(128) NOT NULL COMMENT ''"; + $sql = $qb->dropCommentFromColumn('comment', 'delete_comment'); + $this->assertEquals($expected, $sql); + } + + public function testCommentTable() + { + $qb = $this->getQueryBuilder(); + + $expected = "ALTER TABLE `comment` COMMENT 'This is my table.'"; + $sql = $qb->addCommentOnTable('comment', 'This is my table.'); + $this->assertEquals($expected, $sql); + + $expected = "ALTER TABLE `comment` COMMENT ''"; + $sql = $qb->dropCommentFromTable('comment'); + $this->assertEquals($expected, $sql); + } } diff --git a/tests/framework/db/mssql/MssqlQueryBuilderTest.php b/tests/framework/db/mssql/MssqlQueryBuilderTest.php index c821cea4fe..404079e7c6 100644 --- a/tests/framework/db/mssql/MssqlQueryBuilderTest.php +++ b/tests/framework/db/mssql/MssqlQueryBuilderTest.php @@ -56,6 +56,32 @@ class MssqlQueryBuilderTest extends QueryBuilderTest $this->assertEquals($expectedQueryParams, $actualQueryParams); } + public function testCommentColumn() + { + $qb = $this->getQueryBuilder(); + + $expected = "sp_updateextendedproperty @name = N'MS_Description', @value = 'This is my column.', @level1type = N'Table', @level1name = comment, @level2type = N'Column', @level2name = text"; + $sql = $qb->addCommentOnColumn('comment', 'text', 'This is my column.'); + $this->assertEquals($expected, $sql); + + $expected = "sp_dropextendedproperty @name = N'MS_Description', @level1type = N'Table', @level1name = comment, @level2type = N'Column', @level2name = text"; + $sql = $qb->dropCommentFromColumn('comment', 'text'); + $this->assertEquals($expected, $sql); + } + + public function testCommentTable() + { + $qb = $this->getQueryBuilder(); + + $expected = "sp_updateextendedproperty @name = N'MS_Description', @value = 'This is my table.', @level1type = N'Table', @level1name = comment"; + $sql = $qb->addCommentOnTable('comment', 'This is my table.'); + $this->assertEquals($expected, $sql); + + $expected = "sp_dropextendedproperty @name = N'MS_Description', @level1type = N'Table', @level1name = comment"; + $sql = $qb->dropCommentFromTable('comment'); + $this->assertEquals($expected, $sql); + } + /** * this is not used as a dataprovider for testGetColumnType to speed up the test * when used as dataprovider every single line will cause a reconnect with the database which is not needed here diff --git a/tests/framework/db/oci/OracleQueryBuilderTest.php b/tests/framework/db/oci/OracleQueryBuilderTest.php index c082f89fe7..fd0527ada3 100644 --- a/tests/framework/db/oci/OracleQueryBuilderTest.php +++ b/tests/framework/db/oci/OracleQueryBuilderTest.php @@ -27,4 +27,31 @@ class OracleQueryBuilderTest extends QueryBuilderTest ], ]); } + + + public function testCommentColumn() + { + $qb = $this->getQueryBuilder(); + + $expected = "COMMENT ON COLUMN \"comment\".\"text\" IS 'This is my column.'"; + $sql = $qb->addCommentOnColumn('comment', 'text', 'This is my column.'); + $this->assertEquals($expected, $sql); + + $expected = "COMMENT ON COLUMN \"comment\".\"text\" IS ' '"; + $sql = $qb->dropCommentFromColumn('comment', 'text'); + $this->assertEquals($expected, $sql); + } + + public function testCommentTable() + { + $qb = $this->getQueryBuilder(); + + $expected = "COMMENT ON TABLE \"comment\" IS 'This is my table.'"; + $sql = $qb->addCommentOnTable('comment', 'This is my table.'); + $this->assertEquals($expected, $sql); + + $expected = "COMMENT ON TABLE \"comment\" IS ' '"; + $sql = $qb->dropCommentFromTable('comment'); + $this->assertEquals($expected, $sql); + } } diff --git a/tests/framework/db/pgsql/PostgreSQLQueryBuilderTest.php b/tests/framework/db/pgsql/PostgreSQLQueryBuilderTest.php index b2aa8abf48..c7286999c0 100644 --- a/tests/framework/db/pgsql/PostgreSQLQueryBuilderTest.php +++ b/tests/framework/db/pgsql/PostgreSQLQueryBuilderTest.php @@ -95,4 +95,30 @@ class PostgreSQLQueryBuilderTest extends QueryBuilderTest $sql = $qb->alterColumn('foo1', 'bar', 'reset xyz'); $this->assertEquals($expected, $sql); } + + public function testCommentColumn() + { + $qb = $this->getQueryBuilder(); + + $expected = "COMMENT ON COLUMN \"comment\".\"text\" IS 'This is my column.'"; + $sql = $qb->addCommentOnColumn('comment', 'text', 'This is my column.'); + $this->assertEquals($expected, $sql); + + $expected = "COMMENT ON COLUMN \"comment\".\"text\" IS NULL"; + $sql = $qb->dropCommentFromColumn('comment', 'text'); + $this->assertEquals($expected, $sql); + } + + public function testCommentTable() + { + $qb = $this->getQueryBuilder(); + + $expected = "COMMENT ON TABLE \"comment\" IS 'This is my table.'"; + $sql = $qb->addCommentOnTable('comment', 'This is my table.'); + $this->assertEquals($expected, $sql); + + $expected = "COMMENT ON TABLE \"comment\" IS NULL"; + $sql = $qb->dropCommentFromTable('comment'); + $this->assertEquals($expected, $sql); + } } diff --git a/tests/framework/db/sqlite/SqliteQueryBuilderTest.php b/tests/framework/db/sqlite/SqliteQueryBuilderTest.php index f94885dc2b..844a575657 100644 --- a/tests/framework/db/sqlite/SqliteQueryBuilderTest.php +++ b/tests/framework/db/sqlite/SqliteQueryBuilderTest.php @@ -31,6 +31,30 @@ class SqliteQueryBuilderTest extends QueryBuilderTest parent::testAddDropPrimaryKey(); } + public function testCommentOnColumnSchemaBuilder() + { + $this->setExpectedException('yii\base\NotSupportedException'); + $this->string()->comment('comment'); + } + + public function testCommentColumn() + { + $qb = $this->getQueryBuilder(); + + $this->setExpectedException('yii\base\NotSupportedException'); + $qb->addCommentOnColumn('comment', 'text', 'This is my column.'); + $qb->dropCommentFromColumn('comment', 'text'); + } + + public function testCommentTable() + { + $qb = $this->getQueryBuilder(); + + $this->setExpectedException('yii\base\NotSupportedException'); + $qb->addCommentOnTable('comment', 'This is my table.'); + $qb->dropCommentFromTable('comment'); + } + public function testBatchInsert() { $db = $this->getConnection();