Browse Source

...

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
702476d886
  1. 26
      framework/base/Model.php
  2. 8
      framework/base/ModelBehavior.php
  3. 300
      framework/db/dao/QueryBuilder.php
  4. 16
      framework/db/dao/mysql/QueryBuilder.php
  5. 14
      framework/db/dao/sqlite/QueryBuilder.php
  6. 4
      tests/unit/framework/db/dao/CommandTest.php

26
framework/base/Model.php

@ -22,9 +22,9 @@ namespace yii\base;
*
* Model also provides a set of events for further customization:
*
* - [[onAfterConstruct]]: an event raised at the end of constructor
* - [[onBeforeValidate]]: an event raised at the beginning of [[validate]]
* - [[onAfterValidate]]: an event raised at the end of [[validate]]
* - [[onAfterInit]]: an event raised at the end of [[init()]]
* - [[onBeforeValidate]]: an event raised at the beginning of [[validate()]]
* - [[onAfterValidate]]: an event raised at the end of [[validate()]]
*
* You may directly use Model to store model data, or extend it with customization.
* You may also customize Model by attaching [[ModelBehavior|model behaviors]].
@ -46,7 +46,6 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
public function __construct($scenario = '')
{
$this->_scenario = $scenario;
$this->afterConstruct();
}
/**
@ -62,6 +61,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
public function init()
{
$this->attachBehaviors($this->behaviors());
$this->afterInit();
}
/**
@ -136,7 +136,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
* - validator type: required, specifies the validator to be used. It can be the name of a model
* class method, the name of a built-in validator, or a validator class (or its path alias).
* - on: optional, specifies the [[scenario|scenarios]] (separated by commas) when the validation
* rule can be applied. If this option is not set, the rule will apply to any scenario.
* rule can be applied. If this option is not set, the rule will apply to all scenarios.
* - additional name-value pairs can be specified to initialize the corresponding validator properties.
* Please refer to individual validator class API for possible properties.
*
@ -232,15 +232,15 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
}
/**
* This method is invoked at the end of model constructor.
* The default implementation raises the [[onAfterConstruct]] event.
* This method is invoked at the end of [[init()]].
* The default implementation raises the [[onAfterInit]] event.
* You may override this method to do postprocessing after model creation.
* Make sure you call the parent implementation so that the event is raised properly.
*/
public function afterConstruct()
public function afterInit()
{
if ($this->hasEventHandlers('onAfterConstruct')) {
$this->onAfterConstruct(new Event($this));
if ($this->hasEventHandlers('onAfterInit')) {
$this->onAfterInit(new Event($this));
}
}
@ -285,10 +285,10 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
}
/**
* This event is raised after the model instance is created by new operator.
* This event is raised at the end of [[init()]].
* @param Event $event the event parameter
*/
public function onAfterConstruct($event)
public function onAfterInit($event)
{
$this->raiseEvent(__FUNCTION__, $event);
}
@ -584,7 +584,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc
public function onUnsafeAttribute($name, $value)
{
if (YII_DEBUG) {
\Yii::warning(sprintf('Failed to set unsafe attribute "%s" in "%s".', $name, get_class($this)));
\Yii::warning("Failed to set unsafe attribute '$name' in '" . get_class($this) . "'.");
}
}

8
framework/base/ModelBehavior.php

@ -24,7 +24,7 @@ class ModelBehavior extends Behavior
* Declares event handlers for owner's events.
* The default implementation returns the following event handlers:
*
* - `onAfterConstruct` event: [[afterConstruct]]
* - `onAfterInit` event: [[afterInit]]
* - `onBeforeValidate` event: [[beforeValidate]]
* - `onAfterValidate` event: [[afterValidate]]
*
@ -34,18 +34,18 @@ class ModelBehavior extends Behavior
public function events()
{
return array(
'onAfterConstruct' => 'afterConstruct',
'onAfterInit' => 'afterInit',
'onBeforeValidate' => 'beforeValidate',
'onAfterValidate' => 'afterValidate',
);
}
/**
* Responds to [[Model::onAfterConstruct]] event.
* Responds to [[Model::onAfterInit]] event.
* Override this method if you want to handle the corresponding event of the [[owner]].
* @param Event $event event parameter
*/
public function afterConstruct($event)
public function afterInit($event)
{
}

300
framework/db/dao/QueryBuilder.php

@ -44,9 +44,13 @@ class QueryBuilder extends \yii\base\Object
public $separator = " ";
/**
* @var Query the Query object that is currently processed by the query builder to generate a SQL statement.
* After the SQL statement is generated by [[build()]], this property will be set null.
* This property will be set null upon completion of [[build()]].
*/
public $query;
/**
* @var boolean whether to automatically quote table and column names when generating SQL statements.
*/
public $autoQuote = true;
/**
* Constructor.
@ -99,8 +103,8 @@ class QueryBuilder extends \yii\base\Object
* ~~~
* $params = array();
* $sql = $queryBuilder->insert('tbl_user', array(
* 'name' => 'Sam',
* 'age' => 30,
* 'name' => 'Sam',
* 'age' => 30,
* ), $params);
* ~~~
*
@ -116,7 +120,7 @@ class QueryBuilder extends \yii\base\Object
$placeholders = array();
$count = 0;
foreach ($columns as $name => $value) {
$names[] = $this->driver->quoteColumnName($name);
$names[] = $this->quoteColumnName($name);
if ($value instanceof Expression) {
$placeholders[] = $value->expression;
foreach ($value->params as $n => $v) {
@ -132,7 +136,7 @@ class QueryBuilder extends \yii\base\Object
$this->query->addParams($params);
}
return 'INSERT INTO ' . $this->driver->quoteTableName($table)
return 'INSERT INTO ' . $this->quoteTableName($table)
. ' (' . implode(', ', $names) . ') VALUES ('
. implode(', ', $placeholders) . ')';
}
@ -145,7 +149,7 @@ class QueryBuilder extends \yii\base\Object
* ~~~
* $params = array();
* $sql = $queryBuilder->update('tbl_user', array(
* 'status' => 1,
* 'status' => 1,
* ), 'age > 30', $params);
* ~~~
*
@ -163,12 +167,12 @@ class QueryBuilder extends \yii\base\Object
$count = 0;
foreach ($columns as $name => $value) {
if ($value instanceof Expression) {
$lines[] = $this->driver->quoteSimpleColumnName($name) . '=' . $value->expression;
$lines[] = $this->quoteColumnName($name, true) . '=' . $value->expression;
foreach ($value->params as $n => $v) {
$params[$n] = $v;
}
} else {
$lines[] = $this->driver->quoteSimpleColumnName($name) . '=:p' . $count;
$lines[] = $this->quoteColumnName($name, true) . '=:p' . $count;
$params[':p' . $count] = $value;
$count++;
}
@ -176,7 +180,7 @@ class QueryBuilder extends \yii\base\Object
if ($this->query instanceof Query) {
$this->query->addParams($params);
}
$sql = 'UPDATE ' . $this->driver->quoteTableName($table) . ' SET ' . implode(', ', $lines);
$sql = 'UPDATE ' . $this->quoteTableName($table) . ' SET ' . implode(', ', $lines);
if (($where = $this->buildCondition($condition)) != '') {
$sql .= ' WHERE ' . $where;
}
@ -199,7 +203,7 @@ class QueryBuilder extends \yii\base\Object
*/
public function delete($table, $condition = '')
{
$sql = 'DELETE FROM ' . $this->driver->quoteTableName($table);
$sql = 'DELETE FROM ' . $this->quoteTableName($table);
if (($where = $this->buildCondition($condition)) != '') {
$sql .= ' WHERE ' . $where;
}
@ -221,9 +225,9 @@ class QueryBuilder extends \yii\base\Object
*
* ~~~
* $sql = $queryBuilder->createTable('tbl_user', array(
* 'id' => 'pk',
* 'name' => 'string',
* 'age' => 'integer',
* 'id' => 'pk',
* 'name' => 'string',
* 'age' => 'integer',
* ));
* ~~~
*
@ -237,13 +241,12 @@ class QueryBuilder extends \yii\base\Object
$cols = array();
foreach ($columns as $name => $type) {
if (is_string($name)) {
$cols[] = "\t" . $this->driver->quoteColumnName($name) . ' ' . $this->getColumnType($type);
} else
{
$cols[] = "\t" . $this->quoteColumnName($name) . ' ' . $this->getColumnType($type);
} else {
$cols[] = "\t" . $type;
}
}
$sql = "CREATE TABLE " . $this->driver->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)";
$sql = "CREATE TABLE " . $this->quoteTableName($table) . " (\n" . implode(",\n", $cols) . "\n)";
return $options === null ? $sql : $sql . ' ' . $options;
}
@ -255,7 +258,7 @@ class QueryBuilder extends \yii\base\Object
*/
public function renameTable($oldName, $newName)
{
return 'RENAME TABLE ' . $this->driver->quoteTableName($oldName) . ' TO ' . $this->driver->quoteTableName($newName);
return 'RENAME TABLE ' . $this->quoteTableName($oldName) . ' TO ' . $this->quoteTableName($newName);
}
/**
@ -265,7 +268,7 @@ class QueryBuilder extends \yii\base\Object
*/
public function dropTable($table)
{
return "DROP TABLE " . $this->driver->quoteTableName($table);
return "DROP TABLE " . $this->quoteTableName($table);
}
/**
@ -275,7 +278,7 @@ class QueryBuilder extends \yii\base\Object
*/
public function truncateTable($table)
{
return "TRUNCATE TABLE " . $this->driver->quoteTableName($table);
return "TRUNCATE TABLE " . $this->quoteTableName($table);
}
/**
@ -289,8 +292,8 @@ class QueryBuilder extends \yii\base\Object
*/
public function addColumn($table, $column, $type)
{
return 'ALTER TABLE ' . $this->driver->quoteTableName($table)
. ' ADD ' . $this->driver->quoteColumnName($column) . ' '
return 'ALTER TABLE ' . $this->quoteTableName($table)
. ' ADD ' . $this->quoteColumnName($column) . ' '
. $this->getColumnType($type);
}
@ -302,8 +305,8 @@ class QueryBuilder extends \yii\base\Object
*/
public function dropColumn($table, $column)
{
return "ALTER TABLE " . $this->driver->quoteTableName($table)
. " DROP COLUMN " . $this->driver->quoteSimpleColumnName($column);
return "ALTER TABLE " . $this->quoteTableName($table)
. " DROP COLUMN " . $this->quoteColumnName($column, true);
}
/**
@ -315,9 +318,9 @@ class QueryBuilder extends \yii\base\Object
*/
public function renameColumn($table, $oldName, $newName)
{
return "ALTER TABLE " . $this->driver->quoteTableName($table)
. " RENAME COLUMN " . $this->driver->quoteSimpleColumnName($oldName)
. " TO " . $this->driver->quoteSimpleColumnName($newName);
return "ALTER TABLE " . $this->quoteTableName($table)
. " RENAME COLUMN " . $this->quoteColumnName($oldName, true)
. " TO " . $this->quoteColumnName($newName, true);
}
/**
@ -332,9 +335,9 @@ class QueryBuilder extends \yii\base\Object
*/
public function alterColumn($table, $column, $type)
{
return 'ALTER TABLE ' . $this->driver->quoteTableName($table) . ' CHANGE '
. $this->driver->quoteSimpleColumnName($column) . ' '
. $this->driver->quoteSimpleColumnName($column) . ' '
return 'ALTER TABLE ' . $this->quoteTableName($table) . ' CHANGE '
. $this->quoteColumnName($column, true) . ' '
. $this->quoteColumnName($column, true) . ' '
. $this->getColumnType($type);
}
@ -354,23 +357,11 @@ class QueryBuilder extends \yii\base\Object
*/
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($columns as $i => $col) {
$columns[$i] = $this->driver->quoteColumnName($col);
}
if (!is_array($refColumns)) {
$refColumns = preg_split('/\s*,\s*/', $refColumns, -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($refColumns as $i => $col) {
$refColumns[$i] = $this->driver->quoteColumnName($col);
}
$sql = 'ALTER TABLE ' . $this->driver->quoteTableName($table)
. ' ADD CONSTRAINT ' . $this->driver->quoteColumnName($name)
. ' FOREIGN KEY (' . implode(', ', $columns) . ')'
. ' REFERENCES ' . $this->driver->quoteTableName($refTable)
. ' (' . implode(', ', $refColumns) . ')';
$sql = 'ALTER TABLE ' . $this->quoteTableName($table)
. ' ADD CONSTRAINT ' . $this->quoteColumnName($name)
. ' FOREIGN KEY (' . $this->buildColumns($columns) . ')'
. ' REFERENCES ' . $this->quoteTableName($refTable)
. ' (' . $this->buildColumns($refColumns) . ')';
if ($delete !== null) {
$sql .= ' ON DELETE ' . $delete;
}
@ -388,8 +379,8 @@ class QueryBuilder extends \yii\base\Object
*/
public function dropForeignKey($name, $table)
{
return 'ALTER TABLE ' . $this->driver->quoteTableName($table)
. ' DROP CONSTRAINT ' . $this->driver->quoteColumnName($name);
return 'ALTER TABLE ' . $this->quoteTableName($table)
. ' DROP CONSTRAINT ' . $this->quoteColumnName($name);
}
/**
@ -404,19 +395,10 @@ class QueryBuilder extends \yii\base\Object
*/
public function createIndex($name, $table, $columns, $unique = false)
{
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($columns as $i => $column) {
if (strpos($column, '(') !== false) {
$columns[$i] = $column;
} else {
$columns[$i] = $this->driver->quoteColumnName($column);
}
}
return ($unique ? 'CREATE UNIQUE INDEX ' : 'CREATE INDEX ')
. $this->driver->quoteTableName($name) . ' ON '
. $this->driver->quoteTableName($table) . ' (' . implode(', ', $columns) . ')';
. $this->quoteTableName($name) . ' ON '
. $this->quoteTableName($table)
. ' (' . $this->buildColumns($columns) . ')';
}
/**
@ -427,7 +409,7 @@ class QueryBuilder extends \yii\base\Object
*/
public function dropIndex($name, $table)
{
return 'DROP INDEX ' . $this->driver->quoteTableName($name) . ' ON ' . $this->driver->quoteTableName($table);
return 'DROP INDEX ' . $this->quoteTableName($name) . ' ON ' . $this->quoteTableName($table);
}
/**
@ -525,7 +507,7 @@ class QueryBuilder extends \yii\base\Object
$column = $condition[1];
if (strpos($column, '(') === false) {
$column = $this->connection->quoteColumnName($column);
$column = $this->quoteColumnName($column);
}
if ($operator === 'BETWEEN' || $operator === 'NOT BETWEEN') {
@ -592,26 +574,32 @@ class QueryBuilder extends \yii\base\Object
return $select . ' *';
}
if (is_string($columns)) {
if (strpos($columns, '(') !== false) {
return $select . ' ' . $columns;
}
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-\.])$/', $column, $matches)) {
$columns[$i] = $this->connection->quoteColumnName($matches[1]) . ' AS ' . $this->driver->quoteSimpleColumnName($matches[2]);
if ($this->autoQuote) {
if (!is_array($columns)) {
if (strpos($columns, '(') !== false) {
return $select . ' ' . $columns;
} else {
$columns[$i] = $this->connection->quoteColumnName($column);
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)([\w\-\.])$/', $column, $matches)) {
$columns[$i] = $this->driver->quoteColumnName($matches[1]) . ' AS ' . $this->driver->quoteSimpleColumnName($matches[2]);
} else {
$columns[$i] = $this->driver->quoteColumnName($column);
}
}
}
}
return $select . ' ' . implode(', ', $columns);
if (is_array($columns)) {
$columns = implode(', ', $columns);
}
return $select . ' ' . $columns;
}
/**
@ -624,24 +612,31 @@ class QueryBuilder extends \yii\base\Object
}
$tables = $this->query->from;
if (is_string($tables) && strpos($tables, '(') !== false) {
return 'FROM ' . $tables;
}
if (!is_array($tables)) {
$tables = preg_split('/\s*,\s*/', trim($tables), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($tables as $i => $table) {
if (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i', $table, $matches)) { // with alias
$tables[$i] = $this->connection->quoteTableName($matches[1]) . ' ' . $this->connection->quoteTableName($matches[2]);
if ($this->autoQuote) {
if (!is_array($tables)) {
if (strpos($tables, '(') !== false) {
return 'FROM ' . $tables;
} else {
$tables[$i] = $this->connection->quoteTableName($table);
$tables = preg_split('/\s*,\s*/', trim($tables), -1, PREG_SPLIT_NO_EMPTY);
}
}
foreach ($tables as $i => $table) {
if (strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/i', $table, $matches)) { // with alias
$tables[$i] = $this->driver->quoteTableName($matches[1]) . ' ' . $this->driver->quoteTableName($matches[2]);
} else {
$tables[$i] = $this->driver->quoteTableName($table);
}
}
}
}
if (is_array($tables)) {
$tables = implode(', ', $tables);
}
return 'FROM ' . implode(', ', $tables);
return 'FROM ' . $tables;
}
/**
@ -661,11 +656,11 @@ class QueryBuilder extends \yii\base\Object
if (is_array($join)) { // join type, table name, on-condition
if (isset($join[0], $join[1])) {
$table = $join[1];
if (strpos($table, '(') === false) {
if ($this->autoQuote && strpos($table, '(') === false) {
if (preg_match('/^(.*?)(?i:\s+as\s+|\s+)(.*)$/', $table, $matches)) { // with alias
$table = $this->connection->quoteTableName($matches[1]) . ' ' . $this->connection->quoteTableName($matches[2]);
$table = $this->driver->quoteTableName($matches[1]) . ' ' . $this->driver->quoteTableName($matches[2]);
} else {
$table = $this->connection->quoteTableName($table);
$table = $this->driver->quoteTableName($table);
}
}
$joins[$i] = strtoupper($join[0]) . ' ' . $table;
@ -695,25 +690,11 @@ class QueryBuilder extends \yii\base\Object
*/
protected function buildGroupBy()
{
$columns = $this->query->groupBy;
if (empty($columns)) {
if (empty($this->query->groupBy)) {
return '';
} else {
return 'GROUP BY ' . $this->buildColumns($this->query->groupBy);
}
if (is_string($columns) && strpos($columns, '(') !== false) {
return 'GROUP BY ' . $columns;
}
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
$columns[$i] = $this->connection->quoteColumnName($column);
}
}
return 'GROUP BY ' . implode(', ', $columns);
}
/**
@ -730,29 +711,34 @@ class QueryBuilder extends \yii\base\Object
*/
protected function buildOrderBy()
{
$columns = $this->query->orderBy;
if (empty($columns)) {
if (empty($this->query->orderBy)) {
return '';
}
if (is_string($columns) && strpos($columns, '(') !== false) {
return 'ORDER BY ' . $columns;
}
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
if (preg_match('/^(.*?)\s+(asc|desc)$/i', $column, $matches)) {
$columns[$i] = $this->connection->quoteColumnName($matches[1]) . ' ' . strtoupper($matches[2]);
$columns = $this->query->orderBy;
if ($this->autoQuote) {
if (!is_array($columns)) {
if (strpos($columns, '(') !== false) {
return 'ORDER BY ' . $columns;
} else {
$columns[$i] = $this->connection->quoteColumnName($column);
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
if (preg_match('/^(.*?)\s+(asc|desc)$/i', $column, $matches)) {
$columns[$i] = $this->driver->quoteColumnName($matches[1]) . ' ' . $matches[2];
} else {
$columns[$i] = $this->driver->quoteColumnName($column);
}
}
}
}
if (is_array($columns)) {
$columns = implode(', ', $columns);
}
return 'ORDER BY ' . implode(', ', $columns);
return 'ORDER BY ' . $columns;
}
/**
@ -789,4 +775,64 @@ class QueryBuilder extends \yii\base\Object
}
return "UNION (\n" . implode("\n) UNION (\n", $unions) . "\n)";
}
/**
* Processes columns and properly quote them if necessary.
* This method will quote columns if [[autoQuote]] is true.
* It will join all columns into a string with comma as separators.
* @param string|array $columns the columns to be processed
* @return string the processing result
*/
protected function buildColumns($columns)
{
if ($this->autoQuote) {
if (!is_array($columns)) {
if (strpos($columns, '(') !== false) {
return $columns;
} else {
$columns = preg_split('/\s*,\s*/', $columns, -1, PREG_SPLIT_NO_EMPTY);
}
}
foreach ($columns as $i => $column) {
if (is_object($column)) {
$columns[$i] = (string)$column;
} elseif (strpos($column, '(') === false) {
$columns[$i] = $this->driver->quoteColumnName($column);
}
}
}
return is_array($columns) ? implode(', ', $columns) : $columns;
}
/**
* Quotes a table name for use in a query.
* This method will perform name quoting only when [[autoQuote]] is true.
* @param string $name table name
* @param boolean $simple whether the name should be treated as a simple table name without any prefix.
* @return string the properly quoted table name
*/
protected function quoteTableName($name, $simple = false)
{
if ($this->autoQuote) {
return $simple ? $this->driver->quoteSimpleTableName($name) : $this->driver->quoteTableName($name);
} else {
return $name;
}
}
/**
* Quotes a column name for use in a query.
* This method will perform name quoting only when [[autoQuote]] is true.
* @param string $name column name
* @param boolean $simple whether the name should be treated as a simple column name without any prefix.
* @return string the properly quoted column name
*/
protected function quoteColumnName($name, $simple = false)
{
if ($this->autoQuote) {
return $simple ? $this->driver->quoteSimpleColumnName($name) : $this->driver->quoteColumnName($name);
} else {
return $name;
}
}
}

16
framework/db/dao/mysql/QueryBuilder.php

@ -50,7 +50,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function renameColumn($table, $oldName, $newName)
{
$quotedTable = $this->driver->quoteTableName($table);
$quotedTable = $this->quoteTableName($table);
$row = $this->connection->createCommand('SHOW CREATE TABLE ' . $quotedTable)->queryRow();
if ($row === false) {
throw new Exception("Unable to find '$oldName' in table '$table'.");
@ -64,13 +64,17 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) {
foreach ($matches[1] as $i => $c) {
if ($c === $oldName) {
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($oldName)
. ' ' . $this->driver->quoteColumnName($newName) . ' ' . $matches[2][$i];
return "ALTER TABLE $quotedTable CHANGE "
. $this->quoteColumnName($oldName, true) . ' '
. $this->quoteColumnName($newName, true) . ' '
. $matches[2][$i];
}
}
}
// try to give back a SQL anyway
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($oldName) . ' ' . $newName;
return "ALTER TABLE $quotedTable CHANGE "
. $this->quoteColumnName($oldName, true) . ' '
. $this->quoteColumnName($newName, true);
}
/**
@ -81,7 +85,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function dropForeignKey($name, $table)
{
return 'ALTER TABLE ' . $this->driver->quoteTableName($table)
. ' DROP FOREIGN KEY ' . $this->driver->quoteColumnName($name);
return 'ALTER TABLE ' . $this->quoteTableName($table)
. ' DROP FOREIGN KEY ' . $this->quoteColumnName($name);
}
}

14
framework/db/dao/sqlite/QueryBuilder.php

@ -83,7 +83,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function truncateTable($table)
{
return "DELETE FROM " . $this->driver->quoteTableName($table);
return "DELETE FROM " . $this->quoteTableName($table);
}
/**
@ -94,7 +94,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function dropIndex($name, $table)
{
return 'DROP INDEX ' . $this->driver->quoteTableName($name);
return 'DROP INDEX ' . $this->quoteTableName($name);
}
/**
@ -105,7 +105,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function dropColumn($table, $column)
{
throw new Exception('Dropping DB column is not supported by SQLite.');
throw new Exception(__METHOD__ . ' is not supported by SQLite.');
}
/**
@ -117,7 +117,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function renameColumn($table, $oldName, $newName)
{
throw new Exception('Renaming a DB column is not supported by SQLite.');
throw new Exception(__METHOD__ . ' is not supported by SQLite.');
}
/**
@ -136,7 +136,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null)
{
throw new Exception('Adding a foreign key constraint to an existing table is not supported by SQLite.');
throw new Exception(__METHOD__ . ' is not supported by SQLite.');
}
/**
@ -147,7 +147,7 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function dropForeignKey($name, $table)
{
throw new Exception('Dropping a foreign key constraint is not supported by SQLite.');
throw new Exception(__METHOD__ . ' is not supported by SQLite.');
}
/**
@ -162,6 +162,6 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
*/
public function alterColumn($table, $column, $type)
{
throw new Exception('Altering a DB column is not supported by SQLite.');
throw new Exception(__METHOD__ . ' is not supported by SQLite.');
}
}

4
tests/unit/framework/db/dao/CommandTest.php

@ -26,14 +26,14 @@ class CommandTest extends \yiiunit\MysqlTestCase
$query = new Query;
$query->select('id')->from('tbl_user');
$command = $db->createCommand($query);
$this->assertEquals("SELECT `id`\nFROM `tbl_user`", $command->sql);
$this->assertEquals("SELECT `id` FROM `tbl_user`", $command->sql);
// array
$command = $db->createCommand(array(
'select' => 'name',
'from' => 'tbl_user',
));
$this->assertEquals("SELECT `name`\nFROM `tbl_user`", $command->sql);
$this->assertEquals("SELECT `name` FROM `tbl_user`", $command->sql);
}
function testGetSetSql()

Loading…
Cancel
Save