Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[MODM-29] Allowing strategy to be set for embedded many, reference ma…

…ny and collection types so you can use $pushAll and $pullAll or $set
  • Loading branch information...
commit 7a9e0088153e1f3f7f9a0650f5f7461bbc41ec64 1 parent 7ca29f2
@jwage jwage authored
View
1  lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php
@@ -245,6 +245,7 @@ public function __construct($documentName)
$this->rootDocumentName = $documentName;
$this->reflClass = new \ReflectionClass($documentName);
$this->namespace = $this->reflClass->getNamespaceName();
+ $this->setCollection($this->reflClass->getShortName());
}
/**
View
3  lib/Doctrine/ODM/MongoDB/Mapping/Driver/DoctrineAnnotations.php
@@ -130,6 +130,7 @@ class Field extends Annotation
final class Collection extends Field
{
public $type = 'collection';
+ public $strategy = 'pushPull'; // pushPull, set
}
final class EmbedOne extends Field
{
@@ -146,6 +147,7 @@ class Field extends Annotation
public $targetDocument;
public $discriminatorField;
public $discriminatorMap;
+ public $strategy = 'pushPull'; // pushPull, set
}
final class ReferenceOne extends Field
{
@@ -164,6 +166,7 @@ class Field extends Annotation
public $discriminatorField;
public $discriminatorMap;
public $cascade;
+ public $strategy = 'pushPull'; // pushPull, set
}
final class NotSaved extends Field {}
final class AlsoLoad extends Field {
View
46 lib/Doctrine/ODM/MongoDB/Persisters/BasicDocumentPersister.php
@@ -206,6 +206,7 @@ public function update($document)
$id = $this->_uow->getDocumentIdentifier($document);
$update = $this->prepareUpdateData($document);
+ //print_r($update);
if ( ! empty($update)) {
if ($this->_dm->getEventManager()->hasListeners(ODMEvents::onUpdatePrepared)) {
$this->_dm->getEventManager()->dispatchEvent(
@@ -327,13 +328,23 @@ public function prepareUpdateData($document)
}
if ($mapping['type'] === 'many') {
- // insert diff
- if (isset($changeset[$mapping['fieldName']][2]) && $changeset[$mapping['fieldName']][2]) {
- $result[$this->_cmd . 'pushAll'][$mapping['fieldName']] = $this->_prepareValue($mapping, $changeset[$mapping['fieldName']][2]);
- }
- // delete diff
- if (isset($changeset[$mapping['fieldName']][3]) && $changeset[$mapping['fieldName']][3]) {
- $result[$this->_cmd . 'pullAll'][$mapping['fieldName']] = $this->_prepareValue($mapping, $changeset[$mapping['fieldName']][3]);
+ if ($mapping['strategy'] === 'pushPull') {
+ // insert diff
+ if (isset($changeset[$mapping['fieldName']][2]) && $changeset[$mapping['fieldName']][2]) {
+ $result[$this->_cmd . 'pushAll'][$mapping['fieldName']] = $this->_prepareValue($mapping, $changeset[$mapping['fieldName']][2]);
+ }
+ // delete diff
+ if (isset($changeset[$mapping['fieldName']][3]) && $changeset[$mapping['fieldName']][3]) {
+ $result[$this->_cmd . 'pullAll'][$mapping['fieldName']] = $this->_prepareValue($mapping, $changeset[$mapping['fieldName']][3]);
+ }
+ } elseif ($mapping['strategy'] === 'set') {
+ $old = isset($changeset[$mapping['fieldName']][0]) ? $changeset[$mapping['fieldName']][0] : null;
+ $new = isset($changeset[$mapping['fieldName']][1]) ? $changeset[$mapping['fieldName']][1] : null;
+ $new = $this->_prepareValue($mapping, $new);
+ $old = $this->_prepareValue($mapping, $old);
+ if ($old !== $new) {
+ $result[$this->_cmd . 'set'][$mapping['fieldName']] = $new;
+ }
}
} else {
$old = isset($changeset[$mapping['fieldName']][0]) ? $changeset[$mapping['fieldName']][0] : null;
@@ -493,16 +504,17 @@ private function _addFieldUpdateAtomicOperator(array $mapping, $new, $old, array
*/
private function _addArrayUpdateAtomicOperator(array $mapping, array $new, array $old, array &$result)
{
- // delete
- $deleteDiff = array_udiff_assoc($old, $new, function($a, $b) { return $a === $b ? 0 : 1; });
- if ($deleteDiff) {
- $result[$this->_cmd . 'pullAll'][$mapping['fieldName']] = array_values($deleteDiff);
- }
-
- // insert
- $insertDiff = array_udiff_assoc($new, $old, function($a, $b) {return $a === $b ? 0 : 1;});
- if ($insertDiff) {
- $result[$this->_cmd . 'pushAll'][$mapping['fieldName']] = array_values($insertDiff);
+ if ($mapping['strategy'] === 'pushPull') {
+ $deleteDiff = array_udiff_assoc($old, $new, function($a, $b) {return $a === $b ? 0 : 1; });
+ $insertDiff = array_udiff_assoc($new, $old, function($a, $b) {return $a === $b ? 0 : 1;});
+ if ($deleteDiff) {
+ $result[$this->_cmd . 'pullAll'][$mapping['fieldName']] = array_values($deleteDiff);
+ }
+ if ($insertDiff) {
+ $result[$this->_cmd . 'pushAll'][$mapping['fieldName']] = array_values($insertDiff);
+ }
+ } elseif ($mapping['strategy'] === 'set') {
+ $result[$this->_cmd . 'set'][$mapping['fieldName']] = $new;
}
}
View
58 tests/Doctrine/ODM/MongoDB/Tests/Persisters/BasicDocumentPersisterTest.php
@@ -12,7 +12,10 @@
Documents\Phonenumber,
Documents\Profile,
Documents\File,
- Documents\User;
+ Documents\User,
+ Documents\Strategy,
+ Documents\Message,
+ Documents\Task;
/**
* @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
@@ -70,6 +73,59 @@ public function testNewDocumentInsert()
$this->assertTrue(array_key_exists($this->escape('id'), $update[$this->escape('set')]['account']));
}
+ public function testSetStrategy()
+ {
+ $data = array(
+ '_id' => 'testid',
+ 'logs' => array(
+ array('name' => 'test'),
+ array('name' => 'ok'),
+ array('name' => 'test')
+ ),
+ 'messages' => array(
+ array('name' => 'Message1'),
+ array('name' => 'Message2')
+ ),
+ 'tasks' => array(
+ array(
+ '$db' => 'dbname',
+ '$id' => 'id',
+ '$ref' => 'collname'
+ )
+ )
+ );
+ $test = new Strategy();
+ $this->dm->getHydrator()->hydrate($test, $data);
+ $this->dm->getUnitOfWork()->registerManaged($test, 'testid', $data);
+
+ unset($test->logs[0]);
+ $test->logs[] = 'whatever';
+ $test->messages[] = new Message('Message3');
+ $test->tasks[] = new Task('Task1');
+ $test->tasks[] = new Task('Task2');
+
+ $classMetadata = $this->dm->getClassMetadata('Documents\Strategy');
+ $persister = $this->getMock(
+ 'Doctrine\ODM\MongoDB\Persisters\BasicDocumentPersister',
+ array('update', 'delete', 'executeInserts'),
+ array($this->dm, $classMetadata)
+ );
+ $this->dm->getUnitOfWork()->setDocumentPersister(
+ 'Documents\Strategy', $persister
+ );
+
+ $this->dm->getUnitOfWork()->computeChangeSets();
+ $update = $persister->prepareUpdateData($test);
+
+ $this->assertTrue(isset($update['$set']['logs']));
+ $this->assertEquals(3, count($update['$set']['logs']));
+ $this->assertTrue(isset($update['$set']['messages']));
+ $this->assertEquals(3, count($update['$set']['messages']));
+ $this->assertTrue(isset($update['$set']['tasks']));
+ $this->assertEquals(3, count($update['$set']['tasks']));
+
+ }
+
public function testDocumentUpdate()
{
$this->dm->getUnitOfWork()->setDocumentPersister(
View
33 tests/Documents/Message.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Documents;
+
+/** @EmbeddedDocument */
+class Message
+{
+ /** @Id */
+ private $id;
+
+ /** @String */
+ private $name;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+}
View
19 tests/Documents/Strategy.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Documents;
+
+/** @Document */
+class Strategy
+{
+ /** @Id */
+ public $id;
+
+ /** @Collection(strategy="set") */
+ public $logs = array();
+
+ /** @EmbedMany(targetDocument="Message", strategy="set") */
+ public $messages = array();
+
+ /** @ReferenceMany(targetDocument="Task", strategy="set") */
+ public $tasks = array();
+}
View
33 tests/Documents/Task.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Documents;
+
+/** @Document */
+class Task
+{
+ /** @Id */
+ private $id;
+
+ /** @String */
+ private $name;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.