Browse Source

...

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
cf10943cd3
  1. 90
      framework/db/ar/ActiveFinder.php
  2. 26
      framework/db/ar/ActiveRecord.php
  3. 117
      framework/db/dao/Query.php
  4. 9
      framework/db/dao/QueryBuilder.php
  5. 12
      tests/unit/framework/db/ar/ActiveRecordTest.php

90
framework/db/ar/ActiveFinder.php

@ -17,7 +17,8 @@ use yii\db\Exception;
/** /**
* ActiveFinder.php is ... * ActiveFinder.php is ...
* todo: add SQL monitor * todo: add SQL monitor
* * todo: better handling on join() support in QueryBuilder: use regexp to detect table name and quote it
* todo: do not support anonymous parameter binding
* todo: add ActiveFinderBuilder * todo: add ActiveFinderBuilder
* todo: quote join/on part of the relational query * todo: quote join/on part of the relational query
* todo: modify QueryBuilder about join() methods * todo: modify QueryBuilder about join() methods
@ -29,6 +30,7 @@ use yii\db\Exception;
* todo: lazy loading * todo: lazy loading
* todo: scope * todo: scope
* todo: test via option * todo: test via option
* todo: count, sum, exists
* *
* @property integer $count * @property integer $count
* *
@ -80,6 +82,10 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra
$this->query = new Query; $this->query = new Query;
} }
/**
* Executes query and returns all results as an array.
* @return array the query results. If the query results in nothing, an empty array will be returned.
*/
public function all() public function all()
{ {
if ($this->records === null) { if ($this->records === null) {
@ -89,15 +95,14 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra
} }
/** /**
* @param boolean $limitOne * Executes query and returns a single row of result.
* @return null|ActiveRecord * @return null|array|ActiveRecord the single row of query result. Depending on the setting of [[asArray]],
* the query result may be either an array or an ActiveRecord object. Null will be returned
* if the query results in nothing.
*/ */
public function one($limitOne = true) public function one()
{ {
if ($this->records === null) { if ($this->records === null) {
if ($limitOne) {
$this->limit(1);
}
$this->records = $this->findRecords(); $this->records = $this->findRecords();
} }
return isset($this->records[0]) ? $this->records[0] : null; return isset($this->records[0]) ? $this->records[0] : null;
@ -442,96 +447,73 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra
} }
/** /**
* Appends an INNER JOIN part to the query. * Appends a JOIN part to the query.
* The first parameter specifies what type of join it is.
* @param string $type the type of join, such as INNER JOIN, LEFT JOIN.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters. * @return Query the query object itself
* @return ActiveFinder the query object itself
*/ */
public function join($table, $condition, $params = array()) public function join($type, $table, $on = '', $params = array())
{ {
if (is_array($params)) { $this->query->join($type, $table, $on, $params);
$this->query->join($table, $condition, $params);
} else {
call_user_func_array(array($this->query, __FUNCTION__), func_get_args());
}
return $this; return $this;
} }
/** /**
* Appends a LEFT OUTER JOIN part to the query. * Appends an INNER JOIN part to the query.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return ActiveFinder the query object itself * @return ActiveFinder the query object itself
*/ */
public function leftJoin($table, $condition, $params = array()) public function innerJoin($table, $on, $params = array())
{ {
if (is_array($params)) { $this->query->join($table, $on, $params);
$this->query->leftJoin($table, $condition, $params);
} else {
call_user_func_array(array($this->query, __FUNCTION__), func_get_args());
}
return $this; return $this;
} }
/** /**
* Appends a RIGHT OUTER JOIN part to the query. * Appends a LEFT OUTER JOIN part to the query.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query * @param array $params the parameters (name=>value) to be bound to the query
* @return ActiveFinder the query object itself * @return ActiveFinder the query object itself
*/ */
public function rightJoin($table, $condition, $params = array()) public function leftJoin($table, $on, $params = array())
{
if (is_array($params)) {
$this->query->rightJoin($table, $condition, $params);
} else {
call_user_func_array(array($this->query, __FUNCTION__), func_get_args());
}
return $this;
}
/**
* Appends a CROSS JOIN part to the query.
* Note that not all DBMS support CROSS JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return ActiveFinder the query object itself
*/
public function crossJoin($table)
{ {
$this->query->crossJoin($table); $this->query->leftJoin($table, $on, $params);
return $this; return $this;
} }
/** /**
* Appends a NATURAL JOIN part to the query. * Appends a RIGHT OUTER JOIN part to the query.
* Note that not all DBMS support NATURAL JOIN.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return ActiveFinder the query object itself * @return ActiveFinder the query object itself
*/ */
public function naturalJoin($table) public function rightJoin($table, $on, $params = array())
{ {
$this->query->naturalJoin($table); $this->query->rightJoin($table, $on, $params);
return $this; return $this;
} }
@ -746,7 +728,7 @@ class ActiveFinder extends \yii\base\Object implements \IteratorAggregate, \Arra
$rows = $command->queryAll(); $rows = $command->queryAll();
if (!empty($this->with)) { if (isset($joinTree)) {
foreach ($rows as $row) { foreach ($rows as $row) {
$joinTree->populateData($row); $joinTree->populateData($row);
} }

26
framework/db/ar/ActiveRecord.php

@ -50,6 +50,17 @@ abstract class ActiveRecord extends Model
} }
/** /**
* Returns the database connection used by this AR class.
* By default, the "db" application component is used as the database connection.
* You may override this method if you want to use a different database connection.
* @return Connection the database connection used by this AR class.
*/
public static function getDbConnection()
{
return \Yii::$application->getDb();
}
/**
* Creates an [[ActiveFinder]] instance for query purpose. * Creates an [[ActiveFinder]] instance for query purpose.
* *
* Because [[ActiveFinder]] implements a set of query building methods, * Because [[ActiveFinder]] implements a set of query building methods,
@ -105,10 +116,6 @@ abstract class ActiveRecord extends Model
*/ */
public static function findBySql($sql, $params = array()) public static function findBySql($sql, $params = array())
{ {
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$finder = static::createActiveFinder(); $finder = static::createActiveFinder();
$finder->sql = $sql; $finder->sql = $sql;
return $finder->params($params); return $finder->params($params);
@ -155,17 +162,6 @@ abstract class ActiveRecord extends Model
} }
/** /**
* Returns the database connection used by this AR class.
* By default, the "db" application component is used as the database connection.
* You may override this method if you want to use a different database connection.
* @return Connection the database connection used by this AR class.
*/
public static function getDbConnection()
{
return \Yii::$application->getDb();
}
/**
* Declares the name of the database table associated with this AR class. * Declares the name of the database table associated with this AR class.
* By default this method returns the class name as the table name by calling [[Text::camel2id()]]. * By default this method returns the class name as the table name by calling [[Text::camel2id()]].
* For example, 'Customer' becomes 'customer', and 'OrderDetail' becomes 'order_detail'. * For example, 'Customer' becomes 'customer', and 'OrderDetail' becomes 'order_detail'.

117
framework/db/dao/Query.php

@ -169,17 +169,10 @@ class Query extends \yii\base\Object
* @param string|array $condition the conditions that will be put in the WHERE part. * @param string|array $condition the conditions that will be put in the WHERE part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
*/ */
public function update($table, $columns, $condition = '', $params = array()) public function update($table, $columns, $condition = '', $params = array())
{ {
if (!is_array($params)) {
$params = func_get_args();
array_shift($params);
array_shift($params);
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
$this->operation = array(__FUNCTION__, $table, $columns, $condition, array()); $this->operation = array(__FUNCTION__, $table, $columns, $condition, array());
return $this; return $this;
@ -191,16 +184,10 @@ class Query extends \yii\base\Object
* @param string|array $condition the conditions that will be put in the WHERE part. * @param string|array $condition the conditions that will be put in the WHERE part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
*/ */
public function delete($table, $condition = '', $params = array()) public function delete($table, $condition = '', $params = array())
{ {
if (!is_array($params)) {
$params = func_get_args();
array_shift($params);
unset($params[0]);
}
$this->operation = array(__FUNCTION__, $table, $condition); $this->operation = array(__FUNCTION__, $table, $condition);
return $this->addParams($params); return $this->addParams($params);
} }
@ -484,8 +471,6 @@ class Query extends \yii\base\Object
* *
* @param string|array $condition the conditions that should be put in the WHERE part. * @param string|array $condition the conditions that should be put in the WHERE part.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* For anonymous parameters, they can alternatively be specified as separate parameters to this method.
* For example, `where('type=? AND status=?', 100, 1)`.
* @return Query the query object itself * @return Query the query object itself
* @see andWhere() * @see andWhere()
* @see orWhere() * @see orWhere()
@ -493,10 +478,6 @@ class Query extends \yii\base\Object
public function where($condition, $params = array()) public function where($condition, $params = array())
{ {
$this->where = $condition; $this->where = $condition;
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
@ -507,7 +488,6 @@ class Query extends \yii\base\Object
* @param string|array $condition the new WHERE condition. Please refer to [[where()]] * @param string|array $condition the new WHERE condition. Please refer to [[where()]]
* on how to specify this parameter. * on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see where() * @see where()
* @see orWhere() * @see orWhere()
@ -519,10 +499,6 @@ class Query extends \yii\base\Object
} else { } else {
$this->where = array('and', $this->where, $condition); $this->where = array('and', $this->where, $condition);
} }
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
@ -533,7 +509,6 @@ class Query extends \yii\base\Object
* @param string|array $condition the new WHERE condition. Please refer to [[where()]] * @param string|array $condition the new WHERE condition. Please refer to [[where()]]
* on how to specify this parameter. * on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see where() * @see where()
* @see andWhere() * @see andWhere()
@ -545,109 +520,78 @@ class Query extends \yii\base\Object
} else { } else {
$this->where = array('or', $this->where, $condition); $this->where = array('or', $this->where, $condition);
} }
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
/** /**
* Appends an INNER JOIN part to the query. * Appends a JOIN part to the query.
* The first parameter specifies what type of join it is.
* @param string $type the type of join, such as INNER JOIN, LEFT JOIN.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
*/ */
public function join($table, $condition, $params = array()) public function join($type, $table, $on = '', $params = array())
{ {
$this->join[] = array('JOIN', $table, $condition); $this->join[] = array($type, $table, $on);
if (!is_array($params)) {
$params = func_get_args();
array_shift($params);
unset($params[0]);
}
return $this->addParams($params); return $this->addParams($params);
} }
/** /**
* Appends a LEFT OUTER JOIN part to the query. * Appends an INNER JOIN part to the query.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query * @param array $params the parameters (name=>value) to be bound to the query.
* @return Query the query object itself * @return Query the query object itself
*/ */
public function leftJoin($table, $condition, $params = array()) public function innerJoin($table, $on = '', $params = array())
{ {
$this->join[] = array('LEFT JOIN', $table, $condition); $this->join[] = array('INNER JOIN', $table, $on);
if (!is_array($params)) {
$params = func_get_args();
array_shift($params);
unset($params[0]);
}
return $this->addParams($params); return $this->addParams($params);
} }
/** /**
* Appends a RIGHT OUTER JOIN part to the query. * Appends a LEFT OUTER JOIN part to the query.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $condition the join condition that should appear in the ON part. * @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query * @param array $params the parameters (name=>value) to be bound to the query
* @return Query the query object itself * @return Query the query object itself
*/ */
public function rightJoin($table, $condition, $params = array()) public function leftJoin($table, $on = '', $params = array())
{ {
$this->join[] = array('RIGHT JOIN', $table, $condition); $this->join[] = array('LEFT JOIN', $table, $on);
if (!is_array($params)) {
$params = func_get_args();
array_shift($params);
unset($params[0]);
}
return $this->addParams($params); return $this->addParams($params);
} }
/** /**
* Appends a CROSS JOIN part to the query. * Appends a RIGHT OUTER JOIN part to the query.
* Note that not all DBMS support CROSS JOIN.
* @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression).
* @return Query the query object itself
*/
public function crossJoin($table)
{
$this->join[] = array('CROSS JOIN', $table);
return $this;
}
/**
* Appends a NATURAL JOIN part to the query.
* Note that not all DBMS support NATURAL JOIN.
* @param string $table the table to be joined. * @param string $table the table to be joined.
* Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u'). * Table name can contain schema prefix (e.g. 'public.tbl_user') and/or table alias (e.g. 'tbl_user u').
* The method will automatically quote the table name unless it contains some parenthesis * The method will automatically quote the table name unless it contains some parenthesis
* (which means the table is given as a sub-query or DB expression). * (which means the table is given as a sub-query or DB expression).
* @param string|array $on the join condition that should appear in the ON part.
* Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query
* @return Query the query object itself * @return Query the query object itself
*/ */
public function naturalJoin($table) public function rightJoin($table, $on = '', $params = array())
{ {
$this->join[] = array('NATURAL JOIN', $table); $this->join[] = array('RIGHT JOIN', $table, $on);
return $this; return $this->addParams($params);
} }
/** /**
@ -695,7 +639,6 @@ class Query extends \yii\base\Object
* @param string|array $condition the conditions to be put after HAVING. * @param string|array $condition the conditions to be put after HAVING.
* Please refer to [[where()]] on how to specify this parameter. * Please refer to [[where()]] on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see andHaving() * @see andHaving()
* @see orHaving() * @see orHaving()
@ -703,10 +646,6 @@ class Query extends \yii\base\Object
public function having($condition, $params = array()) public function having($condition, $params = array())
{ {
$this->having = $condition; $this->having = $condition;
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
@ -717,7 +656,6 @@ class Query extends \yii\base\Object
* @param string|array $condition the new HAVING condition. Please refer to [[where()]] * @param string|array $condition the new HAVING condition. Please refer to [[where()]]
* on how to specify this parameter. * on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see having() * @see having()
* @see orHaving() * @see orHaving()
@ -729,10 +667,6 @@ class Query extends \yii\base\Object
} else { } else {
$this->having = array('and', $this->having, $condition); $this->having = array('and', $this->having, $condition);
} }
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
@ -743,7 +677,6 @@ class Query extends \yii\base\Object
* @param string|array $condition the new HAVING condition. Please refer to [[where()]] * @param string|array $condition the new HAVING condition. Please refer to [[where()]]
* on how to specify this parameter. * on how to specify this parameter.
* @param array $params the parameters (name=>value) to be bound to the query. * @param array $params the parameters (name=>value) to be bound to the query.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see having() * @see having()
* @see andHaving() * @see andHaving()
@ -755,10 +688,6 @@ class Query extends \yii\base\Object
} else { } else {
$this->having = array('or', $this->having, $condition); $this->having = array('or', $this->having, $condition);
} }
if (!is_array($params)) {
$params = func_get_args();
unset($params[0]);
}
$this->addParams($params); $this->addParams($params);
return $this; return $this;
} }
@ -840,7 +769,6 @@ class Query extends \yii\base\Object
* Sets the parameters to be bound to the query. * Sets the parameters to be bound to the query.
* @param array $params list of query parameter values indexed by parameter placeholders. * @param array $params list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`. * For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see addParams() * @see addParams()
*/ */
@ -854,7 +782,6 @@ class Query extends \yii\base\Object
* Adds additional parameters to be bound to the query. * Adds additional parameters to be bound to the query.
* @param array $params list of query parameter values indexed by parameter placeholders. * @param array $params list of query parameter values indexed by parameter placeholders.
* For example, `array(':name'=>'Dan', ':age'=>31)`. * For example, `array(':name'=>'Dan', ':age'=>31)`.
* Please refer to [[where()]] on alternative syntax of specifying anonymous parameters.
* @return Query the query object itself * @return Query the query object itself
* @see params() * @see params()
*/ */

9
framework/db/dao/QueryBuilder.php

@ -488,7 +488,7 @@ class QueryBuilder extends \yii\base\Object
); );
if (!is_array($condition)) { if (!is_array($condition)) {
return $condition; return (string)$condition;
} elseif ($condition === array()) { } elseif ($condition === array()) {
return ''; return '';
} }
@ -733,8 +733,11 @@ class QueryBuilder extends \yii\base\Object
} }
} }
$joins[$i] = strtoupper($join[0]) . ' ' . $table; $joins[$i] = strtoupper($join[0]) . ' ' . $table;
if (isset($join[2])) { // join condition if (isset($join[2])) {
$joins[$i] .= ' ON ' . $this->buildCondition($join[2]); $condition = $this->buildCondition($join[2]);
if ($condition !== '') {
$joins[$i] .= ' ON ' . $this->buildCondition($join[2]);
}
} }
} else { } else {
throw new Exception('A join clause must be specified as an array of at least two elements.'); throw new Exception('A join clause must be specified as an array of at least two elements.');

12
tests/unit/framework/db/ar/ActiveRecordTest.php

@ -63,7 +63,8 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$pk = array('order_id' => 2, 'item_id' => 4); $pk = array('order_id' => 2, 'item_id' => 4);
$orderItem = OrderItem::find($pk)->one(); $orderItem = OrderItem::find($pk)->one();
$this->assertEquals(1, $orderItem->quantity); $this->assertEquals(1, $orderItem->quantity);
$orderItem->saveCounters(array('quantity' => -1)); $ret = $orderItem->saveCounters(array('quantity' => -1));
$this->assertTrue($ret);
$this->assertEquals(0, $orderItem->quantity); $this->assertEquals(0, $orderItem->quantity);
$orderItem = OrderItem::find($pk)->one(); $orderItem = OrderItem::find($pk)->one();
$this->assertEquals(0, $orderItem->quantity); $this->assertEquals(0, $orderItem->quantity);
@ -71,9 +72,10 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// updateAll // updateAll
$customer = Customer::find(3)->one(); $customer = Customer::find(3)->one();
$this->assertEquals('user3', $customer->name); $this->assertEquals('user3', $customer->name);
Customer::updateAll(array( $ret = Customer::updateAll(array(
'name' => 'temp', 'name' => 'temp',
), array('id' => 3)); ), array('id' => 3));
$this->assertEquals(1, $ret);
$customer = Customer::find(3)->one(); $customer = Customer::find(3)->one();
$this->assertEquals('temp', $customer->name); $this->assertEquals('temp', $customer->name);
@ -81,9 +83,10 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$pk = array('order_id' => 1, 'item_id' => 2); $pk = array('order_id' => 1, 'item_id' => 2);
$orderItem = OrderItem::find($pk)->one(); $orderItem = OrderItem::find($pk)->one();
$this->assertEquals(2, $orderItem->quantity); $this->assertEquals(2, $orderItem->quantity);
OrderItem::updateCounters(array( $ret = OrderItem::updateCounters(array(
'quantity' => 3, 'quantity' => 3,
), $pk); ), $pk);
$this->assertEquals(1, $ret);
$orderItem = OrderItem::find($pk)->one(); $orderItem = OrderItem::find($pk)->one();
$this->assertEquals(5, $orderItem->quantity); $this->assertEquals(5, $orderItem->quantity);
} }
@ -101,7 +104,8 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// deleteAll // deleteAll
$customers = Customer::find()->all(); $customers = Customer::find()->all();
$this->assertEquals(2, count($customers)); $this->assertEquals(2, count($customers));
Customer::deleteAll(); $ret = Customer::deleteAll();
$this->assertEquals(2, $ret);
$customers = Customer::find()->all(); $customers = Customer::find()->all();
$this->assertEquals(0, count($customers)); $this->assertEquals(0, count($customers));
} }

Loading…
Cancel
Save