Browse Source

elasticsearch AR relations + null values

tags/2.0.0-beta
Carsten Brandt 11 years ago
parent
commit
983b2286ba
  1. 34
      framework/yii/elasticsearch/ActiveQuery.php
  2. 22
      framework/yii/elasticsearch/ActiveRecord.php
  3. 39
      framework/yii/elasticsearch/QueryBuilder.php
  4. 2
      tests/unit/data/ar/elasticsearch/Customer.php
  5. 24
      tests/unit/data/ar/elasticsearch/Order.php
  6. 4
      tests/unit/data/ar/elasticsearch/OrderItem.php
  7. 337
      tests/unit/framework/elasticsearch/ActiveRecordTest.php

34
framework/yii/elasticsearch/ActiveQuery.php

@ -129,4 +129,38 @@ class ActiveQuery extends Query implements ActiveQueryInterface
} }
return $model; return $model;
} }
/**
* @inheritDocs
*/
public function scalar($field, $db = null)
{
$record = parent::one($db);
if ($record !== false) {
if ($field == 'primaryKey') {
return $record['_id'];
} elseif (isset($record['_source'][$field])) {
return $record['_source'][$field];
}
}
return null;
}
/**
* @inheritDocs
*/
public function column($field, $db = null)
{
if ($field == 'primaryKey') {
$command = $this->createCommand($db);
$command->queryParts['fields'] = [];
$rows = $command->queryAll()['hits'];
$result = [];
foreach ($rows as $row) {
$result[] = $row['_id'];
}
return $result;
}
return parent::column($field, $db);
}
} }

22
framework/yii/elasticsearch/ActiveRecord.php

@ -312,16 +312,21 @@ class ActiveRecord extends \yii\db\ActiveRecord
* @param array $attributes attribute values (name-value pairs) to be saved into the table * @param array $attributes attribute values (name-value pairs) to be saved into the table
* @param array $condition the conditions that will be put in the WHERE part of the UPDATE SQL. * @param array $condition the conditions that will be put in the WHERE part of the UPDATE SQL.
* Please refer to [[ActiveQuery::where()]] on how to specify this parameter. * Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
* @param array $params this parameter is ignored in redis implementation. * @param array $params this parameter is ignored in elasticsearch implementation.
* @return integer the number of rows updated * @return integer the number of rows updated
*/ */
public static function updateAll($attributes, $condition = [], $params = []) public static function updateAll($attributes, $condition = [], $params = [])
{ {
if (empty($condition)) { if (count($condition) == 1 && isset($condition['primaryKey'])) {
$primaryKeys = (array) $condition['primaryKey'];
} else {
$primaryKeys = static::find()->where($condition)->column('primaryKey');
}
if (empty($primaryKeys)) {
return 0; return 0;
} }
$bulk = ''; $bulk = '';
foreach((array) $condition as $pk) { foreach((array) $primaryKeys as $pk) {
$action = Json::encode([ $action = Json::encode([
"update" => [ "update" => [
"_id" => $pk, "_id" => $pk,
@ -362,16 +367,21 @@ class ActiveRecord extends \yii\db\ActiveRecord
* *
* @param array $condition the conditions that will be put in the WHERE part of the DELETE SQL. * @param array $condition the conditions that will be put in the WHERE part of the DELETE SQL.
* Please refer to [[ActiveQuery::where()]] on how to specify this parameter. * Please refer to [[ActiveQuery::where()]] on how to specify this parameter.
* @param array $params this parameter is ignored in redis implementation. * @param array $params this parameter is ignored in elasticsearch implementation.
* @return integer the number of rows deleted * @return integer the number of rows deleted
*/ */
public static function deleteAll($condition = [], $params = []) public static function deleteAll($condition = [], $params = [])
{ {
if (empty($condition)) { if (count($condition) == 1 && isset($condition['primaryKey'])) {
$primaryKeys = (array) $condition['primaryKey'];
} else {
$primaryKeys = static::find()->where($condition)->column('primaryKey');
}
if (empty($primaryKeys)) {
return 0; return 0;
} }
$bulk = ''; $bulk = '';
foreach((array) $condition as $pk) { foreach((array) $primaryKeys as $pk) {
$bulk .= Json::encode([ $bulk .= Json::encode([
"delete" => [ "delete" => [
"_id" => $pk, "_id" => $pk,

39
framework/yii/elasticsearch/QueryBuilder.php

@ -152,6 +152,13 @@ class QueryBuilder extends \yii\base\Object
{ {
$parts = []; $parts = [];
foreach($condition as $attribute => $value) { foreach($condition as $attribute => $value) {
if ($attribute == 'primaryKey') {
if ($value == null) { // there is no null pk
$parts[] = ['script' => ['script' => '0==1']];
} else {
$parts[] = ['ids' => ['values' => is_array($value) ? $value : [$value]]];
}
} else {
if (is_array($value)) { // IN condition if (is_array($value)) { // IN condition
$parts[] = ['in' => [$attribute => $value]]; $parts[] = ['in' => [$attribute => $value]];
} else { } else {
@ -162,6 +169,7 @@ class QueryBuilder extends \yii\base\Object
} }
} }
} }
}
return count($parts) === 1 ? $parts[0] : ['and' => $parts]; return count($parts) === 1 ? $parts[0] : ['and' => $parts];
} }
@ -190,6 +198,9 @@ class QueryBuilder extends \yii\base\Object
} }
list($column, $value1, $value2) = $operands; list($column, $value1, $value2) = $operands;
if ($column == 'primaryKey') {
throw new NotSupportedException('Between condition is not supported for primaryKey.');
}
$filter = ['range' => [$column => ['gte' => $value1, 'lte' => $value2]]]; $filter = ['range' => [$column => ['gte' => $value1, 'lte' => $value2]]];
if ($operator == 'not between') { if ($operator == 'not between') {
$filter = ['not' => $filter]; $filter = ['not' => $filter];
@ -197,7 +208,7 @@ class QueryBuilder extends \yii\base\Object
return $filter; return $filter;
} }
private function buildInCondition($operator, $operands, &$params) private function buildInCondition($operator, $operands)
{ {
if (!isset($operands[0], $operands[1])) { if (!isset($operands[0], $operands[1])) {
throw new InvalidParamException("Operator '$operator' requires two operands."); throw new InvalidParamException("Operator '$operator' requires two operands.");
@ -208,7 +219,7 @@ class QueryBuilder extends \yii\base\Object
$values = (array)$values; $values = (array)$values;
if (empty($values) || $column === []) { if (empty($values) || $column === []) {
return $operator === 'in' ? ['script' => ['script' => '0=1']] : []; return $operator === 'in' ? ['script' => ['script' => '0==1']] : [];
} }
if (count($column) > 1) { if (count($column) > 1) {
@ -226,21 +237,32 @@ class QueryBuilder extends \yii\base\Object
unset($values[$i]); unset($values[$i]);
} }
} }
if ($column == 'primaryKey') {
if (empty($values) && $canBeNull) { // there is no null pk
$filter = ['script' => ['script' => '0==1']];
} else {
$filter = ['ids' => ['values' => array_values($values)]];
if ($canBeNull) {
$filter = ['or' => [$filter, ['missing' => ['field' => $column, 'existence' => true, 'null_value' => true]]]];
}
}
} else {
if (empty($values) && $canBeNull) { if (empty($values) && $canBeNull) {
return ['missing' => ['field' => $column, 'existence' => true, 'null_value' => true]]; $filter = ['missing' => ['field' => $column, 'existence' => true, 'null_value' => true]];
} else { } else {
$filter = ['in' => [$column => $values]]; $filter = ['in' => [$column => array_values($values)]];
if ($canBeNull) { if ($canBeNull) {
$filter = ['or' => [$filter, ['missing' => ['field' => $column, 'existence' => true, 'null_value' => true]]]]; $filter = ['or' => [$filter, ['missing' => ['field' => $column, 'existence' => true, 'null_value' => true]]]];
} }
}
}
if ($operator == 'not in') { if ($operator == 'not in') {
$filter = ['not' => $filter]; $filter = ['not' => $filter];
} }
return $filter; return $filter;
} }
}
protected function buildCompositeInCondition($operator, $columns, $values, &$params) protected function buildCompositeInCondition($operator, $columns, $values)
{ {
throw new NotSupportedException('composite in is not supported by elasticsearch.'); throw new NotSupportedException('composite in is not supported by elasticsearch.');
$vss = array(); $vss = array();
@ -265,8 +287,9 @@ class QueryBuilder extends \yii\base\Object
return '(' . implode(', ', $columns) . ") $operator (" . implode(', ', $vss) . ')'; return '(' . implode(', ', $columns) . ") $operator (" . implode(', ', $vss) . ')';
} }
private function buildLikeCondition($operator, $operands, &$params) private function buildLikeCondition($operator, $operands)
{ {
throw new NotSupportedException('like conditions is not supported by elasticsearch.');
if (!isset($operands[0], $operands[1])) { if (!isset($operands[0], $operands[1])) {
throw new Exception("Operator '$operator' requires two operands."); throw new Exception("Operator '$operator' requires two operands.");
} }
@ -276,7 +299,7 @@ class QueryBuilder extends \yii\base\Object
$values = (array)$values; $values = (array)$values;
if (empty($values)) { if (empty($values)) {
return $operator === 'LIKE' || $operator === 'OR LIKE' ? '0=1' : ''; return $operator === 'LIKE' || $operator === 'OR LIKE' ? '0==1' : '';
} }
if ($operator === 'LIKE' || $operator === 'NOT LIKE') { if ($operator === 'LIKE' || $operator === 'NOT LIKE') {

2
tests/unit/data/ar/elasticsearch/Customer.php

@ -24,7 +24,7 @@ class Customer extends ActiveRecord
public function getOrders() public function getOrders()
{ {
return $this->hasMany('Order', array('customer_id' => 'id'))->orderBy('id'); return $this->hasMany(Order::className(), array('customer_id' => 'primaryKey'))->orderBy('create_time');
} }
public static function active($query) public static function active($query)

24
tests/unit/data/ar/elasticsearch/Order.php

@ -19,33 +19,31 @@ class Order extends ActiveRecord
public function getCustomer() public function getCustomer()
{ {
return $this->hasOne('Customer', ['id' => 'customer_id']); return $this->hasOne(Customer::className(), ['primaryKey' => 'customer_id']);
} }
public function getOrderItems() public function getOrderItems()
{ {
return $this->hasMany('OrderItem', ['order_id' => 'id']); return $this->hasMany(OrderItem::className(), ['order_id' => 'primaryKey']);
} }
public function getItems() public function getItems()
{ {
return $this->hasMany('Item', ['id' => 'item_id']) return $this->hasMany(Item::className(), ['primaryKey' => 'item_id'])
->via('orderItems', function ($q) { ->via('orderItems')->orderBy('name');
// additional query configuration
})->orderBy('id');
} }
public function getBooks() // public function getBooks()
{ // {
return $this->hasMany('Item', ['id' => 'item_id']) // return $this->hasMany('Item', ['primaryKey' => 'item_id'])
->viaTable('tbl_order_item', ['order_id' => 'id']) // ->viaTable('tbl_order_item', ['order_id' => 'primaryKey'])
->where(['category_id' => 1]); // ->where(['category_id' => 1]);
} // }
public function beforeSave($insert) public function beforeSave($insert)
{ {
if (parent::beforeSave($insert)) { if (parent::beforeSave($insert)) {
$this->create_time = time(); // $this->create_time = time();
return true; return true;
} else { } else {
return false; return false;

4
tests/unit/data/ar/elasticsearch/OrderItem.php

@ -19,11 +19,11 @@ class OrderItem extends ActiveRecord
public function getOrder() public function getOrder()
{ {
return $this->hasOne('Order', ['id' => 'order_id']); return $this->hasOne(Order::className(), ['primaryKey' => 'order_id']);
} }
public function getItem() public function getItem()
{ {
return $this->hasOne('Item', ['id' => 'item_id']); return $this->hasOne(Item::className(), ['primaryKey' => 'item_id']);
} }
} }

337
tests/unit/framework/elasticsearch/ActiveRecordTest.php

@ -25,15 +25,15 @@ class ActiveRecordTest extends ElasticSearchTestCase
$customer = new Customer(); $customer = new Customer();
$customer->primaryKey = 1; $customer->primaryKey = 1;
$customer->setAttributes(array('email' => 'user1@example.com', 'name' => 'user1', 'address' => 'address1', 'status' => 1), false); $customer->setAttributes(['email' => 'user1@example.com', 'name' => 'user1', 'address' => 'address1', 'status' => 1], false);
$customer->save(false); $customer->save(false);
$customer = new Customer(); $customer = new Customer();
$customer->primaryKey = 2; $customer->primaryKey = 2;
$customer->setAttributes(array('email' => 'user2@example.com', 'name' => 'user2', 'address' => 'address2', 'status' => 1), false); $customer->setAttributes(['email' => 'user2@example.com', 'name' => 'user2', 'address' => 'address2', 'status' => 1], false);
$customer->save(false); $customer->save(false);
$customer = new Customer(); $customer = new Customer();
$customer->primaryKey = 3; $customer->primaryKey = 3;
$customer->setAttributes(array('email' => 'user3@example.com', 'name' => 'user3', 'address' => 'address3', 'status' => 2), false); $customer->setAttributes(['email' => 'user3@example.com', 'name' => 'user3', 'address' => 'address3', 'status' => 2], false);
$customer->save(false); $customer->save(false);
// INSERT INTO tbl_category (name) VALUES ('Books'); // INSERT INTO tbl_category (name) VALUES ('Books');
@ -41,56 +41,56 @@ class ActiveRecordTest extends ElasticSearchTestCase
$item = new Item(); $item = new Item();
$item->primaryKey = 1; $item->primaryKey = 1;
$item->setAttributes(array('name' => 'Agile Web Application Development with Yii1.1 and PHP5', 'category_id' => 1), false); $item->setAttributes(['name' => 'Agile Web Application Development with Yii1.1 and PHP5', 'category_id' => 1], false);
$item->save(false); $item->save(false);
$item = new Item(); $item = new Item();
$item->primaryKey = 2; $item->primaryKey = 2;
$item->setAttributes(array('name' => 'Yii 1.1 Application Development Cookbook', 'category_id' => 1), false); $item->setAttributes(['name' => 'Yii 1.1 Application Development Cookbook', 'category_id' => 1], false);
$item->save(false); $item->save(false);
$item = new Item(); $item = new Item();
$item->primaryKey = 3; $item->primaryKey = 3;
$item->setAttributes(array('name' => 'Ice Age', 'category_id' => 2), false); $item->setAttributes(['name' => 'Ice Age', 'category_id' => 2], false);
$item->save(false); $item->save(false);
$item = new Item(); $item = new Item();
$item->primaryKey = 4; $item->primaryKey = 4;
$item->setAttributes(array('name' => 'Toy Story', 'category_id' => 2), false); $item->setAttributes(['name' => 'Toy Story', 'category_id' => 2], false);
$item->save(false); $item->save(false);
$item = new Item(); $item = new Item();
$item->primaryKey = 5; $item->primaryKey = 5;
$item->setAttributes(array('name' => 'Cars', 'category_id' => 2), false); $item->setAttributes(['name' => 'Cars', 'category_id' => 2], false);
$item->save(false); $item->save(false);
$order = new Order(); $order = new Order();
$order->primaryKey = 1; $order->primaryKey = 1;
$order->setAttributes(array('customer_id' => 1, 'create_time' => 1325282384, 'total' => 110.0), false); $order->setAttributes(['customer_id' => 1, 'create_time' => 1325282384, 'total' => 110.0], false);
$order->save(false); $order->save(false);
$order = new Order(); $order = new Order();
$order->primaryKey = 2; $order->primaryKey = 2;
$order->setAttributes(array('customer_id' => 2, 'create_time' => 1325334482, 'total' => 33.0), false); $order->setAttributes(['customer_id' => 2, 'create_time' => 1325334482, 'total' => 33.0], false);
$order->save(false); $order->save(false);
$order = new Order(); $order = new Order();
$order->primaryKey = 3; $order->primaryKey = 3;
$order->setAttributes(array('customer_id' => 2, 'create_time' => 1325502201, 'total' => 40.0), false); $order->setAttributes(['customer_id' => 2, 'create_time' => 1325502201, 'total' => 40.0], false);
$order->save(false); $order->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 1, 'item_id' => 1, 'quantity' => 1, 'subtotal' => 30.0), false); $orderItem->setAttributes(['order_id' => 1, 'item_id' => 1, 'quantity' => 1, 'subtotal' => 30.0], false);
// $orderItem->save(false); $orderItem->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 1, 'item_id' => 2, 'quantity' => 2, 'subtotal' => 40.0), false); $orderItem->setAttributes(['order_id' => 1, 'item_id' => 2, 'quantity' => 2, 'subtotal' => 40.0], false);
// $orderItem->save(false); $orderItem->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 2, 'item_id' => 4, 'quantity' => 1, 'subtotal' => 10.0), false); $orderItem->setAttributes(['order_id' => 2, 'item_id' => 4, 'quantity' => 1, 'subtotal' => 10.0], false);
// $orderItem->save(false); $orderItem->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 2, 'item_id' => 5, 'quantity' => 1, 'subtotal' => 15.0), false); $orderItem->setAttributes(['order_id' => 2, 'item_id' => 5, 'quantity' => 1, 'subtotal' => 15.0], false);
// $orderItem->save(false); $orderItem->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 2, 'item_id' => 3, 'quantity' => 1, 'subtotal' => 8.0), false); $orderItem->setAttributes(['order_id' => 2, 'item_id' => 3, 'quantity' => 1, 'subtotal' => 8.0], false);
// $orderItem->save(false); $orderItem->save(false);
// $orderItem = new OrderItem(); $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 3, 'item_id' => 2, 'quantity' => 1, 'subtotal' => 40.0), false); $orderItem->setAttributes(['order_id' => 3, 'item_id' => 2, 'quantity' => 1, 'subtotal' => 40.0], false);
// $orderItem->save(false); $orderItem->save(false);
Customer::getDb()->createCommand()->flushIndex(); Customer::getDb()->createCommand()->flushIndex();
} }
@ -118,22 +118,22 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertNull($customer); $this->assertNull($customer);
// query scalar // query scalar
$customerName = Customer::find()->where(array('status' => 2))->scalar('name'); $customerName = Customer::find()->where(['status' => 2])->scalar('name');
$this->assertEquals('user3', $customerName); $this->assertEquals('user3', $customerName);
// find by column values // find by column values
$customer = Customer::find(array('name' => 'user2')); $customer = Customer::find(['name' => 'user2']);
$this->assertTrue($customer instanceof Customer); $this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name); $this->assertEquals('user2', $customer->name);
$customer = Customer::find(array('name' => 'user1', 'id' => 2)); $customer = Customer::find(['name' => 'user1', 'id' => 2]);
$this->assertNull($customer); $this->assertNull($customer);
$customer = Customer::find(array('primaryKey' => 5)); $customer = Customer::find(['primaryKey' => 5]);
$this->assertNull($customer); $this->assertNull($customer);
$customer = Customer::find(array('name' => 'user5')); $customer = Customer::find(['name' => 'user5']);
$this->assertNull($customer); $this->assertNull($customer);
// find by attributes // find by attributes
$customer = Customer::find()->where(array('name' => 'user2'))->one(); $customer = Customer::find()->where(['name' => 'user2'])->one();
$this->assertTrue($customer instanceof Customer); $this->assertTrue($customer instanceof Customer);
$this->assertEquals('user2', $customer->name); $this->assertEquals('user2', $customer->name);
@ -149,7 +149,7 @@ class ActiveRecordTest extends ElasticSearchTestCase
// $this->assertEquals(2, Customer::find()->active()->count()); // $this->assertEquals(2, Customer::find()->active()->count());
// asArray // asArray
$customer = Customer::find()->where(array('name' => 'user2'))->asArray()->one(); $customer = Customer::find()->where(['name' => 'user2'])->asArray()->one();
$this->assertEquals(array( $this->assertEquals(array(
'email' => 'user2@example.com', 'email' => 'user2@example.com',
'name' => 'user2', 'name' => 'user2',
@ -286,14 +286,14 @@ class ActiveRecordTest extends ElasticSearchTestCase
public function testFindComplexCondition() public function testFindComplexCondition()
{ {
$this->assertEquals(2, Customer::find()->where(array('OR', array('name' => 'user1'), array('name' => 'user2')))->count()); $this->assertEquals(2, Customer::find()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->count());
$this->assertEquals(2, count(Customer::find()->where(array('OR', array('name' => 'user1'), array('name' => 'user2')))->all())); $this->assertEquals(2, count(Customer::find()->where(['OR', ['name' => 'user1'], ['name' => 'user2']])->all()));
$this->assertEquals(2, Customer::find()->where(array('name' => array('user1','user2')))->count()); $this->assertEquals(2, Customer::find()->where(['name' => ['user1','user2']])->count());
$this->assertEquals(2, count(Customer::find()->where(array('name' => array('user1','user2')))->all())); $this->assertEquals(2, count(Customer::find()->where(['name' => ['user1','user2']])->all()));
$this->assertEquals(1, Customer::find()->where(array('AND', array('name' => array('user2','user3')), array('BETWEEN', 'status', 2, 4)))->count()); $this->assertEquals(1, Customer::find()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->count());
$this->assertEquals(1, count(Customer::find()->where(array('AND', array('name' => array('user2','user3')), array('BETWEEN', 'status', 2, 4)))->all())); $this->assertEquals(1, count(Customer::find()->where(['AND', ['name' => ['user2','user3']], ['BETWEEN', 'status', 2, 4]])->all()));
} }
public function testFindNullValues() public function testFindNullValues()
@ -301,6 +301,7 @@ class ActiveRecordTest extends ElasticSearchTestCase
$customer = Customer::find(2); $customer = Customer::find(2);
$customer->name = null; $customer->name = null;
$customer->save(false); $customer->save(false);
Customer::getDb()->createCommand()->flushIndex('customers');
$result = Customer::find()->where(['name' => null])->all(); $result = Customer::find()->where(['name' => null])->all();
$this->assertEquals(1, count($result)); $this->assertEquals(1, count($result));
@ -309,132 +310,136 @@ class ActiveRecordTest extends ElasticSearchTestCase
public function testFindColumn() public function testFindColumn()
{ {
$this->assertEquals(array('user1', 'user2', 'user3'), Customer::find()->column('name')); $this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->column('name'));
$this->assertEquals(array('user3', 'user2', 'user1'), Customer::find()->orderBy(array('name' => SORT_DESC))->column('name')); $this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['name' => SORT_DESC])->column('name'));
} }
public function testExists() public function testExists()
{ {
$this->assertTrue(Customer::find()->where(array('name' => 'user1'))->exists()); $this->assertTrue(Customer::find()->where(['name' => 'user1'])->exists());
$this->assertFalse(Customer::find()->where(array('name' => 'user5'))->exists()); $this->assertFalse(Customer::find()->where(['name' => 'user5'])->exists());
}
public function testFindLazy()
{
/** @var $customer Customer */
$customer = Customer::find(2);
$orders = $customer->orders;
$this->assertEquals(2, count($orders));
$orders = $customer->getOrders()->where(['between', 'create_time', 1325334000, 1325400000])->all();
$this->assertEquals(1, count($orders));
$this->assertEquals(2, $orders[0]->primaryKey);
}
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 testFindLazyVia()
{
/** @var $order Order */
$order = Order::find(1);
$this->assertEquals(1, $order->primaryKey);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, $order->items[0]->primaryKey);
$this->assertEquals(1, $order->items[1]->primaryKey);
$order = new Order();
$order->primaryKey = 100;
$this->assertEquals([], $order->items);
}
public function testFindEagerViaRelation()
{
$orders = Order::find()->with('items')->all();
$this->assertEquals(3, count($orders));
$order = $orders[0];
$this->assertEquals(1, $order->primaryKey);
$this->assertEquals(2, count($order->items));
$this->assertEquals(2, $order->items[0]->primaryKey);
$this->assertEquals(1, $order->items[1]->primaryKey);
} }
// public function testFindLazy() public function testFindNestedRelation()
// { {
// /** @var $customer Customer */ $customers = Customer::find()->with('orders', 'orders.items')->all();
// $customer = Customer::find(2); $this->assertEquals(3, count($customers));
// $orders = $customer->orders; $this->assertEquals(1, count($customers[0]->orders));
// $this->assertEquals(2, count($orders)); $this->assertEquals(2, count($customers[1]->orders));
// $this->assertEquals(0, count($customers[2]->orders));
// $orders = $customer->getOrders()->where(array('id' => 3))->all(); $this->assertEquals(2, count($customers[0]->orders[0]->items));
// $this->assertEquals(1, count($orders)); $this->assertEquals(3, count($customers[1]->orders[0]->items));
// $this->assertEquals(3, $orders[0]->id); $this->assertEquals(1, count($customers[1]->orders[1]->items));
// } }
//
// public function testFindEager() public function testLink()
// { {
// $customers = Customer::find()->with('orders')->all(); $customer = Customer::find(2);
// $this->assertEquals(3, count($customers)); $this->assertEquals(2, count($customer->orders));
// $this->assertEquals(1, count($customers[0]->orders));
// $this->assertEquals(2, count($customers[1]->orders)); // has many
// } $order = new Order;
// $order->total = 100;
// public function testFindLazyVia() $this->assertTrue($order->isNewRecord);
// { $customer->link('orders', $order);
// /** @var $order Order */ $this->assertEquals(3, count($customer->orders));
// $order = Order::find(1); $this->assertFalse($order->isNewRecord);
// $this->assertEquals(1, $order->id); Customer::getDb()->createCommand()->flushIndex();
// $this->assertEquals(2, count($order->items)); $this->assertEquals(3, count($customer->getOrders()->all()));
// $this->assertEquals(1, $order->items[0]->id); $this->assertEquals(2, $order->customer_id);
// $this->assertEquals(2, $order->items[1]->id);
// // belongs to
// $order = Order::find(1); $order = new Order;
// $order->id = 100; $order->total = 100;
// $this->assertEquals(array(), $order->items); $this->assertTrue($order->isNewRecord);
// } $customer = Customer::find(1);
// $this->assertNull($order->customer);
// public function testFindEagerViaRelation() $order->link('customer', $customer);
// { $this->assertFalse($order->isNewRecord);
// $orders = Order::find()->with('items')->all(); $this->assertEquals(1, $order->customer_id);
// $this->assertEquals(3, count($orders)); $this->assertEquals(1, $order->customer->primaryKey);
// $order = $orders[0];
// $this->assertEquals(1, $order->id); // via model
// $this->assertEquals(2, count($order->items)); $order = Order::find(1);
// $this->assertEquals(1, $order->items[0]->id); $this->assertEquals(2, count($order->items));
// $this->assertEquals(2, $order->items[1]->id); $this->assertEquals(2, count($order->orderItems));
// } $orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
// $this->assertNull($orderItem);
// public function testFindNestedRelation() $item = Item::find(3);
// { $order->link('items', $item, ['quantity' => 10, 'subtotal' => 100]);
// $customers = Customer::find()->with('orders', 'orders.items')->all(); Customer::getDb()->createCommand()->flushIndex();
// $this->assertEquals(3, count($customers)); $this->assertEquals(3, count($order->items));
// $this->assertEquals(1, count($customers[0]->orders)); $this->assertEquals(3, count($order->orderItems));
// $this->assertEquals(2, count($customers[1]->orders)); $orderItem = OrderItem::find(['order_id' => 1, 'item_id' => 3]);
// $this->assertEquals(0, count($customers[2]->orders)); $this->assertTrue($orderItem instanceof OrderItem);
// $this->assertEquals(2, count($customers[0]->orders[0]->items)); $this->assertEquals(10, $orderItem->quantity);
// $this->assertEquals(3, count($customers[1]->orders[0]->items)); $this->assertEquals(100, $orderItem->subtotal);
// $this->assertEquals(1, count($customers[1]->orders[1]->items)); }
// }
// public function testUnlink()
// public function testLink() {
// { // has many
// $customer = Customer::find(2); $customer = Customer::find(2);
// $this->assertEquals(2, count($customer->orders)); $this->assertEquals(2, count($customer->orders));
// $customer->unlink('orders', $customer->orders[1], true);
// // has many Customer::getDb()->createCommand()->flushIndex();
// $order = new Order; $this->assertEquals(1, count($customer->orders));
// $order->total = 100; $this->assertNull(Order::find(3));
// $this->assertTrue($order->isNewRecord);
// $customer->link('orders', $order); // via model
// $this->assertEquals(3, count($customer->orders)); $order = Order::find(2);
// $this->assertFalse($order->isNewRecord); $this->assertEquals(3, count($order->items));
// $this->assertEquals(3, count($customer->getOrders()->all())); $this->assertEquals(3, count($order->orderItems));
// $this->assertEquals(2, $order->customer_id); $order->unlink('items', $order->items[2], true);
// Customer::getDb()->createCommand()->flushIndex();
// // belongs to $this->assertEquals(2, count($order->items));
// $order = new Order; $this->assertEquals(2, count($order->orderItems));
// $order->total = 100; }
// $this->assertTrue($order->isNewRecord);
// $customer = Customer::find(1);
// $this->assertNull($order->customer);
// $order->link('customer', $customer);
// $this->assertFalse($order->isNewRecord);
// $this->assertEquals(1, $order->customer_id);
// $this->assertEquals(1, $order->customer->id);
//
// // via model
// $order = Order::find(1);
// $this->assertEquals(2, count($order->items));
// $this->assertEquals(2, count($order->orderItems));
// $orderItem = OrderItem::find(array('order_id' => 1, 'item_id' => 3));
// $this->assertNull($orderItem);
// $item = Item::find(3);
// $order->link('items', $item, array('quantity' => 10, 'subtotal' => 100));
// $this->assertEquals(3, count($order->items));
// $this->assertEquals(3, count($order->orderItems));
// $orderItem = OrderItem::find(array('order_id' => 1, 'item_id' => 3));
// $this->assertTrue($orderItem instanceof OrderItem);
// $this->assertEquals(10, $orderItem->quantity);
// $this->assertEquals(100, $orderItem->subtotal);
// }
//
// public function testUnlink()
// {
// // has many
// $customer = Customer::find(2);
// $this->assertEquals(2, count($customer->orders));
// $customer->unlink('orders', $customer->orders[1], true);
// $this->assertEquals(1, count($customer->orders));
// $this->assertNull(Order::find(3));
//
// // via model
// $order = Order::find(2);
// $this->assertEquals(3, count($order->items));
// $this->assertEquals(3, count($order->orderItems));
// $order->unlink('items', $order->items[2], true);
// $this->assertEquals(2, count($order->items));
// $this->assertEquals(2, count($order->orderItems));
// }
public function testInsertNoPk() public function testInsertNoPk()
{ {
@ -489,20 +494,20 @@ class ActiveRecordTest extends ElasticSearchTestCase
$this->assertEquals('user3', $customer->name); $this->assertEquals('user3', $customer->name);
$ret = Customer::updateAll([ $ret = Customer::updateAll([
'name' => 'temp', 'name' => 'temp',
], ['id' => 3]); ], ['name' => 'user3']);
$this->assertEquals(1, $ret); $this->assertEquals(1, $ret);
$customer = Customer::find(3); $customer = Customer::find(3);
$this->assertEquals('temp', $customer->name); $this->assertEquals('temp', $customer->name);
$ret = Customer::updateAll(['name' => 'temp']); $ret = Customer::updateAll(['name' => 'temp']);
$this->assertEquals(0, $ret); $this->assertEquals(3, $ret);
} }
public function testUpdatePk() public function testUpdatePk()
{ {
$this->setExpectedException('yii\base\InvalidCallException'); $this->setExpectedException('yii\base\InvalidCallException');
$pk = array('primaryKey' => 2); $pk = ['primaryKey' => 2];
$orderItem = Order::find($pk); $orderItem = Order::find($pk);
$this->assertEquals(2, $orderItem->primaryKey); $this->assertEquals(2, $orderItem->primaryKey);
@ -525,7 +530,7 @@ class ActiveRecordTest extends ElasticSearchTestCase
// deleteAll // deleteAll
$customers = Customer::find()->all(); $customers = Customer::find()->all();
$this->assertEquals(2, count($customers)); $this->assertEquals(2, count($customers));
$ret = Customer::deleteAll([1,2,3]); $ret = Customer::deleteAll(['name' => ['user1','user3']]);
$this->assertEquals(2, $ret); $this->assertEquals(2, $ret);
Customer::getDb()->createCommand()->flushIndex('customers'); Customer::getDb()->createCommand()->flushIndex('customers');

Loading…
Cancel
Save