Browse Source

renamed groupBy and orderBy to be group and order.

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
769a114d39
  1. 48
      framework/db/ar/ActiveFinder.php
  2. 8
      framework/db/ar/ActiveRecord.php
  3. 9
      framework/db/ar/ActiveRelation.php
  4. 12
      framework/db/ar/JoinElement.php
  5. 54
      framework/db/dao/BaseQuery.php
  6. 8
      framework/db/dao/QueryBuilder.php
  7. 2
      tests/unit/data/ar/Customer.php
  8. 14
      tests/unit/framework/db/ar/ActiveRecordTest.php
  9. 13
      tests/unit/framework/db/dao/CommandTest.php
  10. 30
      tests/unit/framework/db/dao/QueryTest.php

48
framework/db/ar/ActiveFinder.php

@ -103,6 +103,7 @@ class ActiveFinder extends \yii\base\Object
private $_joinCount;
private $_tableAliases;
private $_hasMany;
/**
* @param ActiveQuery $query
@ -112,6 +113,7 @@ class ActiveFinder extends \yii\base\Object
{
$this->_joinCount = 0;
$this->_tableAliases = array();
$this->_hasMany = false;
$joinTree = new JoinElement($this->_joinCount++, $query, null, null);
$this->buildJoinTree($joinTree, $query->with);
$this->initJoinTree($joinTree);
@ -123,7 +125,15 @@ class ActiveFinder extends \yii\base\Object
$joinTree->createRecord($row);
}
return $query->indexBy !== null ? $joinTree->records : array_values($joinTree->records);
if ($query->indexBy !== null) {
$records = array();
foreach ($joinTree->records as $record) {
$records[$record[$query->indexBy]] = $record;
}
return $records;
} else {
return array_values($joinTree->records);
}
}
protected function applyScopes($query)
@ -182,7 +192,8 @@ class ActiveFinder extends \yii\base\Object
throw new Exception("$modelClass has no relation named '$with'.");
}
$relation = clone $relations[$with];
if ($relation->via !== null && isset($relations[$relation->via])) {
if (is_string($relation->via) && isset($relations[$relation->via])) {
// join via an existing relation
$parent2 = $this->buildJoinTree($parent, $relation->via);
$relation->via = null;
if ($parent2->joinOnly === null) {
@ -213,6 +224,14 @@ class ActiveFinder extends \yii\base\Object
} else {
$alias = 't';
}
if ($element->query instanceof ActiveRelation) {
if ($element->query->hasMany) {
$this->_hasMany = true;
}
if ($element->parent->query->asArray !== null && $element->query->asArray === null) {
$element->query->asArray = $element->parent->query->asArray;
}
}
$count = 0;
while (isset($this->_tableAliases[$alias])) {
$alias = 't' . $count++;
@ -279,8 +298,9 @@ class ActiveFinder extends \yii\base\Object
}
if ($element->query instanceof ActiveRelation) {
if ($element->query->via !== null) {
$query->join[] = strtr($element->query->via, $quotedPrefixes);
if (is_array($element->query->via)) {
// todo: join via a pivot table
// $query->join[] = strtr($element->query->via, $quotedPrefixes);
}
if ($element->query->joinType === null) {
@ -311,21 +331,21 @@ class ActiveFinder extends \yii\base\Object
}
}
if ($element->query->orderBy !== null) {
if (!is_array($element->query->orderBy)) {
$element->query->orderBy = preg_split('/\s*,\s*/', trim($element->query->orderBy), -1, PREG_SPLIT_NO_EMPTY);
if ($element->query->order !== null) {
if (!is_array($element->query->order)) {
$element->query->order = preg_split('/\s*,\s*/', trim($element->query->order), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($element->query->orderBy as $orderBy) {
$query->orderBy[] = strtr($orderBy, $prefixes);
foreach ($element->query->order as $order) {
$query->order[] = strtr($order, $prefixes);
}
}
if ($element->query->groupBy !== null) {
if (!is_array($element->query->groupBy)) {
$element->query->groupBy = preg_split('/\s*,\s*/', trim($element->query->groupBy), -1, PREG_SPLIT_NO_EMPTY);
if ($element->query->group !== null) {
if (!is_array($element->query->group)) {
$element->query->group = preg_split('/\s*,\s*/', trim($element->query->group), -1, PREG_SPLIT_NO_EMPTY);
}
foreach ($element->query->groupBy as $groupBy) {
$query->groupBy[] = strtr($groupBy, $prefixes);
foreach ($element->query->group as $group) {
$query->group[] = strtr($group, $prefixes);
}
}

8
framework/db/ar/ActiveRecord.php

@ -80,12 +80,12 @@ abstract class ActiveRecord extends Model
* // find all active customers and order them by their age:
* $customers = Customer::find()
* ->where(array('status' => 1))
* ->orderBy('age')
* ->order('age')
* ->all();
* // or alternatively:
* $customers = Customer::find(array(
* 'where' => array('status' => 1),
* 'orderBy' => 'age',
* 'order' => 'age',
* ))->all();
* ~~~
*
@ -114,7 +114,7 @@ abstract class ActiveRecord extends Model
/**
* Creates an [[ActiveQuery]] instance and query by a given SQL statement.
* Note that because the SQL statement is already specified, calling further
* query methods (such as `where()`, `orderBy()`) on [[ActiveQuery]] will have no effect.
* query methods (such as `where()`, `order()`) on [[ActiveQuery]] will have no effect.
* Methods such as `with()`, `asArray()` can still be called though.
* @param string $sql the SQL statement to be executed
* @param array $params parameters to be bound to the SQL statement during execution.
@ -267,7 +267,7 @@ abstract class ActiveRecord extends Model
* 'manager:Manager' => '@.id = ?.manager_id',
* 'assignments:Assignment[]' => array(
* 'on' => '@.owner_id = ?.id AND @.status = 1',
* 'orderBy' => '@.create_time DESC',
* 'order' => '@.create_time DESC',
* ),
* 'projects:Project[]' => array(
* 'via' => 'assignments',

9
framework/db/ar/ActiveRelation.php

@ -23,6 +23,13 @@ class ActiveRelation extends BaseActiveQuery
*/
public $name;
/**
* @var array the columns of the primary and foreign tables that establish the relation.
* The array keys must be columns of the table for this relation, and the array values
* must be the corresponding columns from the primary table. Do not prefix or quote the column names.
* They will be done automatically by Yii.
*/
public $link;
/**
* @var boolean whether this relation is a one-many relation
*/
public $hasMany;
@ -36,7 +43,7 @@ class ActiveRelation extends BaseActiveQuery
*/
public $on;
/**
* @var string
* @var string|array
*/
public $via;
}

12
framework/db/ar/JoinElement.php

@ -71,7 +71,6 @@ class JoinElement extends \yii\base\Object
*/
public function createRecord($row)
{
if ($this->query->indexBy === null) {
$pk = array();
foreach ($this->pkAlias as $alias) {
if (isset($row[$alias])) {
@ -81,16 +80,9 @@ class JoinElement extends \yii\base\Object
}
}
$pk = count($pk) === 1 ? $pk[0] : serialize($pk);
} else {
$pk = array_search($this->query->indexBy, $this->columnAliases);
if ($pk !== false) {
$pk = $row[$pk];
} else {
throw new Exception("Invalid indexBy: {$this->query->modelClass} has no attribute named '{$this->query->indexBy}'.");
}
}
// create record
// todo: asArray
if (isset($this->records[$pk])) {
$record = $this->records[$pk];
} else {
@ -120,7 +112,7 @@ class JoinElement extends \yii\base\Object
}
if ($child->query->hasMany) {
if ($child->query->indexBy !== null) {
$hash = $childRecord->{$child->query->indexBy};
$hash = $childRecord[$child->query->indexBy];
} else {
$hash = serialize($childRecord->getPrimaryKey());
}

54
framework/db/dao/BaseQuery.php

@ -60,12 +60,12 @@ class BaseQuery extends \yii\base\Object
* @var string|array how to sort the query results. This refers to the ORDER BY clause in a SQL statement.
* It can be either a string (e.g. `'id ASC, name DESC'`) or an array (e.g. `array('id ASC', 'name DESC')`).
*/
public $orderBy;
public $order;
/**
* @var string|array how to group the query results. This refers to the GROUP BY clause in a SQL statement.
* It can be either a string (e.g. `'company, department'`) or an array (e.g. `array('company', 'department')`).
*/
public $groupBy;
public $group;
/**
* @var string|array how to join with other tables. This refers to the JOIN clause in a SQL statement.
* It can either a string (e.g. `'LEFT JOIN tbl_user ON tbl_user.id=author_id'`) or an array (e.g.
@ -329,11 +329,11 @@ class BaseQuery extends \yii\base\Object
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addGroupBy()
* @see addGroup()
*/
public function groupBy($columns)
public function group($columns)
{
$this->groupBy = $columns;
$this->group = $columns;
return $this;
}
@ -344,20 +344,20 @@ class BaseQuery extends \yii\base\Object
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see groupBy()
* @see group()
*/
public function addGroupBy($columns)
public function addGroup($columns)
{
if (empty($this->groupBy)) {
$this->groupBy = $columns;
if (empty($this->group)) {
$this->group = $columns;
} else {
if (!is_array($this->groupBy)) {
$this->groupBy = preg_split('/\s*,\s*/', trim($this->groupBy), -1, PREG_SPLIT_NO_EMPTY);
if (!is_array($this->group)) {
$this->group = preg_split('/\s*,\s*/', trim($this->group), -1, PREG_SPLIT_NO_EMPTY);
}
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
$this->groupBy = array_merge($this->groupBy, $columns);
$this->group = array_merge($this->group, $columns);
}
return $this;
}
@ -427,11 +427,11 @@ class BaseQuery extends \yii\base\Object
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see addOrderBy()
* @see addOrder()
*/
public function orderBy($columns)
public function order($columns)
{
$this->orderBy = $columns;
$this->order = $columns;
return $this;
}
@ -442,20 +442,20 @@ class BaseQuery extends \yii\base\Object
* The method will automatically quote the column names unless a column contains some parenthesis
* (which means the column contains a DB expression).
* @return BaseQuery the query object itself
* @see orderBy()
* @see order()
*/
public function addOrderBy($columns)
public function addOrder($columns)
{
if (empty($this->orderBy)) {
$this->orderBy = $columns;
if (empty($this->order)) {
$this->order = $columns;
} else {
if (!is_array($this->orderBy)) {
$this->orderBy = preg_split('/\s*,\s*/', trim($this->orderBy), -1, PREG_SPLIT_NO_EMPTY);
if (!is_array($this->order)) {
$this->order = preg_split('/\s*,\s*/', trim($this->order), -1, PREG_SPLIT_NO_EMPTY);
}
if (!is_array($columns)) {
$columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
}
$this->orderBy = array_merge($this->orderBy, $columns);
$this->order = array_merge($this->order, $columns);
}
return $this;
}
@ -541,7 +541,7 @@ class BaseQuery extends \yii\base\Object
* takes precedence over this query.
* - [[where]], [[having]]: the new query's corresponding property value
* will be 'AND' together with the existing one.
* - [[params]], [[orderBy]], [[groupBy]], [[join]], [[union]]: the new query's
* - [[params]], [[order]], [[group]], [[join]], [[union]]: the new query's
* corresponding property value will be appended to the existing one.
*
* In general, the merging makes the resulting query more restrictive and specific.
@ -592,12 +592,12 @@ class BaseQuery extends \yii\base\Object
$this->addParams($query->params);
}
if ($query->orderBy !== null) {
$this->addOrderBy($query->orderBy);
if ($query->order !== null) {
$this->addOrder($query->order);
}
if ($query->groupBy !== null) {
$this->addGroupBy($query->groupBy);
if ($query->group !== null) {
$this->addGroup($query->group);
}
if ($query->join !== null) {

8
framework/db/dao/QueryBuilder.php

@ -68,10 +68,10 @@ class QueryBuilder extends \yii\base\Object
$this->buildFrom($query->from),
$this->buildJoin($query->join),
$this->buildWhere($query->where),
$this->buildGroupBy($query->groupBy),
$this->buildGroup($query->group),
$this->buildHaving($query->having),
$this->buildUnion($query->union),
$this->buildOrderBy($query->orderBy),
$this->buildOrder($query->order),
$this->buildLimit($query->limit, $query->offset),
);
return implode($this->separator, array_filter($clauses));
@ -756,7 +756,7 @@ class QueryBuilder extends \yii\base\Object
* @param string|array $columns
* @return string the GROUP BY clause
*/
public function buildGroupBy($columns)
public function buildGroup($columns)
{
if (empty($columns)) {
return '';
@ -779,7 +779,7 @@ class QueryBuilder extends \yii\base\Object
* @param string|array $columns
* @return string the ORDER BY clause built from [[query]].
*/
public function buildOrderBy($columns)
public function buildOrder($columns)
{
if (empty($columns)) {
return '';

2
tests/unit/data/ar/Customer.php

@ -25,7 +25,7 @@ class Customer extends ActiveRecord
{
return array(
'active' => function($q) {
return $q->andWhere('@.status = 1');
return $q->andWhere('@.status = ' . self::STATUS_ACTIVE);
},
);
}

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

@ -200,7 +200,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user3', $customer->name);
$customer = Customer::find()->select('id')->orderBy('id DESC')->one();
$customer = Customer::find()->select('id')->order('id DESC')->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(3, $customer->id);
$this->assertEquals(null, $customer->name);
@ -214,23 +214,27 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals(2, count($customers));
// asArray
$customers = Customer::find()->orderBy('id')->asArray()->all();
$customers = Customer::find()->order('id')->asArray()->all();
$this->assertEquals('user2', $customers[1]['name']);
// indexBy
$customers = Customer::find()->orderBy('id')->indexBy('name')->all();
$customers = Customer::find()->order('id')->indexBy('name')->all();
$this->assertEquals(2, $customers['user2']['id']);
}
public function testEagerLoading()
{
$customers = Customer::find()->with('orders')->orderBy('@.id')->all();
$customers = Customer::find()->with('orders')->order('@.id')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, count($customers[0]->orders));
$this->assertEquals(2, count($customers[1]->orders));
$this->assertEquals(0, count($customers[2]->orders));
$customers = Customer::find()->with('orders.customer')->orderBy('@.id')->all();
$customers = Customer::find()->with('orders.customer')->order('@.id')->all();
$this->assertEquals(3, count($customers));
$this->assertEquals(1, $customers[0]->orders[0]->customer->id);
$this->assertEquals(2, $customers[1]->orders[0]->customer->id);
$this->assertEquals(2, $customers[1]->orders[1]->customer->id);
}
/*

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

@ -21,19 +21,6 @@ class CommandTest extends \yiiunit\MysqlTestCase
$sql = 'SELECT * FROM tbl_customer';
$command = $db->createCommand($sql);
$this->assertEquals($sql, $command->sql);
// Query object
$query = new Query;
$query->select('id')->from('tbl_customer');
$command = $db->createCommand($query);
$this->assertEquals("SELECT `id` FROM `tbl_customer`", $command->sql);
// array
$command = $db->createCommand(array(
'select' => 'name',
'from' => 'tbl_customer',
));
$this->assertEquals("SELECT `name` FROM `tbl_customer`", $command->sql);
}
function testGetSetSql()

30
tests/unit/framework/db/dao/QueryTest.php

@ -13,7 +13,7 @@ class QueryTest extends \yiiunit\MysqlTestCase
{
// default
$query = new Query;
$query->select();
$query->select('*');
$this->assertEquals('*', $query->select);
$this->assertNull($query->distinct);
$this->assertEquals(null, $query->selectOption);
@ -53,17 +53,17 @@ class QueryTest extends \yiiunit\MysqlTestCase
}
function testGroupBy()
function testGroup()
{
$query = new Query;
$query->groupBy('team');
$this->assertEquals('team', $query->groupBy);
$query->group('team');
$this->assertEquals('team', $query->group);
$query->addGroupBy('company');
$this->assertEquals(array('team', 'company'), $query->groupBy);
$query->addGroup('company');
$this->assertEquals(array('team', 'company'), $query->group);
$query->addGroupBy('age');
$this->assertEquals(array('team', 'company', 'age'), $query->groupBy);
$query->addGroup('age');
$this->assertEquals(array('team', 'company', 'age'), $query->group);
}
function testHaving()
@ -82,17 +82,17 @@ class QueryTest extends \yiiunit\MysqlTestCase
$this->assertEquals(array(':id' => 1, ':name' => 'something', ':age' => '30'), $query->params);
}
function testOrderBy()
function testOrder()
{
$query = new Query;
$query->orderBy('team');
$this->assertEquals('team', $query->orderBy);
$query->order('team');
$this->assertEquals('team', $query->order);
$query->addOrderBy('company');
$this->assertEquals(array('team', 'company'), $query->orderBy);
$query->addOrder('company');
$this->assertEquals(array('team', 'company'), $query->order);
$query->addOrderBy('age');
$this->assertEquals(array('team', 'company', 'age'), $query->orderBy);
$query->addOrder('age');
$this->assertEquals(array('team', 'company', 'age'), $query->order);
}
function testLimitOffset()

Loading…
Cancel
Save