From 435acc9188b9ca090c2cef54c91232d4ef755184 Mon Sep 17 00:00:00 2001 From: romanb Date: Thu, 1 Oct 2009 12:00:14 +0000 Subject: [PATCH] [2.0][DDC-24] Fixed (together with some small misc. refactorings). --- .../DBAL/Platforms/AbstractPlatform.php | 7 +++++++ lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php | 6 ++++++ lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 3 ++- .../DBAL/Platforms/OraclePlatform.php | 6 ++++++ .../DBAL/Platforms/PostgreSqlPlatform.php | 6 ++++++ .../DBAL/Platforms/SqlitePlatform.php | 5 +++++ .../DBAL/Schema/PostgreSqlSchemaManager.php | 5 ++++- .../DBAL/Schema/SqliteSchemaManager.php | 3 +++ lib/Doctrine/DBAL/Types/ObjectType.php | 2 +- lib/Doctrine/DBAL/Types/TextType.php | 2 +- lib/Doctrine/ORM/EntityRepository.php | 2 +- .../ORM/Internal/Hydration/ObjectHydrator.php | 4 ++-- .../ORM/Proxy/ProxyClassGenerator.php | 14 ++++++++++--- lib/Doctrine/ORM/UnitOfWork.php | 21 ++++--------------- .../Tests/DBAL/Mocks/MockPlatform.php | 6 ++++++ .../Tests/Mocks/DatabasePlatformMock.php | 3 +++ .../Doctrine/Tests/Models/CMS/CmsAddress.php | 7 +++++++ tests/Doctrine/Tests/Models/CMS/CmsUser.php | 7 +++++++ 18 files changed, 82 insertions(+), 27 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 8d33d3de5..859a34a66 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1551,6 +1551,13 @@ abstract class AbstractPlatform * @param array $field */ abstract public function getVarcharTypeDeclarationSql(array $field); + + /** + * Gets the SQL snippet used to declare a CLOB column type. + * + * @param array $field + */ + abstract public function getClobTypeDeclarationSql(array $field); /** * Gets the name of the platform. diff --git a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php index a675ff5d4..3795d20f5 100644 --- a/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php @@ -365,6 +365,12 @@ class MsSqlPlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } + + /** @override */ + public function getClobTypeDeclarationSql(array $field) + { + return 'TEXT'; + } /** * @override diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index b2cee7ca2..e1548a520 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -231,7 +231,8 @@ class MySqlPlatform extends AbstractPlatform : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); } - public function getClobDeclarationSql(array $field) + /** @override */ + public function getClobTypeDeclarationSql(array $field) { if ( ! empty($field['length'])) { $length = $field['length']; diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 2163f6db5..51b2f30de 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -223,6 +223,12 @@ class OraclePlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)') : ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)'); } + + /** @override */ + public function getClobTypeDeclarationSql(array $field) + { + return 'CLOB'; + } public function getListDatabasesSql() { diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 0515e7d3c..da15373a6 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -742,6 +742,12 @@ class PostgreSqlPlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } + + /** @override */ + public function getClobTypeDeclarationSql(array $field) + { + return 'TEXT'; + } /** * Get the platform name for this instance diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 457008be6..b558056e5 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -370,6 +370,11 @@ class SqlitePlatform extends AbstractPlatform return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); } + + public function getClobTypeDeclarationSql(array $field) + { + return 'CLOB'; + } public function getListSequencesSql($database) { diff --git a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php index d19400add..6f09c13a2 100644 --- a/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -172,6 +172,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager $length = 1; break; case 'text': + $fixed = false; + $type = 'text'; + break; case 'varchar': case 'interval': case '_varchar': @@ -186,7 +189,7 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager $type = 'boolean'; } } elseif (strstr($dbType, 'text')) { - $type = 'clob'; + $type = 'text'; } if ($fixed !== false) { $fixed = true; diff --git a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php index 75b02ff54..e64282deb 100644 --- a/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -138,6 +138,9 @@ class SqliteSchemaManager extends AbstractSchemaManager $length = 8; break; case 'clob': + $fixed = false; + $type = 'text'; + break; case 'tinytext': case 'mediumtext': case 'longtext': diff --git a/lib/Doctrine/DBAL/Types/ObjectType.php b/lib/Doctrine/DBAL/Types/ObjectType.php index fb168dc4a..4716db9df 100644 --- a/lib/Doctrine/DBAL/Types/ObjectType.php +++ b/lib/Doctrine/DBAL/Types/ObjectType.php @@ -11,7 +11,7 @@ class ObjectType extends Type { public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) { - return $platform->getClobDeclarationSql($fieldDeclaration); + return $platform->getClobTypeDeclarationSql($fieldDeclaration); } public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) diff --git a/lib/Doctrine/DBAL/Types/TextType.php b/lib/Doctrine/DBAL/Types/TextType.php index fab3e4ad5..726e28b0c 100644 --- a/lib/Doctrine/DBAL/Types/TextType.php +++ b/lib/Doctrine/DBAL/Types/TextType.php @@ -12,7 +12,7 @@ class TextType extends Type /** @override */ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) { - return $platform->getClobDeclarationSql($fieldDeclaration); + return $platform->getClobTypeDeclarationSql($fieldDeclaration); } public function getName() diff --git a/lib/Doctrine/ORM/EntityRepository.php b/lib/Doctrine/ORM/EntityRepository.php index dbb2c2b86..557b0ca4a 100644 --- a/lib/Doctrine/ORM/EntityRepository.php +++ b/lib/Doctrine/ORM/EntityRepository.php @@ -134,7 +134,7 @@ class EntityRepository $by = substr($method, 9, strlen($method)); $method = 'findOneBy'; } else { - throw new BadMethodCallException("Undefined method '$method'."); + throw new \BadMethodCallException("Undefined method '$method'."); } if ( ! isset($arguments[0])) { diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php index fa505b005..253adef0d 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php @@ -340,7 +340,7 @@ class ObjectHydrator extends AbstractHydrator } else { // Single-valued association $reflFieldValue = $reflField->getValue($baseElement); - if ( ! $reflFieldValue) { + if ( ! $reflFieldValue /* || doctrine.refresh hint set */) { if (isset($nonemptyComponents[$dqlAlias])) { $element = $this->_getEntity($data, $dqlAlias); $reflField->setValue($baseElement, $element); @@ -350,7 +350,7 @@ class ObjectHydrator extends AbstractHydrator // If there is an inverse mapping on the target class its bidirectional if (isset($targetClass->inverseMappings[$relation->sourceEntityName][$relationField])) { $sourceProp = $targetClass->inverseMappings[$relation->sourceEntityName][$relationField]->sourceFieldName; - $targetClass->reflFields[$sourceProp]->setValue($element, $base); + $targetClass->reflFields[$sourceProp]->setValue($element, $baseElement); } else if ($this->_ce[$parentClass] === $targetClass && $relation->mappedByFieldName) { // Special case: bi-directional self-referencing one-one on the same class $targetClass->reflFields[$relationField]->setValue($element, $baseElement); diff --git a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php index 91932bf0d..25cf44ab2 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php +++ b/lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php @@ -109,19 +109,25 @@ class ProxyClassGenerator $methods = $this->_generateMethods($class); $sleepImpl = $this->_generateSleep($class); + $constructorInv = $class->reflClass->hasMethod('__construct') ? 'parent::__construct();' : ''; $placeholders = array( '', '', - '', '' + '', '', + '' ); $replacements = array( - $proxyClassName, $originalClassName, $methods, $sleepImpl + $proxyClassName, $originalClassName, + $methods, $sleepImpl, + $constructorInv ); $file = str_replace($placeholders, $replacements, $file); file_put_contents($fileName, $file); + require $fileName; + return $proxyFullyQualifiedClassName; } @@ -130,7 +136,7 @@ class ProxyClassGenerator $methods = ''; foreach ($class->reflClass->getMethods() as $method) { - if ($method->getName() == '__construct') { + if ($method->isConstructor()) { continue; } @@ -205,6 +211,7 @@ namespace Doctrine\Generated\Proxies { public function __construct($entityPersister, $identifier) { $this->_entityPersister = $entityPersister; $this->_identifier = $identifier; + } private function _load() { if ( ! $this->_loaded) { @@ -241,6 +248,7 @@ namespace Doctrine\Generated\Proxies { $this->_assoc = $assoc; $this->_owner = $owner; $this->_joinColumnValues = $joinColumnValues; + } private function _load() { if ( ! $this->_loaded) { diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index e6ac73794..334b86814 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1427,6 +1427,7 @@ class UnitOfWork implements PropertyChangedListener array_combine($class->identifier, $this->_entityIdentifiers[$oid]), $entity ); + //TODO: refresh (initialized) associations break; default: throw new \InvalidArgumentException("Entity is not MANAGED."); @@ -1656,7 +1657,7 @@ class UnitOfWork implements PropertyChangedListener if (isset($this->_identityMap[$class->rootEntityName][$idHash])) { $entity = $this->_identityMap[$class->rootEntityName][$idHash]; $oid = spl_object_hash($entity); - $overrideLocalChanges = isset($hints[Query::HINT_REFRESH]); + $overrideLocalValues = isset($hints[Query::HINT_REFRESH]); } else { $entity = new $className; $oid = spl_object_hash($entity); @@ -1667,10 +1668,10 @@ class UnitOfWork implements PropertyChangedListener if ($entity instanceof \Doctrine\Common\NotifyPropertyChanged) { $entity->addPropertyChangedListener($this); } - $overrideLocalChanges = true; + $overrideLocalValues = true; } - if ($overrideLocalChanges) { + if ($overrideLocalValues) { if ($this->_useCExtension) { doctrine_populate_data($entity, $data); } else { @@ -1680,20 +1681,6 @@ class UnitOfWork implements PropertyChangedListener } } } - } else { - foreach ($data as $field => $value) { - if (isset($class->reflFields[$field])) { - $currentValue = $class->reflFields[$field]->getValue($entity); - // Only override the current value if: - // a) There was no original value yet (nothing in _originalEntityData) - // or - // b) The original value is the same as the current value (it was not changed). - if ( ! isset($this->_originalEntityData[$oid][$field]) || - $currentValue == $this->_originalEntityData[$oid][$field]) { - $class->reflFields[$field]->setValue($entity, $value); - } - } - } } if (isset($class->lifecycleCallbacks[Events::postLoad])) { diff --git a/tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php b/tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php index 43eb93533..aae08923d 100644 --- a/tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php +++ b/tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php @@ -16,6 +16,12 @@ class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform { return "DUMMYVARCHAR()"; } + + /** @override */ + public function getClobTypeDeclarationSql(array $field) + { + return 'DUMMYCLOB'; + } public function getVarcharDefaultLength() { diff --git a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php index 8fdfe871b..ed1bd0e6d 100644 --- a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php +++ b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php @@ -57,6 +57,9 @@ class DatabasePlatformMock extends \Doctrine\DBAL\Platforms\AbstractPlatform /** @override */ public function getVarcharTypeDeclarationSql(array $field) {} + + /** @override */ + public function getClobTypeDeclarationSql(array $field) {} /* MOCK API */ diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php index 181e28b22..72187afdd 100644 --- a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php +++ b/tests/Doctrine/Tests/Models/CMS/CmsAddress.php @@ -54,4 +54,11 @@ class CmsAddress public function getCity() { return $this->city; } + + public function setUser(CmsUser $user) { + if ($this->user !== $user) { + $this->user = $user; + $user->setAddress($this); + } + } } \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/CMS/CmsUser.php b/tests/Doctrine/Tests/Models/CMS/CmsUser.php index 2a8380794..019a73f61 100644 --- a/tests/Doctrine/Tests/Models/CMS/CmsUser.php +++ b/tests/Doctrine/Tests/Models/CMS/CmsUser.php @@ -107,4 +107,11 @@ class CmsUser } return false; } + + public function setAddress(CmsAddress $address) { + if ($this->address !== $address) { + $this->address = $address; + $address->setUser($this); + } + } }