Browse Source

cleanup of AR

tags/2.0.0-alpha
Qiang Xue 12 years ago
parent
commit
0e3e2698d7
  1. 24
      framework/db/ActiveQuery.php
  2. 85
      framework/db/ActiveRecord.php
  3. 13
      framework/db/ActiveRelation.php
  4. 23
      tests/unit/framework/db/ActiveRecordTest.php

24
framework/db/ActiveQuery.php

@ -181,7 +181,11 @@ class ActiveQuery extends Query
public function scopes($names)
{
$this->scopes = $names;
$this->scopes = func_get_args();
if (isset($this->scopes[0]) && is_array($this->scopes[0])) {
// the parameter is given as an array
$this->scopes = $this->scopes[0];
}
return $this;
}
@ -234,10 +238,10 @@ class ActiveQuery extends Query
protected function normalizeRelations($model, $with)
{
$relations = array();
foreach ($with as $name => $options) {
foreach ($with as $name => $callback) {
if (is_integer($name)) {
$name = $options;
$options = array();
$name = $callback;
$callback = null;
}
if (($pos = strpos($name, '.')) !== false) {
// with sub-relations
@ -260,15 +264,9 @@ class ActiveQuery extends Query
}
if (isset($childName)) {
if (isset($relation->with[$childName])) {
$relation->with[$childName] = array_merge($relation->with, $options);
} else {
$relation->with[$childName] = $options;
}
} else {
foreach ($options as $p => $v) {
$relation->$p = $v;
}
$relation->with[$childName] = $callback;
} elseif ($callback !== null) {
call_user_func($callback, $relation);
}
}
return $relations;

85
framework/db/ActiveRecord.php

@ -16,7 +16,6 @@ use yii\base\ModelEvent;
use yii\db\Exception;
use yii\db\Connection;
use yii\db\TableSchema;
use yii\db\Query;
use yii\db\Expression;
use yii\util\StringHelper;
@ -79,39 +78,37 @@ abstract class ActiveRecord extends Model
* ~~~
* // find all customers
* $customers = Customer::find()->all();
* // find a single customer whose primary key value is 10
* $customer = Customer::find(10);
* // the above is equivalent to:
* Customer::find()->where(array('id' => 10))->one();
* // find all active customers and order them by their age:
* $customers = Customer::find()
* ->where(array('status' => 1))
* ->orderBy('age')
* ->all();
* // or alternatively:
* $customers = Customer::find(array(
* 'where' => array('status' => 1),
* 'orderBy' => 'age',
* ))->all();
* // find a single customer whose primary key value is 10
* $customer = Customer::find(10);
* // the above is equivalent to:
* $customer = Customer::find()->where(array('id' => 10))->one();
* // find a single customer whose age is 30 and whose status is 1
* $customer = Customer::find(array('age' => 30, 'status' => 1));
* // the above is equivalent to:
* $customer = Customer::find()->where(array('age' => 30, 'status' => 1))->one();
* ~~~
*
* @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 and return the
* corresponding record.
* - an array of name-value pairs: it will be used to configure the [[ActiveQuery]] object.
* - an array of name-value pairs: query by a set of column values and return a single record matching them.
* - null: return a new [[ActiveQuery]] object for further query purpose.
*
* @return ActiveQuery|ActiveRecord|boolean the [[ActiveQuery]] instance for query purpose, or
* the ActiveRecord object when a scalar is passed to this method which is considered to be a
* primary key value (false will be returned if no record is found in this case.)
* @return ActiveQuery|ActiveRecord|null When `$q` is null, a new [[ActiveQuery]] instance
* is returned; when `$q` is a scalar or an array, an ActiveRecord object matching it will be
* returned, or null will be returned if no match is found.
*/
public static function find($q = null)
{
$query = static::createQuery();
if (is_array($q)) {
foreach ($q as $name => $value) {
$query->$name = $value;
}
return $query->where($q)->one();
} elseif ($q !== null) {
// query by primary key
$primaryKey = static::primaryKey();
@ -145,35 +142,23 @@ abstract class ActiveRecord extends Model
* // count the total number of customers
* echo Customer::count()->value();
* // count the number of active customers:
* echo Customer::count(array(
* 'where' => array('status' => 1),
* ))->value();
* // equivalent usage:
* echo Customer::count()
* ->where(array('status' => 1))
* ->value();
* // customize the count option
* // customize the count expression
* echo Customer::count('COUNT(DISTINCT age)')->value();
* ~~~
*
* @param array|string $q the query option. This can be one of the followings:
*
* - an array of name-value pairs: it will be used to configure the [[ActiveQuery]] object.
* - a string: the count expression, e.g. 'COUNT(DISTINCT age)'.
* @param string $q the count expression. If null, it means `COUNT(*)`.
*
* @return ActiveQuery the [[ActiveQuery]] instance
*/
public static function count($q = null)
{
$query = static::createQuery();
if (is_array($q)) {
foreach ($q as $name => $value) {
$query->$name = $value;
}
} elseif ($q !== null) {
if ($q !== null) {
$query->select = array($q);
}
if ($query->select === null) {
} elseif ($query->select === null) {
$query->select = array('COUNT(*)');
}
return $query;
@ -441,40 +426,6 @@ abstract class ActiveRecord extends Model
}
/**
* Returns the related record(s).
* This method will return the related record(s) of the current record.
* If the relation is HAS_ONE or BELONGS_TO, it will return a single object
* or null if the object does not exist.
* If the relation is HAS_MANY or MANY_MANY, it will return an array of objects
* or an empty array.
* @param ActiveRelation|string $relation the relation object or the name of the relation
* @param array|\Closure $params additional parameters that customize the query conditions as specified in the relation declaration.
* @return mixed the related object(s).
* @throws Exception if the relation is not specified in [[relations()]].
*/
public function findByRelation($relation, $params = array())
{
if (is_string($relation)) {
$md = $this->getMetaData();
if (!isset($md->relations[$relation])) {
throw new Exception(get_class($this) . ' has no relation named "' . $relation . '".');
}
$relation = $md->relations[$relation];
}
$relation = clone $relation;
if ($params instanceof \Closure) {
$params($relation);
} else {
foreach ($params as $name => $value) {
$relation->$name = $value;
}
}
$finder = new ActiveFinder($this->getDbConnection());
return $finder->findWithRecord($this, $relation);
}
/**
* Returns the list of all attribute names of the model.
* The default implementation will return all column names of the table associated with this AR class.
* @return array list of attribute names.

13
framework/db/ActiveRelation.php

@ -27,7 +27,7 @@ class ActiveRelation extends ActiveQuery
{
/**
* @var boolean whether this relation should populate all query results into AR instances.
* If false, only the first row of the results will be taken.
* If false, only the first row of the results will be retrieved.
*/
public $multiple;
/**
@ -41,11 +41,11 @@ class ActiveRelation extends ActiveQuery
* must be the corresponding columns from the primary table.
* Do not prefix or quote the column names as they will be done automatically by Yii.
*/
public $link;
protected $link;
/**
* @var array|ActiveRelation
*/
public $via;
protected $via;
/**
* @param string $relationName
@ -262,4 +262,11 @@ class ActiveRelation extends ActiveQuery
$sql = $db->getQueryBuilder()->build($this);
return $db->createCommand($sql, $this->params)->queryAll();
}
public function link($model)
{
/**
* 1. Set models
*/
}
}

23
tests/unit/framework/db/ActiveRecordTest.php

@ -36,26 +36,23 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
// find by column values
$customer = Customer::find(array('id' => 2, 'name' => 'user2'));
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
$customer = Customer::find(array('id' => 2, 'name' => 'user1'));
$this->assertNull($customer);
// find by attributes
$customer = Customer::find()->where(array('name' => 'user2'))->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(2, $customer->id);
// find by Query array
$query = array(
'where' => 'id=:id',
'params' => array(':id' => 2),
);
$customer = Customer::find($query)->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
// find count
$this->assertEquals(3, Customer::count()->value());
$this->assertEquals(2, Customer::count(array(
'where' => 'id=1 OR id=2',
))->value());
$this->assertEquals(2, Customer::find()->select('COUNT(*)')->where('id=1 OR id=2')->value());
$this->assertEquals(6, Customer::count('SUM(id)')->value());
// asArray
$customer = Customer::find()->where('id=2')->asArray()->one();
@ -94,9 +91,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testScope()
{
$customers = Customer::find(array(
'scopes' => array('active'),
))->all();
$customers = Customer::find()->scopes('active')->all();
$this->assertEquals(2, count($customers));
$customers = Customer::find()->active()->all();

Loading…
Cancel
Save