diff --git a/UPGRADE_TO_2_0 b/UPGRADE_TO_2_0 index 0d777b528..1dcc807f1 100644 --- a/UPGRADE_TO_2_0 +++ b/UPGRADE_TO_2_0 @@ -1,3 +1,11 @@ +# Update from 2.0-BETA3 to 2.0-BETA4 + +## XML Driver element demoted to attribute + +We changed how the XML Driver allows to define the change-tracking-policy. The working case is now: + + + # Update from 2.0-BETA2 to 2.0-BETA3 ## Serialization of Uninitialized Proxies diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index 9b6b7c629..3a09f24b3 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -75,6 +75,7 @@ + @@ -82,6 +83,14 @@ + + + + + + + + diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 994e65e62..5e5341d1d 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -239,29 +239,6 @@ class Configuration extends \Doctrine\DBAL\Configuration $this->_attributes['metadataCacheImpl'] = $cacheImpl; } - /** - * Gets a boolean flag that indicates whether Doctrine should make use of the - * C extension. - * - * @return boolean TRUE if Doctrine is configured to use the C extension, FALSE otherwise. - */ - public function getUseCExtension() - { - return isset($this->_attributes['useCExtension']) ? - $this->_attributes['useCExtension'] : false; - } - - /** - * Sets a boolean flag that indicates whether Doctrine should make use of the - * C extension. - * - * @param boolean $boolean Whether to make use of the C extension or not. - */ - public function setUseCExtension($boolean) - { - $this->_attributes['useCExtension'] = $boolean; - } - /** * Adds a named DQL query to the configuration. * diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 36df0a60d..a33eb4eb8 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -169,23 +169,30 @@ class AnnotationDriver implements Driver if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) { $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType']; $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value)); + + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate DiscriminatorColumn annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) { + $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn']; + $metadata->setDiscriminatorColumn(array( + 'name' => $discrColumnAnnot->name, + 'type' => $discrColumnAnnot->type, + 'length' => $discrColumnAnnot->length + )); + } else { + throw MappingException::missingDiscriminatorColumn($className); + } + + // Evaluate DiscriminatorMap annotation + if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) { + $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap']; + $metadata->setDiscriminatorMap($discrMapAnnot->value); + } else { + throw MappingException::missingDiscriminatorMap($className); + } + } } - // Evaluate DiscriminatorColumn annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) { - $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn']; - $metadata->setDiscriminatorColumn(array( - 'name' => $discrColumnAnnot->name, - 'type' => $discrColumnAnnot->type, - 'length' => $discrColumnAnnot->length - )); - } - - // Evaluate DiscriminatorMap annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) { - $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap']; - $metadata->setDiscriminatorMap($discrMapAnnot->value); - } // Evaluate DoctrineChangeTrackingPolicy annotation if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) { diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 575fb2230..e8f97d835 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -77,31 +77,38 @@ class XmlDriver extends AbstractFileDriver if (isset($xmlRoot['inheritance-type'])) { $inheritanceType = (string)$xmlRoot['inheritance-type']; $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceType)); - } - // Evaluate - if (isset($xmlRoot->{'discriminator-column'})) { - $discrColumn = $xmlRoot->{'discriminator-column'}; - $metadata->setDiscriminatorColumn(array( - 'name' => (string)$discrColumn['name'], - 'type' => (string)$discrColumn['type'], - 'length' => (string)$discrColumn['length'] - )); - } + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate + if (isset($xmlRoot->{'discriminator-column'})) { + $discrColumn = $xmlRoot->{'discriminator-column'}; + $metadata->setDiscriminatorColumn(array( + 'name' => (string)$discrColumn['name'], + 'type' => (string)$discrColumn['type'], + 'length' => (string)$discrColumn['length'] + )); + } else { + throw MappingException::missingDiscriminatorColumn($className); + } - // Evaluate - if (isset($xmlRoot->{'discriminator-map'})) { - $map = array(); - foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) { - $map[(string)$discrMapElement['value']] = (string)$discrMapElement['class']; + // Evaluate + if (isset($xmlRoot->{'discriminator-map'})) { + $map = array(); + foreach ($xmlRoot->{'discriminator-map'}->{'discriminator-mapping'} AS $discrMapElement) { + $map[(string)$discrMapElement['value']] = (string)$discrMapElement['class']; + } + $metadata->setDiscriminatorMap($map); + } else { + throw MappingException::missingDiscriminatorMap($className); + } } - $metadata->setDiscriminatorMap($map); } + // Evaluate - if (isset($xmlRoot->{'change-tracking-policy'})) { + if (isset($xmlRoot['change-tracking-policy'])) { $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' - . strtoupper((string)$xmlRoot->{'change-tracking-policy'}))); + . strtoupper((string)$xmlRoot['change-tracking-policy']))); } // Evaluate diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index 79c659814..967760785 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -69,22 +69,29 @@ class YamlDriver extends AbstractFileDriver if (isset($element['inheritanceType'])) { $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType']))); + + if ($metadata->inheritanceType != \Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_NONE) { + // Evaluate discriminatorColumn + if (isset($element['discriminatorColumn'])) { + $discrColumn = $element['discriminatorColumn']; + $metadata->setDiscriminatorColumn(array( + 'name' => $discrColumn['name'], + 'type' => $discrColumn['type'], + 'length' => $discrColumn['length'] + )); + } else { + throw MappingException::missingDiscriminatorColumn($className); + } + + // Evaluate discriminatorMap + if (isset($element['discriminatorMap'])) { + $metadata->setDiscriminatorMap($element['discriminatorMap']); + } else { + throw MappingException::missingDiscriminatorMap($className); + } + } } - // Evaluate discriminatorColumn - if (isset($element['discriminatorColumn'])) { - $discrColumn = $element['discriminatorColumn']; - $metadata->setDiscriminatorColumn(array( - 'name' => $discrColumn['name'], - 'type' => $discrColumn['type'], - 'length' => $discrColumn['length'] - )); - } - - // Evaluate discriminatorMap - if (isset($element['discriminatorMap'])) { - $metadata->setDiscriminatorMap($element['discriminatorMap']); - } // Evaluate changeTrackingPolicy if (isset($element['changeTrackingPolicy'])) { diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index 4e7247ab3..9fa5906bf 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -190,6 +190,16 @@ class MappingException extends \Doctrine\ORM\ORMException ); } + public static function missingDiscriminatorMap($className) + { + return new self("Entity class '$className' is using inheritance but no discriminator map was defined."); + } + + public static function missingDiscriminatorColumn($className) + { + return new self("Entity class '$className' is using inheritance but no discriminator column was defined."); + } + /** * @param string $className * @param string $columnName diff --git a/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php b/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php index 0515e4dc0..9be6de464 100644 --- a/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php +++ b/lib/Doctrine/ORM/Persisters/AbstractEntityInheritancePersister.php @@ -74,8 +74,12 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister $class = $this->_declaringClassMap[$column]; if ($class->name == $entityName || is_subclass_of($entityName, $class->name)) { $field = $class->fieldNames[$realColumnName]; - $data[$field] = Type::getType($class->fieldMappings[$field]['type']) - ->convertToPHPValue($value, $this->_platform); + if (isset($data[$field])) { + $data[$realColumnName] = $value; + } else { + $data[$field] = Type::getType($class->fieldMappings[$field]['type']) + ->convertToPHPValue($value, $this->_platform); + } } } else { $data[$realColumnName] = $value; diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 1c47249f9..c2a1f4b63 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -800,8 +800,12 @@ class BasicEntityPersister $column = $this->_resultColumnNames[$column]; if (isset($this->_class->fieldNames[$column])) { $field = $this->_class->fieldNames[$column]; - $data[$field] = Type::getType($this->_class->fieldMappings[$field]['type']) - ->convertToPHPValue($value, $this->_platform); + if (isset($data[$field])) { + $data[$column] = $value; + } else { + $data[$field] = Type::getType($this->_class->fieldMappings[$field]['type']) + ->convertToPHPValue($value, $this->_platform); + } } else { $data[$column] = $value; } diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php index 54d234d06..472e73013 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php +++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -105,6 +105,11 @@ class ProxyFactory $proxyDir = $toDir ?: $this->_proxyDir; $proxyDir = rtrim($proxyDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; foreach ($classes as $class) { + /* @var $class ClassMetadata */ + if ($class->isMappedSuperclass) { + continue; + } + $proxyClassName = str_replace('\\', '', $class->name) . 'Proxy'; $proxyFileName = $proxyDir . $proxyClassName . '.php'; $this->_generateProxyClass($class, $proxyClassName, $proxyFileName, self::$_proxyClassTemplate); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php index f1373201e..3fafccd5b 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class AbsFunction extends FunctionNode { @@ -53,8 +51,6 @@ class AbsFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php index 5615190c8..bb2333a10 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class ConcatFunction extends FunctionNode { @@ -56,8 +54,6 @@ class ConcatFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php index 763a22a59..7bf7683eb 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class CurrentDateFunction extends FunctionNode { @@ -49,8 +47,6 @@ class CurrentDateFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $parser->match(Lexer::T_CLOSE_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php index cd62c6201..133575510 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class CurrentTimeFunction extends FunctionNode { @@ -49,8 +47,6 @@ class CurrentTimeFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $parser->match(Lexer::T_CLOSE_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php index dbb307f54..7b1a25d7a 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php @@ -1,7 +1,20 @@ . */ namespace Doctrine\ORM\Query\AST\Functions; @@ -11,7 +24,13 @@ use Doctrine\ORM\Query\Lexer; /** * "CURRENT_TIMESTAMP" * - * @author robo + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.org + * @since 2.0 + * @author Guilherme Blanco + * @author Jonathan Wage + * @author Roman Borschel + * @author Benjamin Eberlei */ class CurrentTimestampFunction extends FunctionNode { @@ -28,8 +47,6 @@ class CurrentTimestampFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $parser->match(Lexer::T_CLOSE_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php index 825415a7f..b9d36d128 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ abstract class FunctionNode extends Node { diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php index 61bcdf200..fc779e4f7 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class LengthFunction extends FunctionNode { @@ -52,8 +50,6 @@ class LengthFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php index 93bf49ffc..a4ea71696 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class LocateFunction extends FunctionNode { @@ -61,8 +59,6 @@ class LocateFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); @@ -72,6 +68,7 @@ class LocateFunction extends FunctionNode $this->secondStringPrimary = $parser->StringPrimary(); + $lexer = $parser->getLexer(); if ($lexer->isNextToken(Lexer::T_COMMA)) { $parser->match(Lexer::T_COMMA); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php index 20ae182d9..b5d33face 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class LowerFunction extends FunctionNode { @@ -52,8 +50,6 @@ class LowerFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php index 3c0f1dc87..7c52d60b8 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class ModFunction extends FunctionNode { @@ -57,8 +55,6 @@ class ModFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_MOD); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php index 7ba814d53..9065276ba 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php index ab0f8b348..02ffa26a7 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class SqrtFunction extends FunctionNode { @@ -52,8 +50,6 @@ class SqrtFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php index acc8903d8..bfcbdefb3 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class SubstringFunction extends FunctionNode { @@ -62,8 +60,6 @@ class SubstringFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); @@ -73,6 +69,7 @@ class SubstringFunction extends FunctionNode $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); + $lexer = $parser->getLexer(); if ($lexer->isNextToken(Lexer::T_COMMA)) { $parser->match(Lexer::T_COMMA); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php index cea68920a..47b3cecaa 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class TrimFunction extends FunctionNode { diff --git a/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php index e9206fe43..ff2b1e30b 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php @@ -1,7 +1,5 @@ * @author Jonathan Wage * @author Roman Borschel + * @author Benjamin Eberlei */ class UpperFunction extends FunctionNode { @@ -52,8 +50,6 @@ class UpperFunction extends FunctionNode */ public function parse(\Doctrine\ORM\Query\Parser $parser) { - $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index 8f1e97f21..d109832a9 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -1,7 +1,5 @@ orderBy) && $assoc->orderBy !== null) { + $targetClass = $cmf->getMetadataFor($assoc->targetEntityName); + foreach ($assoc->orderBy AS $orderField => $orientation) { + if (!$targetClass->hasField($orderField)) { + $ce[] = "The association " . $class->name."#".$fieldName." is ordered by a foreign field " . + $orderField . " that is not a field on the target entity " . $targetClass->name; + } + } + } } foreach ($class->reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $publicAttr) { diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index aa49ffb3d..57d19056c 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -200,15 +200,6 @@ class UnitOfWork implements PropertyChangedListener * @var array */ private $collectionPersisters = array(); - - /** - * EXPERIMENTAL: - * Flag for whether or not to make use of the C extension which is an experimental - * library that aims to improve the performance of some critical code sections. - * - * @var boolean - */ - private $useCExtension = false; /** * The EventManager used for dispatching events. @@ -235,7 +226,6 @@ class UnitOfWork implements PropertyChangedListener { $this->em = $em; $this->evm = $em->getEventManager(); - $this->useCExtension = $this->em->getConfiguration()->getUseCExtension(); } /** @@ -1812,13 +1802,13 @@ class UnitOfWork implements PropertyChangedListener /** * INTERNAL: - * Creates an entity. Used for reconstitution of entities during hydration. + * Creates an entity. Used for reconstitution of persistent entities. * * @ignore * @param string $className The name of the entity class. * @param array $data The data for the entity. * @param array $hints Any hints to account for during reconstitution/lookup of the entity. - * @return object The entity instance. + * @return object The managed entity instance. * @internal Highly performance-sensitive method. * * @todo Rename: getOrCreateEntity @@ -1874,13 +1864,9 @@ class UnitOfWork implements PropertyChangedListener } if ($overrideLocalValues) { - if ($this->useCExtension) { - doctrine_populate_data($entity, $data); - } else { - foreach ($data as $field => $value) { - if (isset($class->reflFields[$field])) { - $class->reflFields[$field]->setValue($entity, $value); - } + foreach ($data as $field => $value) { + if (isset($class->fieldMappings[$field])) { + $class->reflFields[$field]->setValue($entity, $value); } } @@ -1920,7 +1906,13 @@ class UnitOfWork implements PropertyChangedListener // If it might be a subtype, it can not be lazy $newValue = $assoc->load($entity, null, $this->em, $associatedId); } else { - $newValue = $this->em->getProxyFactory()->getProxy($assoc->targetEntityName, $associatedId); + if ($assoc->fetchMode == Mapping\AssociationMapping::FETCH_EAGER) { + // TODO: Maybe it could be optimized to do an eager fetch with a JOIN inside + // the persister instead of this rather unperformant approach. + $newValue = $this->em->find($assoc->targetEntityName, $associatedId); + } else { + $newValue = $this->em->getProxyFactory()->getProxy($assoc->targetEntityName, $associatedId); + } // PERF: Inlined & optimized code from UnitOfWork#registerManaged() $newValueOid = spl_object_hash($newValue); $this->entityIdentifiers[$newValueOid] = $associatedId; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC522Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC522Test.php new file mode 100644 index 000000000..dbfa024ca --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC522Test.php @@ -0,0 +1,104 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC522Customer'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC522Cart'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC522ForeignKeyTest') + )); + } catch(\Exception $e) { + + } + } + + /** + * @group DDC-522 + */ + public function testJoinColumnWithSameNameAsAssociationField() + { + //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger); + + $cust = new DDC522Customer; + $cust->name = "name"; + $cart = new DDC522Cart; + $cart->total = 0; + $cust->cart = $cart; + $cart->customer = $cust; + $this->_em->persist($cust); + $this->_em->persist($cart); + $this->_em->flush(); + + $this->_em->clear(); + + $r = $this->_em->createQuery("select ca,c from ".get_class($cart)." ca join ca.customer c") + ->getResult(); + + $this->assertTrue($r[0] instanceof DDC522Cart); + $this->assertTrue($r[0]->customer instanceof DDC522Customer); + $this->assertFalse($r[0]->customer instanceof \Doctrine\ORM\Proxy\Proxy); + $this->assertEquals('name', $r[0]->customer->name); + + $fkt = new DDC522ForeignKeyTest(); + $fkt->cartId = $r[0]->id; // ignored for persistence + $fkt->cart = $r[0]; // must be set properly + $this->_em->persist($fkt); + $this->_em->flush(); + $this->_em->clear(); + + $fkt2 = $this->_em->find(get_class($fkt), $fkt->id); + $this->assertEquals($fkt->cart->id, $fkt2->cartId); + $this->assertTrue($fkt2->cart instanceof \Doctrine\ORM\Proxy\Proxy); + $this->assertFalse($fkt2->cart->__isInitialized__); + } +} + +/** @Entity */ +class DDC522Customer { + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + /** @Column */ + public $name; + /** @OneToOne(targetEntity="DDC522Cart", mappedBy="customer") */ + public $cart; +} + +/** @Entity */ +class DDC522Cart { + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + /** @Column(type="integer") */ + public $total; + /** + * @OneToOne(targetEntity="DDC522Customer", inversedBy="cart") + * @JoinColumn(name="customer", referencedColumnName="id") + */ + public $customer; +} + +/** @Entity */ +class DDC522ForeignKeyTest { + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + /** @Column(type="integer", name="cart_id") */ + public $cartId; + /** + * @OneToOne(targetEntity="DDC522Cart") + * @JoinColumn(name="cart_id", referencedColumnName="id") + */ + public $cart; +} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC633Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC633Test.php new file mode 100644 index 000000000..d375f408c --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC633Test.php @@ -0,0 +1,69 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC633Patient'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC633Appointment'), + )); + } catch(\Exception $e) { + + } + } + + public function testOneToOneEager() + { + $app = new DDC633Appointment(); + $pat = new DDC633Patient(); + $app->patient = $pat; + $pat->appointment = $app; + + $this->_em->persist($app); + $this->_em->persist($pat); + $this->_em->flush(); + $this->_em->clear(); + + $eagerAppointment = $this->_em->find(__NAMESPACE__ . '\DDC633Appointment', $app->id); + + $this->assertNotType('Doctrine\ORM\Proxy\Proxy', $eagerAppointment->patient); + } +} + +/** + * @Entity + */ +class DDC633Appointment +{ + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + + /** + * @OneToOne(targetEntity="DDC633Patient", inversedBy="appointment", fetch="EAGER") + */ + public $patient; + +} + +/** + * @Entity + */ +class DDC633Patient +{ + /** @Id @Column(type="integer") @GeneratedValue */ + public $id; + + /** + * @OneToOne(targetEntity="DDC633Appointment", mappedBy="patient") + */ + public $appointment; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php index 484ce01ba..1c3d91eff 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php @@ -28,9 +28,7 @@ class AnnotationDriverTest extends AbstractMappingDriverTest public function testColumnWithMissingTypeDefaultsToString() { $cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\ColumnWithoutType'); - $reader = new \Doctrine\Common\Annotations\AnnotationReader(new \Doctrine\Common\Cache\ArrayCache()); - $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); - $annotationDriver = new \Doctrine\ORM\Mapping\Driver\AnnotationDriver($reader); + $annotationDriver = $this->_loadDriver(); $annotationDriver->loadMetadataForClass('Doctrine\Tests\ORM\Mapping\InvalidColumn', $cm); $this->assertEquals('string', $cm->fieldMappings['id']['type']); @@ -92,6 +90,24 @@ class AnnotationDriverTest extends AbstractMappingDriverTest $this->assertNotContains($extraneousClassName, $classes); } + public function testInheritenceWithoutDiscriminatorMap() + { + $cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\ClassWithoutDiscriminatorMap'); + $annotationDriver = $this->_loadDriver(); + + $this->setExpectedException("Doctrine\ORM\Mapping\MappingException"); + $annotationDriver->loadMetadataForClass($cm->name, $cm); + } + + public function testInheritenceWithoutDiscriminatorColumn() + { + $cm = new ClassMetadata('Doctrine\Tests\ORM\Mapping\ClassWithoutDiscriminatorColumn'); + $annotationDriver = $this->_loadDriver(); + + $this->setExpectedException("Doctrine\ORM\Mapping\MappingException"); + $annotationDriver->loadMetadataForClass($cm->name, $cm); + } + protected function _loadDriverForCMSModels() { $annotationDriver = $this->_loadDriver(); @@ -121,3 +137,25 @@ class ColumnWithoutType /** @Id @Column */ public $id; } + +/** + * @Entity + * @InheritanceType("SINGLE_TABLE") + * @DiscriminatorMap({"a" = "ClassWithoutDiscriminatorColumn"}) + */ +class ClassWithoutDiscriminatorColumn +{ + /** @Id @Column */ + public $id; +} + +/** + * @Entity + * @InheritanceType("SINGLE_TABLE") + * @DiscriminatorColumn(name="discr", type="string") + */ +class ClassWithoutDiscriminatorMap +{ + /** @Id @Column */ + public $id; +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml index e6459afae..14abaef73 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml +++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> - +