Skip to content
Browse files

Cleaned up code a bit and started implementing converter strategy for…

… IDs.
  • Loading branch information...
1 parent 6b11cc2 commit 867d0a7619cfaefe9d9a8d66f67f83e0a5cd1213 @beberlei beberlei committed
View
8 README.md
@@ -20,15 +20,15 @@ The Persistence interfaces are rather overkill for many implementations in the N
Following vendors are targeted:
* Microsoft Azure Table (Implemented)
+* Doctrine\Common\Cache provider (Implemented)
+* RDBMS (Implemented)
+* Couchbase
* Amazon DynamoDB
* CouchDB
* MongoDB
-* Couchbase
* Riak
-* Doctrine\Common\Cache provider (Implemented)
-* RDBMS (Implemented)
-We happly accept contributions for any of the drivers.
+We happily accept contributions for any of the drivers.
## Example
View
4 lib/Doctrine/KeyValueStore/EntityManager.php
@@ -42,12 +42,12 @@ class EntityManager
*/
private $storageDriver;
- public function __construct(Storage $storageDriver, Cache $cache, MappingDriver $mappingDriver)
+ public function __construct(Storage $storageDriver, Cache $cache, MappingDriver $mappingDriver, array $idConverters = array())
{
$cmf = new ClassMetadataFactory($mappingDriver);
$cmf->setCacheDriver($cache);
- $this->unitOfWork = new UnitOfWork($cmf, $storageDriver);
+ $this->unitOfWork = new UnitOfWork($cmf, $storageDriver, $idConverters);
$this->storageDriver = $storageDriver;
}
View
36 lib/Doctrine/KeyValueStore/Id/IdConverterStrategy.php
@@ -0,0 +1,36 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\KeyValueStore\Id;
+
+/**
+ * Serialization Interface for Identifiers
+ *
+ * This is used to simply convert other entities to serialized identifiers
+ * and back, for example if an Object-Relational-Mapper Entity is part
+ * of a key this strategy converts it to its identifier and back.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface IdConverterStrategy
+{
+ function serialize($class, $id);
+ function unserialize($class, $id);
+}
+
View
34 lib/Doctrine/KeyValueStore/Id/NullIdConverter.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\KeyValueStore\Id;
+
+class NullIdConverter implements IdConverterStrategy
+{
+ public function serialize($class, $id)
+ {
+ return $id;
+ }
+
+ public function unserialize($class, $id)
+ {
+ return $id;
+ }
+}
+
View
70 lib/Doctrine/KeyValueStore/UnitOfWork.php
@@ -19,24 +19,34 @@
namespace Doctrine\KeyValueStore;
+use Doctrine\KeyValueStore\Id\NullIdConverter;
+
+/**
+ * UnitOfWork to handle all KeyValueStore entities based on the configured
+ * storage mechanism.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
class UnitOfWork
{
private $cmf;
private $storageDriver;
private $idHandler;
- private $identityMap = array();
private $identifiers;
private $originalData;
private $scheduledInsertions = array();
- private $scheduledDeletions = array();
+ private $scheduledDeletions = array();
+ private $identityMap = array();
+ private $idConverter;
- public function __construct($cmf, $storageDriver)
+ public function __construct($cmf, $storageDriver, $idConverter = null)
{
- $this->cmf = $cmf;
+ $this->cmf = $cmf;
$this->storageDriver = $storageDriver;
- $this->idHandler = $storageDriver->supportsCompositePrimaryKeys() ?
- new Id\CompositeIdHandler() :
- new Id\SingleIdHandler();
+ $this->idConverter = $idConverter ?: new NullIdConverter();
+ $this->idHandler = $storageDriver->supportsCompositePrimaryKeys() ?
+ new Id\CompositeIdHandler() :
+ new Id\SingleIdHandler();
}
public function tryGetById($id)
@@ -51,8 +61,8 @@ public function tryGetById($id)
public function reconsititute($className, $key)
{
$class = $this->cmf->getMetadataFor($className);
- $id = $this->idHandler->normalizeId($class, $key);
- $data = $this->storageDriver->find($class->storageName, $id);
+ $id = $this->idHandler->normalizeId($class, $key);
+ $data = $this->storageDriver->find($class->storageName, $id);
return $this->createEntity($class, $id, $data);
}
@@ -71,7 +81,8 @@ public function createEntity($class, $id, $data)
if ( ! $object) {
$object = $class->newInstance();
}
- $oid = spl_object_hash($object);
+
+ $oid = spl_object_hash($object);
$this->originalData[$oid] = $data;
foreach ($data as $property => $value) {
@@ -84,16 +95,17 @@ public function createEntity($class, $id, $data)
$idHash = $this->idHandler->hash($id);
$this->identityMap[$idHash] = $object;
- $this->identifiers[$oid] = $id;
+ $this->identifiers[$oid] = $id;
return $object;
}
private function computeChangeSet($class, $object)
{
- $snapshot = $this->getObjectSnapshot($class, $object);
- $changeSet = array();
+ $snapshot = $this->getObjectSnapshot($class, $object);
+ $changeSet = array();
$originalData = $this->originalData[spl_object_hash($object)];
+
foreach ($snapshot as $field => $value) {
if ( ! isset($originalData[$field]) || $originalData[$field] !== $value) {
$changeSet[$field] = $value;
@@ -109,6 +121,7 @@ private function computeChangeSet($class, $object)
private function getObjectSnapshot($class, $object)
{
$data = array();
+
foreach ($class->reflFields as $fieldName => $reflProperty) {
if ( ! isset( $class->fields[$fieldName]['id'])) {
$data[$fieldName] = $reflProperty->getValue($object);
@@ -132,7 +145,7 @@ public function scheduleForInsert($object)
}
$class = $this->cmf->getMetadataFor(get_class($object));
- $id = $this->idHandler->getIdentifier($class, $object);
+ $id = $this->idHandler->getIdentifier($class, $object);
if ( ! $id) {
throw new \RuntimeException("Trying to persist entity that has no id.");
@@ -143,8 +156,9 @@ public function scheduleForInsert($object)
if (isset($this->identityMap[$idHash])) {
throw new \RuntimeException("Object with ID already exists.");
}
+
$this->scheduledInsertions[$oid] = $object;
- $this->identityMap[$idHash] = $object;
+ $this->identityMap[$idHash] = $object;
}
public function scheduleForDelete($object)
@@ -165,7 +179,7 @@ private function processIdentityMap()
continue;
}
- $metadata = $this->cmf->getMetadataFor(get_class($object));
+ $metadata = $this->cmf->getMetadataFor(get_class($object));
$changeSet = $this->computeChangeSet($metadata, $object);
if ($changeSet) {
@@ -185,13 +199,13 @@ private function processInsertions()
{
foreach ($this->scheduledInsertions as $object) {
$class = $this->cmf->getMetadataFor(get_class($object));
- $id = $this->idHandler->getIdentifier($class, $object);
+ $id = $this->idHandler->getIdentifier($class, $object);
if ( ! $id) {
throw new \RuntimeException("Trying to persist entity that has no id.");
}
- $data = $this->getObjectSnapshot($class, $object);
+ $data = $this->getObjectSnapshot($class, $object);
$data['php_class'] = $class->name;
$oid = spl_object_hash($object);
@@ -199,8 +213,8 @@ private function processInsertions()
$this->storageDriver->insert($class->storageName, $id, $data);
- $this->originalData[$oid] = $data;
- $this->identifiers[$oid] = $id;
+ $this->originalData[$oid] = $data;
+ $this->identifiers[$oid] = $id;
$this->identityMap[$idHash] = $object;
}
}
@@ -208,9 +222,9 @@ private function processInsertions()
private function processDeletions()
{
foreach ($this->scheduledDeletions as $object) {
- $class = $this->cmf->getMetadataFor(get_class($object));
- $oid = spl_object_hash($object);
- $id = $this->identifiers[$oid];
+ $class = $this->cmf->getMetadataFor(get_class($object));
+ $oid = spl_object_hash($object);
+ $id = $this->identifiers[$oid];
$idHash = $this->idHandler->hash($id);
$this->storageDriver->delete($class->storageName, $id);
@@ -226,16 +240,16 @@ public function commit()
$this->processDeletions();
$this->scheduledInsertions = array();
- $this->scheduledDeletions = array();
+ $this->scheduledDeletions = array();
}
public function clear()
{
$this->scheduledInsertions = array();
- $this->scheduledDeletions = array();
- $this->identifiers = array();
- $this->originalData = array();
- $this->identityMap = array();
+ $this->scheduledDeletions = array();
+ $this->identifiers = array();
+ $this->originalData = array();
+ $this->identityMap = array();
}
}
View
11 tests/Doctrine/Tests/KeyValueStore/Functional/BasicCrudTestCase.php
@@ -97,7 +97,16 @@ public function testUpdateClass()
$this->manager->flush();
- $this->assertEquals(array('id' => 1, 'headline' => 'asdf', 'body' => 'bar', 'text' => 'baz', 'php_class' => __NAMESPACE__ . '\\Post'), $this->find(1));
+ $this->assertEquals(
+ array(
+ 'id' => 1,
+ 'headline' => 'asdf',
+ 'body' => 'bar',
+ 'text' => 'baz',
+ 'php_class' => __NAMESPACE__ . '\\Post'
+ ),
+ $this->find(1)
+ );
}
public function testRemoveClass()

0 comments on commit 867d0a7

Please sign in to comment.
Something went wrong with that request. Please try again.