Browse Source

Implemented new scope declaration syntax.

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
8c26893992
  1. 11
      framework/db/ar/ActiveFinder.php
  2. 8
      framework/db/ar/ActiveQuery.php
  3. 6
      framework/db/ar/ActiveRecord.php
  4. 9
      tests/unit/data/ar/Customer.php
  5. 21
      tests/unit/framework/db/ar/ActiveRecordTest.php

11
framework/db/ar/ActiveFinder.php

@ -196,6 +196,7 @@ class ActiveFinder extends \yii\base\Object
$records[$row[$query->index]] = $row;
}
} else {
/** @var $class ActiveRecord */
$class = $query->modelClass;
if ($query->index === null) {
foreach ($rows as $row) {
@ -212,18 +213,20 @@ class ActiveFinder extends \yii\base\Object
protected function applyScopes($query)
{
/** @var $class ActiveRecord */
$class = $query->modelClass;
$class::defaultScope($query);
if (is_array($query->scopes)) {
$scopes = $class::scopes();
$model = new $class;
foreach ($query->scopes as $name => $params) {
if (is_integer($name)) {
if (is_string($params)) {
// scope name only without parameters
$name = $params;
$params = array();
}
if (isset($scopes[$name])) {
if (method_exists($class, $name)) {
array_unshift($params, $query);
call_user_func_array($scopes[$name], $params);
call_user_func_array(array($model, $name), $params);
} else {
throw new Exception("$class has no scope named '$name'.");
}

8
framework/db/ar/ActiveQuery.php

@ -46,11 +46,9 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
public function __call($name, $params)
{
$class = $this->modelClass;
$scopes = $class::scopes();
if (isset($scopes[$name])) {
array_unshift($params, $this);
return call_user_func_array($scopes[$name], $params);
if (method_exists($this->modelClass, $name)) {
$this->scopes[$name] = $params;
return $this;
} else {
return parent::__call($name, $params);
}

6
framework/db/ar/ActiveRecord.php

@ -164,10 +164,8 @@ abstract class ActiveRecord extends Model
* echo Customer::count('COUNT(DISTINCT age)')->value();
* ~~~
*
* @param mixed $q the query parameter. This can be one of the followings:
*
* - a scalar value (integer or string): query by a single primary key value.
* - an array of name-value pairs: it will be used to configure the [[ActiveQuery]] object for query purpose.
* @param array $q the query configuration. This should be an array of name-value pairs.
* It will be used to configure the [[ActiveQuery]] object for query purpose.
*
* @return integer the counting result
*/

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

@ -21,13 +21,8 @@ class Customer extends ActiveRecord
);
}
public static function scopes()
public function active($query)
{
$status = self::STATUS_ACTIVE;
return array(
'active' => function($q) use ($status){
return $q->andWhere('@.`status` = ' . $status);
},
);
return $query->andWhere('@.`status` = ' . self::STATUS_ACTIVE);
}
}

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

@ -35,7 +35,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testUpdate()
{
// save
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$this->assertFalse($customer->isNewRecord);
@ -43,7 +43,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$customer->save();
$this->assertEquals('user2x', $customer->name);
$this->assertFalse($customer->isNewRecord);
$customer2 = Customer::find(2)->one();
$customer2 = Customer::find(2);
$this->assertEquals('user2x', $customer2->name);
// updateCounters
@ -57,13 +57,13 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals(0, $orderItem->quantity);
// updateAll
$customer = Customer::find(3)->one();
$customer = Customer::find(3);
$this->assertEquals('user3', $customer->name);
$ret = Customer::updateAll(array(
'name' => 'temp',
), array('id' => 3));
$this->assertEquals(1, $ret);
$customer = Customer::find(3)->one();
$customer = Customer::find(3);
$this->assertEquals('temp', $customer->name);
// updateCounters
@ -81,11 +81,11 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testDelete()
{
// delete
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer->delete();
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$this->assertNull($customer);
// deleteAll
@ -140,7 +140,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue($result[2] instanceof Customer);
// find by a single primary key
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
@ -161,7 +161,6 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// find count
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(3, Customer::count());
$this->assertEquals(1, Customer::count(2));
$this->assertEquals(2, Customer::count(array(
'where' => 'id=1 OR id=2',
)));
@ -294,12 +293,12 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testLazyLoading()
{
// has one
$order = Order::find(3)->one();
$order = Order::find(3);
$this->assertTrue($order->customer instanceof Customer);
$this->assertEquals(2, $order->customer->id);
// has many
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$orders = $customer->orders;
$this->assertEquals(2, count($orders));
$this->assertEquals(2, $orders[0]->id);
@ -316,7 +315,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals(2, $orders[2]->books[0]->id);
// customized relation query
$customer = Customer::find(2)->one();
$customer = Customer::find(2);
$orders = $customer->orders(array(
'where' => '@.id = 3',
));

Loading…
Cancel
Save