Skip to content

Bugfix for MODM166 - collections not handled properly in recomputeSingleDocumentChangeSet #336

Merged
merged 1 commit into from Jun 27, 2012

2 participants

@superdweebie

Added test.

Added fix.

Did modest refactoring in uow to remove code duplication between computeChangeSet and recomputeSingleDocumentChangeSet.

@jmikola jmikola commented on the diff Jun 25, 2012
lib/Doctrine/ODM/MongoDB/UnitOfWork.php
foreach ($actualData as $propName => $actualValue) {
+ // skip not saved fields
+ if (isset($class->fieldMappings[$propName]['notSaved']) && $class->fieldMappings[$propName]['notSaved'] === true) {
+ continue;
+ }
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

I noticed this is also (and originally) further down in the method's $class->fieldMappings as $mapping loop. Was it a bug that the field also wasn't skipped in this loop?

@superdweebie
superdweebie added a note Jun 25, 2012

@jmikola I noticed that not saved fields weren't being skipped as early as possible, so I moved it up to make execution a little faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola and 1 other commented on an outdated diff Jun 25, 2012
lib/Doctrine/ODM/MongoDB/UnitOfWork.php
@@ -736,47 +802,6 @@ public function computeChangeSet(ClassMetadata $class, $document)
}
/**
- * Computes all the changes that have been done to documents and collections
- * since the last commit and stores these changes in the _documentChangeSet map
- * temporarily for access by the persisters, until the UoW commit is finished.
- */
- public function computeChangeSets()
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

It doesn't look like this method was changed (only relocated). Assuming there were no changes, can you move it back to keep the diff smaller? It makes it a bit more difficult to review the actual changes in this PR.

@superdweebie
superdweebie added a note Jun 25, 2012

@jmikola I moved it to try and put the methods in a logical order, but I can move it back to make the PR easier to read.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola commented on an outdated diff Jun 25, 2012
...e/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php
+ $phonenumbers[] = $phonenumber->getPhonenumber();
+ }
+ sort($phonenumbers);
+
+ $this->assertEquals(array('1111', '2222'), $phonenumbers);
+ }
+}
+
+class MODM166EventListener
+{
+ public function onFlush(OnFlushEventArgs $eventArgs)
+ {
+ $documentManager = $eventArgs->getDocumentManager();
+ $unitOfWork = $documentManager->getUnitOfWork();
+
+ foreach ($unitOfWork->getScheduledDocumentUpdates() AS $document) {
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

CS: lower-case AS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola commented on an outdated diff Jun 25, 2012
...e/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php
+}
+
+class MODM166EventListener
+{
+ public function onFlush(OnFlushEventArgs $eventArgs)
+ {
+ $documentManager = $eventArgs->getDocumentManager();
+ $unitOfWork = $documentManager->getUnitOfWork();
+
+ foreach ($unitOfWork->getScheduledDocumentUpdates() AS $document) {
+ $metadata = $documentManager->getClassMetadata(get_class($document));
+ $document->addPhonenumber(new Phonenumber('2222'));
+ $unitOfWork->recomputeSingleDocumentChangeSet($metadata, $document);
+ }
+ }
+}
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

CS: Newline at end of file

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola commented on an outdated diff Jun 25, 2012
...e/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace Doctrine\ODM\MongoDB\Tests\Functional\Ticket;
+
+use Doctrine\ODM\MongoDB\Events;
+use Documents\User;
+use Documents\Phonenumber;
+use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs;
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

CS: alphabetical order for use statements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola commented on an outdated diff Jun 25, 2012
...e/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php
+use Documents\Phonenumber;
+use Doctrine\ODM\MongoDB\Event\OnFlushEventArgs;
+
+class MODM166Test extends \Doctrine\ODM\MongoDB\Tests\BaseTest
+{
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->listener = new MODM166EventListener();
+ $evm = $this->dm->getEventManager();
+ $events = array(
+ Events::onFlush
+ );
+ $evm->addEventListener($events, $this->listener);
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

Let's replace these four lines with: $evm->addEventListener(Events::onFlush, $this->listener); to be concise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola jmikola was assigned Jun 25, 2012
@jmikola
Doctrine member
jmikola commented Jun 25, 2012

@superdweebie: It looks like we might be stepping on each others' toes with #329. I'd like to get @jwage to review that first and merge down, so it may be a good idea to hold off on these changes until that's done.

@jmikola
Doctrine member
jmikola commented Jun 25, 2012

@superdweebie: Evidently there's no conflict. Feel free to make any revisions.

@jmikola jmikola commented on the diff Jun 25, 2012
lib/Doctrine/ODM/MongoDB/UnitOfWork.php
- $this->collectionDeletions[] = $orgValue;
- $this->collectionUpdates[] = $actualValue;
- $this->visitedCollections[] = $actualValue;
- }
- }
- } else if ($orgValue !== $actualValue) {
- $changeSet[$propName] = array($orgValue, $actualValue);
- }
- }
- if ($changeSet) {
- if (isset($this->documentChangeSets[$oid])) {
- $this->documentChangeSets[$oid] = $changeSet + $this->documentChangeSets[$oid];
- }
- $this->originalDocumentData[$oid] = $actualData;
- }
+ $this->computeOrRecomputeChangeSet($class, $document, true);
@jmikola
Doctrine member
jmikola added a note Jun 25, 2012

Is it a problem if recomputeSingleDocumentChangeSet() never had the "Look for changes in associations of the document" loop that was in computeChangeSet() and is now in computeOrRecomputeChangeSet()? That is the only difference in execution path that I can see.

@superdweebie
superdweebie added a note Jun 25, 2012

@jmikola Yes, this is the fix for the bug. If recomputeSingleDocumentChangeSet() doesn't have the extra loop, then changes to associations aren't processed properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@superdweebie

@jmikola After stuffing around with git (and learning a few new things), I think I have all your requested changes in the commit.

@jmikola jmikola commented on the diff Jun 26, 2012
lib/Doctrine/ODM/MongoDB/UnitOfWork.php
@@ -895,7 +920,7 @@ private function computeAssociationChanges($parentDocument, $mapping, $value)
* @param object $document The document for which to (re)calculate the change set.
* @throws InvalidArgumentException If the passed document is not MANAGED.
*/
- public function recomputeSingleDocumentChangeSet($class, $document)
+ public function recomputeSingleDocumentChangeSet(ClassMetadata $class, $document)
@jmikola
Doctrine member
jmikola added a note Jun 26, 2012

@jwage: Was there any particular reason many of the UoW methods didn't type-hint for ClassMetadata? Is it a micro-optimization?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@jmikola
Doctrine member
jmikola commented Jun 26, 2012

Thanks @superdweebie; the diff is much more concise now :)

@jwage: I left one question for you above. Beyond that, this PR has my blessing so feel free to merge down if it looks alright to you.

@jmikola
Doctrine member
jmikola commented Jun 27, 2012

@superdweebie: I was just re-testing this and noticed that your test case (MODM166Test) currently passes in the master branch without this commit merged. If that's the case, is there really a bug being fixed in this commit or is it just refactoring?

Based on the diff, the only functional change (not refactoring) that I can see is skipping NotSaved fields in the first foreach loop of computeChangeSet() -- and that's certainly unrelated to the MODM-166.

@superdweebie

@jmikola Are you sure? I just loaded up the latest (commit e2c1fbf), and test for MODM166 was failing against it.

@jmikola
Doctrine member
jmikola commented Jun 27, 2012

My mistake, I must have been on the wrong branch when I tested that.

@jmikola jmikola merged commit 11ddc65 into doctrine:master Jun 27, 2012
@superdweebie

@jmikola :) No problem

@jmikola
Doctrine member
jmikola commented Jun 27, 2012

I checked ORM, and they also have type-hinting in the changeset compute methods (but not elsewhere). That was the only outstanding question, so we're merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.