Commit a8be9ce4 by Qiang Xue

new AR WIP

parent 732bbe79
......@@ -252,7 +252,7 @@ abstract class ActiveRecord extends Model
*/
public static function createActiveQuery()
{
return new ActiveQuery(get_called_class());
return new ActiveQuery(array('modelClass' => get_called_class()));
}
/**
......@@ -382,6 +382,35 @@ abstract class ActiveRecord extends Model
}
}
public function hasOne($class, $link)
{
return new HasOneRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'link' => $link,
));
}
public function hasMany($class, $link)
{
return new HasManyRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'link' => $link,
));
}
public function manyMany($class, $leftLink, $joinTable, $rightLink)
{
return new ManyManyRelation(array(
'modelClass' => $class,
'parentClass' => get_class($this),
'leftLink' => $leftLink,
'joinTable' => $joinTable,
'rightLink' => $rightLink,
));
}
/**
* Initializes the internal storage for the relation.
* This method is internally used by [[ActiveQuery]] when populating relation data.
......
<?php
namespace yii\db\ar;
class HasManyRelation extends Relation
{
public $link;
}
<?php
namespace yii\db\ar;
class HasOneRelation extends Relation
{
public $link;
}
<?php
namespace yii\db\ar;
class ManyManyRelation extends Relation
{
public $joinTable;
public $leftLink;
public $rightLink;
}
<?php
namespace yii\db\ar;
class Relation extends ActiveQuery
{
public $parentClass;
public $parentRecords;
public function findWith($records)
{
}
}
......@@ -532,103 +532,23 @@ class BaseQuery extends \yii\base\Component
/**
* Merges this query with another one.
*
* The merging is done according to the following rules:
*
* - [[select]]: the union of both queries' [[select]] property values.
* - [[selectOption]], [[distinct]], [[from]], [[limit]], [[offset]]: the new query
* 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
* corresponding property value will be appended to the existing one.
*
* In general, the merging makes the resulting query more restrictive and specific.
* If a property of `$query` is not null, it will be used to overwrite
* the corresponding property of `$this`.
* @param BaseQuery $query the new query to be merged with this query.
* @return BaseQuery the query object itself
*/
public function mergeWith(BaseQuery $query)
{
if ($this->select !== $query->select) {
if (empty($this->select)) {
$this->select = $query->select;
} elseif (!empty($query->select)) {
$select1 = is_string($this->select) ? preg_split('/\s*,\s*/', trim($this->select), -1, PREG_SPLIT_NO_EMPTY) : $this->select;
$select2 = is_string($query->select) ? preg_split('/\s*,\s*/', trim($query->select), -1, PREG_SPLIT_NO_EMPTY) : $query->select;
$this->select = array_merge($select1, array_diff($select2, $select1));
}
}
if ($query->selectOption !== null) {
$this->selectOption = $query->selectOption;
}
if ($query->distinct !== null) {
$this->distinct = $query->distinct;
}
if ($query->from !== null) {
$this->from = $query->from;
}
if ($query->limit !== null) {
$this->limit = $query->limit;
}
if ($query->offset !== null) {
$this->offset = $query->offset;
}
if ($query->where !== null) {
$this->andWhere($query->where);
}
if ($query->having !== null) {
$this->andHaving($query->having);
}
if ($query->params !== null) {
$this->addParams($query->params);
}
if ($query->orderBy !== null) {
$this->addOrderBy($query->orderBy);
}
if ($query->groupBy !== null) {
$this->addGroup($query->groupBy);
}
if ($query->join !== null) {
if (empty($this->join)) {
$this->join = $query->join;
} else {
if (!is_array($this->join)) {
$this->join = array($this->join);
}
if (is_array($query->join)) {
$this->join = array_merge($this->join, $query->join);
} else {
$this->join[] = $query->join;
$properties = array(
'select', 'selectOption', 'distinct', 'from',
'where', 'limit', 'offset', 'orderBy', 'groupBy',
'join', 'having', 'union', 'params',
);
foreach ($properties as $name => $value) {
if ($value !== null) {
$this->$name = $value;
}
}
}
if ($query->union !== null) {
if (empty($this->union)) {
$this->union = $query->union;
} else {
if (!is_array($this->union)) {
$this->union = array($this->union);
}
if (is_array($query->union)) {
$this->union = array_merge($this->union, $query->union);
} else {
$this->union[] = $query->union;
}
}
}
return $this;
}
}
......@@ -23,42 +23,14 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue($result instanceof ActiveQuery);
$customer = $result->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(1, $result->count);
$this->assertEquals(1, count($result));
// find all
$result = Customer::find();
$customers = $result->all();
$this->assertTrue(is_array($customers));
$this->assertEquals(3, count($customers));
$this->assertTrue($customers[0] instanceof Customer);
$this->assertTrue($customers[1] instanceof Customer);
$this->assertTrue($customers[2] instanceof Customer);
$this->assertEquals(3, $result->count);
$this->assertEquals(3, count($result));
// check count first
$result = Customer::find();
$this->assertEquals(3, $result->count);
$customer = $result->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(3, $result->count);
// iterator
$result = Customer::find();
$count = 0;
foreach ($result as $customer) {
$this->assertTrue($customer instanceof Customer);
$count++;
}
$this->assertEquals($count, $result->count);
// array access
$result = Customer::find();
$this->assertTrue($result[0] instanceof Customer);
$this->assertTrue($result[1] instanceof Customer);
$this->assertTrue($result[2] instanceof Customer);
$this->assertEquals(3, count($result));
// find by a single primary key
$customer = Customer::find(2);
......@@ -70,7 +42,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertTrue($customer instanceof Customer);
$this->assertEquals(2, $customer->id);
// find by Query
// find by Query array
$query = array(
'where' => 'id=:id',
'params' => array(':id' => 2),
......@@ -80,14 +52,60 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals('user2', $customer->name);
// find count
$this->assertEquals(3, Customer::find()->count());
$this->assertEquals(3, Customer::count());
$this->assertEquals(2, Customer::count(array(
'where' => 'id=1 OR id=2',
)));
$this->assertEquals(2, Customer::count()->where('id=1 OR id=2'));
// $this->assertEquals(3, Customer::count());
// $this->assertEquals(2, Customer::count(array(
// 'where' => 'id=1 OR id=2',
// )));
// $this->assertEquals(2, Customer::find()->select('COUNT(*)')->where('id=1 OR id=2')->value());
}
public function testFindBySql()
{
// find one
$customer = Customer::findBySql('SELECT * FROM tbl_customer ORDER BY id DESC')->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user3', $customer->name);
// find all
$customers = Customer::findBySql('SELECT * FROM tbl_customer')->all();
$this->assertEquals(3, count($customers));
// find with parameter binding
$customer = Customer::findBySql('SELECT * FROM tbl_customer WHERE id=:id', array(':id' => 2))->one();
$this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name);
}
public function testScope()
{
$customers = Customer::find(array(
'scopes' => array('active'),
))->all();
$this->assertEquals(2, count($customers));
$customers = Customer::find()->active()->all();
$this->assertEquals(2, count($customers));
}
//
// public function testFindLazy()
// {
// $customer = Customer::find(2);
// $orders = $customer->orders;
// $this->assertEquals(2, count($orders));
//
// $orders = $customer->orders()->where('id=3')->all();
// $this->assertEquals(1, count($orders));
// $this->assertEquals(3, $orders[0]->id);
// }
//
// public function testFindEager()
// {
// $customers = Customer::find()->with('orders')->all();
// $this->assertEquals(3, count($customers));
// $this->assertEquals(1, count($customers[0]->orders));
// $this->assertEquals(2, count($customers[1]->orders));
// }
// public function testInsert()
// {
// $customer = new Customer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment