Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Rotua Panjaitan
yii2
Commits
0cd6b346
Commit
0cd6b346
authored
Jan 05, 2013
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactoring AR
parent
23572c74
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
97 additions
and
158 deletions
+97
-158
ActiveQuery.php
framework/db/ar/ActiveQuery.php
+59
-24
ActiveRecord.php
framework/db/ar/ActiveRecord.php
+2
-2
ActiveRelation.php
framework/db/ar/ActiveRelation.php
+5
-5
ActiveRecordTest.php
tests/unit/framework/db/ar/ActiveRecordTest.php
+31
-127
No files found.
framework/db/ar/ActiveQuery.php
View file @
0cd6b346
...
...
@@ -32,7 +32,7 @@ class ActiveQuery extends BaseQuery
* @var string the name of the column by which the query result should be indexed.
* This is only used when the query result is returned as an array when calling [[all()]].
*/
public
$index
;
public
$index
By
;
/**
* @var boolean whether to return each record as an array. If false (default), an object
* of [[modelClass]] will be created to represent each record.
...
...
@@ -170,9 +170,9 @@ class ActiveQuery extends BaseQuery
return
$this
;
}
public
function
index
(
$column
)
public
function
index
By
(
$column
)
{
$this
->
index
=
$column
;
$this
->
index
By
=
$column
;
return
$this
;
}
...
...
@@ -186,48 +186,34 @@ class ActiveQuery extends BaseQuery
{
$models
=
array
();
if
(
$this
->
asArray
)
{
if
(
$this
->
index
===
null
)
{
if
(
$this
->
index
By
===
null
)
{
return
$rows
;
}
foreach
(
$rows
as
$row
)
{
$models
[
$row
[
$this
->
index
]]
=
$row
;
$models
[
$row
[
$this
->
index
By
]]
=
$row
;
}
}
else
{
/** @var $class ActiveRecord */
$class
=
$this
->
modelClass
;
if
(
$this
->
index
===
null
)
{
if
(
$this
->
index
By
===
null
)
{
foreach
(
$rows
as
$row
)
{
$models
[]
=
$class
::
create
(
$row
);
}
}
else
{
foreach
(
$rows
as
$row
)
{
$model
=
$class
::
create
(
$row
);
$models
[
$model
->
{
$this
->
index
}]
=
$model
;
$models
[
$model
->
{
$this
->
index
By
}]
=
$model
;
}
}
}
return
$models
;
}
protected
function
fetchRelatedModels
(
&
$models
,
$
relations
)
protected
function
fetchRelatedModels
(
&
$models
,
$
with
)
{
// todo: normalize $relations
$primaryModel
=
new
$this
->
modelClass
;
foreach
(
$relations
as
$name
=>
$properties
)
{
if
(
is_integer
(
$name
))
{
$name
=
$properties
;
$properties
=
array
();
}
if
(
!
method_exists
(
$primaryModel
,
$name
))
{
throw
new
Exception
(
"Unknown relation:
$name
"
);
}
/** @var $relation ActiveRelation */
$relation
=
$primaryModel
->
$name
();
$relation
->
primaryModel
=
null
;
foreach
(
$properties
as
$p
=>
$v
)
{
$relation
->
$p
=
$v
;
}
$relations
=
$this
->
normalizeRelations
(
$primaryModel
,
$with
);
foreach
(
$relations
as
$name
=>
$relation
)
{
if
(
$relation
->
asArray
===
null
)
{
// inherit asArray from primary query
$relation
->
asArray
=
$this
->
asArray
;
...
...
@@ -235,4 +221,53 @@ class ActiveQuery extends BaseQuery
$relation
->
findWith
(
$name
,
$models
);
}
}
/**
* @param ActiveRecord $model
* @param array $with
* @return ActiveRelation[]
* @throws \yii\db\Exception
*/
protected
function
normalizeRelations
(
$model
,
$with
)
{
$relations
=
array
();
foreach
(
$with
as
$name
=>
$options
)
{
if
(
is_integer
(
$name
))
{
$name
=
$options
;
$options
=
array
();
}
if
((
$pos
=
strpos
(
$name
,
'.'
))
!==
false
)
{
// with sub-relations
$childName
=
substr
(
$name
,
$pos
+
1
);
$name
=
substr
(
$name
,
0
,
$pos
);
}
else
{
$childName
=
null
;
}
if
(
!
isset
(
$relations
[
$name
]))
{
if
(
!
method_exists
(
$model
,
$name
))
{
throw
new
Exception
(
"Unknown relation:
$name
"
);
}
/** @var $relation ActiveRelation */
$relation
=
$model
->
$name
();
$relation
->
primaryModel
=
null
;
$relations
[
$name
]
=
$relation
;
}
else
{
$relation
=
$relations
[
$name
];
}
if
(
isset
(
$childName
))
{
if
(
isset
(
$relation
->
with
[
$childName
]))
{
$relation
->
with
[
$childName
]
=
array_merge
(
$relation
->
with
,
$options
);
}
else
{
$relation
->
with
[
$childName
]
=
$options
;
}
}
else
{
foreach
(
$options
as
$p
=>
$v
)
{
$relation
->
$p
=
$v
;
}
}
}
return
$relations
;
}
}
framework/db/ar/ActiveRecord.php
View file @
0cd6b346
...
...
@@ -430,8 +430,8 @@ abstract class ActiveRecord extends Model
public
function
addRelatedRecord
(
$relation
,
$record
)
{
if
(
$relation
->
hasMany
)
{
if
(
$relation
->
index
!==
null
)
{
$this
->
_related
[
$relation
->
name
][
$record
->
{
$relation
->
index
}]
=
$record
;
if
(
$relation
->
index
By
!==
null
)
{
$this
->
_related
[
$relation
->
name
][
$record
->
{
$relation
->
index
By
}]
=
$record
;
}
else
{
$this
->
_related
[
$relation
->
name
][]
=
$record
;
}
...
...
framework/db/ar/ActiveRelation.php
View file @
0cd6b346
...
...
@@ -34,18 +34,18 @@ class ActiveRelation extends ActiveQuery
* @var ActiveRecord the primary model that this relation is associated with.
* This is used only in lazy loading with dynamic query options.
*/
p
rotected
$primaryModel
;
p
ublic
$primaryModel
;
/**
* @var array the columns of the primary and foreign tables that establish the relation.
* The array keys must be columns of the table for this relation, and the array values
* 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.
*/
p
rotected
$link
;
p
ublic
$link
;
/**
* @var array|ActiveRelation
*/
p
rotected
$via
;
p
ublic
$via
;
/**
* @param string $relationName
...
...
@@ -178,7 +178,7 @@ class ActiveRelation extends ActiveQuery
$linkKeys
=
array_keys
(
$link
);
foreach
(
$models
as
$i
=>
$model
)
{
$key
=
$this
->
getModelKey
(
$model
,
$linkKeys
);
if
(
$this
->
index
!==
null
)
{
if
(
$this
->
index
By
!==
null
)
{
$buckets
[
$key
][
$i
]
=
$model
;
}
else
{
$buckets
[
$key
][]
=
$model
;
...
...
@@ -194,7 +194,7 @@ class ActiveRelation extends ActiveQuery
$key2
=
$this
->
getModelKey
(
$viaModel
,
$linkValues
);
if
(
isset
(
$buckets
[
$key2
]))
{
foreach
(
$buckets
[
$key2
]
as
$i
=>
$bucket
)
{
if
(
$this
->
index
!==
null
)
{
if
(
$this
->
index
By
!==
null
)
{
$viaBuckets
[
$key1
][
$i
]
=
$bucket
;
}
else
{
$viaBuckets
[
$key1
][]
=
$bucket
;
...
...
tests/unit/framework/db/ar/ActiveRecordTest.php
View file @
0cd6b346
...
...
@@ -25,8 +25,7 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this
->
assertTrue
(
$customer
instanceof
Customer
);
// find all
$result
=
Customer
::
find
();
$customers
=
$result
->
all
();
$customers
=
Customer
::
find
()
->
all
();
$this
->
assertEquals
(
3
,
count
(
$customers
));
$this
->
assertTrue
(
$customers
[
0
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
1
]
instanceof
Customer
);
...
...
@@ -57,6 +56,23 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
'where'
=>
'id=1 OR id=2'
,
))
->
value
());
$this
->
assertEquals
(
2
,
Customer
::
find
()
->
select
(
'COUNT(*)'
)
->
where
(
'id=1 OR id=2'
)
->
value
());
// asArray
$customer
=
Customer
::
find
()
->
where
(
'id=2'
)
->
asArray
()
->
one
();
$this
->
assertEquals
(
array
(
'id'
=>
'2'
,
'email'
=>
'user2@example.com'
,
'name'
=>
'user2'
,
'address'
=>
'address2'
,
'status'
=>
'1'
,
),
$customer
);
// indexBy
$customers
=
Customer
::
find
()
->
indexBy
(
'name'
)
->
orderBy
(
'id'
)
->
all
();
$this
->
assertEquals
(
3
,
count
(
$customers
));
$this
->
assertTrue
(
$customers
[
'user1'
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
'user2'
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
'user3'
]
instanceof
Customer
);
}
public
function
testFindBySql
()
...
...
@@ -167,6 +183,17 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
$this
->
assertEquals
(
2
,
$order
->
books
[
0
]
->
id
);
}
public
function
testFindNestedRelation
()
{
$customers
=
Customer
::
find
()
->
with
(
'orders'
,
'orders.items'
)
->
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
));
$this
->
assertEquals
(
2
,
count
(
$customers
[
0
]
->
orders
[
0
]
->
items
));
$this
->
assertEquals
(
3
,
count
(
$customers
[
1
]
->
orders
[
0
]
->
items
));
$this
->
assertEquals
(
1
,
count
(
$customers
[
1
]
->
orders
[
1
]
->
items
));
}
// public function testInsert()
// {
...
...
@@ -373,129 +400,5 @@ class ActiveRecordTest extends \yiiunit\MysqlTestCase
// $customers = Customer::find()->orderBy('id')->index('name')->all();
// $this->assertEquals(2, $customers['user2']['id']);
// }
//
// public function testEagerLoading()
// {
// // has many
// $customers = Customer::find()->with('orders')->orderBy('@.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')->orderBy('@.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')->orderBy('@.id')->all();
// $this->assertEquals(3, count($orders));
// $this->assertEquals(1, $orders[0]->items[0]->id);
// $this->assertEquals(2, $orders[0]->items[1]->id);
// $this->assertEquals(3, $orders[1]->items[0]->id);
// $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')->orderBy('@.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')->orderBy('@.id')->limit(2)->all();
// $this->assertEquals(2, count($orders));
// $this->assertEquals(1, $orders[0]->items[0]->id);
//
// /// customize "with" query
// $orders = Order::find()->with(array('items' => function($q) {
// $q->orderBy('@.id DESC');
// }))->orderBy('@.id')->limit(2)->all();
// $this->assertEquals(2, count($orders));
// $this->assertEquals(2, $orders[0]->items[0]->id);
//
// // 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')->orderBy('@.id')->index('id')->asArray()->all();
// $this->assertEquals(3, count($customers));
// $this->assertTrue(isset($customers[1], $customers[2], $customers[3]));
// $this->assertTrue(is_array($customers[1]));
// $this->assertEquals(1, count($customers[1]['orders']));
// $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()
// {
// // has one
// $order = Order::find(3);
// $this->assertTrue($order->customer instanceof Customer);
// $this->assertEquals(2, $order->customer->id);
//
// // has many
// $customer = Customer::find(2);
// $orders = $customer->orders;
// $this->assertEquals(2, count($orders));
// $this->assertEquals(2, $orders[0]->id);
// $this->assertEquals(3, $orders[1]->id);
//
// // has many via join table
// $orders = Order::find()->orderBy('@.id')->all();
// $this->assertEquals(3, count($orders));
// $this->assertEquals(2, count($orders[0]->books));
// $this->assertEquals(1, $orders[0]->books[0]->id);
// $this->assertEquals(2, $orders[0]->books[1]->id);
// $this->assertEquals(array(), $orders[1]->books);
// $this->assertEquals(1, count($orders[2]->books));
// $this->assertEquals(2, $orders[2]->books[0]->id);
//
// // customized relation query
// $customer = Customer::find(2);
// $orders = $customer->orders(array(
// 'where' => '@.id = 3',
// ));
// $this->assertEquals(1, count($orders));
// $this->assertEquals(3, $orders[0]->id);
//
// // original results are kept after customized query
// $orders = $customer->orders;
// $this->assertEquals(2, count($orders));
// $this->assertEquals(2, $orders[0]->id);
// $this->assertEquals(3, $orders[1]->id);
//
// // as array
// $orders = $customer->orders(array(
// 'asArray' => true,
// ));
// $this->assertEquals(2, count($orders));
// $this->assertTrue(is_array($orders[0]));
// $this->assertEquals(2, $orders[0]['id']);
// $this->assertEquals(3, $orders[1]['id']);
//
// // using anonymous function to customize query condition
// $orders = $customer->orders(function($q) {
// $q->orderBy('@.id DESC')->asArray();
// });
// $this->assertEquals(2, count($orders));
// $this->assertTrue(is_array($orders[0]));
// $this->assertEquals(3, $orders[0]['id']);
// $this->assertEquals(2, $orders[1]['id']);
// }
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment