From eddf9937e17b70a4034be6bffdd7122cb3e1e821 Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Tue, 27 Dec 2011 22:35:01 -0500 Subject: [PATCH] ... --- framework/db/dao/ColumnSchema.php | 2 +- framework/db/dao/Connection.php | 2 +- framework/db/dao/Driver.php | 6 +-- framework/db/dao/TableSchema.php | 2 +- framework/db/dao/mysql/Driver.php | 92 +++++++++++++++++---------------- framework/db/dao/mysql/QueryBuilder.php | 17 +++--- 6 files changed, 64 insertions(+), 57 deletions(-) diff --git a/framework/db/dao/ColumnSchema.php b/framework/db/dao/ColumnSchema.php index 807a6dd..b614039 100644 --- a/framework/db/dao/ColumnSchema.php +++ b/framework/db/dao/ColumnSchema.php @@ -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 * @since 2.0 diff --git a/framework/db/dao/Connection.php b/framework/db/dao/Connection.php index 14f3953..7c1b19b 100644 --- a/framework/db/dao/Connection.php +++ b/framework/db/dao/Connection.php @@ -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."); } } } diff --git a/framework/db/dao/Driver.php b/framework/db/dao/Driver.php index e183749..3437868 100644 --- a/framework/db/dao/Driver.php +++ b/framework/db/dao/Driver.php @@ -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 * @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(); /** diff --git a/framework/db/dao/TableSchema.php b/framework/db/dao/TableSchema.php index 777bdda..1ed2420 100644 --- a/framework/db/dao/TableSchema.php +++ b/framework/db/dao/TableSchema.php @@ -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 * diff --git a/framework/db/dao/mysql/Driver.php b/framework/db/dao/mysql/Driver.php index b995e88..3a77236 100644 --- a/framework/db/dao/mysql/Driver.php +++ b/framework/db/dao/mysql/Driver.php @@ -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 * @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,20 +235,23 @@ 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]))); - $pks = array_map('trim', explode(',', str_replace('`', '', $match[3]))); - $constraint = array(str_replace('`', '', $match[2])); - foreach ($fks as $k => $name) { - $constraint[$name] = $pks[$k]; - } - $table->foreignKeys[] = $constraint; + if (preg_match_all($regexp, $sql, $matches, PREG_SET_ORDER)) { + foreach ($matches as $match) { + $fks = array_map('trim', explode(',', str_replace('`', '', $match[1]))); + $pks = array_map('trim', explode(',', str_replace('`', '', $match[3]))); + $constraint = array(str_replace('`', '', $match[2])); + foreach ($fks as $k => $name) { + $constraint[$name] = $pks[$k]; } - break; + $table->foreignKeys[] = $constraint; } } } @@ -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); - } } diff --git a/framework/db/dao/mysql/QueryBuilder.php b/framework/db/dao/mysql/QueryBuilder.php index 5f5934c..d1a46bf 100644 --- a/framework/db/dao/mysql/QueryBuilder.php +++ b/framework/db/dao/mysql/QueryBuilder.php @@ -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; } /**