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
9c7d2b23
Commit
9c7d2b23
authored
Nov 29, 2013
by
Paul Klimov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Mongo Active Record and Active Query fixed.
parent
0f7ded8f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
355 additions
and
9 deletions
+355
-9
ActiveQuery.php
extensions/mongo/ActiveQuery.php
+73
-0
ActiveRecord.php
extensions/mongo/ActiveRecord.php
+11
-8
Query.php
extensions/mongo/Query.php
+5
-1
ActiveRecord.php
tests/unit/data/ar/mongo/ActiveRecord.php
+17
-0
Customer.php
tests/unit/data/ar/mongo/Customer.php
+28
-0
ActiveRecordTest.php
tests/unit/extensions/mongo/ActiveRecordTest.php
+221
-0
No files found.
extensions/mongo/ActiveQuery.php
View file @
9c7d2b23
...
...
@@ -19,4 +19,76 @@ use yii\db\ActiveQueryTrait;
class
ActiveQuery
extends
Query
implements
ActiveQueryInterface
{
use
ActiveQueryTrait
;
/**
* Executes query and returns all results as an array.
* @param Connection $db the DB connection used to create the DB command.
* If null, the DB connection returned by [[modelClass]] will be used.
* @return array the query results. If the query results in nothing, an empty array will be returned.
*/
public
function
all
(
$db
=
null
)
{
$cursor
=
$this
->
buildCursor
(
$db
);
$rows
=
[];
foreach
(
$cursor
as
$row
)
{
$rows
[]
=
$row
;
}
if
(
!
empty
(
$rows
))
{
$models
=
$this
->
createModels
(
$rows
);
if
(
!
empty
(
$this
->
with
))
{
$this
->
findWith
(
$this
->
with
,
$models
);
}
return
$models
;
}
else
{
return
[];
}
}
/**
* Executes query and returns a single row of result.
* @param Connection $db the DB connection used to create the DB command.
* If null, the DB connection returned by [[modelClass]] will be used.
* @return ActiveRecord|array|null a single row of query result. Depending on the setting of [[asArray]],
* the query result may be either an array or an ActiveRecord object. Null will be returned
* if the query results in nothing.
*/
public
function
one
(
$db
=
null
)
{
$row
=
parent
::
one
(
$db
);
if
(
$row
!==
false
)
{
if
(
$this
->
asArray
)
{
$model
=
$row
;
}
else
{
/** @var ActiveRecord $class */
$class
=
$this
->
modelClass
;
$model
=
$class
::
create
(
$row
);
}
if
(
!
empty
(
$this
->
with
))
{
$models
=
[
$model
];
$this
->
findWith
(
$this
->
with
,
$models
);
$model
=
$models
[
0
];
}
return
$model
;
}
else
{
return
null
;
}
}
/**
* Returns the Mongo collection for this query.
* @param Connection $db Mongo connection.
* @return Collection collection instance.
*/
public
function
getCollection
(
$db
=
null
)
{
/** @var ActiveRecord $modelClass */
$modelClass
=
$this
->
modelClass
;
if
(
$db
===
null
)
{
$db
=
$modelClass
::
getDb
();
}
if
(
$this
->
from
===
null
)
{
$this
->
from
=
$modelClass
::
collectionName
();
}
return
$db
->
getCollection
(
$this
->
from
);
}
}
\ No newline at end of file
extensions/mongo/ActiveRecord.php
View file @
9c7d2b23
...
...
@@ -162,11 +162,7 @@ abstract class ActiveRecord extends Model
if
(
!
array_key_exists
(
'multiple'
,
$options
))
{
$options
[
'multiple'
]
=
true
;
}
$data
=
[];
foreach
(
$counters
as
$name
=>
$value
)
{
$data
[
$name
][
'$inc'
]
=
$value
;
}
return
static
::
getCollection
()
->
update
(
$condition
,
$data
,
$options
);
return
static
::
getCollection
()
->
update
(
$condition
,
[
'$inc'
=>
$counters
],
$options
);
}
/**
...
...
@@ -470,13 +466,20 @@ abstract class ActiveRecord extends Model
/**
* Returns the list of all attribute names of the model.
* The default implementation will return all column names of the table associated with this AR class.
* This method must be overridden by child classes to define available attributes.
* Note: primary key attribute "_id" should be always present in returned array.
* For example:
* ~~~
* public function attributes()
* {
* return ['_id', 'name', 'address', 'status'];
* }
* ~~~
* @return array list of attribute names.
*/
public
function
attributes
()
{
// TODO: declare attributes
return
[];
throw
new
InvalidConfigException
(
'The attributes() method of mongo ActiveRecord has to be implemented by child classes.'
);
}
/**
...
...
extensions/mongo/Query.php
View file @
9c7d2b23
...
...
@@ -182,7 +182,11 @@ class Query extends Component implements QueryInterface
public
function
one
(
$db
=
null
)
{
$cursor
=
$this
->
buildCursor
(
$db
);
return
$cursor
->
getNext
();
if
(
$cursor
->
hasNext
())
{
return
$cursor
->
getNext
();
}
else
{
return
false
;
}
}
/**
...
...
tests/unit/data/ar/mongo/ActiveRecord.php
0 → 100644
View file @
9c7d2b23
<?php
namespace
yiiunit\data\ar\mongo
;
/**
* Test Mongo ActiveRecord
*/
class
ActiveRecord
extends
\yii\mongo\ActiveRecord
{
public
static
$db
;
public
static
function
getDb
()
{
return
self
::
$db
;
}
}
\ No newline at end of file
tests/unit/data/ar/mongo/Customer.php
0 → 100644
View file @
9c7d2b23
<?php
namespace
yiiunit\data\ar\mongo
;
class
Customer
extends
ActiveRecord
{
public
static
function
collectionName
()
{
return
'customer'
;
}
public
function
attributes
()
{
return
[
'_id'
,
'name'
,
'email'
,
'address'
,
'status'
,
];
}
public
static
function
activeOnly
(
$query
)
{
$query
->
andWhere
([
'status'
=>
2
]);
}
}
\ No newline at end of file
tests/unit/extensions/mongo/ActiveRecordTest.php
0 → 100644
View file @
9c7d2b23
<?php
namespace
yiiunit\extensions\mongo
;
use
yii\mongo\ActiveQuery
;
use
yiiunit\data\ar\mongo\ActiveRecord
;
use
yiiunit\data\ar\mongo\Customer
;
/**
* @group mongo
*/
class
ActiveRecordTest
extends
MongoTestCase
{
/**
* @var array[] list of test rows.
*/
protected
$testRows
=
[];
protected
function
setUp
()
{
parent
::
setUp
();
ActiveRecord
::
$db
=
$this
->
getConnection
();
$this
->
setUpTestRows
();
}
protected
function
tearDown
()
{
$this
->
dropCollection
(
Customer
::
collectionName
());
parent
::
tearDown
();
}
/**
* Sets up test rows.
*/
protected
function
setUpTestRows
()
{
$collection
=
$this
->
getConnection
()
->
getCollection
(
'customer'
);
$rows
=
[];
for
(
$i
=
1
;
$i
<=
10
;
$i
++
)
{
$rows
[]
=
[
'name'
=>
'name'
.
$i
,
'email'
=>
'email'
.
$i
,
'address'
=>
'address'
.
$i
,
'status'
=>
$i
,
];
}
$collection
->
batchInsert
(
$rows
);
$this
->
testRows
=
$rows
;
}
// Tests :
public
function
testFind
()
{
// find one
$result
=
Customer
::
find
();
$this
->
assertTrue
(
$result
instanceof
ActiveQuery
);
$customer
=
$result
->
one
();
$this
->
assertTrue
(
$customer
instanceof
Customer
);
// find all
$customers
=
Customer
::
find
()
->
all
();
$this
->
assertEquals
(
10
,
count
(
$customers
));
$this
->
assertTrue
(
$customers
[
0
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
1
]
instanceof
Customer
);
// find by _id
$testId
=
$this
->
testRows
[
0
][
'_id'
];
$customer
=
Customer
::
find
(
$testId
);
$this
->
assertTrue
(
$customer
instanceof
Customer
);
$this
->
assertEquals
(
$testId
,
$customer
->
_id
);
// find by column values
$customer
=
Customer
::
find
([
'name'
=>
'name5'
]);
$this
->
assertTrue
(
$customer
instanceof
Customer
);
$this
->
assertEquals
(
$this
->
testRows
[
4
][
'_id'
],
$customer
->
_id
);
$this
->
assertEquals
(
'name5'
,
$customer
->
name
);
$customer
=
Customer
::
find
([
'name'
=>
'unexisting name'
]);
$this
->
assertNull
(
$customer
);
// find by attributes
$customer
=
Customer
::
find
()
->
where
([
'status'
=>
4
])
->
one
();
$this
->
assertTrue
(
$customer
instanceof
Customer
);
$this
->
assertEquals
(
4
,
$customer
->
status
);
// find count, sum, average, min, max, scalar
$this
->
assertEquals
(
10
,
Customer
::
find
()
->
count
());
$this
->
assertEquals
(
1
,
Customer
::
find
()
->
where
([
'status'
=>
2
])
->
count
());
/*$this->assertEquals((1+10)/2*10, Customer::find()->sum('status'));
$this->assertEquals((1+10)/2, Customer::find()->average('status'));
$this->assertEquals(1, Customer::find()->min('status'));
$this->assertEquals(10, Customer::find()->max('status'));*/
// scope
$this
->
assertEquals
(
1
,
Customer
::
find
()
->
activeOnly
()
->
count
());
// asArray
$testRow
=
$this
->
testRows
[
2
];
$customer
=
Customer
::
find
()
->
where
([
'_id'
=>
$testRow
[
'_id'
]])
->
asArray
()
->
one
();
$this
->
assertEquals
(
$testRow
,
$customer
);
// indexBy
$customers
=
Customer
::
find
()
->
indexBy
(
'name'
)
->
all
();
$this
->
assertTrue
(
$customers
[
'name1'
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
'name2'
]
instanceof
Customer
);
// indexBy callable
$customers
=
Customer
::
find
()
->
indexBy
(
function
(
$customer
)
{
return
$customer
->
status
.
'-'
.
$customer
->
status
;
})
->
all
();
$this
->
assertTrue
(
$customers
[
'1-1'
]
instanceof
Customer
);
$this
->
assertTrue
(
$customers
[
'2-2'
]
instanceof
Customer
);
}
public
function
testInsert
()
{
$record
=
new
Customer
;
$record
->
name
=
'new name'
;
$record
->
email
=
'new email'
;
$record
->
address
=
'new address'
;
$record
->
status
=
7
;
$this
->
assertTrue
(
$record
->
isNewRecord
);
$record
->
save
();
$this
->
assertTrue
(
$record
->
_id
instanceof
\MongoId
);
$this
->
assertFalse
(
$record
->
isNewRecord
);
}
/**
* @depends testInsert
*/
public
function
testUpdate
()
{
$record
=
new
Customer
;
$record
->
name
=
'new name'
;
$record
->
email
=
'new email'
;
$record
->
address
=
'new address'
;
$record
->
status
=
7
;
$record
->
save
();
// save
$record
=
Customer
::
find
(
$record
->
_id
);
$this
->
assertTrue
(
$record
instanceof
Customer
);
$this
->
assertEquals
(
7
,
$record
->
status
);
$this
->
assertFalse
(
$record
->
isNewRecord
);
$record
->
status
=
9
;
$record
->
save
();
$this
->
assertEquals
(
9
,
$record
->
status
);
$this
->
assertFalse
(
$record
->
isNewRecord
);
$record2
=
Customer
::
find
(
$record
->
_id
);
$this
->
assertEquals
(
9
,
$record2
->
status
);
// updateAll
$pk
=
[
'_id'
=>
$record
->
_id
];
//$ret = Customer::updateAll(['status' => 55], $pk);
$ret
=
Customer
::
updateAll
([
'$set'
=>
[
'status'
=>
55
]],
$pk
);
$this
->
assertEquals
(
1
,
$ret
);
$record
=
Customer
::
find
(
$pk
);
$this
->
assertEquals
(
55
,
$record
->
status
);
}
/**
* @depends testInsert
*/
public
function
testDelete
()
{
// delete
$record
=
new
Customer
;
$record
->
name
=
'new name'
;
$record
->
email
=
'new email'
;
$record
->
address
=
'new address'
;
$record
->
status
=
7
;
$record
->
save
();
$record
=
Customer
::
find
(
$record
->
_id
);
$record
->
delete
();
$record
=
Customer
::
find
(
$record
->
_id
);
$this
->
assertNull
(
$record
);
// deleteAll
$record
=
new
Customer
;
$record
->
name
=
'new name'
;
$record
->
email
=
'new email'
;
$record
->
address
=
'new address'
;
$record
->
status
=
7
;
$record
->
save
();
$ret
=
Customer
::
deleteAll
([
'name'
=>
'new name'
]);
$this
->
assertEquals
(
1
,
$ret
);
$records
=
Customer
::
find
()
->
where
([
'name'
=>
'new name'
])
->
all
();
$this
->
assertEquals
(
0
,
count
(
$records
));
}
public
function
testUpdateAllCounters
()
{
$this
->
assertEquals
(
1
,
Customer
::
updateAllCounters
([
'status'
=>
10
],
[
'status'
=>
10
]));
$record
=
Customer
::
find
([
'status'
=>
10
]);
$this
->
assertNull
(
$record
);
}
/**
* @depends testUpdateAllCounters
*/
public
function
testUpdateCounters
()
{
$record
=
Customer
::
find
(
$this
->
testRows
[
9
]);
$originalCounter
=
$record
->
status
;
$counterIncrement
=
20
;
$record
->
updateCounters
([
'status'
=>
$counterIncrement
]);
$this
->
assertEquals
(
$originalCounter
+
$counterIncrement
,
$record
->
status
);
$refreshedRecord
=
Customer
::
find
(
$record
->
_id
);
$this
->
assertEquals
(
$originalCounter
+
$counterIncrement
,
$refreshedRecord
->
status
);
}
}
\ 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