Commit ed513b4d by Qiang Xue

...

parent 5ddc1ba1
......@@ -18,20 +18,6 @@ use yii\db\Exception;
* 1. eager loading, base limited and has has_many relations
* 2.
* ActiveFinder.php is ...
* todo: add SQL monitor
* todo: better handling on join() support in QueryBuilder: use regexp to detect table name and quote it
* todo: do not support anonymous parameter binding
* todo: quote join/on part of the relational query
* todo: modify QueryBuilder about join() methods
* todo: unify ActiveFinder and ActiveRelation in query building process
* todo: intelligent table aliasing (first table name, then relation name, finally t?)
* todo: allow using tokens in primary query fragments
* todo: findBySql
* todo: base limited
* todo: lazy loading
* todo: scope
* todo: test via option
* todo: count, sum, exists
*
* @property integer $count
*
......@@ -97,15 +83,21 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
return isset($this->records[0]) ? $this->records[0] : null;
}
/**
* Returns a scalar value for this query.
* The value returned will be the first column in the first row of the query results.
* @return string|boolean the value of the first column in the first row of the query result.
* False is returned if there is no value.
*/
public function value()
{
$result = $this->asArray()->one();
return $result === null ? null : reset($result);
$finder = new ActiveFinder($this->getDbConnection());
return $finder->find($this, true);
}
public function exists()
{
return $this->select(array(new Expression('1')))->asArray()->one() !== null;
return $this->select(array(new Expression('1')))->value() !== false;
}
/**
......@@ -243,6 +235,6 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
protected function findRecords()
{
$finder = new ActiveFinder($this->getDbConnection());
return $finder->findRecords($this);
return $finder->find($this);
}
}
......@@ -134,13 +134,17 @@ abstract class ActiveRecord extends Model
*
* ~~~
* // count the total number of customers
* echo Customer::count();
* // count the number of customers whose primary key value is 10.
* echo Customer::count(10);
* 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
* echo Customer::count('COUNT(DISTINCT age)')->value();
* ~~~
*
* @param mixed $q the query parameter. This can be one of the followings:
......@@ -157,13 +161,9 @@ abstract class ActiveRecord extends Model
foreach ($q as $name => $value) {
$query->$name = $value;
}
} elseif ($q !== null) {
// query by primary key
$primaryKey = static::getMetaData()->table->primaryKey;
$query->where(array($primaryKey[0] => $q));
}
if ($query->select === null) {
$query->select = 'COUNT(*)';
$query->select = array('COUNT(*)');
}
return $query->value();
}
......@@ -561,7 +561,7 @@ abstract class ActiveRecord extends Model
}
$finder = new ActiveFinder($this->getDbConnection());
return $finder->findRelatedRecords($this, $relation);
return $finder->findWithRecord($this, $relation);
}
/**
......
......@@ -39,10 +39,6 @@ class JoinElement extends \yii\base\Object
*/
public $relations = array();
/**
* @var boolean whether this element is only for join purpose. If false, data will be populated into the AR of this element.
*/
public $joinOnly;
/**
* @var array column aliases (alias => original name)
*/
public $columnAliases = array();
......
......@@ -225,18 +225,21 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
public function testEagerLoading()
{
// has many
$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));
// nested
$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);
// has many via relation
$orders = Order::find()->with('items')->order('@.id')->all();
$this->assertEquals(3, count($orders));
$this->assertEquals(1, $orders[0]->items[0]->id);
......@@ -245,18 +248,22 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals(4, $orders[1]->items[1]->id);
$this->assertEquals(5, $orders[1]->items[2]->id);
// has many via join table
$orders = Order::find()->with('books')->order('@.id')->all();
$this->assertEquals(2, count($orders));
$this->assertEquals(1, $orders[0]->books[0]->id);
$this->assertEquals(2, $orders[0]->books[1]->id);
$this->assertEquals(2, $orders[1]->books[0]->id);
// has many and base limited
$orders = Order::find()->with('items')->order('@.id')->limit(2)->all();
$this->assertEquals(2, count($orders));
// findBySql with
$orders = Order::findBySql('SELECT * FROM tbl_order WHERE customer_id=2')->with('items')->all();
$this->assertEquals(2, count($orders));
// index and array
$customers = Customer::find()->with('orders.customer')->order('@.id')->index('id')->asArray()->all();
$this->assertEquals(3, count($customers));
$this->assertTrue(isset($customers[1], $customers[2], $customers[3]));
......@@ -265,6 +272,15 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this->assertEquals(2, count($customers[2]['orders']));
$this->assertEquals(0, count($customers[3]['orders']));
$this->assertTrue(is_array($customers[1]['orders'][0]['customer']));
// count with
$this->assertEquals(3, Order::count());
$value = Order::count(array(
'select' => array('COUNT(DISTINCT @.id, @.customer_id)'),
'with' => 'books',
));
$this->assertEquals(2, $value);
}
public function testLazyLoading()
......
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