Commit eddf9937 by Qiang Xue

...

parent 1dd651df
......@@ -11,7 +11,7 @@
namespace yii\db\dao;
/**
* ColumnSchema class describes the meta data of a column in a database table.
* ColumnSchema class describes the metadata of a column in a database table.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......
......@@ -464,7 +464,7 @@ class Connection extends \yii\base\ApplicationComponent
if (isset($this->driverMap[$driver])) {
return $this->_driver = \Yii::createObject($this->driverMap[$driver], $this);
} else {
throw new Exception("Connection does not support reading meta data for '$driver' database.");
throw new Exception("Connection does not support reading metadata for '$driver' database.");
}
}
}
......
......@@ -15,11 +15,11 @@ use yii\db\Exception;
/**
* Driver is the base class for all database driver classes.
*
* Driver implements the DBMS-specific methods to support retrieving meta data of a database.
* Driver implements the DBMS-specific methods to support retrieving metadata of a database.
*
* @property QueryBuilder $queryBuilder the query builder for this connection.
* @property array $tableNames the names of all tables in this database.
* @property array $tableSchemas the meta data for all tables in this database.
* @property array $tableSchemas the metadata for all tables in this database.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......@@ -54,7 +54,7 @@ abstract class Driver extends \yii\base\Object
*/
private $_tableNames = array();
/**
* @var array list of loaded table meta data (table name => TableSchema)
* @var array list of loaded table metadata (table name => TableSchema)
*/
private $_tables = array();
/**
......
......@@ -11,7 +11,7 @@
namespace yii\db\dao;
/**
* TableSchema represents the meta data of a database table.
* TableSchema represents the metadata of a database table.
*
* @property array $columnNames list of column names
*
......
......@@ -14,7 +14,7 @@ use yii\db\dao\TableSchema;
use yii\db\dao\ColumnSchema;
/**
* Driver is the class for retrieving meta data from a MySQL database (version 4.1.x and 5.x).
* Driver is the class for retrieving metadata from a MySQL database (version 4.1.x and 5.x).
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
......@@ -24,7 +24,7 @@ class Driver extends \yii\db\dao\Driver
/**
* @var array mapping from physical column types (keys) to abstract column types (values)
*/
public $typeMap = array( // dbType => type
public $typeMap = array(
'tinyint' => self::TYPE_SMALLINT,
'bit' => self::TYPE_SMALLINT,
'smallint' => self::TYPE_SMALLINT,
......@@ -75,6 +75,16 @@ class Driver extends \yii\db\dao\Driver
}
/**
* Creates a query builder for the database.
* This method may be overridden by child classes to create a DBMS-specific query builder.
* @return QueryBuilder query builder instance
*/
public function createQueryBuilder()
{
return new QueryBuilder($this->connection);
}
/**
* Loads the metadata for the specified table.
* @param string $name table name
* @return \yii\db\dao\TableSchema driver dependent table metadata. Null if the table does not exist.
......@@ -91,9 +101,9 @@ class Driver extends \yii\db\dao\Driver
}
/**
* Generates various kinds of table names.
* @param \yii\db\dao\TableSchema $table the table instance
* @param string $name the unquoted table name
* Resolves the table name and schema name (if any).
* @param \yii\db\dao\TableSchema $table the table metadata object
* @param string $name the table name
*/
protected function resolveTableNames($table, $name)
{
......@@ -127,16 +137,17 @@ class Driver extends \yii\db\dao\Driver
$this->resolveColumnType($c);
$c->resolvePhpType();
$this->resolveDefaultValue($c, $column['Default']);
$this->resolveColumnDefault($c, $column['Default']);
return $c;
}
/**
* @param \yii\db\dao\ColumnSchema $column
* @param string $value
* Resolves the default value for the column.
* @param \yii\db\dao\ColumnSchema $column the column metadata object
* @param string $value the default value fetched from database
*/
protected function resolveDefaultValue($column, $value)
protected function resolveColumnDefault($column, $value)
{
if ($column->type !== 'timestamp' || $value !== 'CURRENT_TIMESTAMP') {
$column->defaultValue = $column->typecast($value);
......@@ -144,8 +155,8 @@ class Driver extends \yii\db\dao\Driver
}
/**
* Extracts the PHP type from DB type.
* @param \yii\db\dao\ColumnSchema $column the column
* Resolves the abstract data type for the column.
* @param \yii\db\dao\ColumnSchema $column the column metadata object
*/
public function resolveColumnType($column)
{
......@@ -186,7 +197,7 @@ class Driver extends \yii\db\dao\Driver
}
/**
* Collects the table column metadata.
* Collects the metadata of table columns.
* @param \yii\db\dao\TableSchema $table the table metadata
* @return boolean whether the table exists in the database
*/
......@@ -195,21 +206,21 @@ class Driver extends \yii\db\dao\Driver
$sql = 'SHOW COLUMNS FROM ' . $table->quotedName;
try {
$columns = $this->connection->createCommand($sql)->queryAll();
}
catch (\Exception $e) {
} catch (\Exception $e) {
return false;
}
foreach ($columns as $column) {
$table->columns[$c->name] = $c = $this->createColumn($column);
if ($c->isPrimaryKey) {
$column = $this->createColumn($column);
$table->columns[$column->name] = $column;
if ($column->isPrimaryKey) {
if ($table->primaryKey === null) {
$table->primaryKey = $c->name;
$table->primaryKey = $column->name;
} elseif (is_string($table->primaryKey)) {
$table->primaryKey = array($table->primaryKey, $c->name);
$table->primaryKey = array($table->primaryKey, $column->name);
} else {
$table->primaryKey[] = $c->name;
$table->primaryKey[] = $column->name;
}
if ($c->autoIncrement) {
if ($column->autoIncrement) {
$table->sequenceName = '';
}
}
......@@ -224,9 +235,14 @@ class Driver extends \yii\db\dao\Driver
protected function findConstraints($table)
{
$row = $this->connection->createCommand('SHOW CREATE TABLE ' . $table->quotedName)->queryRow();
$matches = array();
if (isset($row['Create Table'])) {
$sql = $row['Create Table'];
} else {
$row = array_values($row);
$sql = $row[1];
}
$regexp = '/FOREIGN KEY\s+\(([^\)]+)\)\s+REFERENCES\s+([^\(^\s]+)\s*\(([^\)]+)\)/mi';
foreach ($row as $sql) {
if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
$fks = array_map('trim', explode(',', str_replace('`', '', $match[1])));
......@@ -237,8 +253,6 @@ class Driver extends \yii\db\dao\Driver
}
$table->foreignKeys[] = $constraint;
}
break;
}
}
}
......@@ -255,19 +269,9 @@ class Driver extends \yii\db\dao\Driver
}
$sql = 'SHOW TABLES FROM ' . $this->quoteSimpleTableName($schema);
$names = $this->connection->createCommand($sql)->queryColumn();
foreach ($names as &$name) {
$name = $schema . '.' . $name;
foreach ($names as $i => $name) {
$names[$i] = $schema . '.' . $name;
}
return $names;
}
/**
* Creates a query builder for the database.
* This method may be overridden by child classes to create a DBMS-specific query builder.
* @return QueryBuilder query builder instance
*/
public function createQueryBuilder()
{
return new QueryBuilder($this->connection);
}
}
......@@ -10,6 +10,8 @@
namespace yii\db\dao\mysql;
use yii\db\Exception;
/**
* QueryBuilder builds a SQL statement based on the specification given as a [[Query]] object.
*
......@@ -42,16 +44,17 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
/**
* Builds a SQL statement for renaming a column.
* @param string $table the table whose column is to be renamed. The name will be properly quoted by the method.
* @param string $name the old name of the column. The name will be properly quoted by the method.
* @param string $oldName the old name of the column. The name will be properly quoted by the method.
* @param string $newName the new name of the column. The name will be properly quoted by the method.
* @return string the SQL statement for renaming a DB column.
*/
public function renameColumn($table, $name, $newName)
public function renameColumn($table, $oldName, $newName)
{
$quotedTable = $this->driver->quoteTableName($table);
$row = $this->connection->createCommand('SHOW CREATE TABLE ' . $quotedTable)->queryRow();
if ($row === false)
throw new CDbException(Yii::t('yii', 'Unable to find "{column}" in table "{table}".', array('{column}' => $name, '{table}' => $table)));
if ($row === false) {
throw new Exception("Unable to find '$oldName' in table '$table'.");
}
if (isset($row['Create Table'])) {
$sql = $row['Create Table'];
} else {
......@@ -60,14 +63,14 @@ class QueryBuilder extends \yii\db\dao\QueryBuilder
}
if (preg_match_all('/^\s*`(.*?)`\s+(.*?),?$/m', $sql, $matches)) {
foreach ($matches[1] as $i => $c) {
if ($c === $name) {
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($name)
if ($c === $oldName) {
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($oldName)
. ' ' . $this->driver->quoteColumnName($newName) . ' ' . $matches[2][$i];
}
}
}
// try to give back a SQL anyway
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($name) . ' ' . $newName;
return "ALTER TABLE $quotedTable CHANGE " . $this->driver->quoteColumnName($oldName) . ' ' . $newName;
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment