Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add mongodb storage

  • Loading branch information...
commit b88ed9e58fcc206d0e238387c0792a3ac3ee8b27 1 parent 4fe8657
@Baachi authored
View
180 lib/Doctrine/KeyValueStore/Storage/MongoDbStorage.php
@@ -0,0 +1,180 @@
+<?php
+
+namespace Doctrine\KeyValueStore\Storage;
+
+/**
+ * MongoDb storage
+ *
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ */
+class MongoDbStorage implements Storage
+{
+ /**
+ * @var \Mongo
+ */
+ protected $mongo;
+
+ /**
+ * @var array
+ */
+ protected $dbOptions;
+
+ /**
+ * @var \MongoCollection
+ */
+ protected $collection;
+
+ /**
+ * Constructor
+ *
+ * @param \Mongo $mongo
+ * @param array $dbOptions
+ */
+ public function __construct(\Mongo $mongo, array $dbOptions = array())
+ {
+ $this->mongo = $mongo;
+ $this->dbOptions = array_merge(array(
+ 'database' => '',
+ 'collection' => '',
+ ), $dbOptions);
+ }
+
+ /**
+ * Initialize the mongodb collection
+ *
+ * @throws \RuntimeException
+ */
+ public function initialize()
+ {
+ if (null !== $this->collection) {
+ return;
+ }
+
+ if (empty($this->dbOptions['database'])) {
+ throw new \RuntimeException('The option "database" must be set');
+ }
+ if (empty($this->dbOptions['collection'])) {
+ throw new \RuntimeException('The option "collection" must be set');
+ }
+
+ $this->collection = $this->mongo->selectDB($this->dbOptions['database'])->selectCollection($this->dbOptions['collection']);
+ }
+
+ /**
+ * Determine if the storage supports updating only a subset of properties,
+ * or if all properties have to be set, even if only a subset of properties
+ * changed.
+ *
+ * @return bool
+ */
+ public function supportsPartialUpdates()
+ {
+ return false;
+ }
+
+ /**
+ * Does this storage support composite primary keys?
+ *
+ * @return bool
+ */
+ public function supportsCompositePrimaryKeys()
+ {
+ return false;
+ }
+
+ /**
+ * Does this storage require composite primary keys?
+ *
+ * @return bool
+ */
+ public function requiresCompositePrimaryKeys()
+ {
+ return false;
+ }
+
+ /**
+ * Insert data into the storage key specified.
+ *
+ * @param string $storageName
+ * @param array|string $key
+ * @param array $data
+ * @return void
+ */
+ public function insert($storageName, $key, array $data)
+ {
+ $this->initialize();
+
+ $value = array(
+ 'key' => $key,
+ 'value' => $data,
+ );
+
+ $this->collection->insert($value);
+ }
+
+ /**
+ * Update data into the given key.
+ *
+ * @param string $storageName
+ * @param array|string $key
+ * @param array $data
+ * @return void
+ */
+ public function update($storageName, $key, array $data)
+ {
+ $this->initialize();
+
+ $value = array(
+ 'key' => $key,
+ 'value' => $data,
+ );
+
+ $this->collection->update(array('key' => $key), $value);
+ }
+
+ /**
+ * Delete data at key
+ *
+ * @param string $storageName
+ * @param array|string $key
+ * @return void
+ */
+ public function delete($storageName, $key)
+ {
+ $this->initialize();
+
+ $this->collection->remove(array('key' => $key));
+ }
+
+ /**
+ * Find data at key
+ *
+ * Important note: The returned array does contain the identifier (again)!
+ *
+ * @param string $storageName
+ * @param array|string $key
+ * @return array
+ */
+ public function find($storageName, $key)
+ {
+ $this->initialize();
+
+ $value = $this->collection->findOne(array('key' => $key), array('value'));
+
+ if ($value) {
+ return $value['value'];
+ }
+
+ return array();
+ }
+
+ /**
+ * Return a name of the underlying storage.
+ *
+ * @return string
+ */
+ public function getName()
+ {
+ return 'mongodb';
+ }
+}
View
140 tests/Doctrine/Tests/KeyValueStore/Storage/MongoDbStorageTest.php
@@ -0,0 +1,140 @@
+<?php
+
+namespace Doctrine\Tests\KeyValueStore\Storage;
+
+use Doctrine\KeyValueStore\Storage\MongoDbStorage;
+
+/**
+ * MongoDb storage testcase
+ *
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
+ */
+class MongoDbStorageTest extends \PHPUnit_Framework_TestCase
+{
+ protected function setUp()
+ {
+ $this->mongo = $this->getMock('\Mongo');
+
+ $this->mongodb = $this->getMockBuilder('\MongoDB')->disableOriginalConstructor()->getMock();
+
+ $this->mongo->expects($this->any())
+ ->method('selectDB')
+ ->will($this->returnValue($this->mongodb));
+
+ $this->collection = $this->getMockBuilder('MongoCollection')->disableOriginalConstructor()->getMock();
+
+ $this->mongodb->expects($this->once())
+ ->method('selectCollection')
+ ->will($this->returnValue($this->collection));
+
+ $this->storage = new MongoDbStorage($this->mongo, array(
+ 'collection' => 'test',
+ 'database' => 'test'
+ ));
+ }
+
+ public function testInsert()
+ {
+ $data = array(
+ 'author' => 'John Doe',
+ 'title' => 'example book',
+ );
+
+ $dbDataset = array();
+
+ $this->collection->expects($this->once())
+ ->method('insert')
+ ->will($this->returnCallback(function($data) use (&$dbDataset) {
+ $dbDataset[] = $data;
+ }));
+
+ $this->storage->insert('mongodb', '1', $data);
+ $this->assertCount(1, $dbDataset);
+
+ $this->assertEquals(array(array('key' => '1', 'value' => $data)), $dbDataset);
+ }
+
+ public function testUpdate()
+ {
+ $data = array(
+ 'author' => 'John Doe',
+ 'title' => 'example book',
+ );
+
+ $dbDataset = array();
+
+ $this->collection->expects($this->once())
+ ->method('update')
+ ->will($this->returnCallback(function($citeria, $data) use (&$dbDataset) {
+ $dbDataset = array($citeria, $data);
+ }));
+
+ $this->storage->update('mongodb', '1', $data);
+
+ $this->assertEquals(array('key' => '1'), $dbDataset[0]);
+ $this->assertEquals(array('key' => '1', 'value' => $data), $dbDataset[1]);
+ }
+
+ public function testDelete()
+ {
+ $dataset = array(
+ array(
+ 'key' => 'foobar',
+ 'value' => array(
+ 'author' => 'John Doe',
+ 'title' => 'example book',
+ ),
+ ),
+ );
+
+ $this->collection->expects($this->once())
+ ->method('remove')
+ ->will($this->returnCallback(function($citeria) use (&$dataset) {
+ foreach ($dataset as $key => $row) {
+ if ($row['key'] === $citeria['key']) {
+ unset($dataset[$key]);
+ }
+ }
+ }
+ ));
+
+ $this->storage->delete('test', 'foobar');
+
+ $this->assertCount(0, $dataset);
+ }
+
+ public function testFind()
+ {
+ $dataset = array(
+ array(
+ 'key' => 'foobar',
+ 'value' => array(
+ 'author' => 'John Doe',
+ 'title' => 'example book',
+ ),
+ ),
+ );
+
+ $this->collection->expects($this->once())
+ ->method('findOne')
+ ->will($this->returnCallback(function($citeria, $fields) use (&$dataset) {
+ foreach ($dataset as $key => $row) {
+ if ($row['key'] === $citeria['key']) {
+ return $row;
+ }
+ }
+ }
+ ));
+
+ $data = $this->storage->find('test', 'foobar');
+
+ $this->assertEquals($dataset[0]['value'], $data);
+ }
+
+ public function testGetName()
+ {
+ $this->storage->initialize();
+
+ $this->assertEquals('mongodb', $this->storage->getName());
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.