You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
833 lines
32 KiB
833 lines
32 KiB
<?php |
|
namespace yiiunit\framework\db; |
|
|
|
use yiiunit\data\ar\ActiveRecord; |
|
use yiiunit\data\ar\BitValues; |
|
use yiiunit\data\ar\Category; |
|
use yiiunit\data\ar\Customer; |
|
use yiiunit\data\ar\Document; |
|
use yiiunit\data\ar\NullValues; |
|
use yiiunit\data\ar\OrderItem; |
|
use yiiunit\data\ar\Order; |
|
use yiiunit\data\ar\Item; |
|
use yiiunit\data\ar\OrderItemWithNullFK; |
|
use yiiunit\data\ar\OrderWithNullFK; |
|
use yiiunit\data\ar\Profile; |
|
use yiiunit\data\ar\Type; |
|
use yiiunit\framework\ar\ActiveRecordTestTrait; |
|
use yiiunit\framework\db\cubrid\CubridActiveRecordTest; |
|
use yiiunit\data\ar\Animal; |
|
use yiiunit\data\ar\Cat; |
|
use yiiunit\data\ar\Dog; |
|
|
|
/** |
|
* @group db |
|
* @group mysql |
|
*/ |
|
class ActiveRecordTest extends DatabaseTestCase |
|
{ |
|
use ActiveRecordTestTrait; |
|
|
|
protected function setUp() |
|
{ |
|
parent::setUp(); |
|
ActiveRecord::$db = $this->getConnection(); |
|
} |
|
|
|
public function getCustomerClass() |
|
{ |
|
return Customer::className(); |
|
} |
|
|
|
public function getItemClass() |
|
{ |
|
return Item::className(); |
|
} |
|
|
|
public function getOrderClass() |
|
{ |
|
return Order::className(); |
|
} |
|
|
|
public function getOrderItemClass() |
|
{ |
|
return OrderItem::className(); |
|
} |
|
|
|
public function getOrderWithNullFKClass() |
|
{ |
|
return OrderWithNullFK::className(); |
|
} |
|
public function getOrderItemWithNullFKmClass() |
|
{ |
|
return OrderItemWithNullFK::className(); |
|
} |
|
|
|
public function testCustomColumns() |
|
{ |
|
// find custom column |
|
if ($this->driverName === 'oci') { |
|
$customer = Customer::find()->select(['{{customer}}.*', '([[status]]*2) AS [[status2]]']) |
|
->where(['name' => 'user3'])->one(); |
|
} else { |
|
$customer = Customer::find()->select(['*', '([[status]]*2) AS [[status2]]']) |
|
->where(['name' => 'user3'])->one(); |
|
} |
|
$this->assertEquals(3, $customer->id); |
|
$this->assertEquals(4, $customer->status2); |
|
} |
|
|
|
public function testStatisticalFind() |
|
{ |
|
// find count, sum, average, min, max, scalar |
|
$this->assertEquals(3, Customer::find()->count()); |
|
$this->assertEquals(2, Customer::find()->where('[[id]]=1 OR [[id]]=2')->count()); |
|
$this->assertEquals(6, Customer::find()->sum('[[id]]')); |
|
$this->assertEquals(2, Customer::find()->average('[[id]]')); |
|
$this->assertEquals(1, Customer::find()->min('[[id]]')); |
|
$this->assertEquals(3, Customer::find()->max('[[id]]')); |
|
$this->assertEquals(3, Customer::find()->select('COUNT(*)')->scalar()); |
|
} |
|
|
|
public function testFindScalar() |
|
{ |
|
// query scalar |
|
$customerName = Customer::find()->where(['[[id]]' => 2])->select('[[name]]')->scalar(); |
|
$this->assertEquals('user2', $customerName); |
|
} |
|
|
|
public function testFindColumn() |
|
{ |
|
/* @var $this TestCase|ActiveRecordTestTrait */ |
|
$this->assertEquals(['user1', 'user2', 'user3'], Customer::find()->select('[[name]]')->column()); |
|
$this->assertEquals(['user3', 'user2', 'user1'], Customer::find()->orderBy(['[[name]]' => SORT_DESC])->select('[[name]]')->column()); |
|
} |
|
|
|
public function testFindBySql() |
|
{ |
|
// find one |
|
$customer = Customer::findBySql('SELECT * FROM {{customer}} ORDER BY [[id]] DESC')->one(); |
|
$this->assertTrue($customer instanceof Customer); |
|
$this->assertEquals('user3', $customer->name); |
|
|
|
// find all |
|
$customers = Customer::findBySql('SELECT * FROM {{customer}}')->all(); |
|
$this->assertEquals(3, count($customers)); |
|
|
|
// find with parameter binding |
|
$customer = Customer::findBySql('SELECT * FROM {{customer}} WHERE [[id]]=:id', [':id' => 2])->one(); |
|
$this->assertTrue($customer instanceof Customer); |
|
$this->assertEquals('user2', $customer->name); |
|
} |
|
|
|
/** |
|
* @depends testFindBySql |
|
* |
|
* @see https://github.com/yiisoft/yii2/issues/8593 |
|
*/ |
|
public function testCountWithFindBySql() |
|
{ |
|
$query = Customer::findBySql('SELECT * FROM {{customer}}'); |
|
$this->assertEquals(3, $query->count()); |
|
$query = Customer::findBySql('SELECT * FROM {{customer}} WHERE [[id]]=:id', [':id' => 2]); |
|
$this->assertEquals(1, $query->count()); |
|
} |
|
|
|
public function testFindLazyViaTable() |
|
{ |
|
/* @var $order Order */ |
|
$order = Order::findOne(1); |
|
$this->assertEquals(1, $order->id); |
|
$this->assertEquals(2, count($order->books)); |
|
$this->assertEquals(1, $order->items[0]->id); |
|
$this->assertEquals(2, $order->items[1]->id); |
|
|
|
$order = Order::findOne(2); |
|
$this->assertEquals(2, $order->id); |
|
$this->assertEquals(0, count($order->books)); |
|
|
|
$order = Order::find()->where(['id' => 1])->asArray()->one(); |
|
$this->assertTrue(is_array($order)); |
|
} |
|
|
|
public function testFindEagerViaTable() |
|
{ |
|
$orders = Order::find()->with('books')->orderBy('id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
|
|
$order = $orders[0]; |
|
$this->assertEquals(1, $order->id); |
|
$this->assertEquals(2, count($order->books)); |
|
$this->assertEquals(1, $order->books[0]->id); |
|
$this->assertEquals(2, $order->books[1]->id); |
|
|
|
$order = $orders[1]; |
|
$this->assertEquals(2, $order->id); |
|
$this->assertEquals(0, count($order->books)); |
|
|
|
$order = $orders[2]; |
|
$this->assertEquals(3, $order->id); |
|
$this->assertEquals(1, count($order->books)); |
|
$this->assertEquals(2, $order->books[0]->id); |
|
|
|
// https://github.com/yiisoft/yii2/issues/1402 |
|
$orders = Order::find()->with('books')->orderBy('id')->asArray()->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertTrue(is_array($orders[0]['orderItems'][0])); |
|
|
|
$order = $orders[0]; |
|
$this->assertTrue(is_array($order)); |
|
$this->assertEquals(1, $order['id']); |
|
$this->assertEquals(2, count($order['books'])); |
|
$this->assertEquals(1, $order['books'][0]['id']); |
|
$this->assertEquals(2, $order['books'][1]['id']); |
|
} |
|
|
|
// deeply nested table relation |
|
public function testDeeplyNestedTableRelation() |
|
{ |
|
/* @var $customer Customer */ |
|
$customer = Customer::findOne(1); |
|
$this->assertNotNull($customer); |
|
|
|
$items = $customer->orderItems; |
|
|
|
$this->assertEquals(2, count($items)); |
|
$this->assertInstanceOf(Item::className(), $items[0]); |
|
$this->assertInstanceOf(Item::className(), $items[1]); |
|
$this->assertEquals(1, $items[0]->id); |
|
$this->assertEquals(2, $items[1]->id); |
|
} |
|
|
|
/** |
|
* https://github.com/yiisoft/yii2/issues/5341 |
|
* |
|
* Issue: Plan 1 -- * Account * -- * User |
|
* Our Tests: Category 1 -- * Item * -- * Order |
|
*/ |
|
public function testDeeplyNestedTableRelation2() |
|
{ |
|
/* @var $category Category */ |
|
$category = Category::findOne(1); |
|
$this->assertNotNull($category); |
|
$orders = $category->orders; |
|
$this->assertEquals(2, count($orders)); |
|
$this->assertInstanceOf(Order::className(), $orders[0]); |
|
$this->assertInstanceOf(Order::className(), $orders[1]); |
|
$ids = [$orders[0]->id, $orders[1]->id]; |
|
sort($ids); |
|
$this->assertEquals([1, 3], $ids); |
|
|
|
$category = Category::findOne(2); |
|
$this->assertNotNull($category); |
|
$orders = $category->orders; |
|
$this->assertEquals(1, count($orders)); |
|
$this->assertInstanceOf(Order::className(), $orders[0]); |
|
$this->assertEquals(2, $orders[0]->id); |
|
|
|
} |
|
|
|
public function testStoreNull() |
|
{ |
|
$record = new NullValues(); |
|
$this->assertNull($record->var1); |
|
$this->assertNull($record->var2); |
|
$this->assertNull($record->var3); |
|
$this->assertNull($record->stringcol); |
|
|
|
$record->var1 = 123; |
|
$record->var2 = 456; |
|
$record->var3 = 789; |
|
$record->stringcol = 'hello!'; |
|
|
|
$record->save(false); |
|
$this->assertTrue($record->refresh()); |
|
|
|
$this->assertEquals(123, $record->var1); |
|
$this->assertEquals(456, $record->var2); |
|
$this->assertEquals(789, $record->var3); |
|
$this->assertEquals('hello!', $record->stringcol); |
|
|
|
$record->var1 = null; |
|
$record->var2 = null; |
|
$record->var3 = null; |
|
$record->stringcol = null; |
|
|
|
$record->save(false); |
|
$this->assertTrue($record->refresh()); |
|
|
|
$this->assertNull($record->var1); |
|
$this->assertNull($record->var2); |
|
$this->assertNull($record->var3); |
|
$this->assertNull($record->stringcol); |
|
|
|
$record->var1 = 0; |
|
$record->var2 = 0; |
|
$record->var3 = 0; |
|
$record->stringcol = ''; |
|
|
|
$record->save(false); |
|
$this->assertTrue($record->refresh()); |
|
|
|
$this->assertEquals(0, $record->var1); |
|
$this->assertEquals(0, $record->var2); |
|
$this->assertEquals(0, $record->var3); |
|
$this->assertEquals('', $record->stringcol); |
|
} |
|
|
|
public function testStoreEmpty() |
|
{ |
|
$record = new NullValues(); |
|
|
|
// this is to simulate empty html form submission |
|
$record->var1 = ''; |
|
$record->var2 = ''; |
|
$record->var3 = ''; |
|
$record->stringcol = ''; |
|
|
|
$record->save(false); |
|
$this->assertTrue($record->refresh()); |
|
|
|
// https://github.com/yiisoft/yii2/commit/34945b0b69011bc7cab684c7f7095d837892a0d4#commitcomment-4458225 |
|
$this->assertTrue($record->var1 === $record->var2); |
|
$this->assertTrue($record->var2 === $record->var3); |
|
} |
|
|
|
public function testIsPrimaryKey() |
|
{ |
|
$this->assertFalse(Customer::isPrimaryKey([])); |
|
$this->assertTrue(Customer::isPrimaryKey(['id'])); |
|
$this->assertFalse(Customer::isPrimaryKey(['id', 'name'])); |
|
$this->assertFalse(Customer::isPrimaryKey(['name'])); |
|
$this->assertFalse(Customer::isPrimaryKey(['name', 'email'])); |
|
|
|
$this->assertFalse(OrderItem::isPrimaryKey([])); |
|
$this->assertFalse(OrderItem::isPrimaryKey(['order_id'])); |
|
$this->assertFalse(OrderItem::isPrimaryKey(['item_id'])); |
|
$this->assertFalse(OrderItem::isPrimaryKey(['quantity'])); |
|
$this->assertFalse(OrderItem::isPrimaryKey(['quantity', 'subtotal'])); |
|
$this->assertTrue(OrderItem::isPrimaryKey(['order_id', 'item_id'])); |
|
$this->assertFalse(OrderItem::isPrimaryKey(['order_id', 'item_id', 'quantity'])); |
|
} |
|
|
|
public function testJoinWith() |
|
{ |
|
// left join and eager loading |
|
$orders = Order::find()->joinWith('customer')->orderBy('customer.id DESC, order.id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, $orders[1]->id); |
|
$this->assertEquals(1, $orders[2]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('customer')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('customer')); |
|
$this->assertTrue($orders[2]->isRelationPopulated('customer')); |
|
|
|
// inner join filtering and eager loading |
|
$orders = Order::find()->innerJoinWith([ |
|
'customer' => function ($query) { |
|
$query->where('{{customer}}.[[id]]=2'); |
|
}, |
|
])->orderBy('order.id')->all(); |
|
$this->assertEquals(2, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, $orders[1]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('customer')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('customer')); |
|
|
|
// inner join filtering, eager loading, conditions on both primary and relation |
|
$orders = Order::find()->innerJoinWith([ |
|
'customer' => function ($query) { |
|
$query->where(['customer.id' => 2]); |
|
}, |
|
])->where(['order.id' => [1, 2]])->orderBy('order.id')->all(); |
|
$this->assertEquals(1, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('customer')); |
|
|
|
// inner join filtering without eager loading |
|
$orders = Order::find()->innerJoinWith([ |
|
'customer' => function ($query) { |
|
$query->where('{{customer}}.[[id]]=2'); |
|
}, |
|
], false)->orderBy('order.id')->all(); |
|
$this->assertEquals(2, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, $orders[1]->id); |
|
$this->assertFalse($orders[0]->isRelationPopulated('customer')); |
|
$this->assertFalse($orders[1]->isRelationPopulated('customer')); |
|
|
|
// inner join filtering without eager loading, conditions on both primary and relation |
|
$orders = Order::find()->innerJoinWith([ |
|
'customer' => function ($query) { |
|
$query->where(['customer.id' => 2]); |
|
}, |
|
], false)->where(['order.id' => [1, 2]])->orderBy('order.id')->all(); |
|
$this->assertEquals(1, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertFalse($orders[0]->isRelationPopulated('customer')); |
|
|
|
// join with via-relation |
|
$orders = Order::find()->innerJoinWith('books')->orderBy('order.id')->all(); |
|
$this->assertEquals(2, count($orders)); |
|
$this->assertEquals(1, $orders[0]->id); |
|
$this->assertEquals(3, $orders[1]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('books')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('books')); |
|
$this->assertEquals(2, count($orders[0]->books)); |
|
$this->assertEquals(1, count($orders[1]->books)); |
|
|
|
// join with sub-relation |
|
$orders = Order::find()->innerJoinWith([ |
|
'items' => function ($q) { |
|
$q->orderBy('item.id'); |
|
}, |
|
'items.category' => function ($q) { |
|
$q->where('{{category}}.[[id]] = 2'); |
|
}, |
|
])->orderBy('order.id')->all(); |
|
$this->assertEquals(1, count($orders)); |
|
$this->assertTrue($orders[0]->isRelationPopulated('items')); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, count($orders[0]->items)); |
|
$this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); |
|
$this->assertEquals(2, $orders[0]->items[0]->category->id); |
|
|
|
// join with table alias |
|
$orders = Order::find()->joinWith([ |
|
'customer' => function ($q) { |
|
$q->from('customer c'); |
|
} |
|
])->orderBy('c.id DESC, order.id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, $orders[1]->id); |
|
$this->assertEquals(1, $orders[2]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('customer')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('customer')); |
|
$this->assertTrue($orders[2]->isRelationPopulated('customer')); |
|
|
|
// join with ON condition |
|
$orders = Order::find()->joinWith('books2')->orderBy('order.id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(1, $orders[0]->id); |
|
$this->assertEquals(2, $orders[1]->id); |
|
$this->assertEquals(3, $orders[2]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('books2')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('books2')); |
|
$this->assertTrue($orders[2]->isRelationPopulated('books2')); |
|
$this->assertEquals(2, count($orders[0]->books2)); |
|
$this->assertEquals(0, count($orders[1]->books2)); |
|
$this->assertEquals(1, count($orders[2]->books2)); |
|
|
|
// lazy loading with ON condition |
|
$order = Order::findOne(1); |
|
$this->assertEquals(2, count($order->books2)); |
|
$order = Order::findOne(2); |
|
$this->assertEquals(0, count($order->books2)); |
|
$order = Order::findOne(3); |
|
$this->assertEquals(1, count($order->books2)); |
|
|
|
// eager loading with ON condition |
|
$orders = Order::find()->with('books2')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(1, $orders[0]->id); |
|
$this->assertEquals(2, $orders[1]->id); |
|
$this->assertEquals(3, $orders[2]->id); |
|
$this->assertTrue($orders[0]->isRelationPopulated('books2')); |
|
$this->assertTrue($orders[1]->isRelationPopulated('books2')); |
|
$this->assertTrue($orders[2]->isRelationPopulated('books2')); |
|
$this->assertEquals(2, count($orders[0]->books2)); |
|
$this->assertEquals(0, count($orders[1]->books2)); |
|
$this->assertEquals(1, count($orders[2]->books2)); |
|
|
|
// join with count and query |
|
$query = Order::find()->joinWith('customer'); |
|
$count = $query->count(); |
|
$this->assertEquals(3, $count); |
|
$orders = $query->all(); |
|
$this->assertEquals(3, count($orders)); |
|
|
|
// https://github.com/yiisoft/yii2/issues/2880 |
|
$query = Order::findOne(1); |
|
$customer = $query->getCustomer()->joinWith([ |
|
'orders' => function ($q) { $q->orderBy([]); } |
|
])->one(); |
|
$this->assertEquals(1, $customer->id); |
|
$order = Order::find()->joinWith([ |
|
'items' => function ($q) { |
|
$q->from(['items' => 'item']) |
|
->orderBy('items.id'); |
|
}, |
|
])->orderBy('order.id')->one(); |
|
|
|
// join with sub-relation called inside Closure |
|
$orders = Order::find()->joinWith([ |
|
'items' => function ($q) { |
|
$q->orderBy('item.id'); |
|
$q->joinWith([ |
|
'category'=> function ($q) { |
|
$q->where('{{category}}.[[id]] = 2'); |
|
} |
|
]); |
|
}, |
|
])->orderBy('order.id')->all(); |
|
$this->assertEquals(1, count($orders)); |
|
$this->assertTrue($orders[0]->isRelationPopulated('items')); |
|
$this->assertEquals(2, $orders[0]->id); |
|
$this->assertEquals(3, count($orders[0]->items)); |
|
$this->assertTrue($orders[0]->items[0]->isRelationPopulated('category')); |
|
$this->assertEquals(2, $orders[0]->items[0]->category->id); |
|
} |
|
|
|
public function testJoinWithAndScope() |
|
{ |
|
// hasOne inner join |
|
$customers = Customer::find()->active()->innerJoinWith('profile')->orderBy('customer.id')->all(); |
|
$this->assertEquals(1, count($customers)); |
|
$this->assertEquals(1, $customers[0]->id); |
|
$this->assertTrue($customers[0]->isRelationPopulated('profile')); |
|
|
|
// hasOne outer join |
|
$customers = Customer::find()->active()->joinWith('profile')->orderBy('customer.id')->all(); |
|
$this->assertEquals(2, count($customers)); |
|
$this->assertEquals(1, $customers[0]->id); |
|
$this->assertEquals(2, $customers[1]->id); |
|
$this->assertTrue($customers[0]->isRelationPopulated('profile')); |
|
$this->assertTrue($customers[1]->isRelationPopulated('profile')); |
|
$this->assertInstanceOf(Profile::className(), $customers[0]->profile); |
|
$this->assertNull($customers[1]->profile); |
|
|
|
// hasMany |
|
$customers = Customer::find()->active()->joinWith([ |
|
'orders' => function ($q) { |
|
$q->orderBy('order.id'); |
|
} |
|
])->orderBy('customer.id DESC, order.id')->all(); |
|
$this->assertEquals(2, count($customers)); |
|
$this->assertEquals(2, $customers[0]->id); |
|
$this->assertEquals(1, $customers[1]->id); |
|
$this->assertTrue($customers[0]->isRelationPopulated('orders')); |
|
$this->assertTrue($customers[1]->isRelationPopulated('orders')); |
|
} |
|
|
|
/** |
|
* This query will do the same join twice, ensure duplicated JOIN gets removed |
|
* https://github.com/yiisoft/yii2/pull/2650 |
|
*/ |
|
public function testJoinWithVia() |
|
{ |
|
Order::getDb()->getQueryBuilder()->separator = "\n"; |
|
Order::find()->joinWith('itemsInOrder1')->joinWith([ |
|
'items' => function ($q) { |
|
$q->orderBy('item.id'); |
|
}, |
|
])->all(); |
|
} |
|
|
|
public function testInverseOf() |
|
{ |
|
// eager loading: find one and all |
|
$customer = Customer::find()->with('orders2')->where(['id' => 1])->one(); |
|
$this->assertTrue($customer->orders2[0]->customer2 === $customer); |
|
$customers = Customer::find()->with('orders2')->where(['id' => [1, 3]])->all(); |
|
$this->assertTrue($customers[0]->orders2[0]->customer2 === $customers[0]); |
|
$this->assertTrue(empty($customers[1]->orders2)); |
|
// lazy loading |
|
$customer = Customer::findOne(2); |
|
$orders = $customer->orders2; |
|
$this->assertTrue(count($orders) === 2); |
|
$this->assertTrue($customer->orders2[0]->customer2 === $customer); |
|
$this->assertTrue($customer->orders2[1]->customer2 === $customer); |
|
// ad-hoc lazy loading |
|
$customer = Customer::findOne(2); |
|
$orders = $customer->getOrders2()->all(); |
|
$this->assertTrue(count($orders) === 2); |
|
$this->assertTrue($customer->orders2[0]->customer2 === $customer); |
|
$this->assertTrue($customer->orders2[1]->customer2 === $customer); |
|
|
|
// the other way around |
|
$customer = Customer::find()->with('orders2')->where(['id' => 1])->asArray()->one(); |
|
$this->assertTrue($customer['orders2'][0]['customer2']['id'] === $customer['id']); |
|
$customers = Customer::find()->with('orders2')->where(['id' => [1, 3]])->asArray()->all(); |
|
$this->assertTrue($customer['orders2'][0]['customer2']['id'] === $customers[0]['id']); |
|
$this->assertTrue(empty($customers[1]['orders2'])); |
|
|
|
$orders = Order::find()->with('customer2')->where(['id' => 1])->all(); |
|
$this->assertTrue($orders[0]->customer2->orders2 === [$orders[0]]); |
|
$order = Order::find()->with('customer2')->where(['id' => 1])->one(); |
|
$this->assertTrue($order->customer2->orders2 === [$order]); |
|
|
|
$orders = Order::find()->with('customer2')->where(['id' => 1])->asArray()->all(); |
|
$this->assertTrue($orders[0]['customer2']['orders2'][0]['id'] === $orders[0]['id']); |
|
$order = Order::find()->with('customer2')->where(['id' => 1])->asArray()->one(); |
|
$this->assertTrue($order['customer2']['orders2'][0]['id'] === $orders[0]['id']); |
|
|
|
$orders = Order::find()->with('customer2')->where(['id' => [1, 3]])->all(); |
|
$this->assertTrue($orders[0]->customer2->orders2 === [$orders[0]]); |
|
$this->assertTrue($orders[1]->customer2->orders2 === [$orders[1]]); |
|
|
|
$orders = Order::find()->with('customer2')->where(['id' => [2, 3]])->orderBy('id')->all(); |
|
$this->assertTrue($orders[0]->customer2->orders2 === $orders); |
|
$this->assertTrue($orders[1]->customer2->orders2 === $orders); |
|
|
|
$orders = Order::find()->with('customer2')->where(['id' => [2, 3]])->orderBy('id')->asArray()->all(); |
|
$this->assertTrue($orders[0]['customer2']['orders2'][0]['id'] === $orders[0]['id']); |
|
$this->assertTrue($orders[0]['customer2']['orders2'][1]['id'] === $orders[1]['id']); |
|
$this->assertTrue($orders[1]['customer2']['orders2'][0]['id'] === $orders[0]['id']); |
|
$this->assertTrue($orders[1]['customer2']['orders2'][1]['id'] === $orders[1]['id']); |
|
} |
|
|
|
public function testDefaultValues() |
|
{ |
|
$model = new Type(); |
|
$model->loadDefaultValues(); |
|
$this->assertEquals(1, $model->int_col2); |
|
$this->assertEquals('something', $model->char_col2); |
|
$this->assertEquals(1.23, $model->float_col2); |
|
$this->assertEquals(33.22, $model->numeric_col); |
|
$this->assertEquals(true, $model->bool_col2); |
|
|
|
if ($this instanceof CubridActiveRecordTest) { |
|
// cubrid has non-standard timestamp representation |
|
$this->assertEquals('12:00:00 AM 01/01/2002', $model->time); |
|
} else { |
|
$this->assertEquals('2002-01-01 00:00:00', $model->time); |
|
} |
|
|
|
$model = new Type(); |
|
$model->char_col2 = 'not something'; |
|
|
|
$model->loadDefaultValues(); |
|
$this->assertEquals('not something', $model->char_col2); |
|
|
|
$model = new Type(); |
|
$model->char_col2 = 'not something'; |
|
|
|
$model->loadDefaultValues(false); |
|
$this->assertEquals('something', $model->char_col2); |
|
} |
|
|
|
public function testUnlinkAllViaTable() |
|
{ |
|
/* @var $orderClass \yii\db\ActiveRecordInterface */ |
|
$orderClass = $this->getOrderClass(); |
|
/* @var $orderItemClass \yii\db\ActiveRecordInterface */ |
|
$orderItemClass = $this->getOrderItemClass(); |
|
/* @var $itemClass \yii\db\ActiveRecordInterface */ |
|
$itemClass = $this->getItemClass(); |
|
/* @var $orderItemsWithNullFKClass \yii\db\ActiveRecordInterface */ |
|
$orderItemsWithNullFKClass = $this->getOrderItemWithNullFKmClass(); |
|
|
|
// via table with delete |
|
/* @var $order Order */ |
|
$order = $orderClass::findOne(1); |
|
$this->assertEquals(2, count($order->booksViaTable)); |
|
$orderItemCount = $orderItemClass::find()->count(); |
|
$this->assertEquals(5, $itemClass::find()->count()); |
|
$order->unlinkAll('booksViaTable', true); |
|
$this->afterSave(); |
|
$this->assertEquals(5, $itemClass::find()->count()); |
|
$this->assertEquals($orderItemCount - 2, $orderItemClass::find()->count()); |
|
$this->assertEquals(0, count($order->booksViaTable)); |
|
|
|
// via table without delete |
|
$this->assertEquals(2, count($order->booksWithNullFKViaTable)); |
|
$orderItemCount = $orderItemsWithNullFKClass::find()->count(); |
|
$this->assertEquals(5, $itemClass::find()->count()); |
|
$order->unlinkAll('booksWithNullFKViaTable',false); |
|
$this->assertEquals(0, count($order->booksWithNullFKViaTable)); |
|
$this->assertEquals(2,$orderItemsWithNullFKClass::find()->where(['AND', ['item_id' => [1, 2]], ['order_id' => null]])->count()); |
|
$this->assertEquals($orderItemCount, $orderItemsWithNullFKClass::find()->count()); |
|
$this->assertEquals(5, $itemClass::find()->count()); |
|
} |
|
|
|
public function testCastValues() |
|
{ |
|
$model = new Type(); |
|
$model->int_col = 123; |
|
$model->int_col2 = 456; |
|
$model->smallint_col = 42; |
|
$model->char_col = '1337'; |
|
$model->char_col2 = 'test'; |
|
$model->char_col3 = 'test123'; |
|
$model->float_col = 3.742; |
|
$model->float_col2 = 42.1337; |
|
$model->bool_col = true; |
|
$model->bool_col2 = false; |
|
$model->save(false); |
|
|
|
/* @var $model Type */ |
|
$model = Type::find()->one(); |
|
$this->assertSame(123, $model->int_col); |
|
$this->assertSame(456, $model->int_col2); |
|
$this->assertSame(42, $model->smallint_col); |
|
$this->assertSame('1337', trim($model->char_col)); |
|
$this->assertSame('test', $model->char_col2); |
|
$this->assertSame('test123', $model->char_col3); |
|
// $this->assertSame(1337.42, $model->float_col); |
|
// $this->assertSame(42.1337, $model->float_col2); |
|
// $this->assertSame(true, $model->bool_col); |
|
// $this->assertSame(false, $model->bool_col2); |
|
} |
|
|
|
public function testIssues() |
|
{ |
|
// https://github.com/yiisoft/yii2/issues/4938 |
|
$category = Category::findOne(2); |
|
$this->assertTrue($category instanceof Category); |
|
$this->assertEquals(3, $category->getItems()->count()); |
|
$this->assertEquals(1, $category->getLimitedItems()->count()); |
|
$this->assertEquals(1, $category->getLimitedItems()->distinct(true)->count()); |
|
|
|
// https://github.com/yiisoft/yii2/issues/3197 |
|
$orders = Order::find()->with('orderItems')->orderBy('id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(2, count($orders[0]->orderItems)); |
|
$this->assertEquals(3, count($orders[1]->orderItems)); |
|
$this->assertEquals(1, count($orders[2]->orderItems)); |
|
$orders = Order::find()->with(['orderItems' => function ($q) { $q->indexBy('item_id'); }])->orderBy('id')->all(); |
|
$this->assertEquals(3, count($orders)); |
|
$this->assertEquals(2, count($orders[0]->orderItems)); |
|
$this->assertEquals(3, count($orders[1]->orderItems)); |
|
$this->assertEquals(1, count($orders[2]->orderItems)); |
|
|
|
// https://github.com/yiisoft/yii2/issues/8149 |
|
$model = new Customer(); |
|
$model->name = 'test'; |
|
$model->email = 'test'; |
|
$model->save(false); |
|
$model->updateCounters(['status' => 1]); |
|
$this->assertEquals(1, $model->status); |
|
} |
|
|
|
public function testPopulateRecordCallWhenQueryingOnParentClass() |
|
{ |
|
(new Cat())->save(false); |
|
(new Dog())->save(false); |
|
|
|
$animal = Animal::find()->where(['type' => Dog::className()])->one(); |
|
$this->assertEquals('bark', $animal->getDoes()); |
|
|
|
$animal = Animal::find()->where(['type' => Cat::className()])->one(); |
|
$this->assertEquals('meow', $animal->getDoes()); |
|
} |
|
|
|
public function testSaveEmpty() |
|
{ |
|
$record = new NullValues; |
|
$this->assertTrue($record->save(false)); |
|
$this->assertEquals(1, $record->id); |
|
} |
|
|
|
public function testOptimisticLock() |
|
{ |
|
/* @var $record Document */ |
|
|
|
$record = Document::findOne(1); |
|
$record->content = 'New Content'; |
|
$record->save(false); |
|
$this->assertEquals(1, $record->version); |
|
|
|
$record = Document::findOne(1); |
|
$record->content = 'Rewrite attempt content'; |
|
$record->version = 0; |
|
$this->setExpectedException('yii\db\StaleObjectException'); |
|
$record->save(false); |
|
} |
|
|
|
public function testPopulateWithoutPk() |
|
{ |
|
// tests with single pk asArray |
|
$aggregation = Customer::find() |
|
->select(['{{customer}}.[[status]]', 'SUM({{order}}.[[total]]) AS [[sumtotal]]']) |
|
->joinWith('ordersPlain', false) |
|
->groupBy('{{customer}}.[[status]]') |
|
->orderBy('status') |
|
->asArray() |
|
->all(); |
|
|
|
$expected = [ |
|
[ |
|
'status' => 1, |
|
'sumtotal' => 183, |
|
], |
|
[ |
|
'status' => 2, |
|
'sumtotal' => 0, |
|
], |
|
]; |
|
$this->assertEquals($expected, $aggregation); |
|
|
|
// tests with single pk with Models |
|
$aggregation = Customer::find() |
|
->select(['{{customer}}.[[status]]', 'SUM({{order}}.[[total]]) AS [[sumTotal]]']) |
|
->joinWith('ordersPlain', false) |
|
->groupBy('{{customer}}.[[status]]') |
|
->orderBy('status') |
|
->all(); |
|
$this->assertCount(2, $aggregation); |
|
$this->assertContainsOnlyInstancesOf(Customer::className(), $aggregation); |
|
foreach($aggregation as $item) { |
|
if ($item->status == 1) { |
|
$this->assertEquals(183, $item->sumTotal); |
|
} elseif ($item->status == 2) { |
|
$this->assertEquals(0, $item->sumTotal); |
|
} |
|
} |
|
|
|
// tests with composite pk asArray |
|
$aggregation = OrderItem::find() |
|
->select(['[[order_id]]', 'SUM([[subtotal]]) AS [[subtotal]]']) |
|
->joinWith('order', false) |
|
->groupBy('[[order_id]]') |
|
->orderBy('[[order_id]]') |
|
->asArray() |
|
->all(); |
|
$expected = [ |
|
[ |
|
'order_id' => 1, |
|
'subtotal' => 70, |
|
], |
|
[ |
|
'order_id' => 2, |
|
'subtotal' => 33, |
|
], |
|
[ |
|
'order_id' => 3, |
|
'subtotal' => 40, |
|
], |
|
]; |
|
$this->assertEquals($expected, $aggregation); |
|
|
|
// tests with composite pk with Models |
|
$aggregation = OrderItem::find() |
|
->select(['[[order_id]]', 'SUM([[subtotal]]) AS [[subtotal]]']) |
|
->joinWith('order', false) |
|
->groupBy('[[order_id]]') |
|
->orderBy('[[order_id]]') |
|
->all(); |
|
$this->assertCount(3, $aggregation); |
|
$this->assertContainsOnlyInstancesOf(OrderItem::className(), $aggregation); |
|
foreach($aggregation as $item) { |
|
if ($item->order_id == 1) { |
|
$this->assertEquals(70, $item->subtotal); |
|
} elseif ($item->order_id == 2) { |
|
$this->assertEquals(33, $item->subtotal); |
|
} elseif ($item->order_id == 3) { |
|
$this->assertEquals(40, $item->subtotal); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* https://github.com/yiisoft/yii2/issues/9006 |
|
*/ |
|
public function testBit() |
|
{ |
|
$falseBit = BitValues::findOne(1); |
|
$this->assertEquals(false, $falseBit->val); |
|
|
|
$trueBit = BitValues::findOne(2); |
|
$this->assertEquals(true, $trueBit->val); |
|
} |
|
}
|
|
|