diff --git a/framework/base/Model.php b/framework/base/Model.php index 5b9dc00..88668e4 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -281,7 +281,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc */ public function onInit($event) { - $this->raiseEvent(__METHOD__, $event); + $this->raiseEvent(__FUNCTION__, $event); } /** @@ -290,7 +290,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc */ public function onAfterConstruct($event) { - $this->raiseEvent(__METHOD__, $event); + $this->raiseEvent(__FUNCTION__, $event); } /** @@ -299,7 +299,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc */ public function onBeforeValidate($event) { - $this->raiseEvent(__METHOD__, $event); + $this->raiseEvent(__FUNCTION__, $event); } /** @@ -308,7 +308,7 @@ class Model extends Component implements Initable, \IteratorAggregate, \ArrayAcc */ public function onAfterValidate($event) { - $this->raiseEvent(__METHOD__, $event); + $this->raiseEvent(__FUNCTION__, $event); } /** diff --git a/framework/db/dao/ColumnSchema.php b/framework/db/dao/ColumnSchema.php index 3498f59..3e498cb 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 column meta data of a database table. + * ColumnSchema class describes the meta data of a column in a database table. * * @author Qiang Xue * @since 2.0 @@ -23,7 +23,7 @@ class ColumnSchema extends \yii\base\Component */ public $name; /** - * @var string raw name of this column. This is the quoted name that can be directly used in SQL queries. + * @var string the quoted name of this column. */ public $quotedName; /** @@ -42,7 +42,7 @@ class ColumnSchema extends \yii\base\Component */ public $phpType; /** - * @var string the DB type of this column. Possible DB types vary according to the DBMS. + * @var string the DB type of this column. Possible DB types vary according to the type of DBMS. */ public $dbType; /** @@ -50,11 +50,11 @@ class ColumnSchema extends \yii\base\Component */ public $defaultValue; /** - * @var array enumerable values + * @var array enumerable values. This is set only if the column is declared to be an enumerable type. */ public $enumValues; /** - * @var integer size of the column. + * @var integer display size of the column. */ public $size; /** @@ -75,7 +75,7 @@ class ColumnSchema extends \yii\base\Component public $autoIncrement = false; /** * @var boolean whether this column is unsigned. This is only meaningful - * when [[type]] is `integer` or `bigint`. + * when [[type]] is `smallint`, `integer` or `bigint`. */ public $unsigned; @@ -83,7 +83,7 @@ class ColumnSchema extends \yii\base\Component * Extracts the PHP type from DB type. * @return string PHP type name. */ - protected function getPhpType() + protected function extractPhpType() { static $typeMap = array( // logical type => php type 'smallint' => 'integer', @@ -104,7 +104,8 @@ class ColumnSchema extends \yii\base\Component } /** - * Converts the input value to the type that this column is of. + * Converts the input value according to [[phpType]]. + * If the value is null or an [[Expression]], it will not be converted. * @param mixed $value input value * @return mixed converted value */ diff --git a/framework/db/dao/DataReader.php b/framework/db/dao/DataReader.php index 67d2f59..bdacb55 100644 --- a/framework/db/dao/DataReader.php +++ b/framework/db/dao/DataReader.php @@ -32,6 +32,11 @@ use yii\db\Exception; * [[fetchMode]]. See the [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php) * for more details about possible fetch mode. * + * @property boolean $isClosed whether the reader is closed or not. + * @property integer $rowCount number of rows contained in the result. + * @property integer $columnCount the number of columns in the result set. + * @property mixed $fetchMode fetch mode used when retrieving the data. + * * @author Qiang Xue * @since 2.0 */ diff --git a/framework/db/dao/Query.php b/framework/db/dao/Query.php index 938d814..d134753 100644 --- a/framework/db/dao/Query.php +++ b/framework/db/dao/Query.php @@ -34,6 +34,8 @@ namespace yii\db\dao; * And by calling [[createCommand()]], we can get a [[Command]] instance which can be further * used to perform/execute the DB query against a database. * + * @property string $sql the SQL statement represented by this query object. + * * @author Qiang Xue * @since 2.0 */ @@ -512,6 +514,38 @@ class Query extends \yii\base\Object } /** + * Sets the parameters to be bound to the query. + * @param array list of query parameter values indexed by parameter placeholders. + * For example, `array(':name'=>'Dan', ':age'=>31)`. + * @return Query the query object itself + * @see addParams() + */ + public function params($params) + { + $this->params = $params; + return $this; + } + + /** + * Adds additional parameters to be bound to the query. + * @param array list of query parameter values indexed by parameter placeholders. + * For example, `array(':name'=>'Dan', ':age'=>31)`. + * @return Query the query object itself + * @see params() + */ + public function addParams($params) + { + foreach ($params as $name => $value) { + if (is_integer($name)) { + $this->params[] = $value; + } else { + $this->params[$name] = $value; + } + } + return $this; + } + + /** * Creates and executes an INSERT SQL statement. * The method will properly escape the column names, and bind the values to be inserted. * @param string $table the table that new rows will be inserted into. @@ -520,7 +554,7 @@ class Query extends \yii\base\Object */ public function insert($table, $columns) { - $this->operation = array('insert', $table, $columns, array()); + $this->operation = array(__FUNCTION__, $table, $columns, array()); return $this; } @@ -537,7 +571,7 @@ class Query extends \yii\base\Object public function update($table, $columns, $condition = '', $params = array()) { $this->addParams($params); - $this->operation = array('update', $table, $columns, $condition, array()); + $this->operation = array(__FUNCTION__, $table, $columns, $condition, array()); return $this; } @@ -551,7 +585,7 @@ class Query extends \yii\base\Object */ public function delete($table, $condition = '', $params = array()) { - $this->operation = array('delete', $table, $condition); + $this->operation = array(__FUNCTION__, $table, $condition); return $this->addParams($params); } @@ -575,7 +609,7 @@ class Query extends \yii\base\Object */ public function createTable($table, $columns, $options = null) { - $this->operation = array('createTable', $table, $columns, $options); + $this->operation = array(__FUNCTION__, $table, $columns, $options); return $this; } @@ -587,7 +621,7 @@ class Query extends \yii\base\Object */ public function renameTable($table, $newName) { - $this->operation = array('renameTable', $table, $newName); + $this->operation = array(__FUNCTION__, $table, $newName); return $this; } @@ -598,7 +632,7 @@ class Query extends \yii\base\Object */ public function dropTable($table) { - $this->operation = array('dropTable', $table); + $this->operation = array(__FUNCTION__, $table); return $this; } @@ -609,7 +643,7 @@ class Query extends \yii\base\Object */ public function truncateTable($table) { - $this->operation = array('truncateTable', $table); + $this->operation = array(__FUNCTION__, $table); return $this; } @@ -624,7 +658,7 @@ class Query extends \yii\base\Object */ public function addColumn($table, $column, $type) { - $this->operation = array('addColumn', $table, $column, $type); + $this->operation = array(__FUNCTION__, $table, $column, $type); return $this; } @@ -636,7 +670,7 @@ class Query extends \yii\base\Object */ public function dropColumn($table, $column) { - $this->operation = array('dropColumn', $table, $column); + $this->operation = array(__FUNCTION__, $table, $column); return $this; } @@ -649,7 +683,7 @@ class Query extends \yii\base\Object */ public function renameColumn($table, $name, $newName) { - $this->operation = array('renameColumn', $table, $name, $newName); + $this->operation = array(__FUNCTION__, $table, $name, $newName); return $this; } @@ -664,7 +698,7 @@ class Query extends \yii\base\Object */ public function alterColumn($table, $column, $type) { - $this->operation = array('alterColumn', $table, $column, $type); + $this->operation = array(__FUNCTION__, $table, $column, $type); return $this; } @@ -682,7 +716,7 @@ class Query extends \yii\base\Object */ public function addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete = null, $update = null) { - $this->operation = array('addForeignKey', $name, $table, $columns, $refTable, $refColumns, $delete, $update); + $this->operation = array(__FUNCTION__, $name, $table, $columns, $refTable, $refColumns, $delete, $update); return $this; } @@ -694,7 +728,7 @@ class Query extends \yii\base\Object */ public function dropForeignKey($name, $table) { - $this->operation = array('dropForeignKey', $name, $table); + $this->operation = array(__FUNCTION__, $name, $table); return $this; } @@ -709,7 +743,7 @@ class Query extends \yii\base\Object */ public function createIndex($name, $table, $columns, $unique = false) { - $this->operation = array('createIndex', $name, $table, $columns, $unique); + $this->operation = array(__FUNCTION__, $name, $table, $columns, $unique); return $this; } @@ -721,39 +755,7 @@ class Query extends \yii\base\Object */ public function dropIndex($name, $table) { - $this->operation = array('dropIndex', $name, $table); - return $this; - } - - /** - * Sets the parameters to be bound to the query. - * @param array list of query parameter values indexed by parameter placeholders. - * For example, `array(':name'=>'Dan', ':age'=>31)`. - * @return Query the query object itself - * @see addParams() - */ - public function params($params) - { - $this->params = $params; - return $this; - } - - /** - * Adds additional parameters to be bound to the query. - * @param array list of query parameter values indexed by parameter placeholders. - * For example, `array(':name'=>'Dan', ':age'=>31)`. - * @return Query the query object itself - * @see params() - */ - public function addParams($params) - { - foreach ($params as $name => $value) { - if (is_integer($name)) { - $this->params[] = $value; - } else { - $this->params[$name] = $value; - } - } + $this->operation = array(__FUNCTION__, $name, $table); return $this; } diff --git a/framework/db/dao/QueryBuilder.php b/framework/db/dao/QueryBuilder.php index e4a7e9b..3790f9f 100644 --- a/framework/db/dao/QueryBuilder.php +++ b/framework/db/dao/QueryBuilder.php @@ -34,6 +34,11 @@ class QueryBuilder extends \yii\base\Object */ public $schema; /** + * @var string the separator between different fragments of a SQL statement. + * Defaults to an empty space. This is mainly used by [[build()]] when generating a SQL statement. + */ + public $separator = " "; + /** * @var Query the Query object. This is set when calling [[build()]] to generate a non-SELECT SQL statement. */ private $_query; @@ -49,32 +54,36 @@ class QueryBuilder extends \yii\base\Object } /** - * @param Query $query - * @return string + * Generates a SQL statement from a [[Query]] object. + * Note that when generating SQL statements for INSERT and UPDATE queries, + * the query object's [[Query::params]] property may be appended with new parameters. + * @param Query $query the [[Query]] object from which the SQL statement will be generated + * @return string the generated SQL statement */ public function build($query) { - // non-SELECT query if ($query->operation !== null) { + // non-SELECT query $this->_query = $query; $method = array_shift($query->operation); $sql = call_user_func_array(array($this, $method), $query->operation); $this->_query = null; return $sql; + } else { + // SELECT query + $clauses = array( + $this->buildSelect($query), + $this->buildFrom($query), + $this->buildJoin($query), + $this->buildWhere($query), + $this->buildGroupBy($query), + $this->buildHaving($query), + $this->buildUnion($query), + $this->buildOrderBy($query), + $this->buildLimit($query), + ); + return implode($this->separator, array_filter($clauses)); } - // SELECT query - $clauses = array( - $this->buildSelect($query), - $this->buildFrom($query), - $this->buildJoin($query), - $this->buildWhere($query), - $this->buildGroupBy($query), - $this->buildHaving($query), - $this->buildUnion($query), - $this->buildOrderBy($query), - $this->buildLimit($query), - ); - return implode("\n", array_filter($clauses)); } /** @@ -82,7 +91,8 @@ class QueryBuilder extends \yii\base\Object * The method will properly escape the column names, and bind the values to be inserted. * @param string $table the table that new rows will be inserted into. * @param array $columns the column data (name=>value) to be inserted into the table. - * @param array $params the parameters to be bound to the query. + * @param array $params the parameters to be bound to the query. This method will modify + * this parameter by appending new parameters to be bound to the query. * @return integer number of rows affected by the execution. */ public function insert($table, $columns, &$params = array()) @@ -119,7 +129,8 @@ class QueryBuilder extends \yii\base\Object * @param array $columns the column data (name=>value) to be updated. * @param mixed $condition the condition that will be put in the WHERE part. Please * refer to [[Query::where()]] on how to specify condition. - * @param array $params the parameters to be bound to the query. + * @param array $params the parameters to be bound to the query. This method will modify + * this parameter by appending new parameters to be bound to the query. * @return integer number of rows affected by the execution. */ public function update($table, $columns, $condition = '', &$params = array()) diff --git a/framework/db/dao/Schema.php b/framework/db/dao/Schema.php index af3b249..d5826e4 100644 --- a/framework/db/dao/Schema.php +++ b/framework/db/dao/Schema.php @@ -13,7 +13,13 @@ namespace yii\db\dao; use yii\db\Exception; /** - * Schema is the base class for retrieving metadata information. + * Schema represents the meta data of a database. + * + * Schema retrieves and maintains the meta data of database tables and columns. + * + * @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. * * @author Qiang Xue * @since 2.0 @@ -37,18 +43,26 @@ abstract class Schema extends \yii\base\Object const TYPE_MONEY = 'money'; /** - * @var \yii\db\dao\Connection the database connection + * @var Connection the database connection */ public $connection; - + /** + * @var array list of ALL table names in the database + */ private $_tableNames = array(); + /** + * @var array list of loaded table meta data (table name => TableSchema) + */ private $_tables = array(); + /** + * @var QueryBuilder the query builder for this database + */ private $_builder; /** * Loads the metadata for the specified table. * @param string $name table name - * @return TableSchema driver dependent table metadata, null if the table does not exist. + * @return TableSchema DBMS-dependent table metadata, null if the table does not exist. */ abstract protected function loadTableSchema($name); @@ -64,31 +78,28 @@ abstract class Schema extends \yii\base\Object /** * Obtains the metadata for the named table. * @param string $name table name. The table name may contain schema name if any. Do not quote the table name. + * @param boolean $refresh whether to reload the table schema even if it is found in the cache. * @return TableSchema table metadata. Null if the named table does not exist. */ - public function getTableSchema($name) + public function getTableSchema($name, $refresh = false) { - if (isset($this->_tables[$name])) { + if (isset($this->_tables[$name]) && !$refresh) { return $this->_tables[$name]; } - if (strpos($name, '{{') !== false) { - $realName = preg_replace('/\{\{(.*?)\}\}/', $this->connection->tablePrefix . '$1', $name); - } else { - $realName = $name; - } - $db = $this->connection; + $realName = $db->expandTablePrefix($name); + // temporarily disable query caching if ($db->queryCachingDuration >= 0) { $qcDuration = $db->queryCachingDuration; $db->queryCachingDuration = -1; } - if (!in_array($name, $db->schemaCachingExclude) && $db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) { - $key = __CLASS__ . "/{$db->dsn}/{$db->username}/{$name}"; - if (($table = $cache->get($key)) === false) { + if (!in_array($name, $db->schemaCachingExclude, true) && $db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) { + $key = $this->getCacheKey($name); + if ($refresh || ($table = $cache->get($key)) === false) { $table = $this->loadTableSchema($realName); if ($table !== null) { $cache->set($key, $table, $db->schemaCachingDuration); @@ -107,10 +118,20 @@ abstract class Schema extends \yii\base\Object } /** + * Returns the cache key for the specified table name. + * @param string $name the table name + * @return string the cache key + */ + public function getCacheKey($name) + { + return __CLASS__ . "/{$this->connection->dsn}/{$this->connection->username}/{$name}"; + } + + /** * Returns the metadata for all tables in the database. * @param string $schema the schema of the tables. Defaults to empty string, meaning the current or default schema. * @return array the metadata for all tables in the database. - * Each array element is an instance of {@link CDbTableSchema} (or its child class). + * Each array element is an instance of [[TableSchema]] (or its child class). */ public function getTableSchemas($schema = '') { @@ -158,8 +179,7 @@ abstract class Schema extends \yii\base\Object $db = $this->connection; if ($db->schemaCachingDuration >= 0 && ($cache = \Yii::$application->getComponent($db->schemaCacheID)) !== null) { foreach ($this->_tables as $name => $table) { - $key = __CLASS__ . ":{$db->dsn}/{$db->username}/{$name}"; - $cache->delete($key); + $cache->delete($this->getCacheKey($name)); } } $this->_tables = array(); @@ -209,8 +229,7 @@ abstract class Schema extends \yii\base\Object if (($pos = strrpos($name, '.')) !== false) { $prefix = $this->quoteTableName(substr($name, 0, $pos)) . '.'; $name = substr($name, $pos + 1); - } else - { + } else { $prefix = ''; } return $prefix . $this->quoteSimpleColumnName($name); diff --git a/framework/db/dao/TableSchema.php b/framework/db/dao/TableSchema.php index cfd475a..a5a576a 100644 --- a/framework/db/dao/TableSchema.php +++ b/framework/db/dao/TableSchema.php @@ -13,7 +13,9 @@ namespace yii\db\dao; /** * TableSchema is the base class for representing the metadata of a database table. * - * It may be extended by different DBMS driver to provide DBMS-specific table metadata. + * It may be extended by different DBMS driver to represent DBMS-specific table metadata. + * + * @property array $columnNames list of column names * * @author Qiang Xue * @since 2.0 @@ -61,7 +63,7 @@ class TableSchema extends \yii\base\Object * Gets the named column metadata. * This is a convenient method for retrieving a named column even if it does not exist. * @param string $name column name - * @return CDbColumnSchema metadata of the named column. Null if the named column does not exist. + * @return ColumnSchema metadata of the named column. Null if the named column does not exist. */ public function getColumn($name) { @@ -69,6 +71,7 @@ class TableSchema extends \yii\base\Object } /** + * Returns the names of all columns in this table. * @return array list of column names */ public function getColumnNames() diff --git a/framework/db/dao/Transaction.php b/framework/db/dao/Transaction.php index fc261b1..081037b 100644 --- a/framework/db/dao/Transaction.php +++ b/framework/db/dao/Transaction.php @@ -15,7 +15,7 @@ use yii\db\Exception; /** * Transaction represents a DB transaction. * - * It is usually created by calling [[Connection::beginTransaction]]. + * It is usually created by calling [[Connection::beginTransaction()]]. * * The following code is a typical example of using transactions (note that some * DBMS may not support transactions): @@ -39,7 +39,7 @@ class Transaction extends \yii\base\Object { /** * @var boolean whether this transaction is active. Only an active transaction - * can [[commit]] or [[rollBack]]. This property is set true when the transaction is started. + * can [[commit()]] or [[rollBack()]]. This property is set true when the transaction is started. */ public $active; /** diff --git a/framework/db/dao/mysql/ColumnSchema.php b/framework/db/dao/mysql/ColumnSchema.php index bbcd1b6..4ec9ce1 100644 --- a/framework/db/dao/mysql/ColumnSchema.php +++ b/framework/db/dao/mysql/ColumnSchema.php @@ -88,7 +88,7 @@ class ColumnSchema extends \yii\db\dao\ColumnSchema } } - $this->phpType = $this->getPhpType(); + $this->phpType = $this->extractPhpType(); } /**