Details
-
Type:
Improvement
-
Status:
Open
-
Priority:
Minor
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: None
-
Component/s: ORM
-
Security Level: All
-
Labels:None
Description
Currently our UnitOfWork computes the changeset by checking actual instances of Objects.
// UnitOfWork, lines 501-507 foreach ($actualData as $propName => $actualValue) { $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null; if (is_object($orgValue) && $orgValue !== $actualValue) { $changeSet[$propName] = array($orgValue, $actualValue); } else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) $changeSet[$propName] = array($orgValue, $actualValue); }
While this is ok when you do new object assignments, it just bypass same instances of same object, since the hash is the same.
A user on IRC (post-o-matic) has a quite complex object logic that he would like to avoid clone and even instantiate another class.
I agree with him that cloning is not the ideal technique, mainly because the changeset would always compute the object (since then hashs would be different).
He implemented this datatype:
class EffortGraphType extends Type { public function getSqlDeclaration(array $fieldDeclaration, AbstractPlatform $platform) { return $platform->getClobTypeDeclarationSql($fieldDeclaration); } public function convertToPHPValue($value, AbstractPlatform $platform) { return new EffortGraph(unserialize($value)); } public function convertToDatabaseValue($value, AbstractPlatform $platform) { return serialize($value->getGraphPoints()); } public function getName() { return 'effort_graph'; } }
I was thinking in a possible alternative and it came up to me the same basic idea we have with operators overloading OR Comparable interface of Java. I know in Java it supports way more things, but at least for this situation (as a start point) it would make developer's life easier.
Basic idea is to have an interface in Doctrine\Common:
namespace Doctrine\Common; interface Comparable { public function compareTo($value); }
And update our UnitOfWork to take advantage of it:
// UnitOfWork, lines 501-507 foreach ($actualData as $propName => $actualValue) { $orgValue = isset($originalData[$propName]) ? $originalData[$propName] : null; if (is_object($orgValue)) { $isDiff = ($orgValue instanceof Doctrine\Common\Comparable) ? $orgValue->compareTo($actualValue) : ($orgValue !== $actualValue); if ($isDiff) { $changeSet[$propName] = array($orgValue, $actualValue); } } else if ($orgValue != $actualValue || ($orgValue === null ^ $actualValue === null)) $changeSet[$propName] = array($orgValue, $actualValue); }
In this user's usecase, it'd require him to update the EffortGraph class and implement Comparable interface.
For his specific situation, he'd need to store original value and updated value, just like we do internally in UnitOfWork for Entities.
What's the final status of this?
IMHO this should be incorporated, since it adds a powerful support that users can take advantage in our Types.
Cheers,