From a87845980d000bc0f57b9079f2e91e868212ed2e Mon Sep 17 00:00:00 2001 From: Anton Grebnev Date: Tue, 22 Nov 2011 16:29:00 +0400 Subject: [PATCH] added methods to MongoDriver for custom commands, findAndModify, count --- model/MongoDbCommand.php | 26 ++++++++++++++++++++- model/MongoDriver.php | 31 +++++++++++++++++++++++++ model/MongoModel.php | 5 ++++ model/MongoStatement.php | 18 +++++++++++---- tests/model/MongoDbCommandTest.php | 24 ++++++++++++++++++- tests/model/MongoDriverTest.php | 47 ++++++++++++++++++++++++++++++++++++++ tests/model/MongoModelTest.php | 12 ++++++++++ 7 files changed, 156 insertions(+), 7 deletions(-) diff --git a/model/MongoDbCommand.php b/model/MongoDbCommand.php index 288f32c..7c9328d 100644 --- a/model/MongoDbCommand.php +++ b/model/MongoDbCommand.php @@ -18,6 +18,8 @@ class MongoCommandBuilder const REMOVE = 'Remove'; + const COMMAND = 'Command'; + static public function factory($type, $collection = null) { $class = ucfirst($type) . 'MongoCommand'; @@ -167,4 +169,26 @@ class RemoveMongoCommand extends MongoDbCommand } } - + class CommandMongoCommand extends MongoDbCommand + { + protected $command; + + protected function concreteExecute() + { + $db = $this->collection->db; + if($db instanceof MongoDB) { + return $db->command($this->command); + } else { + return false; + } + } + + protected function checkParams() + { + if (isset($this->collection) && isset($this->command)) { + return true; + } else { + return false; + } + } + } diff --git a/model/MongoDriver.php b/model/MongoDriver.php index 76efee2..8efd68b 100644 --- a/model/MongoDriver.php +++ b/model/MongoDriver.php @@ -26,6 +26,11 @@ class MongoDriver extends NoSqlDbDriver return $this->connection->selectCollection($this->db, $name); } + public function count($collection, $query = array(), $limit = 0, $skip = 0) + { + return $this->getCollection($collection)->count($query, $limit, $skip); + } + public function find($collection, $condition = array(), $fields = array()) { $command = MongoCommandBuilder::factory(MongoCommandBuilder::FIND, $this->getCollection($collection)); @@ -48,6 +53,30 @@ class MongoDriver extends NoSqlDbDriver return $this->query($command, $params); } + public function findAndModify($collection, $query, $update, $sort = array(), $field = array(), $upsert = false, $new = false, $remove = false) + { + $command = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->getCollection($collection)); + $cmd = array( + 'findAndModify' => $collection, + 'query' => $query, + 'update' => $update, + 'sort' => $sort, + 'fields' => $field, + 'new' => $new, + 'upsert' => $upsert, + 'remove' => $remove + ); + $params = array('command' => $cmd); + return $this->query($command, $params); + } + + public function command($collection, $cmd) + { + $command = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->getCollection($collection)); + $params = array('command' => $cmd); + return $this->query($command, $params); + } + public function insert($collection, $data, $safe = true) { $command = MongoCommandBuilder::factory(MongoCommandBuilder::INSERT, $this->getCollection($collection)); @@ -85,6 +114,8 @@ class MongoDriver extends NoSqlDbDriver return $this->query($command, $params)->affectedRows(); } + + /** * @param mixed $request * @return DbStatement diff --git a/model/MongoModel.php b/model/MongoModel.php index 8063862..8eb1814 100644 --- a/model/MongoModel.php +++ b/model/MongoModel.php @@ -13,6 +13,11 @@ abstract class MongoModel extends Model { + public function count($query = array(), $limit = 0, $skip = 0) + { + return $this->db->count($this->table(), $query, $limit, $skip); + } + public function find($condition = array()) { return $this->db->find($this->table(), $condition); diff --git a/model/MongoStatement.php b/model/MongoStatement.php index c3b5f13..399cb67 100644 --- a/model/MongoStatement.php +++ b/model/MongoStatement.php @@ -16,7 +16,7 @@ class MongoStatement extends DbStatement protected $insertId = false; - public function order($sort = array()) + public function order($sort = array()) { if ($this->result instanceof MongoCursor) { $this->result->sort($sort); @@ -96,8 +96,10 @@ class MongoStatement extends DbStatement public function affectedRows() { if (is_array($this->result)) { - if (isset($this->result['ok']) && $this->result['ok'] == 1 && isset($this->result['n'])) { - return $this->result['n']; + if (isset($this->result['ok']) && $this->result['ok'] == 1) { + if (isset($this->result['n'])) { + return $this->result['n']; + } } else { return false; } @@ -115,7 +117,7 @@ class MongoStatement extends DbStatement } /** - * @param MongoDbComand $request + * @param MongoDbCommand $request * @return bool */ protected function driverExecute($request) @@ -134,8 +136,14 @@ class MongoStatement extends DbStatement } if ($result instanceof MongoCursor || is_array($result)) { $this->result = $result; + if (is_array($result) && isset($result['value'])) { + $this->result = $result['value']; + } + if (is_array($result) && isset($result['values'])) { + $this->result = $result['values']; + } } - if($request instanceof InsertMongoCommand) { + if ($request instanceof InsertMongoCommand) { $this->insertId = $request->getInsertId(); } return true; diff --git a/tests/model/MongoDbCommandTest.php b/tests/model/MongoDbCommandTest.php index a1cc437..75a18d6 100644 --- a/tests/model/MongoDbCommandTest.php +++ b/tests/model/MongoDbCommandTest.php @@ -84,7 +84,7 @@ class MongoDbCommandTest extends PHPUnit_Framework_TestCase ->bindParam('condition', array('name' => 'insert')) ->bindParam('fields', array()) ->bindParam('multiple', false); - + $result = $cmd->execute(); $this->assertEquals('insert', $result['name']); } @@ -199,4 +199,26 @@ class MongoDbCommandTest extends PHPUnit_Framework_TestCase $cmd = MongoCommandBuilder::factory(MongoCommandBuilder::REMOVE, $this->collection); $cmd->execute(); } + + /** + * @expectedException Exception + * @expectedExceptionMessage CommandMongoCommand error. Bind all required params first. + */ + public function testCommandCommandNotAllParamsBinded() + { + $cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, $this->collection); + $cmd->execute(); + } + + public function testCommandCommandNotMongoDb() + { + $cmd = MongoCommandBuilder::factory(MongoCommandBuilder::COMMAND, new CollectionMock()); + $cmd->bindParam('command', array()); + $this->assertFalse($cmd->execute()); + } +} + +class CollectionMock +{ + public $db = array(); } diff --git a/tests/model/MongoDriverTest.php b/tests/model/MongoDriverTest.php index da61ebc..edcedd4 100644 --- a/tests/model/MongoDriverTest.php +++ b/tests/model/MongoDriverTest.php @@ -176,6 +176,20 @@ class MongoDriverTest extends PHPUnit_Framework_TestCase /** * @runInSeparateProcess */ + public function testCount() + { + if (!defined('DEBUG')) { + define('DEBUG', false); + } + $mongo = new MongoDriver($this->conf); + $this->assertEquals(5, $mongo->count('items')); + $this->assertEquals(2, $mongo->count('items', array('name' => 'eggs'))); + $this->assertEquals(1, $mongo->count('items', array('name' => 'eggs'), 1)); + } + + /** + * @runInSeparateProcess + */ public function testGet() { if (!defined('DEBUG')) { @@ -279,4 +293,37 @@ class MongoDriverTest extends PHPUnit_Framework_TestCase $this->assertEquals(1, $mongo->update('items', array('$set' => array('price' => 200, 'date' => 'today')), array('name' => 'ball'), true, true)); $this->assertEquals('today', $mongo->get('items', array('name' => 'ball'))->fetch()->date); } + + /** + * @runInSeparateProcess + */ + public function testFindAndModify() + { + if (!defined('DEBUG')) { + define('DEBUG', false); + } + + $mongo = new MongoDriver($this->conf); + + $this->assertEquals(10, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity); + $result = $mongo->findAndModify('items', array('name' => 'bread'), array('$set' => array('quantity' => 20))); + $this->assertEquals(10, $result->fetch()->quantity); + $this->assertEquals(20, $mongo->get('items', array('name' => 'bread'))->fetch()->quantity); + } + + /** + * @runInSeparateProcess + */ + public function testCommand() + { + if (!defined('DEBUG')) { + define('DEBUG', false); + } + $mongo = new MongoDriver($this->conf); + $result = $mongo->command('items', array('distinct' =>'items', 'key' => 'name')); + $this->assertEquals(4, count($result->fetch(DB::FETCH_ASSOC))); + + + + } } \ No newline at end of file diff --git a/tests/model/MongoModelTest.php b/tests/model/MongoModelTest.php index 00403a0..695b788 100644 --- a/tests/model/MongoModelTest.php +++ b/tests/model/MongoModelTest.php @@ -101,6 +101,18 @@ class MongoModelTest extends PHPUnit_Framework_TestCase /** * @runInSeparateProcess */ + public function testCount() + { + if (!defined('DEBUG')) { + define('DEBUG', false); + } + $this->assertEquals(5, $this->model->count()); + $this->assertEquals(2, $this->model->count(array('name' => 'eggs'))); + } + + /** + * @runInSeparateProcess + */ public function testFetch() { if (!defined('DEBUG')) {