Browse Source

cleanup of AR

tags/2.0.0-beta
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) 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; return $this;
} }
@ -234,10 +238,10 @@ class ActiveQuery extends Query
protected function normalizeRelations($model, $with) protected function normalizeRelations($model, $with)
{ {
$relations = array(); $relations = array();
foreach ($with as $name => $options) { foreach ($with as $name => $callback) {
if (is_integer($name)) { if (is_integer($name)) {
$name = $options; $name = $callback;
$options = array(); $callback = null;
} }
if (($pos = strpos($name, '.')) !== false) { if (($pos = strpos($name, '.')) !== false) {
// with sub-relations // with sub-relations
@ -260,15 +264,9 @@ class ActiveQuery extends Query
} }
if (isset($childName)) { if (isset($childName)) {
if (isset($relation->with[$childName])) { $relation->with[$childName] = $callback;
$relation->with[$childName] = array_merge($relation->with, $options); } elseif ($callback !== null) {
} else { call_user_func($callback, $relation);
$relation->with[$childName] = $options;
}
} else {
foreach ($options as $p => $v) {
$relation->$p = $v;
}
} }
} }
return $relations; return $relations;

85
framework/db/ActiveRecord.php

@ -16,7 +16,6 @@ use yii\base\ModelEvent;
use yii\db\Exception; use yii\db\Exception;
use yii\db\Connection; use yii\db\Connection;
use yii\db\TableSchema; use yii\db\TableSchema;
use yii\db\Query;
use yii\db\Expression; use yii\db\Expression;
use yii\util\StringHelper; use yii\util\StringHelper;
@ -79,39 +78,37 @@ abstract class ActiveRecord extends Model
* ~~~ * ~~~
* // find all customers * // find all customers
* $customers = Customer::find()->all(); * $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: * // find all active customers and order them by their age:
* $customers = Customer::find() * $customers = Customer::find()
* ->where(array('status' => 1)) * ->where(array('status' => 1))
* ->orderBy('age') * ->orderBy('age')
* ->all(); * ->all();
* // or alternatively: * // find a single customer whose primary key value is 10
* $customers = Customer::find(array( * $customer = Customer::find(10);
* 'where' => array('status' => 1), * // the above is equivalent to:
* 'orderBy' => 'age', * $customer = Customer::find()->where(array('id' => 10))->one();
* ))->all(); * // 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: * @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 * - a scalar value (integer or string): query by a single primary key value and return the
* corresponding record. * 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 * @return ActiveQuery|ActiveRecord|null When `$q` is null, a new [[ActiveQuery]] instance
* the ActiveRecord object when a scalar is passed to this method which is considered to be a * is returned; when `$q` is a scalar or an array, an ActiveRecord object matching it will be
* primary key value (false will be returned if no record is found in this case.) * returned, or null will be returned if no match is found.
*/ */
public static function find($q = null) public static function find($q = null)
{ {
$query = static::createQuery(); $query = static::createQuery();
if (is_array($q)) { if (is_array($q)) {
foreach ($q as $name => $value) { return $query->where($q)->one();
$query->$name = $value;
}
} elseif ($q !== null) { } elseif ($q !== null) {
// query by primary key // query by primary key
$primaryKey = static::primaryKey(); $primaryKey = static::primaryKey();
@ -145,35 +142,23 @@ abstract class ActiveRecord extends Model
* // count the total number of customers * // count the total number of customers
* echo Customer::count()->value(); * echo Customer::count()->value();
* // count the number of active customers: * // count the number of active customers:
* echo Customer::count(array(
* 'where' => array('status' => 1),
* ))->value();
* // equivalent usage:
* echo Customer::count() * echo Customer::count()
* ->where(array('status' => 1)) * ->where(array('status' => 1))
* ->value(); * ->value();
* // customize the count option * // customize the count expression
* echo Customer::count('COUNT(DISTINCT age)')->value(); * echo Customer::count('COUNT(DISTINCT age)')->value();
* ~~~ * ~~~
* *
* @param array|string $q the query option. This can be one of the followings: * @param string $q the count expression. If null, it means `COUNT(*)`.
*
* - 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)'.
* *
* @return ActiveQuery the [[ActiveQuery]] instance * @return ActiveQuery the [[ActiveQuery]] instance
*/ */
public static function count($q = null) public static function count($q = null)
{ {
$query = static::createQuery(); $query = static::createQuery();
if (is_array($q)) { if ($q !== null) {
foreach ($q as $name => $value) {
$query->$name = $value;
}
} elseif ($q !== null) {
$query->select = array($q); $query->select = array($q);
} } elseif ($query->select === null) {
if ($query->select === null) {
$query->select = array('COUNT(*)'); $query->select = array('COUNT(*)');
} }
return $query; 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. * 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. * The default implementation will return all column names of the table associated with this AR class.
* @return array list of attribute names. * @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. * @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; public $multiple;
/** /**
@ -41,11 +41,11 @@ class ActiveRelation extends ActiveQuery
* must be the corresponding columns from the primary table. * 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. * Do not prefix or quote the column names as they will be done automatically by Yii.
*/ */
public $link; protected $link;
/** /**
* @var array|ActiveRelation * @var array|ActiveRelation
*/ */
public $via; protected $via;
/** /**
* @param string $relationName * @param string $relationName
@ -262,4 +262,11 @@ class ActiveRelation extends ActiveQuery
$sql = $db->getQueryBuilder()->build($this); $sql = $db->getQueryBuilder()->build($this);
return $db->createCommand($sql, $this->params)->queryAll(); 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->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name); $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 // find by attributes
$customer = Customer::find()->where(array('name' => 'user2'))->one(); $customer = Customer::find()->where(array('name' => 'user2'))->one();
$this->assertTrue($customer instanceof Customer); $this->assertTrue($customer instanceof Customer);
$this->assertEquals(2, $customer->id); $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 // find count
$this->assertEquals(3, Customer::count()->value()); $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(2, Customer::find()->select('COUNT(*)')->where('id=1 OR id=2')->value());
$this->assertEquals(6, Customer::count('SUM(id)')->value());
// asArray // asArray
$customer = Customer::find()->where('id=2')->asArray()->one(); $customer = Customer::find()->where('id=2')->asArray()->one();
@ -94,9 +91,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testScope() public function testScope()
{ {
$customers = Customer::find(array( $customers = Customer::find()->scopes('active')->all();
'scopes' => array('active'),
))->all();
$this->assertEquals(2, count($customers)); $this->assertEquals(2, count($customers));
$customers = Customer::find()->active()->all(); $customers = Customer::find()->active()->all();

Loading…
Cancel
Save