From ab542e97dfb2296d0686ae52eda47521859439cd Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 25 May 2023 08:47:35 +0200 Subject: [PATCH 001/128] Allow symfony/console 7 (#10724) --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a897bbbf8fd..864ab6e161f 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "doctrine/lexer": "^2", "doctrine/persistence": "^2.4 || ^3", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, From eda1909c756ccbd95379deb39c22732c3738be60 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Aug 2023 14:43:38 +0200 Subject: [PATCH 002/128] Deprecate not-enabling lazy-ghosts and decouple from doctrine/common's proxies (#10837) --- .../ORM/ORMInvalidArgumentException.php | 27 ++ lib/Doctrine/ORM/Proxy/ProxyFactory.php | 356 ++++++++++++++---- phpstan-baseline.neon | 19 +- psalm-baseline.xml | 41 +- 4 files changed, 370 insertions(+), 73 deletions(-) diff --git a/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/lib/Doctrine/ORM/ORMInvalidArgumentException.php index e09114c0e7f..97ba4384c76 100644 --- a/lib/Doctrine/ORM/ORMInvalidArgumentException.php +++ b/lib/Doctrine/ORM/ORMInvalidArgumentException.php @@ -15,6 +15,7 @@ use function get_debug_type; use function gettype; use function implode; +use function is_scalar; use function method_exists; use function reset; use function spl_object_id; @@ -261,6 +262,32 @@ public static function invalidEntityName($entityName) return new self(sprintf('Entity name must be a string, %s given', get_debug_type($entityName))); } + /** @param mixed $value */ + public static function invalidAutoGenerateMode($value): self + { + return new self(sprintf('Invalid auto generate mode "%s" given.', is_scalar($value) ? (string) $value : get_debug_type($value))); + } + + public static function missingPrimaryKeyValue(string $className, string $idField): self + { + return new self(sprintf('Missing value for primary key %s on %s', $idField, $className)); + } + + public static function proxyDirectoryRequired(): self + { + return new self('You must configure a proxy directory. See docs for details'); + } + + public static function proxyNamespaceRequired(): self + { + return new self('You must configure a proxy namespace'); + } + + public static function proxyDirectoryNotWritable(string $proxyDirectory): self + { + return new self(sprintf('Your proxy directory "%s" must be writable', $proxyDirectory)); + } + /** * Helper method to show an object as string. * diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php index 63c925861c4..0660c423f0d 100644 --- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php +++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -9,30 +9,94 @@ use Doctrine\Common\Proxy\Proxy as CommonProxy; use Doctrine\Common\Proxy\ProxyDefinition; use Doctrine\Common\Proxy\ProxyGenerator; -use Doctrine\Common\Util\ClassUtils; +use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityNotFoundException; +use Doctrine\ORM\ORMInvalidArgumentException; use Doctrine\ORM\Persisters\Entity\EntityPersister; use Doctrine\ORM\Proxy\Proxy as LegacyProxy; use Doctrine\ORM\UnitOfWork; use Doctrine\ORM\Utility\IdentifierFlattener; use Doctrine\Persistence\Mapping\ClassMetadata; +use Doctrine\Persistence\Proxy; use ReflectionProperty; use Symfony\Component\VarExporter\ProxyHelper; -use Symfony\Component\VarExporter\VarExporter; use Throwable; +use function array_combine; use function array_flip; +use function array_intersect_key; +use function bin2hex; +use function chmod; +use function class_exists; +use function dirname; +use function file_exists; +use function file_put_contents; +use function filemtime; +use function is_bool; +use function is_dir; +use function is_int; +use function is_writable; +use function ltrim; +use function mkdir; +use function preg_match_all; +use function random_bytes; +use function rename; +use function rtrim; use function str_replace; use function strpos; +use function strrpos; +use function strtr; use function substr; -use function uksort; +use function ucfirst; + +use const DIRECTORY_SEPARATOR; +use const PHP_VERSION_ID; /** * This factory is used to create proxy objects for entities at runtime. */ class ProxyFactory extends AbstractProxyFactory { + /** + * Never autogenerate a proxy and rely that it was generated by some + * process before deployment. + */ + public const AUTOGENERATE_NEVER = 0; + + /** + * Always generates a new proxy in every request. + * + * This is only sane during development. + */ + public const AUTOGENERATE_ALWAYS = 1; + + /** + * Autogenerate the proxy class when the proxy file does not exist. + * + * This strategy causes a file_exists() call whenever any proxy is used the + * first time in a request. + */ + public const AUTOGENERATE_FILE_NOT_EXISTS = 2; + + /** + * Generate the proxy classes using eval(). + * + * This strategy is only sane for development, and even then it gives me + * the creeps a little. + */ + public const AUTOGENERATE_EVAL = 3; + + /** + * Autogenerate the proxy class when the proxy file does not exist or + * when the proxied file changed. + * + * This strategy causes a file_exists() call whenever any proxy is used the + * first time in a request. When the proxied file is changed, the proxy will + * be updated. + */ + public const AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED = 4; + private const PROXY_CLASS_TEMPLATE = <<<'EOPHP' extends \ implements \ - public function __construct(?\Closure $initializer = null, ?\Closure $cloner = null) - { - if ($cloner !== null) { - return; - } - - self::createLazyGhost($initializer, , $this); - } - public function __isInitialized(): bool { return isset($this->lazyObjectState) && $this->isLazyObjectInitialized(); @@ -73,9 +128,15 @@ public function __serialize(): array /** @var UnitOfWork The UnitOfWork this factory uses to retrieve persisters */ private $uow; + /** @var string */ + private $proxyDir; + /** @var string */ private $proxyNs; + /** @var self::AUTOGENERATE_* */ + private $autoGenerate; + /** * The IdentifierFlattener used for manipulating identifiers * @@ -83,8 +144,11 @@ public function __serialize(): array */ private $identifierFlattener; - /** @var ProxyDefinition[] */ - private $definitions = []; + /** @var array */ + private $proxyFactories = []; + + /** @var bool */ + private $isLazyGhostObjectEnabled = true; /** * Initializes a new instance of the ProxyFactory class that is @@ -97,23 +161,40 @@ public function __serialize(): array */ public function __construct(EntityManagerInterface $em, $proxyDir, $proxyNs, $autoGenerate = self::AUTOGENERATE_NEVER) { - $proxyGenerator = new ProxyGenerator($proxyDir, $proxyNs); - - if ($em->getConfiguration()->isLazyGhostObjectEnabled()) { - $proxyGenerator->setPlaceholder('baseProxyInterface', InternalProxy::class); - $proxyGenerator->setPlaceholder('useLazyGhostTrait', Closure::fromCallable([$this, 'generateUseLazyGhostTrait'])); - $proxyGenerator->setPlaceholder('skippedProperties', Closure::fromCallable([$this, 'generateSkippedProperties'])); - $proxyGenerator->setPlaceholder('serializeImpl', Closure::fromCallable([$this, 'generateSerializeImpl'])); - $proxyGenerator->setProxyClassTemplate(self::PROXY_CLASS_TEMPLATE); - } else { + if (! $em->getConfiguration()->isLazyGhostObjectEnabled()) { + if (PHP_VERSION_ID >= 80100) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/10837/', + 'Not enabling lazy ghost objects is deprecated and will not be supported in Doctrine ORM 3.0. Ensure Doctrine\ORM\Configuration::setLazyGhostObjectEnabled(true) is called to enable them.' + ); + } + + $this->isLazyGhostObjectEnabled = false; + + $proxyGenerator = new ProxyGenerator($proxyDir, $proxyNs); $proxyGenerator->setPlaceholder('baseProxyInterface', LegacyProxy::class); + + parent::__construct($proxyGenerator, $em->getMetadataFactory(), $autoGenerate); } - parent::__construct($proxyGenerator, $em->getMetadataFactory(), $autoGenerate); + if (! $proxyDir) { + throw ORMInvalidArgumentException::proxyDirectoryRequired(); + } + + if (! $proxyNs) { + throw ORMInvalidArgumentException::proxyNamespaceRequired(); + } + + if (is_int($autoGenerate) ? $autoGenerate < 0 || $autoGenerate > 4 : ! is_bool($autoGenerate)) { + throw ORMInvalidArgumentException::invalidAutoGenerateMode($autoGenerate); + } $this->em = $em; $this->uow = $em->getUnitOfWork(); + $this->proxyDir = $proxyDir; $this->proxyNs = $proxyNs; + $this->autoGenerate = (int) $autoGenerate; $this->identifierFlattener = new IdentifierFlattener($this->uow, $em->getMetadataFactory()); } @@ -122,19 +203,57 @@ public function __construct(EntityManagerInterface $em, $proxyDir, $proxyNs, $au */ public function getProxy($className, array $identifier) { - $proxy = parent::getProxy($className, $identifier); + if (! $this->isLazyGhostObjectEnabled) { + return parent::getProxy($className, $identifier); + } - if (! $this->em->getConfiguration()->isLazyGhostObjectEnabled()) { - return $proxy; + $proxyFactory = $this->proxyFactories[$className] ?? $this->getProxyFactory($className); + + return $proxyFactory($identifier); + } + + /** + * Generates proxy classes for all given classes. + * + * @param ClassMetadata[] $classes The classes (ClassMetadata instances) for which to generate proxies. + * @param string|null $proxyDir The target directory of the proxy classes. If not specified, the + * directory configured on the Configuration of the EntityManager used + * by this factory is used. + * + * @return int Number of generated proxies. + */ + public function generateProxyClasses(array $classes, $proxyDir = null) + { + if (! $this->isLazyGhostObjectEnabled) { + return parent::generateProxyClasses($classes, $proxyDir); } - $initializer = $this->definitions[$className]->initializer; + $generated = 0; + + foreach ($classes as $class) { + if ($this->skipClass($class)) { + continue; + } + + $proxyFileName = $this->getProxyFileName($class->getName(), $proxyDir ?: $this->proxyDir); + $proxyClassName = self::generateProxyClassName($class->getName(), $this->proxyNs); - $proxy->__construct(static function (InternalProxy $object) use ($initializer, $proxy): void { - $initializer($object, $proxy); - }); + $this->generateProxyClass($class, $proxyFileName, $proxyClassName); - return $proxy; + ++$generated; + } + + return $generated; + } + + /** + * {@inheritDoc} + * + * @deprecated ProxyFactory::resetUninitializedProxy() is deprecated and will be removed in version 3.0 of doctrine/orm. + */ + public function resetUninitializedProxy(CommonProxy $proxy) + { + return parent::resetUninitializedProxy($proxy); } /** @@ -149,23 +268,19 @@ protected function skipClass(ClassMetadata $metadata) /** * {@inheritDoc} + * + * @deprecated ProxyFactory::createProxyDefinition() is deprecated and will be removed in version 3.0 of doctrine/orm. */ protected function createProxyDefinition($className) { $classMetadata = $this->em->getClassMetadata($className); $entityPersister = $this->uow->getEntityPersister($className); - if ($this->em->getConfiguration()->isLazyGhostObjectEnabled()) { - $initializer = $this->createLazyInitializer($classMetadata, $entityPersister); - $cloner = static function (): void { - }; - } else { - $initializer = $this->createInitializer($classMetadata, $entityPersister); - $cloner = $this->createCloner($classMetadata, $entityPersister); - } + $initializer = $this->createInitializer($classMetadata, $entityPersister); + $cloner = $this->createCloner($classMetadata, $entityPersister); - return $this->definitions[$className] = new ProxyDefinition( - ClassUtils::generateProxyClassName($className, $this->proxyNs), + return new ProxyDefinition( + self::generateProxyClassName($className, $this->proxyNs), $classMetadata->getIdentifierFieldNames(), $classMetadata->getReflectionProperties(), $initializer, @@ -176,6 +291,8 @@ protected function createProxyDefinition($className) /** * Creates a closure capable of initializing a proxy * + * @deprecated ProxyFactory::createInitializer() is deprecated and will be removed in version 3.0 of doctrine/orm. + * * @psalm-return Closure(CommonProxy):void * * @throws EntityNotFoundException @@ -241,16 +358,16 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister * * @throws EntityNotFoundException */ - private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister): Closure + private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister, IdentifierFlattener $identifierFlattener): Closure { - return function (InternalProxy $proxy, InternalProxy $original) use ($entityPersister, $classMetadata): void { + return static function (InternalProxy $proxy, InternalProxy $original) use ($entityPersister, $classMetadata, $identifierFlattener): void { $identifier = $classMetadata->getIdentifierValues($original); $entity = $entityPersister->loadById($identifier, $original); if ($entity === null) { throw EntityNotFoundException::fromClassNameAndIdentifier( $classMetadata->getName(), - $this->identifierFlattener->flattenIdentifier($classMetadata, $identifier) + $identifierFlattener->flattenIdentifier($classMetadata, $identifier) ); } @@ -265,7 +382,6 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi continue; } - $property->setAccessible(true); $property->setValue($proxy, $property->getValue($entity)); } }; @@ -274,6 +390,8 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi /** * Creates a closure capable of finalizing state a cloned proxy * + * @deprecated ProxyFactory::createCloner() is deprecated and will be removed in version 3.0 of doctrine/orm. + * * @psalm-return Closure(CommonProxy):void * * @throws EntityNotFoundException @@ -310,25 +428,18 @@ private function createCloner(ClassMetadata $classMetadata, EntityPersister $ent }; } - private function generateUseLazyGhostTrait(ClassMetadata $class): string + private function getProxyFileName(string $className, string $baseDirectory): string { - $code = ProxyHelper::generateLazyGhost($class->getReflectionClass()); - $code = substr($code, 7 + (int) strpos($code, "\n{")); - $code = substr($code, 0, (int) strpos($code, "\n}")); - $code = str_replace('LazyGhostTrait;', str_replace("\n ", "\n", 'LazyGhostTrait { - initializeLazyObject as __load; - setLazyObjectAsInitialized as public __setInitialized; - isLazyObjectInitialized as private; - createLazyGhost as private; - resetLazyObject as private; - }'), $code); + $baseDirectory = $baseDirectory ?: $this->proxyDir; - return $code; + return rtrim($baseDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . InternalProxy::MARKER + . str_replace('\\', '', $className) . '.php'; } - private function generateSkippedProperties(ClassMetadata $class): string + private function getProxyFactory(string $className): Closure { $skippedProperties = []; + $class = $this->em->getClassMetadata($className); $identifiers = array_flip($class->getIdentifierFieldNames()); $filter = ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE; $reflector = $class->getReflectionClass(); @@ -350,11 +461,123 @@ private function generateSkippedProperties(ClassMetadata $class): string $reflector = $reflector->getParentClass(); } - uksort($skippedProperties, 'strnatcmp'); + $className = $class->getName(); // aliases and case sensitivity + $entityPersister = $this->uow->getEntityPersister($className); + $initializer = $this->createLazyInitializer($class, $entityPersister, $this->identifierFlattener); + $proxyClassName = $this->loadProxyClass($class); + $identifierFields = array_intersect_key($class->getReflectionProperties(), $identifiers); + + $proxyFactory = Closure::bind(static function (array $identifier) use ($initializer, $skippedProperties, $identifierFields, $className): InternalProxy { + $proxy = self::createLazyGhost(static function (InternalProxy $object) use ($initializer, &$proxy): void { + $initializer($object, $proxy); + }, $skippedProperties); + + foreach ($identifierFields as $idField => $reflector) { + if (! isset($identifier[$idField])) { + throw ORMInvalidArgumentException::missingPrimaryKeyValue($className, $idField); + } + + $reflector->setValue($proxy, $identifier[$idField]); + } + + return $proxy; + }, null, $proxyClassName); + + return $this->proxyFactories[$className] = $proxyFactory; + } + + private function loadProxyClass(ClassMetadata $class): string + { + $proxyClassName = self::generateProxyClassName($class->getName(), $this->proxyNs); + + if (class_exists($proxyClassName, false)) { + return $proxyClassName; + } + + if ($this->autoGenerate === self::AUTOGENERATE_EVAL) { + $this->generateProxyClass($class, null, $proxyClassName); + + return $proxyClassName; + } + + $fileName = $this->getProxyFileName($class->getName(), $this->proxyDir); + + switch ($this->autoGenerate) { + case self::AUTOGENERATE_FILE_NOT_EXISTS_OR_CHANGED: + if (file_exists($fileName) && filemtime($fileName) >= filemtime($class->getReflectionClass()->getFileName())) { + break; + } + // no break + case self::AUTOGENERATE_FILE_NOT_EXISTS: + if (file_exists($fileName)) { + break; + } + // no break + case self::AUTOGENERATE_ALWAYS: + $this->generateProxyClass($class, $fileName, $proxyClassName); + break; + } + + require $fileName; - $code = VarExporter::export($skippedProperties); - $code = str_replace(VarExporter::export($class->getName()), 'parent::class', $code); - $code = str_replace("\n", "\n ", $code); + return $proxyClassName; + } + + private function generateProxyClass(ClassMetadata $class, ?string $fileName, string $proxyClassName): void + { + $i = strrpos($proxyClassName, '\\'); + $placeholders = [ + '' => $class->getName(), + '' => substr($proxyClassName, 0, $i), + '' => substr($proxyClassName, 1 + $i), + '' => InternalProxy::class, + ]; + + preg_match_all('(<([a-zA-Z]+)>)', self::PROXY_CLASS_TEMPLATE, $placeholderMatches); + + foreach (array_combine($placeholderMatches[0], $placeholderMatches[1]) as $placeholder => $name) { + $placeholders[$placeholder] ?? $placeholders[$placeholder] = $this->{'generate' . ucfirst($name)}($class); + } + + $proxyCode = strtr(self::PROXY_CLASS_TEMPLATE, $placeholders); + + if (! $fileName) { + if (! class_exists($proxyClassName)) { + eval(substr($proxyCode, 5)); + } + + return; + } + + $parentDirectory = dirname($fileName); + + if (! is_dir($parentDirectory) && ! @mkdir($parentDirectory, 0775, true)) { + throw ORMInvalidArgumentException::proxyDirectoryNotWritable($this->proxyDir); + } + + if (! is_writable($parentDirectory)) { + throw ORMInvalidArgumentException::proxyDirectoryNotWritable($this->proxyDir); + } + + $tmpFileName = $fileName . '.' . bin2hex(random_bytes(12)); + + file_put_contents($tmpFileName, $proxyCode); + @chmod($tmpFileName, 0664); + rename($tmpFileName, $fileName); + } + + private function generateUseLazyGhostTrait(ClassMetadata $class): string + { + $code = ProxyHelper::generateLazyGhost($class->getReflectionClass()); + $code = substr($code, 7 + (int) strpos($code, "\n{")); + $code = substr($code, 0, (int) strpos($code, "\n}")); + $code = str_replace('LazyGhostTrait;', str_replace("\n ", "\n", 'LazyGhostTrait { + initializeLazyObject as __load; + setLazyObjectAsInitialized as public __setInitialized; + isLazyObjectInitialized as private; + createLazyGhost as private; + resetLazyObject as private; + }'), $code); return $code; } @@ -365,7 +588,7 @@ private function generateSerializeImpl(ClassMetadata $class): string $properties = $reflector->hasMethod('__serialize') ? 'parent::__serialize()' : '(array) $this'; $code = '$properties = ' . $properties . '; - unset($properties["\0" . self::class . "\0lazyObjectState"], $properties[\'__isCloning\']); + unset($properties["\0" . self::class . "\0lazyObjectState"]); '; @@ -387,4 +610,9 @@ private function generateSerializeImpl(ClassMetadata $class): string return $data;'; } + + private static function generateProxyClassName(string $className, string $proxyNamespace): string + { + return rtrim($proxyNamespace, '\\') . '\\' . Proxy::MARKER . '\\' . ltrim($className, '\\'); + } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 87d9dc9837c..10e6a2dac50 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -286,12 +286,22 @@ parameters: path: lib/Doctrine/ORM/Proxy/ProxyFactory.php - - message: "#^Call to an undefined method Doctrine\\\\Common\\\\Proxy\\\\Proxy\\:\\:__construct\\(\\)\\.$#" + message: "#^Call to an undefined method Doctrine\\\\Common\\\\Proxy\\\\Proxy\\:\\:__wakeup\\(\\)\\.$#" count: 1 path: lib/Doctrine/ORM/Proxy/ProxyFactory.php - - message: "#^Call to an undefined method Doctrine\\\\Common\\\\Proxy\\\\Proxy\\:\\:__wakeup\\(\\)\\.$#" + message: "#^Call to an undefined static method Doctrine\\\\ORM\\\\Proxy\\\\ProxyFactory\\:\\:createLazyGhost\\(\\)\\.$#" + count: 1 + path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + + - + message: "#^Comparison operation \"\\<\" between 0\\|1\\|2\\|3\\|4 and 0 is always false\\.$#" + count: 1 + path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + + - + message: "#^Comparison operation \"\\>\" between 0\\|1\\|2\\|3\\|4 and 4 is always false\\.$#" count: 1 path: lib/Doctrine/ORM/Proxy/ProxyFactory.php @@ -300,6 +310,11 @@ parameters: count: 3 path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + - + message: "#^Result of \\|\\| is always false\\.$#" + count: 1 + path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + - message: "#^Parameter \\#2 \\$sqlParams of method Doctrine\\\\ORM\\\\Query\\:\\:evictResultSetCache\\(\\) expects array\\, array\\ given\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2b887162e50..fb8846989ba 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1386,32 +1386,59 @@ $classMetadata $classMetadata - - __construct(static function (InternalProxy $object) use ($initializer, $proxy): void { - $initializer($object, $proxy); - })]]> - + + createCloner + createInitializer + getReflectionProperties()]]> getMetadataFactory()]]> getMetadataFactory()]]> + + Closure + + + proxyFactories]]> + isEmbeddedClass]]> isMappedSuperclass]]> + + proxyFactories[$className] = $proxyFactory]]> + + + $i + + + $i + name]]> name]]> + getValue setAccessible - setAccessible + setValue + setValue + + + 4]]> + - __construct __wakeup + + + + + require $fileName + From 47cf50bcd50896f3d3d92c3f774199bc429b4dfc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 7 Aug 2023 15:20:38 +0200 Subject: [PATCH 003/128] Add note about not-enabling lazy-ghosts (#10887) --- UPGRADE.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index 326d17de079..db6a80bf248 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,3 +1,10 @@ +# Upgrade to 2.17 + +## Deprecate not-enabling lazy-ghosts + +Not enabling lazy ghost objects is deprecated. In ORM 3.0, they will be always enabled. +Ensure `Doctrine\ORM\Configuration::setLazyGhostObjectEnabled(true)` is called to enable them. + # Upgrade to 2.16 ## Deprecated accepting duplicate IDs in the identity map From aa333e2f1d3cb2cd50e714791b5cd1f606e9cb6a Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 24 Aug 2023 10:36:04 +0200 Subject: [PATCH 004/128] Support Symfony 7 by adding return types conditionally (#10919) --- .../ClearCache/CollectionRegionCommand.php | 10 ++--- .../ClearCache/EntityRegionCommand.php | 10 ++--- .../Command/ClearCache/MetadataCommand.php | 10 ++--- .../Command/ClearCache/QueryCommand.php | 10 ++--- .../Command/ClearCache/QueryRegionCommand.php | 10 ++--- .../Command/ClearCache/ResultCommand.php | 10 ++--- .../Command/ConvertDoctrine1SchemaCommand.php | 10 ++--- .../Console/Command/ConvertMappingCommand.php | 10 ++--- .../EnsureProductionSettingsCommand.php | 10 ++--- .../Command/GenerateEntitiesCommand.php | 10 ++--- .../Command/GenerateProxiesCommand.php | 10 ++--- .../Command/GenerateRepositoriesCommand.php | 10 ++--- .../ORM/Tools/Console/Command/InfoCommand.php | 10 ++--- .../Tools/Console/Command/RunDqlCommand.php | 10 ++--- .../Command/SchemaTool/AbstractCommand.php | 10 ++--- .../Console/Command/ValidateSchemaCommand.php | 10 ++--- .../Tools/Console/CommandCompatibility.php | 35 +++++++++++++++++ .../Console/Helper/EntityManagerHelper.php | 39 ++++++++++++++----- phpcs.xml.dist | 5 ++- psalm.xml | 6 +++ 20 files changed, 138 insertions(+), 107 deletions(-) create mode 100644 lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php index 9c76abd597c..84e911f171b 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Cache; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -20,6 +21,8 @@ */ class CollectionRegionCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -58,12 +61,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php index 1f5af3ddc6a..51d08946521 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Cache; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -20,6 +21,8 @@ */ class EntityRegionCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -57,12 +60,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php index be4fd37d31b..96decbc50a9 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Tools\Console\Command\ClearCache; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -18,6 +19,8 @@ */ class MetadataCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -31,12 +34,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php index 3ce2fb6cf1b..bdce5adfe4b 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php @@ -9,6 +9,7 @@ use Doctrine\Common\Cache\FlushableCache; use Doctrine\Common\Cache\XcacheCache; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use LogicException; use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -28,6 +29,8 @@ */ class QueryCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -55,12 +58,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php index 03140902e55..faca872e0f1 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Cache; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -20,6 +21,8 @@ */ class QueryRegionCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -56,12 +59,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php index 8dcaad4b38e..b79916bfab0 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php @@ -10,6 +10,7 @@ use Doctrine\Common\Cache\XcacheCache; use Doctrine\ORM\Configuration; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use InvalidArgumentException; use LogicException; use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -29,6 +30,8 @@ */ class ResultCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -56,12 +59,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php index c5a78c85191..df0d42dc702 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\ConvertDoctrine1Schema; use Doctrine\ORM\Tools\EntityGenerator; use Doctrine\ORM\Tools\Export\ClassMetadataExporter; @@ -34,6 +35,8 @@ */ class ConvertDoctrine1SchemaCommand extends Command { + use CommandCompatibility; + /** @var EntityGenerator|null */ private $entityGenerator = null; @@ -87,12 +90,7 @@ protected function configure() ->setHelp('Converts Doctrine 1.x schema into a Doctrine 2.x schema.'); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = new SymfonyStyle($input, $output); $ui->getErrorStyle()->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.'); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php index de4c3f4065f..f3bdea25f14 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Connection; use Doctrine\ORM\Mapping\Driver\DatabaseDriver; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\Console\MetadataFilter; use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; use Doctrine\ORM\Tools\EntityGenerator; @@ -37,6 +38,8 @@ */ class ConvertMappingCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -84,12 +87,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = new SymfonyStyle($input, $output); $ui->getErrorStyle()->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.'); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php index f6511f388b4..bb5df1637a4 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -19,6 +20,8 @@ */ class EnsureProductionSettingsCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -29,12 +32,7 @@ protected function configure() ->setHelp('Verify that Doctrine is properly configured for a production environment.'); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); $ui->warning('This console command has been deprecated and will be removed in a future version of Doctrine ORM.'); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php index 5a3937884f0..7fdcb98bc8e 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\Console\MetadataFilter; use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory; use Doctrine\ORM\Tools\EntityGenerator; @@ -28,6 +29,8 @@ */ class GenerateEntitiesCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -67,12 +70,7 @@ class is supposed to extend which. You have to adjust the entity ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); $ui->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.'); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php index edfa82c3d41..6a602869857 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\Console\MetadataFilter; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; @@ -26,6 +27,8 @@ */ class GenerateProxiesCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -38,12 +41,7 @@ protected function configure() ->setHelp('Generates proxy classes for entity classes.'); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php index 454d699ed5d..54379d5f6b7 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\Console\MetadataFilter; use Doctrine\ORM\Tools\EntityRepositoryGenerator; use InvalidArgumentException; @@ -27,6 +28,8 @@ */ class GenerateRepositoriesCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -39,12 +42,7 @@ protected function configure() ->setHelp('Generate repository classes from your mapping information.'); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); $ui->warning('Command ' . $this->getName() . ' is deprecated and will be removed in Doctrine ORM 3.0.'); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php index b97708693b8..01f2fc2869a 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Tools\Console\Command; use Doctrine\ORM\Mapping\MappingException; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -20,6 +21,8 @@ */ class InfoCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -34,12 +37,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php index 580aa137747..f8611da0b11 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Tools\Console\Command; use Doctrine\Common\Util\Debug; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use LogicException; use RuntimeException; use Symfony\Component\Console\Input\InputArgument; @@ -27,6 +28,8 @@ */ class RunDqlCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -58,12 +61,7 @@ protected function configure() ); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = new SymfonyStyle($input, $output); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php index 6bdec3e2cf8..cabf90759a7 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Tools\Console\Command\SchemaTool; use Doctrine\ORM\Tools\Console\Command\AbstractEntityManagerCommand; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\SchemaTool; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -17,6 +18,8 @@ */ abstract class AbstractCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** * @param mixed[] $metadatas * @@ -24,12 +27,7 @@ abstract class AbstractCommand extends AbstractEntityManagerCommand */ abstract protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas, SymfonyStyle $ui); - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = new SymfonyStyle($input, $output); diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php index 92278ceda38..7c216445786 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools\Console\Command; +use Doctrine\ORM\Tools\Console\CommandCompatibility; use Doctrine\ORM\Tools\SchemaValidator; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -20,6 +21,8 @@ */ class ValidateSchemaCommand extends AbstractEntityManagerCommand { + use CommandCompatibility; + /** @return void */ protected function configure() { @@ -31,12 +34,7 @@ protected function configure() ->setHelp('Validate that the mapping files are correct and in sync with the database.'); } - /** - * {@inheritDoc} - * - * @return int - */ - protected function execute(InputInterface $input, OutputInterface $output) + private function doExecute(InputInterface $input, OutputInterface $output): int { $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); diff --git a/lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php b/lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php new file mode 100644 index 00000000000..4e16698f5d2 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php @@ -0,0 +1,35 @@ +hasReturnType()) { + /** @internal */ + trait CommandCompatibility + { + protected function execute(InputInterface $input, OutputInterface $output): int + { + return $this->doExecute($input, $output); + } + } +} else { + /** @internal */ + trait CommandCompatibility + { + /** + * {@inheritDoc} + * + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + return $this->doExecute($input, $output); + } + } +} diff --git a/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php b/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php index 17af65e4209..cf4f9d2aec5 100644 --- a/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php +++ b/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php @@ -6,7 +6,34 @@ use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; +use ReflectionMethod; use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Helper\HelperInterface; + +if ((new ReflectionMethod(HelperInterface::class, 'getName'))->hasReturnType()) { + /** @internal */ + trait EntityManagerHelperCompatibility + { + public function getName(): string + { + return 'entityManager'; + } + } +} else { + /** @internal */ + trait EntityManagerHelperCompatibility + { + /** + * {@inheritDoc} + * + * @return string + */ + public function getName() + { + return 'entityManager'; + } + } +} /** * Doctrine CLI Connection Helper. @@ -15,6 +42,8 @@ */ class EntityManagerHelper extends Helper { + use EntityManagerHelperCompatibility; + /** * Doctrine ORM EntityManagerInterface. * @@ -43,14 +72,4 @@ public function getEntityManager() { return $this->_em; } - - /** - * {@inheritDoc} - * - * @return string - */ - public function getName() - { - return 'entityManager'; - } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 45cb762abbc..420e6f91c1a 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -49,11 +49,14 @@ lib/Doctrine/ORM/Mapping/Driver/CompatibilityAnnotationDriver.php + lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php + lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php tests/* - */tests/* + lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php + tests/* diff --git a/psalm.xml b/psalm.xml index 9cb91ee7714..1e083bafc2d 100644 --- a/psalm.xml +++ b/psalm.xml @@ -121,6 +121,12 @@ + + + + + + From 0f67ba2176017181347d1647ce22f93b43403d74 Mon Sep 17 00:00:00 2001 From: DavideBicego Date: Thu, 27 Apr 2023 15:58:52 +0200 Subject: [PATCH 005/128] Adds metadata field type validation against Entity property type This avoid situations where you might map a decimal to a float, when it should really be mapped to a string. This is a big pitfall because in that situation, the ORM will consider the field changed every time. --- lib/Doctrine/ORM/Tools/SchemaValidator.php | 107 ++++++++++++++++++ .../Functional/Ticket/GH10661/GH10661Test.php | 53 +++++++++ .../Ticket/GH10661/InvalidChildEntity.php | 20 ++++ .../Ticket/GH10661/InvalidEntity.php | 25 ++++ 4 files changed, 205 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index 28ec5c12066..c6948aa85ff 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -4,33 +4,73 @@ namespace Doctrine\ORM\Tools; +use Doctrine\DBAL\Types\AsciiStringType; +use Doctrine\DBAL\Types\BigIntType; +use Doctrine\DBAL\Types\BooleanType; +use Doctrine\DBAL\Types\DecimalType; +use Doctrine\DBAL\Types\FloatType; +use Doctrine\DBAL\Types\GuidType; +use Doctrine\DBAL\Types\IntegerType; +use Doctrine\DBAL\Types\JsonType; +use Doctrine\DBAL\Types\SimpleArrayType; +use Doctrine\DBAL\Types\SmallIntType; +use Doctrine\DBAL\Types\StringType; +use Doctrine\DBAL\Types\TextType; use Doctrine\DBAL\Types\Type; use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use ReflectionNamedType; use function array_diff; +use function array_filter; use function array_key_exists; +use function array_map; +use function array_push; use function array_search; use function array_values; +use function assert; use function class_exists; use function class_parents; use function count; use function get_class; use function implode; use function in_array; +use function sprintf; + +use const PHP_VERSION_ID; /** * Performs strict validation of the mapping schema * * @link www.doctrine-project.com + * + * @psalm-import-type FieldMapping from ClassMetadata */ class SchemaValidator { /** @var EntityManagerInterface */ private $em; + /** + * It maps built-in Doctrine types to PHP types + */ + private const BUILTIN_TYPES_MAP = [ + AsciiStringType::class => 'string', + BigIntType::class => 'string', + BooleanType::class => 'bool', + DecimalType::class => 'string', + FloatType::class => 'float', + GuidType::class => 'string', + IntegerType::class => 'int', + JsonType::class => 'array', + SimpleArrayType::class => 'array', + SmallIntType::class => 'int', + StringType::class => 'string', + TextType::class => 'string', + ]; + public function __construct(EntityManagerInterface $em) { $this->em = $em; @@ -92,6 +132,11 @@ public function validateClass(ClassMetadataInfo $class) } } + // PHP 7.4 introduces the ability to type properties, so we can't validate them in previous versions + if (PHP_VERSION_ID >= 70400) { + array_push($ce, ...$this->validatePropertiesTypes($class)); + } + if ($class->isEmbeddedClass && count($class->associationMappings) > 0) { $ce[] = "Embeddable '" . $class->name . "' does not support associations"; @@ -304,4 +349,66 @@ public function getUpdateSchemaList(): array return $schemaTool->getUpdateSchemaSql($allMetadata, true); } + + /** @return list containing the found issues */ + private function validatePropertiesTypes(ClassMetadataInfo $class): array + { + return array_values( + array_filter( + array_map( + /** @param FieldMapping $fieldMapping */ + function (array $fieldMapping) use ($class): ?string { + $fieldName = $fieldMapping['fieldName']; + assert(isset($class->reflFields[$fieldName])); + $propertyType = $class->reflFields[$fieldName]->getType(); + + // If the field type is not a built-in type, we cannot check it + if (! Type::hasType($fieldMapping['type'])) { + return null; + } + + // If the property type is not a named type, we cannot check it + if (! ($propertyType instanceof ReflectionNamedType)) { + return null; + } + + $metadataFieldType = $this->findBuiltInType(Type::getType($fieldMapping['type'])); + + //If the metadata field type is not a mapped built-in type, we cannot check it + if ($metadataFieldType === null) { + return null; + } + + $propertyType = $propertyType->getName(); + + // If the property type is the same as the metadata field type, we are ok + if ($propertyType === $metadataFieldType) { + return null; + } + + return sprintf( + "The field '%s#%s' has the property type '%s' that differs from the metadata field type '%s' returned by the '%s' DBAL type.", + $class->name, + $fieldName, + $propertyType, + $metadataFieldType, + $fieldMapping['type'] + ); + }, + $class->fieldMappings + ) + ) + ); + } + + /** + * The exact DBAL type must be used (no subclasses), since consumers of doctrine/orm may have their own + * customization around field types. + */ + private function findBuiltInType(Type $type): ?string + { + $typeName = get_class($type); + + return self::BUILTIN_TYPES_MAP[$typeName] ?? null; + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php new file mode 100644 index 00000000000..6bc7f4a6124 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php @@ -0,0 +1,53 @@ += 7.4 + */ +final class GH10661Test extends OrmTestCase +{ + /** @var EntityManagerInterface */ + private $em; + + /** @var SchemaValidator */ + private $validator; + + protected function setUp(): void + { + $this->em = $this->getTestEntityManager(); + $this->validator = new SchemaValidator($this->em); + } + + public function testMetadataFieldTypeNotCoherentWithEntityPropertyType(): void + { + $class = $this->em->getClassMetadata(InvalidEntity::class); + $ce = $this->validator->validateClass($class); + + self::assertEquals( + ["The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidEntity#property1' has the property type 'float' that differs from the metadata field type 'string' returned by the 'decimal' DBAL type."], + $ce + ); + } + + public function testMetadataFieldTypeNotCoherentWithEntityPropertyTypeWithInheritance(): void + { + $class = $this->em->getClassMetadata(InvalidChildEntity::class); + $ce = $this->validator->validateClass($class); + + self::assertEquals( + [ + "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidChildEntity#property1' has the property type 'float' that differs from the metadata field type 'string' returned by the 'decimal' DBAL type.", + "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidChildEntity#property2' has the property type 'int' that differs from the metadata field type 'string' returned by the 'string' DBAL type.", + "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidChildEntity#anotherProperty' has the property type 'string' that differs from the metadata field type 'bool' returned by the 'boolean' DBAL type.", + ], + $ce + ); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php new file mode 100644 index 00000000000..123b8b0f436 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php @@ -0,0 +1,20 @@ + Date: Sat, 7 Oct 2023 11:46:19 +0200 Subject: [PATCH 006/128] Remove CommitOrderCalculator and related classes They are unused, and since they are internal, it should be fine to remove them without a deprecation. --- UPGRADE.md | 7 - .../ORM/Internal/CommitOrder/Edge.php | 46 ----- .../ORM/Internal/CommitOrder/Vertex.php | 49 ----- .../ORM/Internal/CommitOrder/VertexState.php | 28 --- .../ORM/Internal/CommitOrderCalculator.php | 177 ------------------ lib/Doctrine/ORM/UnitOfWork.php | 15 +- psalm-baseline.xml | 6 - psalm.xml | 4 - .../Tests/ORM/CommitOrderCalculatorTest.php | 122 ------------ 9 files changed, 2 insertions(+), 452 deletions(-) delete mode 100644 lib/Doctrine/ORM/Internal/CommitOrder/Edge.php delete mode 100644 lib/Doctrine/ORM/Internal/CommitOrder/Vertex.php delete mode 100644 lib/Doctrine/ORM/Internal/CommitOrder/VertexState.php delete mode 100644 lib/Doctrine/ORM/Internal/CommitOrderCalculator.php delete mode 100644 tests/Doctrine/Tests/ORM/CommitOrderCalculatorTest.php diff --git a/UPGRADE.md b/UPGRADE.md index db6a80bf248..593739fa2bd 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -33,13 +33,6 @@ avoided. When using database-provided, auto-incrementing IDs, this may lead to IDs being assigned to entities in a different order than it was previously the case. -## Deprecated `\Doctrine\ORM\Internal\CommitOrderCalculator` and related classes - -With changes made to the commit order computation, the internal classes -`\Doctrine\ORM\Internal\CommitOrderCalculator`, `\Doctrine\ORM\Internal\CommitOrder\Edge`, -`\Doctrine\ORM\Internal\CommitOrder\Vertex` and `\Doctrine\ORM\Internal\CommitOrder\VertexState` -have been deprecated and will be removed in ORM 3.0. - ## Deprecated returning post insert IDs from `EntityPersister::executeInserts()` Persisters implementing `\Doctrine\ORM\Persisters\Entity\EntityPersister` should no longer diff --git a/lib/Doctrine/ORM/Internal/CommitOrder/Edge.php b/lib/Doctrine/ORM/Internal/CommitOrder/Edge.php deleted file mode 100644 index 98bb7378955..00000000000 --- a/lib/Doctrine/ORM/Internal/CommitOrder/Edge.php +++ /dev/null @@ -1,46 +0,0 @@ -from = $from; - $this->to = $to; - $this->weight = $weight; - } -} diff --git a/lib/Doctrine/ORM/Internal/CommitOrder/Vertex.php b/lib/Doctrine/ORM/Internal/CommitOrder/Vertex.php deleted file mode 100644 index c748bd7eab0..00000000000 --- a/lib/Doctrine/ORM/Internal/CommitOrder/Vertex.php +++ /dev/null @@ -1,49 +0,0 @@ - */ - public $dependencyList = []; - - public function __construct(string $hash, ClassMetadata $value) - { - Deprecation::triggerIfCalledFromOutside( - 'doctrine/orm', - 'https://github.com/doctrine/orm/pull/10547', - 'The %s class is deprecated and will be removed in ORM 3.0', - self::class - ); - - $this->hash = $hash; - $this->value = $value; - } -} diff --git a/lib/Doctrine/ORM/Internal/CommitOrder/VertexState.php b/lib/Doctrine/ORM/Internal/CommitOrder/VertexState.php deleted file mode 100644 index 24d2fb54ee1..00000000000 --- a/lib/Doctrine/ORM/Internal/CommitOrder/VertexState.php +++ /dev/null @@ -1,28 +0,0 @@ - - */ - private $nodeList = []; - - /** - * Volatile variable holding calculated nodes during sorting process. - * - * @psalm-var list - */ - private $sortedNodeList = []; - - public function __construct() - { - Deprecation::triggerIfCalledFromOutside( - 'doctrine/orm', - 'https://github.com/doctrine/orm/pull/10547', - 'The %s class is deprecated and will be removed in ORM 3.0', - self::class - ); - } - - /** - * Checks for node (vertex) existence in graph. - * - * @param string $hash - * - * @return bool - */ - public function hasNode($hash) - { - return isset($this->nodeList[$hash]); - } - - /** - * Adds a new node (vertex) to the graph, assigning its hash and value. - * - * @param string $hash - * @param ClassMetadata $node - * - * @return void - */ - public function addNode($hash, $node) - { - $this->nodeList[$hash] = new Vertex($hash, $node); - } - - /** - * Adds a new dependency (edge) to the graph using their hashes. - * - * @param string $fromHash - * @param string $toHash - * @param int $weight - * - * @return void - */ - public function addDependency($fromHash, $toHash, $weight) - { - $this->nodeList[$fromHash]->dependencyList[$toHash] - = new Edge($fromHash, $toHash, $weight); - } - - /** - * Return a valid order list of all current nodes. - * The desired topological sorting is the reverse post order of these searches. - * - * {@internal Highly performance-sensitive method.} - * - * @psalm-return list - */ - public function sort() - { - foreach ($this->nodeList as $vertex) { - if ($vertex->state !== VertexState::NOT_VISITED) { - continue; - } - - $this->visit($vertex); - } - - $sortedList = $this->sortedNodeList; - - $this->nodeList = []; - $this->sortedNodeList = []; - - return array_reverse($sortedList); - } - - /** - * Visit a given node definition for reordering. - * - * {@internal Highly performance-sensitive method.} - */ - private function visit(Vertex $vertex): void - { - $vertex->state = VertexState::IN_PROGRESS; - - foreach ($vertex->dependencyList as $edge) { - $adjacentVertex = $this->nodeList[$edge->to]; - - switch ($adjacentVertex->state) { - case VertexState::VISITED: - // Do nothing, since node was already visited - break; - - case VertexState::IN_PROGRESS: - if ( - isset($adjacentVertex->dependencyList[$vertex->hash]) && - $adjacentVertex->dependencyList[$vertex->hash]->weight < $edge->weight - ) { - // If we have some non-visited dependencies in the in-progress dependency, we - // need to visit them before adding the node. - foreach ($adjacentVertex->dependencyList as $adjacentEdge) { - $adjacentEdgeVertex = $this->nodeList[$adjacentEdge->to]; - - if ($adjacentEdgeVertex->state === VertexState::NOT_VISITED) { - $this->visit($adjacentEdgeVertex); - } - } - - $adjacentVertex->state = VertexState::VISITED; - - $this->sortedNodeList[] = $adjacentVertex->value; - } - - break; - - case VertexState::NOT_VISITED: - $this->visit($adjacentVertex); - } - } - - if ($vertex->state !== VertexState::VISITED) { - $vertex->state = VertexState::VISITED; - - $this->sortedNodeList[] = $vertex->value; - } - } -} diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index dd0150a5afd..607957a48f6 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -27,7 +27,6 @@ use Doctrine\ORM\Exception\ORMException; use Doctrine\ORM\Exception\UnexpectedAssociationValue; use Doctrine\ORM\Id\AssignedGenerator; -use Doctrine\ORM\Internal\CommitOrderCalculator; use Doctrine\ORM\Internal\HydrationCompleteHandler; use Doctrine\ORM\Internal\TopologicalSort; use Doctrine\ORM\Mapping\ClassMetadata; @@ -1682,11 +1681,11 @@ public function addToIdentityMap($entity) clearing the EntityManager; - you might have been using EntityManager#getReference() to create a reference for a nonexistent ID that was subsequently (by the RDBMS) assigned to another -entity. +entity. Otherwise, it might be an ORM-internal inconsistency, please report it. -To opt-in to the new exception, call +To opt-in to the new exception, call \Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap on the entity manager's configuration. EXCEPTION @@ -2721,16 +2720,6 @@ public function lock($entity, int $lockMode, $lockVersion = null): void } } - /** - * Gets the CommitOrderCalculator used by the UnitOfWork to order commits. - * - * @return CommitOrderCalculator - */ - public function getCommitOrderCalculator() - { - return new Internal\CommitOrderCalculator(); - } - /** * Clears the UnitOfWork. * diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 958283bf003..1e43faeba9e 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -400,12 +400,6 @@ getTableHiLoUpdateNextValSql - - - state !== VertexState::VISITED]]> - state !== VertexState::VISITED]]> - - IterableResult diff --git a/psalm.xml b/psalm.xml index 1e083bafc2d..56c364634a4 100644 --- a/psalm.xml +++ b/psalm.xml @@ -45,10 +45,6 @@ - - - - diff --git a/tests/Doctrine/Tests/ORM/CommitOrderCalculatorTest.php b/tests/Doctrine/Tests/ORM/CommitOrderCalculatorTest.php deleted file mode 100644 index a9d3004683a..00000000000 --- a/tests/Doctrine/Tests/ORM/CommitOrderCalculatorTest.php +++ /dev/null @@ -1,122 +0,0 @@ -_calc = new CommitOrderCalculator(); - } - - public function testCommitOrdering1(): void - { - $class1 = new ClassMetadata(NodeClass1::class); - $class2 = new ClassMetadata(NodeClass2::class); - $class3 = new ClassMetadata(NodeClass3::class); - $class4 = new ClassMetadata(NodeClass4::class); - $class5 = new ClassMetadata(NodeClass5::class); - - $this->_calc->addNode($class1->name, $class1); - $this->_calc->addNode($class2->name, $class2); - $this->_calc->addNode($class3->name, $class3); - $this->_calc->addNode($class4->name, $class4); - $this->_calc->addNode($class5->name, $class5); - - $this->_calc->addDependency($class1->name, $class2->name, 1); - $this->_calc->addDependency($class2->name, $class3->name, 1); - $this->_calc->addDependency($class3->name, $class4->name, 1); - $this->_calc->addDependency($class5->name, $class1->name, 1); - - $sorted = $this->_calc->sort(); - - // There is only 1 valid ordering for this constellation - $correctOrder = [$class5, $class1, $class2, $class3, $class4]; - - self::assertSame($correctOrder, $sorted); - } - - public function testCommitOrdering2(): void - { - $class1 = new ClassMetadata(NodeClass1::class); - $class2 = new ClassMetadata(NodeClass2::class); - - $this->_calc->addNode($class1->name, $class1); - $this->_calc->addNode($class2->name, $class2); - - $this->_calc->addDependency($class1->name, $class2->name, 0); - $this->_calc->addDependency($class2->name, $class1->name, 1); - - $sorted = $this->_calc->sort(); - - // There is only 1 valid ordering for this constellation - $correctOrder = [$class2, $class1]; - - self::assertSame($correctOrder, $sorted); - } - - public function testCommitOrdering3(): void - { - // this test corresponds to the GH7259Test::testPersistFileBeforeVersion functional test - $class1 = new ClassMetadata(NodeClass1::class); - $class2 = new ClassMetadata(NodeClass2::class); - $class3 = new ClassMetadata(NodeClass3::class); - $class4 = new ClassMetadata(NodeClass4::class); - - $this->_calc->addNode($class1->name, $class1); - $this->_calc->addNode($class2->name, $class2); - $this->_calc->addNode($class3->name, $class3); - $this->_calc->addNode($class4->name, $class4); - - $this->_calc->addDependency($class4->name, $class1->name, 1); - $this->_calc->addDependency($class1->name, $class2->name, 1); - $this->_calc->addDependency($class4->name, $class3->name, 1); - $this->_calc->addDependency($class1->name, $class4->name, 0); - - $sorted = $this->_calc->sort(); - - // There is only multiple valid ordering for this constellation, but - // the class4, class1, class2 ordering is important to break the cycle - // on the nullable link. - $correctOrders = [ - [$class4, $class1, $class2, $class3], - [$class4, $class1, $class3, $class2], - [$class4, $class3, $class1, $class2], - ]; - - // We want to perform a strict comparison of the array - self::assertContains($sorted, $correctOrders, '', false, true); - } -} - -class NodeClass1 -{ -} -class NodeClass2 -{ -} -class NodeClass3 -{ -} -class NodeClass4 -{ -} -class NodeClass5 -{ -} From 68fc3b6458ec97e953848d1dd7265c2db5988023 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Sat, 7 Oct 2023 20:19:49 +0200 Subject: [PATCH 007/128] allow to disable "DISTINCT" added to the sql query by the limit subquery walker --- .../ORM/Tools/Pagination/LimitSubqueryWalker.php | 8 +++++--- lib/Doctrine/ORM/Tools/Pagination/Paginator.php | 2 ++ .../Tools/Pagination/LimitSubqueryWalkerTest.php | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php index 23da4f68b0c..9090a803457 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php @@ -50,12 +50,14 @@ public function walkSelectStatement(SelectStatement $AST) throw new RuntimeException('Paginating an entity with foreign key as identifier only works when using the Output Walkers. Call Paginator#setUseOutputWalkers(true) before iterating the paginator.'); } - $this->_getQuery()->setHint( + $query = $this->_getQuery(); + + $query->setHint( self::IDENTIFIER_TYPE, Type::getType($rootClass->fieldMappings[$identifier]['type']) ); - $this->_getQuery()->setHint(self::FORCE_DBAL_TYPE_CONVERSION, true); + $query->setHint(self::FORCE_DBAL_TYPE_CONVERSION, true); $pathExpression = new PathExpression( PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, @@ -66,7 +68,7 @@ public function walkSelectStatement(SelectStatement $AST) $pathExpression->type = PathExpression::TYPE_STATE_FIELD; $AST->selectClause->selectExpressions = [new SelectExpression($pathExpression, '_dctrn_id')]; - $AST->selectClause->isDistinct = true; + $AST->selectClause->isDistinct = ($query->getHints()[Paginator::HINT_ENABLE_DISTINCT] ?? true) === true; if (! isset($AST->orderByClause)) { return; diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php index b3572edfe0d..ca41360ec6b 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php +++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php @@ -34,6 +34,8 @@ class Paginator implements Countable, IteratorAggregate { use SQLResultCasing; + public const HINT_ENABLE_DISTINCT = 'paginator.distinct.enable'; + /** @var Query */ private $query; diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php index d3e3364d416..d54c1b95bc5 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php @@ -6,6 +6,7 @@ use Doctrine\ORM\Query; use Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker; +use Doctrine\ORM\Tools\Pagination\Paginator; /** @group DDC-1613 */ class LimitSubqueryWalkerTest extends PaginationTestCase @@ -24,6 +25,21 @@ public function testLimitSubquery(): void ); } + public function testHintCanDisableDistinct(): void + { + $dql = 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'; + $query = $this->entityManager->createQuery($dql); + $limitQuery = clone $query; + + $limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [LimitSubqueryWalker::class]); + $limitQuery->setHint(Paginator::HINT_ENABLE_DISTINCT, false); + + self::assertEquals( + 'SELECT m0_.id AS id_0 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id', + $limitQuery->getSQL() + ); + } + public function testLimitSubqueryWithSort(): void { $dql = 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title'; From 55699a9129e482a2ac6efaa09f4f697b2f3be85d Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Sun, 8 Oct 2023 20:52:51 +0200 Subject: [PATCH 008/128] document Paginator::HINT_ENABLE_DISTINCT --- docs/en/tutorials/pagination.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/en/tutorials/pagination.rst b/docs/en/tutorials/pagination.rst index dd584a4b2a8..da6f7cf6f66 100644 --- a/docs/en/tutorials/pagination.rst +++ b/docs/en/tutorials/pagination.rst @@ -43,3 +43,18 @@ the future. .. note:: ``fetchJoinCollection`` argument set to ``true`` might affect results if you use aggregations in your query. + +By using the ``Paginator::HINT_ENABLE_DISTINCT`` you can instruct doctrine that the query to be executed +will not produce "duplicate" rows (only to-one relations are joined), thus the SQL limit will work as expected. +In this way the `DISTINCT` keyword will be omitted and can bring important performance improvements. + +.. code-block:: php + + createQuery($dql) + ->setHint(Paginator::HINT_ENABLE_DISTINCT, false) + ->setFirstResult(0) + ->setMaxResults(100); From ef2123bd0f475af99e21e388d589e1f668955aa4 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 9 Oct 2023 15:30:10 +0200 Subject: [PATCH 009/128] Remove use of PartialObjectExyxpression for LimitSubqueryOutputWalker to prepare for removal. --- .../ORM/Tools/Pagination/LimitSubqueryOutputWalker.php | 4 +--- .../ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 6bcd178d030..c920864107b 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -15,7 +15,6 @@ use Doctrine\ORM\OptimisticLockException; use Doctrine\ORM\Query; use Doctrine\ORM\Query\AST\OrderByClause; -use Doctrine\ORM\Query\AST\PartialObjectExpression; use Doctrine\ORM\Query\AST\PathExpression; use Doctrine\ORM\Query\AST\SelectExpression; use Doctrine\ORM\Query\AST\SelectStatement; @@ -335,7 +334,7 @@ private function addMissingItemsFromOrderByToSelect(SelectStatement $AST): void // Add select items which were not excluded to the AST's select clause. foreach ($selects as $idVar => $fields) { - $AST->selectClause->selectExpressions[] = new SelectExpression(new PartialObjectExpression($idVar, array_keys($fields)), null, true); + $AST->selectClause->selectExpressions[] = new SelectExpression($idVar, null, true); } } @@ -374,7 +373,6 @@ private function recreateInnerSql( string $innerSql ): string { [$searchPatterns, $replacements] = $this->generateSqlAliasReplacements(); - $orderByItems = []; foreach ($orderByClause->orderByItems as $orderByItem) { diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index c143494cf1e..b7ef0ac106b 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -229,7 +229,7 @@ public function testCountQueryWithArithmeticOrderByCondition(): void ); } - public function testCountQueryWithComplexScalarOrderByItem(): void + public function testCountQueryWithComplexScalarOrderByItemWithoutJoin(): void { $query = $this->entityManager->createQuery( 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageHeight * a.imageWidth DESC' @@ -244,7 +244,7 @@ public function testCountQueryWithComplexScalarOrderByItem(): void ); } - public function testCountQueryWithComplexScalarOrderByItemJoined(): void + public function testCountQueryWithComplexScalarOrderByItemJoinedWithoutPartial(): void { $query = $this->entityManager->createQuery( 'SELECT u FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.imageHeight * a.imageWidth DESC' From 84a762e12ebd631e6a98cdf47cd041f95de58e85 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 9 Oct 2023 15:35:48 +0200 Subject: [PATCH 010/128] Adjust tests for new sql generation --- .../ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index b7ef0ac106b..e3863300412 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -254,7 +254,7 @@ public function testCountQueryWithComplexScalarOrderByItemJoinedWithoutPartial() $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_1 * imageWidth_2 FROM (SELECT u0_.id AS id_0, a1_.imageHeight AS imageHeight_1, a1_.imageWidth AS imageWidth_2, a1_.user_id AS user_id_3 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_1 * imageWidth_2 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_3 * imageWidth_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image AS image_2, a1_.imageHeight AS imageHeight_3, a1_.imageWidth AS imageWidth_4, a1_.imageAltDesc AS imageAltDesc_5, a1_.user_id AS user_id_6 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_3 * imageWidth_4 DESC) dctrn_result', $query->getSQL() ); } @@ -269,7 +269,7 @@ public function testCountQueryWithComplexScalarOrderByItemJoinedWithPartial(): v $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_3 * imageWidth_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.imageAltDesc AS imageAltDesc_2, a1_.imageHeight AS imageHeight_3, a1_.imageWidth AS imageWidth_4, a1_.user_id AS user_id_5 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_3 * imageWidth_4 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_5 * imageWidth_6 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.imageAltDesc AS imageAltDesc_2, a1_.id AS id_3, a1_.image AS image_4, a1_.imageHeight AS imageHeight_5, a1_.imageWidth AS imageWidth_6, a1_.imageAltDesc AS imageAltDesc_7, a1_.user_id AS user_id_8 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_5 * imageWidth_6 DESC) dctrn_result', $query->getSQL() ); } @@ -328,7 +328,7 @@ public function testLimitSubqueryWithOrderByInnerJoined(): void $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_1 FROM (SELECT b0_.id AS id_0, a1_.name AS name_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_1 ASC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT b0_.id AS id_0, a1_.id AS id_1, a1_.name AS name_2, b0_.author_id AS author_id_3, b0_.category_id AS category_id_4 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_2 ASC) dctrn_result', $query->getSQL() ); } From 083b1f98c1eda51140b18ea7245fa7c90bc70134 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 9 Oct 2023 15:42:41 +0200 Subject: [PATCH 011/128] Housekeeping: phpcs --- lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index c920864107b..52a35b83435 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -373,7 +373,7 @@ private function recreateInnerSql( string $innerSql ): string { [$searchPatterns, $replacements] = $this->generateSqlAliasReplacements(); - $orderByItems = []; + $orderByItems = []; foreach ($orderByClause->orderByItems as $orderByItem) { // Walk order by item to get string representation of it and From dc899e26cf6501febdeba2be7cc48f321d709732 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 13 Dec 2020 19:51:00 +0100 Subject: [PATCH 012/128] [GH-1569] Add new SUBSELECT fetch mode for OneToMany associations. Co-authored-by: Wouter M. van Vliet --- .../ORM/Mapping/ClassMetadataInfo.php | 6 + lib/Doctrine/ORM/Mapping/OneToMany.php | 2 +- lib/Doctrine/ORM/UnitOfWork.php | 80 +++++++++++- .../SubselectFetchCollectionTest.php | 115 ++++++++++++++++++ 4 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 9d8f27cd1a8..6cf3c588a12 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -194,6 +194,12 @@ class ClassMetadataInfo implements ClassMetadata */ public const FETCH_EXTRA_LAZY = 4; + /** + * Specifies that all entities of a collection valued association are fetched using a single or more + * additional WHERE IN queries. + */ + const FETCH_SUBSELECT = 5; + /** * Identifies a one-to-one association. */ diff --git a/lib/Doctrine/ORM/Mapping/OneToMany.php b/lib/Doctrine/ORM/Mapping/OneToMany.php index c3ffa16da27..fb9c4c3a61d 100644 --- a/lib/Doctrine/ORM/Mapping/OneToMany.php +++ b/lib/Doctrine/ORM/Mapping/OneToMany.php @@ -39,7 +39,7 @@ final class OneToMany implements MappingAttribute * @var string * @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY' * @readonly - * @Enum({"LAZY", "EAGER", "EXTRA_LAZY"}) + * @Enum({"LAZY", "EAGER", "EXTRA_LAZY", "SUBSELECT"}) */ public $fetch = 'LAZY'; diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index dd0150a5afd..7f9e3c274de 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -315,6 +315,9 @@ class UnitOfWork implements PropertyChangedListener */ private $eagerLoadingEntities = []; + /** @var array */ + private $subselectLoadingEntities = []; + /** @var bool */ protected $hasCache = false; @@ -3112,6 +3115,8 @@ public function createEntity($className, array $data, &$hints = []) if ($assoc['fetch'] === ClassMetadata::FETCH_EAGER) { $this->loadCollection($pColl); $pColl->takeSnapshot(); + } elseif ($assoc['fetch'] == ClassMetadata::FETCH_SUBSELECT) { + $this->scheduleCollectionForBatchLoading($pColl, $class); } $this->originalEntityData[$oid][$field] = $pColl; @@ -3128,7 +3133,7 @@ public function createEntity($className, array $data, &$hints = []) /** @return void */ public function triggerEagerLoads() { - if (! $this->eagerLoadingEntities) { + if (! $this->eagerLoadingEntities && ! $this->subselectLoadingEntities) { return; } @@ -3147,6 +3152,55 @@ public function triggerEagerLoads() array_combine($class->identifier, [array_values($ids)]) ); } + + $subselectLoadingEntities = $this->subselectLoadingEntities; // avoid recursion + $this->subselectLoadingEntities = []; + + foreach($subselectLoadingEntities as $group) { + $this->subselectLoadCollection($group['items'], $group['mapping']); + } + } + + /** + * Load all data into the given collections, according to the specified mapping + * + * @param PersistentCollection[] $collections + * @param array $mapping + */ + private function subselectLoadCollection(array $collections, array $mapping) : void + { + $targetEntity = $mapping['targetEntity']; + $class = $this->em->getClassMetadata($mapping['sourceEntity']); + $mappedBy = $mapping['mappedBy']; + + $entities = []; + $index = []; + + foreach ($collections as $idHash => $collection) { + $index[$idHash] = $collection; + $entities[] = $collection->getOwner(); + } + + $found = $this->em->getRepository($targetEntity)->findBy([ + $mappedBy => $entities + ]); + + $targetClass = $this->em->getClassMetadata($targetEntity); + $targetProperty = $targetClass->getReflectionProperty($mappedBy); + + foreach ($found as $targetValue) { + $sourceEntity = $targetProperty->getValue($targetValue); + + $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); + $idHash = implode(' ', $id); + + $index[$idHash]->add($targetValue); + } + + foreach ($index as $association) { + $association->setInitialized(true); + $association->takeSnapshot(); + } } /** @@ -3176,6 +3230,30 @@ public function loadCollection(PersistentCollection $collection) $collection->setInitialized(true); } + /** + * Schedule this collection for batch loading at the end of the UnitOfWork + */ + private function scheduleCollectionForBatchLoading(PersistentCollection $collection, ClassMetadata $sourceClass) : void + { + $mapping = $collection->getMapping(); + $name = $mapping['sourceEntity'] . '#' . $mapping['fieldName']; + + if (! isset($this->subselectLoadingEntities[$name])) { + $this->subselectLoadingEntities[$name] = [ + 'items' => [], + 'mapping' => $mapping, + ]; + } + + $id = $this->identifierFlattener->flattenIdentifier( + $sourceClass, + $sourceClass->getIdentifierValues($collection->getOwner()) + ); + $idHash = implode(' ', $id); + + $this->subselectLoadingEntities[$name]['items'][$idHash] = $collection; + } + /** * Gets the identity map of the UnitOfWork. * diff --git a/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php new file mode 100644 index 00000000000..30965a2e57b --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php @@ -0,0 +1,115 @@ +_schemaTool->createSchema([ + $this->_em->getClassMetadata(SubselectFetchOwner::class), + $this->_em->getClassMetadata(SubselectFetchChild::class), + ]); + } catch(\Exception $e) { + } + } + + public function testSubselectFetchMode() + { + $owner = $this->createOwnerWithChildren(2); + $owner2 = $this->createOwnerWithChildren(3); + + $this->_em->flush(); + + $this->_em->clear(); + + $owner = $this->_em->find(SubselectFetchOwner::class, $owner->id); + + $afterQueryCount = $this->getCurrentQueryCount(); + $this->assertCount(2, $owner->children); + $anotherQueryCount = $this->getCurrentQueryCount(); + + $this->assertEquals($anotherQueryCount, $afterQueryCount); + + $this->assertCount(3, $this->_em->find(SubselectFetchOwner::class, $owner2->id)->children); + + $this->_em->clear(); + + $beforeQueryCount = $this->getCurrentQueryCount(); + $owners = $this->_em->getRepository(SubselectFetchOwner::class)->findAll(); + $anotherQueryCount = $this->getCurrentQueryCount(); + + // the findAll() + 1 subselect loading both collections of the two returned $owners + $this->assertEquals($beforeQueryCount + 2, $anotherQueryCount); + + $this->assertCount(2, $owners[0]->children); + $this->assertCount(3, $owners[1]->children); + + // both collections are already initialized and count'ing them does not make a difference in total query count + $this->assertEquals($anotherQueryCount, $this->getCurrentQueryCount()); + } + + /** + * @return SubselectFetchOwner + * @throws \Doctrine\ORM\ORMException + */ + protected function createOwnerWithChildren(int $children): SubselectFetchOwner + { + $owner = new SubselectFetchOwner(); + $this->_em->persist($owner); + + for ($i = 0; $i < $children; $i++) { + $child = new SubselectFetchChild(); + $child->owner = $owner; + + $owner->children->add($child); + + $this->_em->persist($child); + } + + return $owner; + } +} + +/** + * @Entity + */ +class SubselectFetchOwner +{ + /** @Id @Column(type="integer") @GeneratedValue() */ + public $id; + + /** + * @var ArrayCollection + * + * @OneToMany(targetEntity="SubselectFetchChild", mappedBy="owner", fetch="SUBSELECT") + */ + public $children; + + public function __construct() + { + $this->children = new ArrayCollection(); + } +} + +/** + * @Entity + */ +class SubselectFetchChild +{ + /** @Id @Column(type="integer") @GeneratedValue() */ + public $id; + + /** + * @ManyToOne(targetEntity="SubselectFetchOwner", inversedBy="children") + * + * @var SubselectFetchOwner + */ + public $owner; +} \ No newline at end of file From fdceb82454236908996dfa58d85fd6a734419701 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 07:49:38 +0200 Subject: [PATCH 013/128] Disallow WITH keyword on fetch joined associatiosn via subselect. --- lib/Doctrine/ORM/Query/QueryException.php | 8 ++++ lib/Doctrine/ORM/Query/SqlWalker.php | 4 ++ .../SubselectFetchCollectionTest.php | 37 ++++++++++++------- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php index be9b8ed750e..e7010a21b82 100644 --- a/lib/Doctrine/ORM/Query/QueryException.php +++ b/lib/Doctrine/ORM/Query/QueryException.php @@ -204,6 +204,14 @@ public static function iterateWithFetchJoinNotAllowed($assoc) ); } + public static function subselectFetchJoinWithNotAllowed($assoc): QueryException + { + return new self( + 'Associations with fetch-mode subselects may not be using WITH conditions in + "' . $assoc['sourceEntity'] . '#' . $assoc['fieldName'] . '".' + ); + } + public static function iterateWithMixedResultNotAllowed(): QueryException { return new self('Iterating a query with mixed results (using scalars) is not supported.'); diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index a677ca26710..a0202eaef81 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1047,6 +1047,10 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi } } + if ($relation['fetch'] === ClassMetadata::FETCH_SUBSELECT) { + throw QueryException::subselectFetchJoinWithNotAllowed($assoc); + } + $targetTableJoin = null; // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot diff --git a/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php index 30965a2e57b..66b5e65b161 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php @@ -3,7 +3,9 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\Query\QueryException; use Doctrine\Tests\OrmFunctionalTestCase; +use Doctrine\ORM\Mapping as ORM; class SubselectFetchCollectionTest extends OrmFunctionalTestCase { @@ -20,7 +22,7 @@ protected function setUp() : void } } - public function testSubselectFetchMode() + public function testSubselectFetchMode(): void { $owner = $this->createOwnerWithChildren(2); $owner2 = $this->createOwnerWithChildren(3); @@ -31,9 +33,9 @@ public function testSubselectFetchMode() $owner = $this->_em->find(SubselectFetchOwner::class, $owner->id); - $afterQueryCount = $this->getCurrentQueryCount(); + $afterQueryCount = count($this->getQueryLog()->queries); $this->assertCount(2, $owner->children); - $anotherQueryCount = $this->getCurrentQueryCount(); + $anotherQueryCount = count($this->getQueryLog()->queries); $this->assertEquals($anotherQueryCount, $afterQueryCount); @@ -41,9 +43,9 @@ public function testSubselectFetchMode() $this->_em->clear(); - $beforeQueryCount = $this->getCurrentQueryCount(); + $beforeQueryCount = count($this->getQueryLog()->queries); $owners = $this->_em->getRepository(SubselectFetchOwner::class)->findAll(); - $anotherQueryCount = $this->getCurrentQueryCount(); + $anotherQueryCount = count($this->getQueryLog()->queries); // the findAll() + 1 subselect loading both collections of the two returned $owners $this->assertEquals($beforeQueryCount + 2, $anotherQueryCount); @@ -52,7 +54,16 @@ public function testSubselectFetchMode() $this->assertCount(3, $owners[1]->children); // both collections are already initialized and count'ing them does not make a difference in total query count - $this->assertEquals($anotherQueryCount, $this->getCurrentQueryCount()); + $this->assertEquals($anotherQueryCount, count($this->getQueryLog()->queries)); + } + + public function testSubselectFetchJoinWithNotAllowed(): void + { + $this->expectException(QueryException::class); + $this->expectExceptionMessage('Associations with fetch-mode subselects may not be using WITH conditions'); + + $query = $this->_em->createQuery('SELECT o, c FROM ' . SubselectFetchOwner::class . ' o JOIN o.children c WITH c.id = 1'); + $query->getResult(); } /** @@ -78,17 +89,17 @@ protected function createOwnerWithChildren(int $children): SubselectFetchOwner } /** - * @Entity + * @ORM\Entity */ class SubselectFetchOwner { - /** @Id @Column(type="integer") @GeneratedValue() */ + /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ public $id; /** * @var ArrayCollection * - * @OneToMany(targetEntity="SubselectFetchChild", mappedBy="owner", fetch="SUBSELECT") + * @ORM\OneToMany(targetEntity="SubselectFetchChild", mappedBy="owner", fetch="SUBSELECT") */ public $children; @@ -99,17 +110,17 @@ public function __construct() } /** - * @Entity + * @ORM\Entity */ class SubselectFetchChild { - /** @Id @Column(type="integer") @GeneratedValue() */ + /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ public $id; /** - * @ManyToOne(targetEntity="SubselectFetchOwner", inversedBy="children") + * @ORM\ManyToOne(targetEntity="SubselectFetchOwner", inversedBy="children") * * @var SubselectFetchOwner */ public $owner; -} \ No newline at end of file +} From 47952c32281a05e20fc701c19093299bfdc76299 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 07:51:13 +0200 Subject: [PATCH 014/128] Houskeeping: phpcs --- lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 2 +- lib/Doctrine/ORM/UnitOfWork.php | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 6cf3c588a12..8d2200877f7 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -198,7 +198,7 @@ class ClassMetadataInfo implements ClassMetadata * Specifies that all entities of a collection valued association are fetched using a single or more * additional WHERE IN queries. */ - const FETCH_SUBSELECT = 5; + public const FETCH_SUBSELECT = 5; /** * Identifies a one-to-one association. diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 7f9e3c274de..0968dee74f5 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3115,7 +3115,7 @@ public function createEntity($className, array $data, &$hints = []) if ($assoc['fetch'] === ClassMetadata::FETCH_EAGER) { $this->loadCollection($pColl); $pColl->takeSnapshot(); - } elseif ($assoc['fetch'] == ClassMetadata::FETCH_SUBSELECT) { + } elseif ($assoc['fetch'] === ClassMetadata::FETCH_SUBSELECT) { $this->scheduleCollectionForBatchLoading($pColl, $class); } @@ -3153,10 +3153,10 @@ public function triggerEagerLoads() ); } - $subselectLoadingEntities = $this->subselectLoadingEntities; // avoid recursion + $subselectLoadingEntities = $this->subselectLoadingEntities; // avoid recursion $this->subselectLoadingEntities = []; - foreach($subselectLoadingEntities as $group) { + foreach ($subselectLoadingEntities as $group) { $this->subselectLoadCollection($group['items'], $group['mapping']); } } @@ -3165,9 +3165,9 @@ public function triggerEagerLoads() * Load all data into the given collections, according to the specified mapping * * @param PersistentCollection[] $collections - * @param array $mapping + * @param array $mapping */ - private function subselectLoadCollection(array $collections, array $mapping) : void + private function subselectLoadCollection(array $collections, array $mapping): void { $targetEntity = $mapping['targetEntity']; $class = $this->em->getClassMetadata($mapping['sourceEntity']); @@ -3181,9 +3181,7 @@ private function subselectLoadCollection(array $collections, array $mapping) : v $entities[] = $collection->getOwner(); } - $found = $this->em->getRepository($targetEntity)->findBy([ - $mappedBy => $entities - ]); + $found = $this->em->getRepository($targetEntity)->findBy([$mappedBy => $entities]); $targetClass = $this->em->getClassMetadata($targetEntity); $targetProperty = $targetClass->getReflectionProperty($mappedBy); @@ -3233,7 +3231,7 @@ public function loadCollection(PersistentCollection $collection) /** * Schedule this collection for batch loading at the end of the UnitOfWork */ - private function scheduleCollectionForBatchLoading(PersistentCollection $collection, ClassMetadata $sourceClass) : void + private function scheduleCollectionForBatchLoading(PersistentCollection $collection, ClassMetadata $sourceClass): void { $mapping = $collection->getMapping(); $name = $mapping['sourceEntity'] . '#' . $mapping['fieldName']; @@ -3245,7 +3243,7 @@ private function scheduleCollectionForBatchLoading(PersistentCollection $collect ]; } - $id = $this->identifierFlattener->flattenIdentifier( + $id = $this->identifierFlattener->flattenIdentifier( $sourceClass, $sourceClass->getIdentifierValues($collection->getOwner()) ); From b9e55bad4d132e70dae3316904c804361c79a136 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 07:59:29 +0200 Subject: [PATCH 015/128] Introduce configuration option for subselect batch size. --- lib/Doctrine/ORM/Configuration.php | 10 +++++++++ lib/Doctrine/ORM/UnitOfWork.php | 33 ++++++++++++++++-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index ca5063667c2..3f41a692176 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -1127,4 +1127,14 @@ public function isRejectIdCollisionInIdentityMapEnabled(): bool { return $this->_attributes['rejectIdCollisionInIdentityMap'] ?? false; } + + public function setFetchModeSubselectBatchSize(int $batchSize = 100): void + { + $this->_attributes['fetchModeSubselectBatchSize'] = $batchSize; + } + + public function getFetchModeSubselectBatchSize(): int + { + return $this->_attributes['fetchModeSubselectBatchSize'] ?? 100; + } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 0968dee74f5..0598829b4fe 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -52,6 +52,7 @@ use Throwable; use UnexpectedValueException; +use function array_chunk; use function array_combine; use function array_diff_key; use function array_filter; @@ -3173,29 +3174,31 @@ private function subselectLoadCollection(array $collections, array $mapping): vo $class = $this->em->getClassMetadata($mapping['sourceEntity']); $mappedBy = $mapping['mappedBy']; - $entities = []; - $index = []; + $batches = array_chunk($collections, $this->em->getConfiguration()->getFetchModeSubselectBatchSize(), true); - foreach ($collections as $idHash => $collection) { - $index[$idHash] = $collection; - $entities[] = $collection->getOwner(); - } + foreach ($batches as $collectionBatch) { + $entities = []; + + foreach ($collectionBatch as $collection) { + $entities[] = $collection->getOwner(); + } - $found = $this->em->getRepository($targetEntity)->findBy([$mappedBy => $entities]); + $found = $this->em->getRepository($targetEntity)->findBy([$mappedBy => $entities]); - $targetClass = $this->em->getClassMetadata($targetEntity); - $targetProperty = $targetClass->getReflectionProperty($mappedBy); + $targetClass = $this->em->getClassMetadata($targetEntity); + $targetProperty = $targetClass->getReflectionProperty($mappedBy); - foreach ($found as $targetValue) { - $sourceEntity = $targetProperty->getValue($targetValue); + foreach ($found as $targetValue) { + $sourceEntity = $targetProperty->getValue($targetValue); - $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); - $idHash = implode(' ', $id); + $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); + $idHash = implode(' ', $id); - $index[$idHash]->add($targetValue); + $collectionBatch[$idHash]->add($targetValue); + } } - foreach ($index as $association) { + foreach ($collections as $association) { $association->setInitialized(true); $association->takeSnapshot(); } From 41410e6be13bc1cc67b2ab1706c59e105ba8e749 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 08:17:25 +0200 Subject: [PATCH 016/128] Go through Persister API instead of indirectly through repository. --- lib/Doctrine/ORM/UnitOfWork.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 0598829b4fe..537dd2f6c46 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3183,7 +3183,7 @@ private function subselectLoadCollection(array $collections, array $mapping): vo $entities[] = $collection->getOwner(); } - $found = $this->em->getRepository($targetEntity)->findBy([$mappedBy => $entities]); + $found = $this->getEntityPersister($targetEntity)->loadAll([$mappedBy => $entities]); $targetClass = $this->em->getClassMetadata($targetEntity); $targetProperty = $targetClass->getReflectionProperty($mappedBy); From ff28ba8080e378399c32237a41814cc2fd86d757 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 08:25:04 +0200 Subject: [PATCH 017/128] Disallow use of fetch=SUBSELECT on to-one associations. --- lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 4 ++++ lib/Doctrine/ORM/Mapping/MappingException.php | 9 +++++++++ .../Tests/ORM/Mapping/ClassMetadataTest.php | 14 ++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 8d2200877f7..3379e06890e 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1831,6 +1831,10 @@ protected function _validateAndCompleteAssociationMapping(array $mapping) $mapping['fetch'] = self::FETCH_LAZY; } + if ($mapping['fetch'] === self::FETCH_SUBSELECT && $mapping['type'] & self::TO_ONE) { + throw MappingException::illegalFetchSubselectAssociation($this->name, $mapping['fieldName']); + } + // Cascades $cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : []; diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index c0a5d1392fe..cf69a546f51 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -742,6 +742,15 @@ public static function illegalToManyIdentifierAssociation($className, $field) )); } + public static function illegalFetchSubselectAssociation(string $className, string $field): MappingException + { + return new self(sprintf( + 'Cannot use fetch-mode SUBSELECT for a to-one association on entity "%s#%s".', + $className, + $field + )); + } + /** * @param string $className * diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index 79da971300d..a4cf08f8a26 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -1353,6 +1353,20 @@ public function testRejectsEmbeddableWithoutValidClassName(): void 'columnPrefix' => false, ]); } + + public function testIllegalFetchModeSubselect(): void + { + $metadata = new ClassMetadata(TestEntity1::class); + + $this->expectException(MappingException::class); + $this->expectExceptionMessage('Cannot use fetch-mode SUBSELECT for a to-one association on entity'); + + $metadata->mapManyToOne([ + 'fieldName' => 'association', + 'targetEntity' => DDC2700MappedSuperClass::class, + 'fetch' => ClassMetadata::FETCH_SUBSELECT, + ]); + } } /** @MappedSuperclass */ From 0e3489b24033d3f2947fa2c08e55b75b5f74541e Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 10 Oct 2023 11:35:09 +0200 Subject: [PATCH 018/128] Don't assert that BIGINTs are stored as strings (#10980) --- .../Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php index 3fa0adb5f19..9e302a3c9e5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php @@ -60,24 +60,24 @@ public function testSavesVeryLargeIntegerAutoGeneratedValue(): void self::assertSame($veryLargeId, $entity->id); } - public function testSavesIntegerAutoGeneratedValueAsString(): void + public function testSavesIntegerAutoGeneratedValue(): void { $entity = new DDC3634Entity(); $this->_em->persist($entity); $this->_em->flush(); - self::assertIsString($entity->id); + self::assertNotNull($entity->id); } - public function testSavesIntegerAutoGeneratedValueAsStringWithJoinedInheritance(): void + public function testSavesIntegerAutoGeneratedValueWithJoinedInheritance(): void { $entity = new DDC3634JTIChildEntity(); $this->_em->persist($entity); $this->_em->flush(); - self::assertIsString($entity->id); + self::assertNotNull($entity->id); } } From a1e055b6085beb895bbe8a73af93a04dbf22ab71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 10 Oct 2023 13:46:14 +0200 Subject: [PATCH 019/128] Deprecate EntityManager*::getPartialReference() Partial objects have been deprecated, so it makes no sense to still have this way of getting some. --- UPGRADE.md | 4 ++++ lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php | 8 ++++++++ lib/Doctrine/ORM/EntityManager.php | 6 ++++++ lib/Doctrine/ORM/EntityManagerInterface.php | 2 ++ psalm.xml | 1 + .../ORM/Decorator/EntityManagerDecoratorTest.php | 11 +++++++++++ tests/Doctrine/Tests/ORM/EntityManagerTest.php | 1 + 7 files changed, 33 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index 593739fa2bd..107a44f0bf7 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,9 @@ # Upgrade to 2.17 +## Deprecate `EntityManagerInterface::getPartialReference()` + +This method does not have a replacement and will be removed in 3.0. + ## Deprecate not-enabling lazy-ghosts Not enabling lazy ghost objects is deprecated. In ORM 3.0, they will be always enabled. diff --git a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php index 0ad6e9ddb3e..c8007e40ae1 100644 --- a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php +++ b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Decorator; +use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Query\ResultSetMapping; @@ -170,6 +171,13 @@ public function getReference($entityName, $id) */ public function getPartialReference($entityName, $identifier) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/10987', + 'Method %s is deprecated and will be removed in 3.0.', + __METHOD__ + ); + return $this->wrapped->getPartialReference($entityName, $identifier); } diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 94a609f0692..6838a787c77 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -571,6 +571,12 @@ public function getReference($entityName, $id) */ public function getPartialReference($entityName, $identifier) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/10987', + 'Method %s is deprecated and will be removed in 3.0.', + __METHOD__ + ); $class = $this->metadataFactory->getMetadataFor(ltrim($entityName, '\\')); $entity = $this->unitOfWork->tryGetById($identifier, $class->rootEntityName); diff --git a/lib/Doctrine/ORM/EntityManagerInterface.php b/lib/Doctrine/ORM/EntityManagerInterface.php index 7bea03dc19e..326cb933a59 100644 --- a/lib/Doctrine/ORM/EntityManagerInterface.php +++ b/lib/Doctrine/ORM/EntityManagerInterface.php @@ -200,6 +200,8 @@ public function getReference($entityName, $id); * never be visible to the application (especially not event listeners) as it will * never be loaded in the first place. * + * @deprecated 2.7 This method is being removed from the ORM and won't have any replacement + * * @param string $entityName The name of the entity type. * @param mixed $identifier The entity identifier. * @psalm-param class-string $entityName diff --git a/psalm.xml b/psalm.xml index 56c364634a4..f4007535120 100644 --- a/psalm.xml +++ b/psalm.xml @@ -90,6 +90,7 @@ + diff --git a/tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php b/tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php index 965cf045169..55af448fcde 100644 --- a/tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php +++ b/tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM\Decorator; +use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\Decorator\EntityManagerDecorator; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Query\ResultSetMapping; @@ -22,6 +23,8 @@ class EntityManagerDecoratorTest extends TestCase { + use VerifyDeprecations; + public const VOID_METHODS = [ 'persist', 'remove', @@ -122,4 +125,12 @@ public function testAllMethodCallsAreDelegatedToTheWrappedInstance($method, arra self::assertSame($return, $decorator->$method(...$parameters)); } + + public function testGetPartialReferenceIsDeprecated(): void + { + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/10987'); + $decorator = new class ($this->wrapped) extends EntityManagerDecorator { + }; + $decorator->getPartialReference(stdClass::class, 1); + } } diff --git a/tests/Doctrine/Tests/ORM/EntityManagerTest.php b/tests/Doctrine/Tests/ORM/EntityManagerTest.php index 5a5eadcfe5c..c3ad9f559e7 100644 --- a/tests/Doctrine/Tests/ORM/EntityManagerTest.php +++ b/tests/Doctrine/Tests/ORM/EntityManagerTest.php @@ -131,6 +131,7 @@ public function testCreateQueryDqlIsOptional(): void public function testGetPartialReference(): void { + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/10987'); $user = $this->entityManager->getPartialReference(CmsUser::class, 42); self::assertTrue($this->entityManager->contains($user)); self::assertEquals(42, $user->id); From 922365d2c5539f5b456ea21877048407341938c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 10 Oct 2023 15:05:23 +0200 Subject: [PATCH 020/128] Add missing "deprecated" annotation on the annotation driver --- lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 2 ++ psalm.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 24ffa0d4168..5e3049f61af 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -30,6 +30,8 @@ /** * The AnnotationDriver reads the mapping metadata from docblock annotations. + * + * @deprecated This class will be removed in 3.0 without replacement. */ class AnnotationDriver extends CompatibilityAnnotationDriver { diff --git a/psalm.xml b/psalm.xml index 56c364634a4..43e7baf4dca 100644 --- a/psalm.xml +++ b/psalm.xml @@ -36,6 +36,7 @@ + From 194f5062bb804502291148a63c9b583eaa3d3b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 29 Jan 2022 12:28:23 +0100 Subject: [PATCH 021/128] Add method name in exception When we assert a given exception should be thrown, and get this instead, it is hard to figure out what went wrong. --- tests/Doctrine/Tests/Mocks/ConnectionMock.php | 10 ++++++++-- .../Tests/Mocks/DatabasePlatformMock.php | 17 ++++++++++++++--- tests/Doctrine/Tests/Mocks/DriverMock.php | 7 ++++++- .../Tests/ORM/Functional/Ticket/DDC3634Test.php | 6 +++++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/Doctrine/Tests/Mocks/ConnectionMock.php b/tests/Doctrine/Tests/Mocks/ConnectionMock.php index 51763326492..e25c8e0d5dc 100644 --- a/tests/Doctrine/Tests/Mocks/ConnectionMock.php +++ b/tests/Doctrine/Tests/Mocks/ConnectionMock.php @@ -87,12 +87,18 @@ public function delete($table, array $criteria, array $types = []) */ public function fetchColumn($statement, array $params = [], $colunm = 0, array $types = []) { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } public function query(?string $sql = null): Result { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } /** diff --git a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php index 1e15c5e9df6..aa87106d25f 100644 --- a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php +++ b/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php @@ -8,6 +8,8 @@ use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Platforms\AbstractPlatform; +use function sprintf; + /** * Mock class for DatabasePlatform. */ @@ -15,7 +17,10 @@ class DatabasePlatformMock extends AbstractPlatform { public function prefersIdentityColumns(): bool { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } public function supportsIdentityColumns(): bool @@ -25,7 +30,10 @@ public function supportsIdentityColumns(): bool public function prefersSequences(): bool { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } public function supportsSequences(): bool @@ -94,7 +102,10 @@ public function getClobTypeDeclarationSQL(array $field) public function getName(): string { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } /** diff --git a/tests/Doctrine/Tests/Mocks/DriverMock.php b/tests/Doctrine/Tests/Mocks/DriverMock.php index 867d13e7f34..04154e55f91 100644 --- a/tests/Doctrine/Tests/Mocks/DriverMock.php +++ b/tests/Doctrine/Tests/Mocks/DriverMock.php @@ -12,6 +12,8 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager; use Exception; +use function sprintf; + /** * Mock class for Driver. */ @@ -70,7 +72,10 @@ public function setSchemaManager(AbstractSchemaManager $sm): void */ public function getName() { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php index 3fa0adb5f19..e98e87f6202 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php @@ -20,6 +20,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use function debug_backtrace; +use function sprintf; use const PHP_INT_MAX; @@ -347,7 +348,10 @@ public function query($sql = null): Result /** {@inheritDoc} */ public function executeUpdate($query, array $params = [], array $types = []): int { - throw new BadMethodCallException('Call to deprecated method.'); + throw new BadMethodCallException(sprintf( + 'Call to deprecated method %s().', + __METHOD__ + )); } /** {@inheritDoc} */ From 40bfe07172f1ec33ecf28e4d8791958ff26ac621 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 10 Oct 2023 16:29:00 +0200 Subject: [PATCH 022/128] Make sure to many assocatinos are also respecting AbstractQuery::setFetchMode --- lib/Doctrine/ORM/UnitOfWork.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 537dd2f6c46..ed3455ecc76 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -2953,6 +2953,10 @@ public function createEntity($className, array $data, &$hints = []) continue; } + if (! isset($hints['fetchMode'][$class->name][$field])) { + $hints['fetchMode'][$class->name][$field] = $assoc['fetch']; + } + $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); switch (true) { @@ -3016,10 +3020,6 @@ public function createEntity($className, array $data, &$hints = []) break; } - if (! isset($hints['fetchMode'][$class->name][$field])) { - $hints['fetchMode'][$class->name][$field] = $assoc['fetch']; - } - // Foreign key is set // Check identity map first // FIXME: Can break easily with composite keys if join column values are in @@ -3113,11 +3113,14 @@ public function createEntity($className, array $data, &$hints = []) $reflField = $class->reflFields[$field]; $reflField->setValue($entity, $pColl); - if ($assoc['fetch'] === ClassMetadata::FETCH_EAGER) { - $this->loadCollection($pColl); - $pColl->takeSnapshot(); - } elseif ($assoc['fetch'] === ClassMetadata::FETCH_SUBSELECT) { - $this->scheduleCollectionForBatchLoading($pColl, $class); + switch ($hints['fetchMode'][$class->name][$field]) { + case ClassMetadata::FETCH_EAGER: + $this->loadCollection($pColl); + $pColl->takeSnapshot(); + break; + case ClassMetadata::FETCH_SUBSELECT: + $this->scheduleCollectionForBatchLoading($pColl, $class); + break; } $this->originalEntityData[$oid][$field] = $pColl; From 143ee2569762a3a6761ddb95283d4829bf5cc9a9 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 10 Oct 2023 17:16:01 +0200 Subject: [PATCH 023/128] Allow creating mocks of the Query class (#10990) --- lib/Doctrine/ORM/NativeQuery.php | 4 +++- lib/Doctrine/ORM/Query.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/NativeQuery.php b/lib/Doctrine/ORM/NativeQuery.php index 4c3203b4326..aa44539d544 100644 --- a/lib/Doctrine/ORM/NativeQuery.php +++ b/lib/Doctrine/ORM/NativeQuery.php @@ -11,8 +11,10 @@ /** * Represents a native SQL query. + * + * @final */ -final class NativeQuery extends AbstractQuery +class NativeQuery extends AbstractQuery { /** @var string */ private $sql; diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php index 8a1d2507450..a9be33b4da3 100644 --- a/lib/Doctrine/ORM/Query.php +++ b/lib/Doctrine/ORM/Query.php @@ -44,8 +44,10 @@ /** * A Query object represents a DQL query. + * + * @final */ -final class Query extends AbstractQuery +class Query extends AbstractQuery { /** * A query object is in CLEAN state when it has NO unparsed/unprocessed DQL parts. From e89b680a285ea4c694cdaf9edb4490d904c23e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Fri, 20 Aug 2021 20:39:26 +0200 Subject: [PATCH 024/128] Deprecate reliance on non-optimal defaults What was optimal 10 years ago no longer is, and things might change in the future. Using AUTO is still the best solution in most cases, and it should be easy to make it mean something else when it is not. --- UPGRADE.md | 36 +++++++++-- docs/en/reference/basic-mapping.rst | 37 ++++++++--- lib/Doctrine/ORM/Configuration.php | 17 +++++ .../ORM/Mapping/ClassMetadataFactory.php | 64 +++++++++++++++++-- phpstan-dbal2.neon | 5 ++ psalm-baseline.xml | 1 + .../ORM/Mapping/ClassMetadataFactoryTest.php | 56 ++++++++++++++++ 7 files changed, 196 insertions(+), 20 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 107a44f0bf7..6d2947f6e68 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,33 @@ # Upgrade to 2.17 +## Deprecated: reliance on the non-optimal defaults that come with the `AUTO` identifier generation strategy + +When the `AUTO` identifier generation strategy was introduced, the best +strategy at the time was selected for each database platform. +A lot of time has passed since then, and support for better strategies has been +added. + +Because of that, it is now deprecated to rely on the historical defaults when +they differ from what we recommend now. + +Instead, you should pick a strategy for each database platform you use, and it +will be used when using `AUTO`. As of now, only PostgreSQL is affected by this. +It is recommended that PostgreSQL user configure their new applications to use +`IDENTITY`: + +```php +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\ORM\Configuration; + +assert($configuration instanceof Configuration); +$configuration->setIdentityGenerationPreferences([ + PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_IDENTITY, +]); +``` + +If migrating an existing application is too costly, the deprecation can be +addressed by configuring `SEQUENCE` as the default strategy. + ## Deprecate `EntityManagerInterface::getPartialReference()` This method does not have a replacement and will be removed in 3.0. @@ -14,7 +42,7 @@ Ensure `Doctrine\ORM\Configuration::setLazyGhostObjectEnabled(true)` is called t ## Deprecated accepting duplicate IDs in the identity map For any given entity class and ID value, there should be only one object instance -representing the entity. +representing the entity. In https://github.com/doctrine/orm/pull/10785, a check was added that will guard this in the identity map. The most probable cause for violations of this rule are collisions @@ -48,12 +76,12 @@ persister call `Doctrine\ORM\UnitOfWork::assignPostInsertId()` instead. In ORM 3.0, a change will be made regarding how the `AttributeDriver` reports field mappings. This change is necessary to be able to detect (and reject) some invalid mapping configurations. -To avoid surprises during 2.x upgrades, the new mode is opt-in. It can be activated on the +To avoid surprises during 2.x upgrades, the new mode is opt-in. It can be activated on the `AttributeDriver` and `AnnotationDriver` by setting the `$reportFieldsWhereDeclared` constructor parameter to `true`. It will cause `MappingException`s to be thrown when invalid configurations are detected. -Not enabling the new mode will cause a deprecation notice to be raised. In ORM 3.0, +Not enabling the new mode will cause a deprecation notice to be raised. In ORM 3.0, only the new mode will be available. # Upgrade to 2.15 @@ -73,7 +101,7 @@ and will be an error in 3.0. ## Deprecated undeclared entity inheritance -As soon as an entity class inherits from another entity class, inheritance has to +As soon as an entity class inherits from another entity class, inheritance has to be declared by adding the appropriate configuration for the root entity. ## Deprecated stubs for "concrete table inheritance" diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index f6f166b6fb4..3bc4b5d33fe 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -422,9 +422,25 @@ the field that serves as the identifier with the ``#[Id]`` attribute. # fields here In most cases using the automatic generator strategy (``#[GeneratedValue]``) is -what you want. It defaults to the identifier generation mechanism your current -database vendor prefers: AUTO_INCREMENT with MySQL, sequences with PostgreSQL -and Oracle and so on. +what you want, but for backwards-compatibility reasons it might not. It +defaults to the identifier generation mechanism your current database +vendor preferred at the time that strategy was introduced: +``AUTO_INCREMENT`` with MySQL, sequences with PostgreSQL and Oracle and +so on. +We now recommend using ``IDENTITY`` for PostgreSQL, and you can achieve +that while still using the ``AUTO`` strategy, by configuring what it +defaults to. + +.. code-block:: php + + setIdentityGenerationPreferences([ + PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + ]); .. _identifier-generation-strategies: @@ -441,17 +457,18 @@ Here is the list of possible generation strategies: - ``AUTO`` (default): Tells Doctrine to pick the strategy that is preferred by the used database platform. The preferred strategies - are IDENTITY for MySQL, SQLite, MsSQL and SQL Anywhere and SEQUENCE - for Oracle and PostgreSQL. This strategy provides full portability. -- ``SEQUENCE``: Tells Doctrine to use a database sequence for ID - generation. This strategy does currently not provide full - portability. Sequences are supported by Oracle, PostgreSql and - SQL Anywhere. + are ``IDENTITY`` for MySQL, SQLite, MsSQL and SQL Anywhere and, for + historical reasons, ``SEQUENCE`` for Oracle and PostgreSQL. This + strategy provides full portability. - ``IDENTITY``: Tells Doctrine to use special identity columns in the database that generate a value on insertion of a row. This strategy does currently not provide full portability and is supported by the following platforms: MySQL/SQLite/SQL Anywhere - (AUTO\_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL). + (``AUTO_INCREMENT``), MSSQL (``IDENTITY``) and PostgreSQL (``SERIAL``). +- ``SEQUENCE``: Tells Doctrine to use a database sequence for ID + generation. This strategy does currently not provide full + portability. Sequences are supported by Oracle, PostgreSql and + SQL Anywhere. - ``UUID`` (deprecated): Tells Doctrine to use the built-in Universally Unique Identifier generator. This strategy provides full portability. - ``NONE``: Tells Doctrine that the identifiers are assigned (and diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index ca5063667c2..c6eccc25405 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -13,6 +13,7 @@ use Doctrine\Common\Cache\Psr6\CacheAdapter; use Doctrine\Common\Cache\Psr6\DoctrineProvider; use Doctrine\Common\Persistence\PersistentObject; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Cache\CacheConfiguration; use Doctrine\ORM\Cache\Exception\CacheException; @@ -27,6 +28,7 @@ use Doctrine\ORM\Exception\ProxyClassesAlwaysRegenerating; use Doctrine\ORM\Exception\UnknownEntityNamespace; use Doctrine\ORM\Internal\Hydration\AbstractHydrator; +use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\ORM\Mapping\DefaultEntityListenerResolver; use Doctrine\ORM\Mapping\DefaultNamingStrategy; @@ -68,6 +70,21 @@ class Configuration extends \Doctrine\DBAL\Configuration /** @var mixed[] */ protected $_attributes = []; + /** @psalm-var array, ClassMetadata::GENERATOR_TYPE_*> */ + private $identityGenerationPreferences = []; + + /** @psalm-param array, ClassMetadata::GENERATOR_TYPE_*> $value */ + public function setIdentityGenerationPreferences(array $value): void + { + $this->identityGenerationPreferences = $value; + } + + /** @psalm-return array, ClassMetadata::GENERATOR_TYPE_*> $value */ + public function getIdentityGenerationPreferences(): array + { + return $this->identityGenerationPreferences; + } + /** * Sets the directory where Doctrine generates any necessary proxy class files. * diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 333da89feed..34c98d37d56 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -33,11 +33,13 @@ use function assert; use function class_exists; +use function constant; use function count; use function end; use function explode; use function get_class; use function in_array; +use function is_a; use function is_subclass_of; use function str_contains; use function strlen; @@ -71,6 +73,28 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory /** @var mixed[] */ private $embeddablesActiveNesting = []; + private const LEGACY_DEFAULTS_FOR_ID_GENERATION = [ + 'Doctrine\DBAL\Platforms\MySqlPlatform' => ClassMetadata::GENERATOR_TYPE_IDENTITY, + 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + Platforms\DB2Platform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + Platforms\MySQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + Platforms\OraclePlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + Platforms\PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + Platforms\SQLServerPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + Platforms\SqlitePlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + ]; + + private const RECOMMENDED_STRATEGY = [ + 'Doctrine\DBAL\Platforms\MySqlPlatform' => 'IDENTITY', + 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => 'IDENTITY', + Platforms\DB2Platform::class => 'IDENTITY', + Platforms\MySQLPlatform::class => 'IDENTITY', + Platforms\OraclePlatform::class => 'SEQUENCE', + Platforms\PostgreSQLPlatform::class => 'IDENTITY', + Platforms\SQLServerPlatform::class => 'IDENTITY', + Platforms\SqlitePlatform::class => 'IDENTITY', + ]; + /** @return void */ public function setEntityManager(EntityManagerInterface $em) { @@ -725,14 +749,42 @@ private function completeIdGeneratorMapping(ClassMetadataInfo $class): void } } - /** @psalm-return ClassMetadata::GENERATOR_TYPE_SEQUENCE|ClassMetadata::GENERATOR_TYPE_IDENTITY */ + /** @psalm-return ClassMetadata::GENERATOR_TYPE_* */ private function determineIdGeneratorStrategy(AbstractPlatform $platform): int { - if ( - $platform instanceof Platforms\OraclePlatform - || $platform instanceof Platforms\PostgreSQLPlatform - ) { - return ClassMetadata::GENERATOR_TYPE_SEQUENCE; + assert($this->em !== null); + foreach ($this->em->getConfiguration()->getIdentityGenerationPreferences() as $platformFamily => $strategy) { + if (is_a($platform, $platformFamily)) { + return $strategy; + } + } + + foreach (self::LEGACY_DEFAULTS_FOR_ID_GENERATION as $platformFamily => $strategy) { + if (is_a($platform, $platformFamily)) { + $recommendedStrategyName = self::RECOMMENDED_STRATEGY[$platformFamily]; + if ($strategy !== constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $recommendedStrategyName)) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/issues/8893', + <<<'DEPRECATION' +Relying on non-optimal defaults for ID generation is deprecated. +Instead, configure identifier generation strategies explicitly through +configuration. +We currently recommend "%s" for "%s", so you should use +$configuration->setIdentityGenerationPreferences([ + "%s" => ClassMetadata::GENERATOR_TYPE_%s, +]); +DEPRECATION + , + $recommendedStrategyName, + $platformFamily, + $platformFamily, + $recommendedStrategyName + ); + } + + return $strategy; + } } if ($platform->supportsIdentityColumns()) { diff --git a/phpstan-dbal2.neon b/phpstan-dbal2.neon index 646aceadc5c..c2a8bcb4476 100644 --- a/phpstan-dbal2.neon +++ b/phpstan-dbal2.neon @@ -54,6 +54,11 @@ parameters: count: 1 path: lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php + - + message: '#^Class Doctrine\\DBAL\\Platforms\\MySQLPlatform not found\.$#' + count: 2 + path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php + # Symfony cache supports passing a key prefix to the clear method. - '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/' diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 1e43faeba9e..38a29728619 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -537,6 +537,7 @@ $class $class + $platformFamily new UuidGenerator() diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index a268361a904..eae9e871192 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -9,6 +9,8 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Platforms\OraclePlatform; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\Configuration; use Doctrine\ORM\EntityManagerInterface; @@ -151,6 +153,60 @@ public function testGetMetadataForReturnsLoadedCustomIdGenerator(): void self::assertInstanceOf(CustomIdGenerator::class, $actual->idGenerator); } + /** @param array, ClassMetadata::GENERATOR_TYPE_*> $preferences */ + private function setUpCmfForPlatform(AbstractPlatform $platform, array $preferences = []): ClassMetadataFactoryTestSubject + { + $cmf = new ClassMetadataFactoryTestSubject(); + $driver = $this->createMock(Driver::class); + $driver->method('getDatabasePlatform') + ->willReturn($platform); + $entityManager = $this->createEntityManager( + new MetadataDriverMock(), + new Connection([], $driver) + ); + $cmf->setEntityManager($entityManager); + $entityManager->getConfiguration()->setIdentityGenerationPreferences($preferences); + + return $cmf; + } + + public function testRelyingOnLegacyIdGenerationDefaultsIsDeprecatedIfItResultsInASuboptimalDefault(): void + { + $cm = $this->createValidClassMetadata(); + $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); + + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform()); + $cmf->setMetadataForClass($cm->name, $cm); + + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $cmf->getMetadataFor($cm->name); + } + + public function testSpecifyingIdGenerationStrategyThroughConfigurationFixesTheDeprecation(): void + { + $cm = $this->createValidClassMetadata(); + $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); + + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform(), [ + PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, + ]); + $cmf->setMetadataForClass($cm->name, $cm); + + $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $cmf->getMetadataFor($cm->name); + } + + public function testRelyingOnLegacyIdGenerationDefaultsIsOKIfItResultsInTheCurrentlyRecommendedStrategyBeingUsed(): void + { + $cm = $this->createValidClassMetadata(); + $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); + $cmf = $this->setUpCmfForPlatform(new OraclePlatform()); + $cmf->setMetadataForClass($cm->name, $cm); + + $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $cmf->getMetadataFor($cm->name); + } + public function testGetMetadataForThrowsExceptionOnUnknownCustomGeneratorClass(): void { $cm1 = $this->createValidClassMetadata(); From fdfca0f0e7e0963cbfdd91de3b02a7a33eb6ecd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Wed, 11 Oct 2023 19:44:07 +0200 Subject: [PATCH 025/128] Undeprecate Autoloader class We plan to sunset doctrine/common, and should move the Autoloader class to doctrine/orm --- UPGRADE.md | 5 +++++ docs/en/reference/advanced-configuration.rst | 2 +- lib/Doctrine/ORM/Proxy/Autoloader.php | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 6d2947f6e68..1db52439499 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,10 @@ # Upgrade to 2.17 +## Undeprecate `Doctrine\ORM\Proxy\Autoloader` + +It will be a full-fledged class, no longer extending +`Doctrine\Common\Proxy\Autoloader` in 3.0.x. + ## Deprecated: reliance on the non-optimal defaults that come with the `AUTO` identifier generation strategy When the `AUTO` identifier generation strategy was introduced, the best diff --git a/docs/en/reference/advanced-configuration.rst b/docs/en/reference/advanced-configuration.rst index 6761ac1b974..42a0833aca1 100644 --- a/docs/en/reference/advanced-configuration.rst +++ b/docs/en/reference/advanced-configuration.rst @@ -408,7 +408,7 @@ means that you have to register a special autoloader for these classes: .. code-block:: php Date: Fri, 13 Oct 2023 18:57:12 +0200 Subject: [PATCH 026/128] Remove useless check (#11006) --- lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php b/lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php index 42b4cbaf85c..cc344bd0970 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php @@ -69,8 +69,7 @@ public function getPropertyAttribute(ReflectionProperty $property, $attributeNam )); } - return $this->getPropertyAttributes($property)[$attributeName] - ?? ($this->isRepeatable($attributeName) ? new RepeatableAttributeCollection() : null); + return $this->getPropertyAttributes($property)[$attributeName] ?? null; } /** From 76fd34f76607b1b96f381377c1c51df292c759aa Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 14:04:30 +0200 Subject: [PATCH 027/128] Avoid new fetch mode, use this strategy with fetch=EAGER for collections. --- lib/Doctrine/ORM/Configuration.php | 4 +- .../ORM/Mapping/ClassMetadataInfo.php | 4 -- lib/Doctrine/ORM/Mapping/MappingException.php | 9 --- lib/Doctrine/ORM/Mapping/OneToMany.php | 2 +- .../Entity/BasicEntityPersister.php | 2 +- lib/Doctrine/ORM/Query/QueryException.php | 4 +- lib/Doctrine/ORM/Query/SqlWalker.php | 6 +- lib/Doctrine/ORM/UnitOfWork.php | 40 +++++++------ ...nTest.php => EagerFetchCollectionTest.php} | 57 ++++++++++--------- .../ORM/Functional/Ticket/DDC440Test.php | 4 +- .../ORM/Functional/Ticket/GH10808Test.php | 3 +- 11 files changed, 62 insertions(+), 73 deletions(-) rename tests/Doctrine/Tests/ORM/Functional/{SubselectFetchCollectionTest.php => EagerFetchCollectionTest.php} (61%) diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php index 3f41a692176..90ae2d95838 100644 --- a/lib/Doctrine/ORM/Configuration.php +++ b/lib/Doctrine/ORM/Configuration.php @@ -1128,12 +1128,12 @@ public function isRejectIdCollisionInIdentityMapEnabled(): bool return $this->_attributes['rejectIdCollisionInIdentityMap'] ?? false; } - public function setFetchModeSubselectBatchSize(int $batchSize = 100): void + public function setEagerFetchBatchSize(int $batchSize = 100): void { $this->_attributes['fetchModeSubselectBatchSize'] = $batchSize; } - public function getFetchModeSubselectBatchSize(): int + public function getEagerFetchBatchSize(): int { return $this->_attributes['fetchModeSubselectBatchSize'] ?? 100; } diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 3379e06890e..8d2200877f7 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1831,10 +1831,6 @@ protected function _validateAndCompleteAssociationMapping(array $mapping) $mapping['fetch'] = self::FETCH_LAZY; } - if ($mapping['fetch'] === self::FETCH_SUBSELECT && $mapping['type'] & self::TO_ONE) { - throw MappingException::illegalFetchSubselectAssociation($this->name, $mapping['fieldName']); - } - // Cascades $cascades = isset($mapping['cascade']) ? array_map('strtolower', $mapping['cascade']) : []; diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index cf69a546f51..c0a5d1392fe 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -742,15 +742,6 @@ public static function illegalToManyIdentifierAssociation($className, $field) )); } - public static function illegalFetchSubselectAssociation(string $className, string $field): MappingException - { - return new self(sprintf( - 'Cannot use fetch-mode SUBSELECT for a to-one association on entity "%s#%s".', - $className, - $field - )); - } - /** * @param string $className * diff --git a/lib/Doctrine/ORM/Mapping/OneToMany.php b/lib/Doctrine/ORM/Mapping/OneToMany.php index fb9c4c3a61d..c3ffa16da27 100644 --- a/lib/Doctrine/ORM/Mapping/OneToMany.php +++ b/lib/Doctrine/ORM/Mapping/OneToMany.php @@ -39,7 +39,7 @@ final class OneToMany implements MappingAttribute * @var string * @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY' * @readonly - * @Enum({"LAZY", "EAGER", "EXTRA_LAZY", "SUBSELECT"}) + * @Enum({"LAZY", "EAGER", "EXTRA_LAZY"}) */ public $fetch = 'LAZY'; diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index 32ac1d4f531..f968e7b7162 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -1264,7 +1264,7 @@ protected function getSelectColumnsSQL() } $isAssocToOneInverseSide = $assoc['type'] & ClassMetadata::TO_ONE && ! $assoc['isOwningSide']; - $isAssocFromOneEager = $assoc['type'] !== ClassMetadata::MANY_TO_MANY && $assoc['fetch'] === ClassMetadata::FETCH_EAGER; + $isAssocFromOneEager = $assoc['type'] & ClassMetadata::TO_ONE && $assoc['fetch'] === ClassMetadata::FETCH_EAGER; if (! ($isAssocFromOneEager || $isAssocToOneInverseSide)) { continue; diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php index e7010a21b82..f71cd7ced78 100644 --- a/lib/Doctrine/ORM/Query/QueryException.php +++ b/lib/Doctrine/ORM/Query/QueryException.php @@ -204,10 +204,10 @@ public static function iterateWithFetchJoinNotAllowed($assoc) ); } - public static function subselectFetchJoinWithNotAllowed($assoc): QueryException + public static function eagerFetchJoinWithNotAllowed($assoc): QueryException { return new self( - 'Associations with fetch-mode subselects may not be using WITH conditions in + 'Associations with fetch-mode=EAGER may not be using WITH conditions in "' . $assoc['sourceEntity'] . '#' . $assoc['fieldName'] . '".' ); } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index a0202eaef81..6bb9caa9e26 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1047,12 +1047,10 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi } } - if ($relation['fetch'] === ClassMetadata::FETCH_SUBSELECT) { - throw QueryException::subselectFetchJoinWithNotAllowed($assoc); + if ($relation['fetch'] === ClassMetadata::FETCH_EAGER && $condExpr !== null) { + throw QueryException::eagerFetchJoinWithNotAllowed($assoc); } - $targetTableJoin = null; - // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot // be the owning side and previously we ensured that $assoc is always the owning side of the associations. // The owning side is necessary at this point because only it contains the JoinColumn information. diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index ed3455ecc76..d2e23ba1499 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -316,8 +316,8 @@ class UnitOfWork implements PropertyChangedListener */ private $eagerLoadingEntities = []; - /** @var array */ - private $subselectLoadingEntities = []; + /** @var array> */ + private $eagerLoadingCollections = []; /** @var bool */ protected $hasCache = false; @@ -2764,6 +2764,7 @@ public function clear($entityName = null) $this->pendingCollectionElementRemovals = $this->visitedCollections = $this->eagerLoadingEntities = + $this->eagerLoadingCollections = $this->orphanRemovals = []; } else { Deprecation::triggerIfCalledFromOutside( @@ -3115,10 +3116,6 @@ public function createEntity($className, array $data, &$hints = []) switch ($hints['fetchMode'][$class->name][$field]) { case ClassMetadata::FETCH_EAGER: - $this->loadCollection($pColl); - $pColl->takeSnapshot(); - break; - case ClassMetadata::FETCH_SUBSELECT: $this->scheduleCollectionForBatchLoading($pColl, $class); break; } @@ -3137,7 +3134,7 @@ public function createEntity($className, array $data, &$hints = []) /** @return void */ public function triggerEagerLoads() { - if (! $this->eagerLoadingEntities && ! $this->subselectLoadingEntities) { + if (! $this->eagerLoadingEntities && ! $this->eagerLoadingCollections) { return; } @@ -3157,11 +3154,11 @@ public function triggerEagerLoads() ); } - $subselectLoadingEntities = $this->subselectLoadingEntities; // avoid recursion - $this->subselectLoadingEntities = []; + $eagerLoadingCollections = $this->eagerLoadingCollections; // avoid recursion + $this->eagerLoadingCollections = []; - foreach ($subselectLoadingEntities as $group) { - $this->subselectLoadCollection($group['items'], $group['mapping']); + foreach ($eagerLoadingCollections as $group) { + $this->eagerLoadCollections($group['items'], $group['mapping']); } } @@ -3169,15 +3166,17 @@ public function triggerEagerLoads() * Load all data into the given collections, according to the specified mapping * * @param PersistentCollection[] $collections - * @param array $mapping + * @param array $mapping + * + * @psalm-var array{items: PersistentCollection[], mapping: array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null}} $mapping */ - private function subselectLoadCollection(array $collections, array $mapping): void + private function eagerLoadCollections(array $collections, array $mapping): void { $targetEntity = $mapping['targetEntity']; $class = $this->em->getClassMetadata($mapping['sourceEntity']); $mappedBy = $mapping['mappedBy']; - $batches = array_chunk($collections, $this->em->getConfiguration()->getFetchModeSubselectBatchSize(), true); + $batches = array_chunk($collections, $this->em->getConfiguration()->getEagerFetchBatchSize(), true); foreach ($batches as $collectionBatch) { $entities = []; @@ -3197,7 +3196,12 @@ private function subselectLoadCollection(array $collections, array $mapping): vo $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); $idHash = implode(' ', $id); - $collectionBatch[$idHash]->add($targetValue); + if ($mapping['indexBy']) { + $indexByProperty = $targetClass->getReflectionProperty($mapping['indexBy']); + $collectionBatch[$idHash]->hydrateSet($indexByProperty->getValue($targetValue), $targetValue); + } else { + $collectionBatch[$idHash]->add($targetValue); + } } } @@ -3242,8 +3246,8 @@ private function scheduleCollectionForBatchLoading(PersistentCollection $collect $mapping = $collection->getMapping(); $name = $mapping['sourceEntity'] . '#' . $mapping['fieldName']; - if (! isset($this->subselectLoadingEntities[$name])) { - $this->subselectLoadingEntities[$name] = [ + if (! isset($this->eagerLoadingCollections[$name])) { + $this->eagerLoadingCollections[$name] = [ 'items' => [], 'mapping' => $mapping, ]; @@ -3255,7 +3259,7 @@ private function scheduleCollectionForBatchLoading(PersistentCollection $collect ); $idHash = implode(' ', $id); - $this->subselectLoadingEntities[$name]['items'][$idHash] = $collection; + $this->eagerLoadingCollections[$name]['items'][$idHash] = $collection; } /** diff --git a/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php similarity index 61% rename from tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php rename to tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index 66b5e65b161..02209aaa46a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/SubselectFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -1,50 +1,55 @@ _schemaTool->createSchema([ - $this->_em->getClassMetadata(SubselectFetchOwner::class), - $this->_em->getClassMetadata(SubselectFetchChild::class), + $this->_em->getClassMetadata(EagerFetchOwner::class), + $this->_em->getClassMetadata(EagerFetchChild::class), ]); - } catch(\Exception $e) { + } catch (Exception $e) { } } - public function testSubselectFetchMode(): void + public function testEagerFetchMode(): void { - $owner = $this->createOwnerWithChildren(2); + $owner = $this->createOwnerWithChildren(2); $owner2 = $this->createOwnerWithChildren(3); $this->_em->flush(); - $this->_em->clear(); - $owner = $this->_em->find(SubselectFetchOwner::class, $owner->id); + $owner = $this->_em->find(EagerFetchOwner::class, $owner->id); $afterQueryCount = count($this->getQueryLog()->queries); $this->assertCount(2, $owner->children); + $anotherQueryCount = count($this->getQueryLog()->queries); $this->assertEquals($anotherQueryCount, $afterQueryCount); - $this->assertCount(3, $this->_em->find(SubselectFetchOwner::class, $owner2->id)->children); + $this->assertCount(3, $this->_em->find(EagerFetchOwner::class, $owner2->id)->children); $this->_em->clear(); - $beforeQueryCount = count($this->getQueryLog()->queries); - $owners = $this->_em->getRepository(SubselectFetchOwner::class)->findAll(); + $beforeQueryCount = count($this->getQueryLog()->queries); + $owners = $this->_em->getRepository(EagerFetchOwner::class)->findAll(); $anotherQueryCount = count($this->getQueryLog()->queries); // the findAll() + 1 subselect loading both collections of the two returned $owners @@ -60,23 +65,19 @@ public function testSubselectFetchMode(): void public function testSubselectFetchJoinWithNotAllowed(): void { $this->expectException(QueryException::class); - $this->expectExceptionMessage('Associations with fetch-mode subselects may not be using WITH conditions'); + $this->expectExceptionMessage('Associations with fetch-mode=EAGER may not be using WITH conditions'); - $query = $this->_em->createQuery('SELECT o, c FROM ' . SubselectFetchOwner::class . ' o JOIN o.children c WITH c.id = 1'); + $query = $this->_em->createQuery('SELECT o, c FROM ' . EagerFetchOwner::class . ' o JOIN o.children c WITH c.id = 1'); $query->getResult(); } - /** - * @return SubselectFetchOwner - * @throws \Doctrine\ORM\ORMException - */ - protected function createOwnerWithChildren(int $children): SubselectFetchOwner + protected function createOwnerWithChildren(int $children): EagerFetchOwner { - $owner = new SubselectFetchOwner(); + $owner = new EagerFetchOwner(); $this->_em->persist($owner); for ($i = 0; $i < $children; $i++) { - $child = new SubselectFetchChild(); + $child = new EagerFetchChild(); $child->owner = $owner; $owner->children->add($child); @@ -91,15 +92,15 @@ protected function createOwnerWithChildren(int $children): SubselectFetchOwner /** * @ORM\Entity */ -class SubselectFetchOwner +class EagerFetchOwner { /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ public $id; /** - * @var ArrayCollection + * @ORM\OneToMany(targetEntity="EagerFetchChild", mappedBy="owner", fetch="EAGER") * - * @ORM\OneToMany(targetEntity="SubselectFetchChild", mappedBy="owner", fetch="SUBSELECT") + * @var ArrayCollection */ public $children; @@ -112,15 +113,15 @@ public function __construct() /** * @ORM\Entity */ -class SubselectFetchChild +class EagerFetchChild { /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ public $id; /** - * @ORM\ManyToOne(targetEntity="SubselectFetchOwner", inversedBy="children") + * @ORM\ManyToOne(targetEntity="EagerFetchOwner", inversedBy="children") * - * @var SubselectFetchOwner + * @var EagerFetchOwner */ public $owner; } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php index 4c9f1289db6..8101a38d418 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php @@ -49,7 +49,7 @@ public function testOriginalEntityDataEmptyWhenProxyLoadedFromTwoAssociations(): $phone->setClient($client); $phone2 = new DDC440Phone(); - $phone->setId(2); + $phone2->setId(2); $phone2->setNumber('418 222-2222'); $phone2->setClient($client); @@ -88,10 +88,10 @@ public function testOriginalEntityDataEmptyWhenProxyLoadedFromTwoAssociations(): class DDC440Phone { /** - * @var int * @Column(name="id", type="integer") * @Id * @GeneratedValue(strategy="AUTO") + * @var int */ protected $id; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php index a2ff78f43a9..78966fe8073 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php @@ -39,8 +39,7 @@ public function testDQLDeferredEagerLoad(): void $query = $this->_em->createQuery( 'SELECT appointment from Doctrine\Tests\ORM\Functional\Ticket\GH10808Appointment appointment - JOIN appointment.child appointment_child - WITH appointment_child.id = 1' + JOIN appointment.child appointment_child' ); // By default, UnitOfWork::HINT_DEFEREAGERLOAD is set to 'true' From cd54c56278f4b67bae6aef2d96b724f352bcf213 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 14:21:15 +0200 Subject: [PATCH 028/128] Directly load many to many collections, batching not supported yet. fix tests. --- lib/Doctrine/ORM/UnitOfWork.php | 11 +++++++---- .../Tests/ORM/Functional/Ticket/DDC2350Test.php | 4 ++-- .../Tests/ORM/Mapping/ClassMetadataTest.php | 14 -------------- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index d2e23ba1499..3bdaf4ee40d 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3114,10 +3114,13 @@ public function createEntity($className, array $data, &$hints = []) $reflField = $class->reflFields[$field]; $reflField->setValue($entity, $pColl); - switch ($hints['fetchMode'][$class->name][$field]) { - case ClassMetadata::FETCH_EAGER: + if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { + if ($assoc['type'] === ClassMetadata::ONE_TO_MANY) { $this->scheduleCollectionForBatchLoading($pColl, $class); - break; + } elseif ($assoc['type'] === ClassMetadata::MANY_TO_MANY) { + $this->loadCollection($pColl); + $pColl->takeSnapshot(); + } } $this->originalEntityData[$oid][$field] = $pColl; @@ -3196,7 +3199,7 @@ private function eagerLoadCollections(array $collections, array $mapping): void $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); $idHash = implode(' ', $id); - if ($mapping['indexBy']) { + if (isset($mapping['indexBy'])) { $indexByProperty = $targetClass->getReflectionProperty($mapping['indexBy']); $collectionBatch[$idHash]->hydrateSet($indexByProperty->getValue($targetValue), $targetValue); } else { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php index 2f9e7c514bd..3fe53e6bc2f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php @@ -44,11 +44,11 @@ public function testEagerCollectionsAreOnlyRetrievedOnce(): void $this->getQueryLog()->reset()->enable(); $user = $this->_em->find(DDC2350User::class, $user->id); - $this->assertQueryCount(1); + $this->assertQueryCount(2); self::assertCount(2, $user->reportedBugs); - $this->assertQueryCount(1); + $this->assertQueryCount(2); } } diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index a4cf08f8a26..79da971300d 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -1353,20 +1353,6 @@ public function testRejectsEmbeddableWithoutValidClassName(): void 'columnPrefix' => false, ]); } - - public function testIllegalFetchModeSubselect(): void - { - $metadata = new ClassMetadata(TestEntity1::class); - - $this->expectException(MappingException::class); - $this->expectExceptionMessage('Cannot use fetch-mode SUBSELECT for a to-one association on entity'); - - $metadata->mapManyToOne([ - 'fieldName' => 'association', - 'targetEntity' => DDC2700MappedSuperClass::class, - 'fetch' => ClassMetadata::FETCH_SUBSELECT, - ]); - } } /** @MappedSuperclass */ From bf74b434b8677cce42d9bc6a223c585f195fa69f Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 14:23:20 +0200 Subject: [PATCH 029/128] Housekeeping: phpcs --- .../ORM/Functional/EagerFetchCollectionTest.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index 02209aaa46a..c37e9e1a41f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -94,7 +94,13 @@ protected function createOwnerWithChildren(int $children): EagerFetchOwner */ class EagerFetchOwner { - /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ + /** + * @ORM\Column(type="integer") + * @ORM\Id + * @ORM\GeneratedValue() + * + * @var int + */ public $id; /** @@ -115,7 +121,13 @@ public function __construct() */ class EagerFetchChild { - /** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue() */ + /** + * @ORM\Column(type="integer") + * @ORM\Id + * @ORM\GeneratedValue() + * + * @var int + */ public $id; /** From 8ec599bb176018ad80b12aafa408736f06eb55c4 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 15:28:57 +0200 Subject: [PATCH 030/128] Static analysis --- lib/Doctrine/ORM/Query/QueryException.php | 4 ++-- lib/Doctrine/ORM/Query/SqlWalker.php | 2 +- lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php | 2 ++ lib/Doctrine/ORM/UnitOfWork.php | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php index f71cd7ced78..9604ff5e107 100644 --- a/lib/Doctrine/ORM/Query/QueryException.php +++ b/lib/Doctrine/ORM/Query/QueryException.php @@ -204,11 +204,11 @@ public static function iterateWithFetchJoinNotAllowed($assoc) ); } - public static function eagerFetchJoinWithNotAllowed($assoc): QueryException + public static function eagerFetchJoinWithNotAllowed(string $sourceEntity, string $fieldName): QueryException { return new self( 'Associations with fetch-mode=EAGER may not be using WITH conditions in - "' . $assoc['sourceEntity'] . '#' . $assoc['fieldName'] . '".' + "' . $sourceEntity . '#' . $fieldName . '".' ); } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 6bb9caa9e26..d3ff78a2405 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1048,7 +1048,7 @@ public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joi } if ($relation['fetch'] === ClassMetadata::FETCH_EAGER && $condExpr !== null) { - throw QueryException::eagerFetchJoinWithNotAllowed($assoc); + throw QueryException::eagerFetchJoinWithNotAllowed($assoc['sourceEntity'], $assoc['fieldName']); } // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php index cfaa4770654..15f218199be 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -211,6 +211,8 @@ protected function _getFetchModeString($mode) case ClassMetadataInfo::FETCH_LAZY: return 'LAZY'; } + + return 'LAZY'; } /** diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 3bdaf4ee40d..d724427508d 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3171,7 +3171,7 @@ public function triggerEagerLoads() * @param PersistentCollection[] $collections * @param array $mapping * - * @psalm-var array{items: PersistentCollection[], mapping: array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null}} $mapping + * @psalm-param array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null} $mapping */ private function eagerLoadCollections(array $collections, array $mapping): void { From 8057b51f8591709818be4783b6ba6321040f11fe Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 15:37:53 +0200 Subject: [PATCH 031/128] last violation hopefully --- lib/Doctrine/ORM/UnitOfWork.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 4e9416de497..7faa73e70ce 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3159,7 +3159,6 @@ public function triggerEagerLoads() * * @param PersistentCollection[] $collections * @param array $mapping - * * @psalm-param array{targetEntity: class-string, sourceEntity: class-string, mappedBy: string, indexBy: string|null} $mapping */ private function eagerLoadCollections(array $collections, array $mapping): void @@ -3245,9 +3244,12 @@ private function scheduleCollectionForBatchLoading(PersistentCollection $collect ]; } + $owner = $collection->getOwner(); + assert($owner !== null); + $id = $this->identifierFlattener->flattenIdentifier( $sourceClass, - $sourceClass->getIdentifierValues($collection->getOwner()) + $sourceClass->getIdentifierValues($owner) ); $idHash = implode(' ', $id); From 3f2fa309d49db2ad40717131682bd60cbde4b35c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 14 Oct 2023 15:56:42 +0200 Subject: [PATCH 032/128] Add another testcase for DQL based fetch eager of collection. --- .../Functional/EagerFetchCollectionTest.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index c37e9e1a41f..a748e2ec30d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -62,6 +62,31 @@ public function testEagerFetchMode(): void $this->assertEquals($anotherQueryCount, count($this->getQueryLog()->queries)); } + public function testEagerFetchModeWithDQL(): void + { + $owner = $this->createOwnerWithChildren(2); + $owner2 = $this->createOwnerWithChildren(3); + + $this->_em->flush(); + $this->_em->clear(); + + $query = $this->_em->createQuery('SELECT o FROM ' . EagerFetchOwner::class . ' o'); + $query->setFetchMode(EagerFetchOwner::class, 'children', ORM\ClassMetadata::FETCH_EAGER); + + $beforeQueryCount = count($this->getQueryLog()->queries); + $owners = $query->getResult(); + $afterQueryCount = count($this->getQueryLog()->queries); + + $this->assertEquals($beforeQueryCount + 2, $afterQueryCount); + + $owners[0]->children->count(); + $owners[1]->children->count(); + + $anotherQueryCount = count($this->getQueryLog()->queries); + + $this->assertEquals($anotherQueryCount, $afterQueryCount); + } + public function testSubselectFetchJoinWithNotAllowed(): void { $this->expectException(QueryException::class); From bf69d0ac4ea6ebf69bef772fd5ef33e51a9f9584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 14 Oct 2023 19:48:11 +0200 Subject: [PATCH 033/128] Implement proxy name resolver (#11009) It is important to have the same implementation as used in doctrine/persistence without relying on copy/paste. --- lib/Doctrine/ORM/AbstractQuery.php | 4 +- lib/Doctrine/ORM/Cache/DefaultCache.php | 4 +- .../ORM/Cache/DefaultEntityHydrator.php | 4 +- .../AbstractCollectionPersister.php | 4 +- .../ReadOnlyCachedCollectionPersister.php | 4 +- .../Entity/AbstractEntityPersister.php | 6 +-- .../Entity/ReadOnlyCachedEntityPersister.php | 4 +- lib/Doctrine/ORM/EntityManager.php | 4 +- .../ORM/Mapping/ClassMetadataFactory.php | 3 ++ .../Entity/BasicEntityPersister.php | 4 +- .../Proxy/DefaultProxyClassNameResolver.php | 40 +++++++++++++++++++ phpcs.xml.dist | 5 +++ psalm-baseline.xml | 9 +++++ .../ORM/Functional/PostLoadEventTest.php | 4 +- .../ORM/Functional/ReferenceProxyTest.php | 4 +- 15 files changed, 80 insertions(+), 23 deletions(-) create mode 100644 lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index 6cfc76d7ed0..7532681580c 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -10,7 +10,6 @@ use Doctrine\Common\Cache\Psr6\DoctrineProvider; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; -use Doctrine\Common\Util\ClassUtils; use Doctrine\DBAL\Cache\QueryCacheProfile; use Doctrine\DBAL\Result; use Doctrine\Deprecations\Deprecation; @@ -20,6 +19,7 @@ use Doctrine\ORM\Cache\TimestampCacheKey; use Doctrine\ORM\Internal\Hydration\IterableResult; use Doctrine\ORM\Mapping\MappingException as ORMMappingException; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\Query\Parameter; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Query\ResultSetMapping; @@ -430,7 +430,7 @@ public function processParameterValue($value) } try { - $class = ClassUtils::getClass($value); + $class = DefaultProxyClassNameResolver::getClass($value); $value = $this->_em->getUnitOfWork()->getSingleIdentifierValue($value); if ($value === null) { diff --git a/lib/Doctrine/ORM/Cache/DefaultCache.php b/lib/Doctrine/ORM/Cache/DefaultCache.php index bf67186bd9b..ff9b60ba402 100644 --- a/lib/Doctrine/ORM/Cache/DefaultCache.php +++ b/lib/Doctrine/ORM/Cache/DefaultCache.php @@ -4,12 +4,12 @@ namespace Doctrine\ORM\Cache; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Cache; use Doctrine\ORM\Cache\Persister\CachedPersister; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\ORMInvalidArgumentException; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\UnitOfWork; use function is_array; @@ -293,7 +293,7 @@ private function buildCollectionCacheKey( private function toIdentifierArray(ClassMetadata $metadata, $identifier): array { if (is_object($identifier)) { - $class = ClassUtils::getClass($identifier); + $class = DefaultProxyClassNameResolver::getClass($identifier); if ($this->em->getMetadataFactory()->hasMetadataFor($class)) { $identifier = $this->uow->getSingleIdentifierValue($identifier); diff --git a/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php b/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php index 32170f41094..d97d805a393 100644 --- a/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php +++ b/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php @@ -4,9 +4,9 @@ namespace Doctrine\ORM\Cache; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\Query; use Doctrine\ORM\UnitOfWork; use Doctrine\ORM\Utility\IdentifierFlattener; @@ -112,7 +112,7 @@ public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $e } if (! isset($assoc['id'])) { - $targetClass = ClassUtils::getClass($data[$name]); + $targetClass = DefaultProxyClassNameResolver::getClass($data[$name]); $targetId = $this->uow->getEntityIdentifier($data[$name]); $data[$name] = new AssociationCacheEntry($targetClass, $targetId); diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php b/lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php index 9667cbc4252..ad81823b84c 100644 --- a/lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php @@ -6,7 +6,6 @@ use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; -use Doctrine\Common\Util\ClassUtils; use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Cache\CollectionCacheKey; use Doctrine\ORM\Cache\CollectionHydrator; @@ -19,6 +18,7 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\Persisters\Collection\CollectionPersister; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\UnitOfWork; use function array_values; @@ -148,7 +148,7 @@ public function storeCollectionCache(CollectionCacheKey $key, $elements) } $class = $this->targetEntity; - $className = ClassUtils::getClass($elements[$index]); + $className = DefaultProxyClassNameResolver::getClass($elements[$index]); if ($className !== $this->targetEntity->name) { $class = $this->metadataFactory->getMetadataFor($className); diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php b/lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php index ca927eed848..5722172d0ab 100644 --- a/lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php @@ -4,9 +4,9 @@ namespace Doctrine\ORM\Cache\Persister\Collection; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyCollection; use Doctrine\ORM\PersistentCollection; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; class ReadOnlyCachedCollectionPersister extends NonStrictReadWriteCachedCollectionPersister { @@ -17,7 +17,7 @@ public function update(PersistentCollection $collection) { if ($collection->isDirty() && $collection->getSnapshot()) { throw CannotUpdateReadOnlyCollection::fromEntityAndField( - ClassUtils::getClass($collection->getOwner()), + DefaultProxyClassNameResolver::getClass($collection->getOwner()), $this->association['fieldName'] ); } diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php b/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php index 2ea4c132ba8..5831af99816 100644 --- a/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php @@ -5,7 +5,6 @@ namespace Doctrine\ORM\Cache\Persister\Entity; use Doctrine\Common\Collections\Criteria; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Cache; use Doctrine\ORM\Cache\CollectionCacheKey; use Doctrine\ORM\Cache\EntityCacheKey; @@ -21,6 +20,7 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\Persisters\Entity\EntityPersister; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\UnitOfWork; use function array_merge; @@ -190,7 +190,7 @@ public function getEntityHydrator() public function storeEntityCache($entity, EntityCacheKey $key) { $class = $this->class; - $className = ClassUtils::getClass($entity); + $className = DefaultProxyClassNameResolver::getClass($entity); if ($className !== $this->class->name) { $class = $this->metadataFactory->getMetadataFor($className); @@ -438,7 +438,7 @@ public function loadById(array $identifier, $entity = null) } $class = $this->class; - $className = ClassUtils::getClass($entity); + $className = DefaultProxyClassNameResolver::getClass($entity); if ($className !== $this->class->name) { $class = $this->metadataFactory->getMetadataFor($className); diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php b/lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php index 3e7e32af654..497815950e5 100644 --- a/lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php +++ b/lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php @@ -4,8 +4,8 @@ namespace Doctrine\ORM\Cache\Persister\Entity; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Cache\Exception\CannotUpdateReadOnlyEntity; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; /** * Specific read-only region entity persister @@ -17,6 +17,6 @@ class ReadOnlyCachedEntityPersister extends NonStrictReadWriteCachedEntityPersis */ public function update($entity) { - throw CannotUpdateReadOnlyEntity::fromEntity(ClassUtils::getClass($entity)); + throw CannotUpdateReadOnlyEntity::fromEntity(DefaultProxyClassNameResolver::getClass($entity)); } } diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 6838a787c77..21d2c7d3421 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -9,7 +9,6 @@ use Doctrine\Common\Cache\Psr6\CacheAdapter; use Doctrine\Common\EventManager; use Doctrine\Common\Persistence\PersistentObject; -use Doctrine\Common\Util\ClassUtils; use Doctrine\DBAL\Connection; use Doctrine\DBAL\DriverManager; use Doctrine\DBAL\LockMode; @@ -24,6 +23,7 @@ use Doctrine\ORM\Exception\UnrecognizedIdentifierFields; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataFactory; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\Proxy\ProxyFactory; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\FilterCollection; @@ -444,7 +444,7 @@ public function find($className, $id, $lockMode = null, $lockVersion = null) foreach ($id as $i => $value) { if (is_object($value)) { - $className = ClassUtils::getClass($value); + $className = DefaultProxyClassNameResolver::getClass($value); if ($this->metadataFactory->hasMetadataFor($className)) { $id[$i] = $this->unitOfWork->getSingleIdentifierValue($value); diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 34c98d37d56..2ad71382e85 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -24,6 +24,7 @@ use Doctrine\ORM\Mapping\Exception\CannotGenerateIds; use Doctrine\ORM\Mapping\Exception\InvalidCustomGenerator; use Doctrine\ORM\Mapping\Exception\UnknownGeneratorType; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory; use Doctrine\Persistence\Mapping\ClassMetadata as ClassMetadataInterface; use Doctrine\Persistence\Mapping\Driver\MappingDriver; @@ -98,6 +99,8 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory /** @return void */ public function setEntityManager(EntityManagerInterface $em) { + parent::setProxyClassNameResolver(new DefaultProxyClassNameResolver()); + $this->em = $em; } diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index 32ac1d4f531..82d3eb3763f 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -7,7 +7,6 @@ use BackedEnum; use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\Expr\Comparison; -use Doctrine\Common\Util\ClassUtils; use Doctrine\DBAL\Connection; use Doctrine\DBAL\LockMode; use Doctrine\DBAL\Platforms\AbstractPlatform; @@ -26,6 +25,7 @@ use Doctrine\ORM\Persisters\Exception\UnrecognizedField; use Doctrine\ORM\Persisters\SqlExpressionVisitor; use Doctrine\ORM\Persisters\SqlValueVisitor; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\Query; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Repository\Exception\InvalidFindByCall; @@ -2028,7 +2028,7 @@ private function getIndividualValue($value): array return [$value->value]; } - $valueClass = ClassUtils::getClass($value); + $valueClass = DefaultProxyClassNameResolver::getClass($value); if ($this->em->getMetadataFactory()->isTransient($valueClass)) { return [$value]; diff --git a/lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php b/lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php new file mode 100644 index 00000000000..a9d0a3dba93 --- /dev/null +++ b/lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php @@ -0,0 +1,40 @@ +resolveClassName(get_class($object)); + } +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 420e6f91c1a..b3c2ab6149e 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -195,6 +195,11 @@ tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php + + + tests/Doctrine/Tests/Proxy/DefaultProxyClassNameResolverTest.php + + tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 38a29728619..c9c79e0f4a0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1366,6 +1366,15 @@ $columnList + + + $className + substr($className, $pos + Proxy::MARKER_LENGTH + 2) + + + string + + $classMetadata diff --git a/tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php b/tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php index 286494493f0..74518f79a1c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php @@ -4,9 +4,9 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Event\PostLoadEventArgs; use Doctrine\ORM\Events; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\Tests\Models\CMS\CmsAddress; use Doctrine\Tests\Models\CMS\CmsEmail; use Doctrine\Tests\Models\CMS\CmsPhonenumber; @@ -302,7 +302,7 @@ class PostLoadListenerLoadEntityInEventHandler public function postLoad(PostLoadEventArgs $event): void { $object = $event->getObject(); - $class = ClassUtils::getClass($object); + $class = DefaultProxyClassNameResolver::getClass($object); if (! isset($this->firedByClasses[$class])) { $this->firedByClasses[$class] = 1; } else { diff --git a/tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php b/tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php index c0b147dfc56..88c14253e20 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php @@ -5,7 +5,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Common\Proxy\Proxy as CommonProxy; -use Doctrine\Common\Util\ClassUtils; +use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver; use Doctrine\ORM\Proxy\InternalProxy; use Doctrine\Tests\Models\Company\CompanyAuction; use Doctrine\Tests\Models\ECommerce\ECommerceProduct; @@ -227,7 +227,7 @@ public function testCommonPersistenceProxy(): void $entity = $this->_em->getReference(ECommerceProduct::class, $id); assert($entity instanceof ECommerceProduct); - $className = ClassUtils::getClass($entity); + $className = DefaultProxyClassNameResolver::getClass($entity); self::assertInstanceOf(InternalProxy::class, $entity); self::assertTrue($this->isUninitializedObject($entity)); From a33a3813b2b8546e5c614451f707c0a07ae1cefa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 12 Oct 2023 13:09:49 +0200 Subject: [PATCH 034/128] Copy Debug class from doctrine/common This reduces our dependency to this shared library that now holds very little code we use. The class has not been copied verbatim: - Unused parameters and methods have been removed. - The class is final and internal. - Coding standards have been enforced, including enabling strict_types, which lead to casting a variable to string before feeding it to explode(). - A bug found by static analysis has been addressed, where an INI setting obtained with ini_get() was compared with true, which is never returned by that function. - Tests are improved to run on all PHP versions --- .../Tools/Console/Command/RunDqlCommand.php | 4 +- lib/Doctrine/ORM/Tools/Debug.php | 168 +++++++++++++++++ phpcs.xml.dist | 5 + psalm-baseline.xml | 7 +- psalm.xml | 5 + tests/Doctrine/Tests/ORM/Tools/DebugTest.php | 174 ++++++++++++++++++ .../Tests/ORM/Tools/TestAsset/ChildClass.php | 15 ++ .../ChildWithSameAttributesClass.php | 15 ++ .../Tests/ORM/Tools/TestAsset/ParentClass.php | 15 ++ 9 files changed, 400 insertions(+), 8 deletions(-) create mode 100644 lib/Doctrine/ORM/Tools/Debug.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/DebugTest.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php create mode 100644 tests/Doctrine/Tests/ORM/Tools/TestAsset/ParentClass.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php index f8611da0b11..61f1eef78f1 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php @@ -4,8 +4,8 @@ namespace Doctrine\ORM\Tools\Console\Command; -use Doctrine\Common\Util\Debug; use Doctrine\ORM\Tools\Console\CommandCompatibility; +use Doctrine\ORM\Tools\Debug; use LogicException; use RuntimeException; use Symfony\Component\Console\Input\InputArgument; @@ -116,7 +116,7 @@ private function doExecute(InputInterface $input, OutputInterface $output): int $resultSet = $query->execute([], constant($hydrationMode)); - $ui->text(Debug::dump($resultSet, (int) $input->getOption('depth'), true, false)); + $ui->text(Debug::dump($resultSet, (int) $input->getOption('depth'))); return 0; } diff --git a/lib/Doctrine/ORM/Tools/Debug.php b/lib/Doctrine/ORM/Tools/Debug.php new file mode 100644 index 00000000000..153abac4a44 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/Debug.php @@ -0,0 +1,168 @@ +toArray(); + } + + if (! $maxDepth) { + return is_object($var) ? get_class($var) + : (is_array($var) ? 'Array(' . count($var) . ')' : $var); + } + + if (is_array($var)) { + $return = []; + + foreach ($var as $k => $v) { + $return[$k] = self::export($v, $maxDepth - 1); + } + + return $return; + } + + if (! is_object($var)) { + return $var; + } + + $return = new stdClass(); + if ($var instanceof DateTimeInterface) { + $return->__CLASS__ = get_class($var); + $return->date = $var->format('c'); + $return->timezone = $var->getTimezone()->getName(); + + return $return; + } + + $return->__CLASS__ = DefaultProxyClassNameResolver::getClass($var); + + if ($var instanceof Proxy) { + $return->__IS_PROXY__ = true; + $return->__PROXY_INITIALIZED__ = $var->__isInitialized(); + } + + if ($var instanceof ArrayObject || $var instanceof ArrayIterator) { + $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1); + } + + return self::fillReturnWithClassAttributes($var, $return, $maxDepth); + } + + /** + * Fill the $return variable with class attributes + * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075} + * + * @param object $var + * + * @return mixed + */ + private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth) + { + $clone = (array) $var; + + foreach (array_keys($clone) as $key) { + $aux = explode("\0", (string) $key); + $name = end($aux); + if ($aux[0] === '') { + $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private'); + } + + $return->$name = self::export($clone[$key], $maxDepth - 1); + } + + return $return; + } +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist index b3c2ab6149e..9f7dba86050 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -59,6 +59,11 @@ tests/* + + lib/Doctrine/ORM/Tools/Debug.php + tests/Doctrine/Tests/ORM/Tools/DebugTest.php + + lib/Doctrine/ORM/Events.php lib/Doctrine/ORM/Tools/ToolEvents.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index c9c79e0f4a0..72069f0765a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -536,8 +536,8 @@ $class $class - $platformFamily + new UuidGenerator() @@ -2415,11 +2415,6 @@ getAllClassNames - - - getOption('depth'), true, false)]]> - - int diff --git a/psalm.xml b/psalm.xml index 81d8fe8476b..8905a3c4086 100644 --- a/psalm.xml +++ b/psalm.xml @@ -125,6 +125,11 @@ + + + + + diff --git a/tests/Doctrine/Tests/ORM/Tools/DebugTest.php b/tests/Doctrine/Tests/ORM/Tools/DebugTest.php new file mode 100644 index 00000000000..413c577fa66 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/DebugTest.php @@ -0,0 +1,174 @@ +foo = 'bar'; + $obj->bar = 1234; + + $var = Debug::export($obj, 2); + self::assertEquals('stdClass', $var->__CLASS__); + } + + public function testExportObjectWithReference(): void + { + $foo = 'bar'; + $bar = ['foo' => & $foo]; + $baz = (object) $bar; + + $var = Debug::export($baz, 2); + $baz->foo = 'tab'; + + self::assertEquals('bar', $var->foo); + self::assertEquals('tab', $bar['foo']); + } + + public function testExportArray(): void + { + $array = ['a' => 'b', 'b' => ['c', 'd' => ['e', 'f']]]; + $var = Debug::export($array, 2); + $expected = $array; + $expected['b']['d'] = 'Array(2)'; + self::assertEquals($expected, $var); + } + + public function testExportDateTime(): void + { + $obj = new DateTime('2010-10-10 10:10:10', new DateTimeZone('UTC')); + + $var = Debug::export($obj, 2); + self::assertEquals('DateTime', $var->__CLASS__); + self::assertEquals('2010-10-10T10:10:10+00:00', $var->date); + } + + public function testExportDateTimeImmutable(): void + { + $obj = new DateTimeImmutable('2010-10-10 10:10:10', new DateTimeZone('UTC')); + + $var = Debug::export($obj, 2); + self::assertEquals('DateTimeImmutable', $var->__CLASS__); + self::assertEquals('2010-10-10T10:10:10+00:00', $var->date); + } + + public function testExportDateTimeZone(): void + { + $obj = new DateTimeImmutable('2010-10-10 12:34:56', new DateTimeZone('Europe/Rome')); + + $var = Debug::export($obj, 2); + self::assertEquals('DateTimeImmutable', $var->__CLASS__); + self::assertEquals('2010-10-10T12:34:56+02:00', $var->date); + } + + public function testExportArrayTraversable(): void + { + $obj = new ArrayObject(['foobar']); + + $var = Debug::export($obj, 2); + self::assertContains('foobar', $var->__STORAGE__); + + $it = new ArrayIterator(['foobar']); + + $var = Debug::export($it, 5); + self::assertContains('foobar', $var->__STORAGE__); + } + + /** + * @param array $expected + * + * @dataProvider provideAttributesCases + */ + public function testExportParentAttributes(TestAsset\ParentClass $class, array $expected): void + { + $actualRepresentation = print_r($class, true); + $expectedRepresentation = print_r($expected, true); + + $actualRepresentation = substr($actualRepresentation, strpos($actualRepresentation, '(')); + $expectedRepresentation = substr($expectedRepresentation, strpos($expectedRepresentation, '(')); + + self::assertSame($expectedRepresentation, $actualRepresentation); + + $var = Debug::export($class, 3); + $var = (array) $var; + unset($var['__CLASS__']); + + self::assertSame($expected, $var); + } + + public function testCollectionsAreCastIntoArrays(): void + { + $collection = new ArrayCollection(); + $collection->add('foo'); + $collection->add('bar'); + + $var = Debug::export($collection, 2); + self::assertEquals(['foo', 'bar'], $var); + } + + /** + * @psalm-return array + */ + public function provideAttributesCases(): iterable + { + return [ + 'different-attributes' => [ + new TestAsset\ChildClass(), + version_compare(PHP_VERSION, '8.1', '<') ? + [ + 'childPublicAttribute' => 4, + 'childProtectedAttribute:protected' => 5, + 'childPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ChildClass:private' => 6, + 'parentPublicAttribute' => 1, + 'parentProtectedAttribute:protected' => 2, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ParentClass:private' => 3, + ] : + [ + 'parentPublicAttribute' => 1, + 'parentProtectedAttribute:protected' => 2, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ParentClass:private' => 3, + 'childPublicAttribute' => 4, + 'childProtectedAttribute:protected' => 5, + 'childPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ChildClass:private' => 6, + ], + ], + 'same-attributes' => [ + new TestAsset\ChildWithSameAttributesClass(), + version_compare(PHP_VERSION, '8.1', '<') ? + [ + 'parentPublicAttribute' => 4, + 'parentProtectedAttribute:protected' => 5, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ChildWithSameAttributesClass:private' => 6, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ParentClass:private' => 3, + ] : + [ + 'parentPublicAttribute' => 4, + 'parentProtectedAttribute:protected' => 5, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ParentClass:private' => 3, + 'parentPrivateAttribute:Doctrine\Tests\ORM\Tools\TestAsset\ChildWithSameAttributesClass:private' => 6, + ], + ], + ]; + } +} diff --git a/tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php b/tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php new file mode 100644 index 00000000000..35e11456da1 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php @@ -0,0 +1,15 @@ + Date: Fri, 13 Oct 2023 19:50:25 +0200 Subject: [PATCH 035/128] Address split of doctrine/common doctrine/common has been split in several packages. A lot of what was true about doctrine/common is true about doctrine/persistence today, so let us simply reuse the existing paragraphs and mention persistence instead of common. --- docs/en/reference/architecture.rst | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/en/reference/architecture.rst b/docs/en/reference/architecture.rst index c9d16a69ff9..00d1c419734 100644 --- a/docs/en/reference/architecture.rst +++ b/docs/en/reference/architecture.rst @@ -24,28 +24,34 @@ performance it is also recommended that you use APC with PHP. Doctrine ORM Packages ------------------- -Doctrine ORM is divided into three main packages. +Doctrine ORM is divided into four main packages. -- Common -- DBAL (includes Common) -- ORM (includes DBAL+Common) +- `Collections `_ +- `Event Manager `_ +- `Persistence `_ +- `DBAL `_ +- ORM (depends on DBAL+Persistence+Collections) This manual mainly covers the ORM package, sometimes touching parts -of the underlying DBAL and Common packages. The Doctrine code base +of the underlying DBAL and Persistence packages. The Doctrine code base is split in to these packages for a few reasons and they are to... - ...make things more maintainable and decoupled -- ...allow you to use the code in Doctrine Common without the ORM - or DBAL +- ...allow you to use the code in Doctrine Persistence and Collections + without the ORM or DBAL - ...allow you to use the DBAL without the ORM -The Common Package -~~~~~~~~~~~~~~~~~~ +Collection, Event Manager and Persistence +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The Common package contains highly reusable components that have no -dependencies beyond the package itself (and PHP, of course). The -root namespace of the Common package is ``Doctrine\Common``. +The Collection, Event Manager and Persistence packages contain highly +reusable components that have no dependencies beyond the packages +themselves (and PHP, of course). The root namespace of the Persistence +package is ``Doctrine\Persistence``. The root namespace of the +Collection package is ``Doctrine\Common\Collections``, for historical +reasons. The root namespace of the Event Manager package is just +``Doctrine\Common``, also for historical reasons. The DBAL Package ~~~~~~~~~~~~~~~~ @@ -199,5 +205,3 @@ typical implementation of the to keep track of all the things that need to be done the next time ``flush`` is invoked. You usually do not directly interact with a ``UnitOfWork`` but with the ``EntityManager`` instead. - - From 866283d1a7a316390890276df92b12645251ba2e Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 17 Oct 2023 18:19:38 +0200 Subject: [PATCH 036/128] Fix the support for enum types in the ResultSetMappingBuilder --- .../ORM/Query/ResultSetMappingBuilder.php | 5 ++ .../Ticket/GH11017/GH11017Entity.php | 29 +++++++++++ .../Functional/Ticket/GH11017/GH11017Enum.php | 11 +++++ .../Functional/Ticket/GH11017/GH11017Test.php | 49 +++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php diff --git a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php index a65b52c87f0..8002df787b6 100644 --- a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php +++ b/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php @@ -154,6 +154,11 @@ protected function addAllClassFields($class, $alias, $columnAliasMap = []) } $this->addFieldResult($alias, $columnAlias, $propertyName); + + $enumType = $classMetadata->getFieldMapping($propertyName)['enumType'] ?? null; + if (! empty($enumType)) { + $this->addEnumResult($columnAlias, $enumType); + } } foreach ($classMetadata->associationMappings as $associationMapping) { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php new file mode 100644 index 00000000000..25d0a90d733 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php @@ -0,0 +1,29 @@ +setUpEntitySchema([ + GH11017Entity::class, + ]); + } + + public function testPostPersistListenerUpdatingObjectFieldWhileOtherInsertPending(): void + { + $entity1 = new GH11017Entity(); + $entity1->field = GH11017Enum::FIRST; + $this->_em->persist($entity1); + + $this->_em->flush(); + $this->_em->clear(); + + $rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT); + $rsm->addRootEntityFromClassMetadata(GH11017Entity::class, 'e'); + + $tableName = $this->_em->getClassMetadata(GH11017Entity::class)->getTableName(); + $sql = sprintf('SELECT %s FROM %s e WHERE id = :id', $rsm->generateSelectClause(), $tableName); + + $query = $this->_em->createNativeQuery($sql, $rsm) + ->setParameter('id', $entity1->id); + + $entity1Reloaded = $query->getSingleResult(AbstractQuery::HYDRATE_ARRAY); + self::assertNotNull($entity1Reloaded); + self::assertSame($entity1->field, $entity1Reloaded['field']); + } +} From 293299a3149f1f810dd133e4c0a99fc9c29391bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 16 Oct 2023 13:27:00 +0200 Subject: [PATCH 037/128] Make phpdoc accurate When transforming these phpdoc types into native types, things break down. They are correct according to the EBNF, but in practice, there are so-called phase 2 optimizations that allow using ConditionalPrimary, ConditionalFactor and ConditionalTerm instances in places where ConditionalExpression is used. --- .../ORM/Query/AST/ConditionalFactor.php | 2 +- .../ORM/Query/AST/ConditionalPrimary.php | 4 +-- .../ORM/Query/AST/ConditionalTerm.php | 2 +- lib/Doctrine/ORM/Query/AST/HavingClause.php | 4 +-- lib/Doctrine/ORM/Query/AST/Join.php | 2 +- .../AST/Phase2OptimizableConditional.php | 17 ++++++++++++ lib/Doctrine/ORM/Query/AST/WhenClause.php | 6 ++--- lib/Doctrine/ORM/Query/AST/WhereClause.php | 4 +-- lib/Doctrine/ORM/Query/SqlWalker.php | 12 ++++----- .../ORM/Tools/Pagination/WhereInWalker.php | 6 +---- phpstan-baseline.neon | 15 ++++------- psalm-baseline.xml | 27 ------------------- 12 files changed, 41 insertions(+), 60 deletions(-) create mode 100644 lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php b/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php index 654b0259263..a39a02c819a 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php @@ -9,7 +9,7 @@ * * @link www.doctrine-project.org */ -class ConditionalFactor extends Node +class ConditionalFactor extends Node implements Phase2OptimizableConditional { /** @var bool */ public $not = false; diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php b/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php index 381e81488ac..c0c7e917b20 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php @@ -9,12 +9,12 @@ * * @link www.doctrine-project.org */ -class ConditionalPrimary extends Node +class ConditionalPrimary extends Node implements Phase2OptimizableConditional { /** @var Node|null */ public $simpleConditionalExpression; - /** @var ConditionalExpression|null */ + /** @var ConditionalExpression|Phase2OptimizableConditional|null */ public $conditionalExpression; /** @return bool */ diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php b/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php index 9444422be24..37cd95e4e30 100644 --- a/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php +++ b/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php @@ -9,7 +9,7 @@ * * @link www.doctrine-project.org */ -class ConditionalTerm extends Node +class ConditionalTerm extends Node implements Phase2OptimizableConditional { /** @var mixed[] */ public $conditionalFactors = []; diff --git a/lib/Doctrine/ORM/Query/AST/HavingClause.php b/lib/Doctrine/ORM/Query/AST/HavingClause.php index fbbc3930045..f2891a4c745 100644 --- a/lib/Doctrine/ORM/Query/AST/HavingClause.php +++ b/lib/Doctrine/ORM/Query/AST/HavingClause.php @@ -6,10 +6,10 @@ class HavingClause extends Node { - /** @var ConditionalExpression */ + /** @var ConditionalExpression|Phase2OptimizableConditional */ public $conditionalExpression; - /** @param ConditionalExpression $conditionalExpression */ + /** @param ConditionalExpression|Phase2OptimizableConditional $conditionalExpression */ public function __construct($conditionalExpression) { $this->conditionalExpression = $conditionalExpression; diff --git a/lib/Doctrine/ORM/Query/AST/Join.php b/lib/Doctrine/ORM/Query/AST/Join.php index 7b0759228ad..9c595a457ae 100644 --- a/lib/Doctrine/ORM/Query/AST/Join.php +++ b/lib/Doctrine/ORM/Query/AST/Join.php @@ -25,7 +25,7 @@ class Join extends Node /** @var Node|null */ public $joinAssociationDeclaration = null; - /** @var ConditionalExpression|null */ + /** @var ConditionalExpression|Phase2OptimizableConditional|null */ public $conditionalExpression = null; /** diff --git a/lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php b/lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php new file mode 100644 index 00000000000..276f8f8d945 --- /dev/null +++ b/lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php @@ -0,0 +1,17 @@ +conditionalExpression = $conditionalExpression; diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index a677ca26710..2bbd800c3b5 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -1010,9 +1010,9 @@ private function generateRangeVariableDeclarationSQL( /** * Walks down a JoinAssociationDeclaration AST node, thereby generating the appropriate SQL. * - * @param AST\JoinAssociationDeclaration $joinAssociationDeclaration - * @param int $joinType - * @param AST\ConditionalExpression $condExpr + * @param AST\JoinAssociationDeclaration $joinAssociationDeclaration + * @param int $joinType + * @param AST\ConditionalExpression|AST\Phase2OptimizableConditional $condExpr * @psalm-param AST\Join::JOIN_TYPE_* $joinType * * @return string @@ -2048,7 +2048,7 @@ public function walkWhereClause($whereClause) /** * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL. * - * @param AST\ConditionalExpression $condExpr + * @param AST\ConditionalExpression|AST\Phase2OptimizableConditional $condExpr * * @return string * @@ -2068,7 +2068,7 @@ public function walkConditionalExpression($condExpr) /** * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. * - * @param AST\ConditionalTerm $condTerm + * @param AST\ConditionalTerm|AST\ConditionalFactor|AST\ConditionalPrimary $condTerm * * @return string * @@ -2088,7 +2088,7 @@ public function walkConditionalTerm($condTerm) /** * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. * - * @param AST\ConditionalFactor $factor + * @param AST\ConditionalFactor|AST\ConditionalPrimary $factor * * @return string The SQL. * diff --git a/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php b/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php index 6613e1e7474..0e88dad6ef0 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php @@ -6,7 +6,6 @@ use Doctrine\ORM\Query\AST\ArithmeticExpression; use Doctrine\ORM\Query\AST\ConditionalExpression; -use Doctrine\ORM\Query\AST\ConditionalFactor; use Doctrine\ORM\Query\AST\ConditionalPrimary; use Doctrine\ORM\Query\AST\ConditionalTerm; use Doctrine\ORM\Query\AST\InListExpression; @@ -96,10 +95,7 @@ public function walkSelectStatement(SelectStatement $AST) ), ] ); - } elseif ( - $AST->whereClause->conditionalExpression instanceof ConditionalExpression - || $AST->whereClause->conditionalExpression instanceof ConditionalFactor - ) { + } else { $tmpPrimary = new ConditionalPrimary(); $tmpPrimary->conditionalExpression = $AST->whereClause->conditionalExpression; $AST->whereClause->conditionalExpression = new ConditionalTerm( diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 87d9dc9837c..f85a4fc74cd 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -440,6 +440,11 @@ parameters: count: 1 path: lib/Doctrine/ORM/Query/SqlWalker.php + - + message: "#^Parameter \\#1 \\$condTerm of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkConditionalTerm\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalFactor\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalPrimary\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalTerm, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Phase2OptimizableConditional given\\.$#" + count: 1 + path: lib/Doctrine/ORM/Query/SqlWalker.php + - message: "#^Result of && is always false\\.$#" count: 1 @@ -595,16 +600,6 @@ parameters: count: 1 path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php - - - message: "#^Instanceof between \\*NEVER\\* and Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalFactor will always evaluate to false\\.$#" - count: 1 - path: lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php - - - - message: "#^Instanceof between Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalExpression and Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalPrimary will always evaluate to false\\.$#" - count: 1 - path: lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php - - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 1414b70c24d..17103a694c0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -2022,18 +2022,13 @@ $AST - $conditionalExpression $expr $pathExp - ConditionalExpression()]]> - ConditionalExpression()]]> lexer->getLiteral($token)]]> lexer->getLiteral($token)]]> lexer->getLiteral($token)]]> - ConditionalExpression()]]> - ConditionalExpression()]]> SimpleArithmeticExpression()]]> @@ -2145,11 +2140,6 @@ $expr - - $condExpr - $condTerm - $factor - string @@ -2158,7 +2148,6 @@ pathExpression]]> - conditionalExpression]]> whereClause]]> @@ -2194,7 +2183,6 @@ $whereClause !== null - not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary)]]> @@ -2633,21 +2621,6 @@ $orderByClause - - - whereClause->conditionalExpression instanceof ConditionalExpression - || $AST->whereClause->conditionalExpression instanceof ConditionalFactor]]> - whereClause->conditionalExpression instanceof ConditionalFactor]]> - whereClause->conditionalExpression instanceof ConditionalPrimary]]> - - - whereClause->conditionalExpression]]> - - - whereClause->conditionalExpression instanceof ConditionalExpression - || $AST->whereClause->conditionalExpression instanceof ConditionalFactor]]> - - $classes From 6993ad28edfc0faaa7c02c19c18a0507438388a8 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 22 Oct 2023 20:07:04 +0200 Subject: [PATCH 038/128] 1:1 and M:1 associations also use fetch batch size configuration now. --- lib/Doctrine/ORM/UnitOfWork.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 7faa73e70ce..b1fef6d2012 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3139,11 +3139,14 @@ public function triggerEagerLoads() continue; } - $class = $this->em->getClassMetadata($entityName); + $class = $this->em->getClassMetadata($entityName); + $batches = array_chunk($ids, $this->em->getConfiguration()->getEagerFetchBatchSize()); - $this->getEntityPersister($entityName)->loadAll( - array_combine($class->identifier, [array_values($ids)]) - ); + foreach ($batches as $batchedIds) { + $this->getEntityPersister($entityName)->loadAll( + array_combine($class->identifier, [$batchedIds]) + ); + } } $eagerLoadingCollections = $this->eagerLoadingCollections; // avoid recursion From d03aed1265ffdabd71ffc3ce5e38467f653f3c8c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 22 Oct 2023 20:08:06 +0200 Subject: [PATCH 039/128] Explain internals of eager loading in a bit more detail and how its configured. --- docs/en/reference/working-with-objects.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/en/reference/working-with-objects.rst b/docs/en/reference/working-with-objects.rst index f10c0ab091d..ef48a9a14bc 100644 --- a/docs/en/reference/working-with-objects.rst +++ b/docs/en/reference/working-with-objects.rst @@ -782,6 +782,23 @@ and these associations are mapped as EAGER, they will automatically be loaded together with the entity being queried and is thus immediately available to your application. +Eager Loading can also be configured at runtime through +``AbstractQuery::setFetchMode`` in DQL or Native Queries. + +Eager loading for many-to-one and one-to-one associations is using either a +LEFT JOIN or a second query for fetching the related entity eagerly. + +Eager loading for many-to-one associations uses a second query to load +the collections for several entities at the same time. + +When many-to-many, one-to-one or one-to-many associations are eagerly loaded, +then the global batch size configuration is used to avoid IN(?) queries with +too many arguments. The default batch size is 100 and can be changed with +``Configuration::setEagerFetchBatchSize()``. + +For eagerly laoded Many-To-Many associations one query has to made for each +collection. + By Lazy Loading ~~~~~~~~~~~~~~~ From 609e10df36f958980be916a87fae7f3d99026368 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 22 Oct 2023 20:08:18 +0200 Subject: [PATCH 040/128] Address review comments. --- .../ORM/Mapping/ClassMetadataInfo.php | 6 ----- .../Functional/EagerFetchCollectionTest.php | 24 +++++-------------- 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 8d2200877f7..9d8f27cd1a8 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -194,12 +194,6 @@ class ClassMetadataInfo implements ClassMetadata */ public const FETCH_EXTRA_LAZY = 4; - /** - * Specifies that all entities of a collection valued association are fetched using a single or more - * additional WHERE IN queries. - */ - public const FETCH_SUBSELECT = 5; - /** * Identifies a one-to-one association. */ diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index a748e2ec30d..90cd1793a9d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -8,7 +8,6 @@ use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Query\QueryException; use Doctrine\Tests\OrmFunctionalTestCase; -use Exception; use function count; @@ -18,13 +17,7 @@ protected function setUp(): void { parent::setUp(); - try { - $this->_schemaTool->createSchema([ - $this->_em->getClassMetadata(EagerFetchOwner::class), - $this->_em->getClassMetadata(EagerFetchChild::class), - ]); - } catch (Exception $e) { - } + $this->createSchemaForModels(EagerFetchOwner::class, EagerFetchChild::class); } public function testEagerFetchMode(): void @@ -40,26 +33,21 @@ public function testEagerFetchMode(): void $afterQueryCount = count($this->getQueryLog()->queries); $this->assertCount(2, $owner->children); - $anotherQueryCount = count($this->getQueryLog()->queries); - - $this->assertEquals($anotherQueryCount, $afterQueryCount); + $this->assertQueryCount($afterQueryCount, 'The $owner->children collection should already be initialized by find EagerFetchOwner before.'); $this->assertCount(3, $this->_em->find(EagerFetchOwner::class, $owner2->id)->children); $this->_em->clear(); - $beforeQueryCount = count($this->getQueryLog()->queries); - $owners = $this->_em->getRepository(EagerFetchOwner::class)->findAll(); - $anotherQueryCount = count($this->getQueryLog()->queries); + $beforeQueryCount = count($this->getQueryLog()->queries); + $owners = $this->_em->getRepository(EagerFetchOwner::class)->findAll(); - // the findAll() + 1 subselect loading both collections of the two returned $owners - $this->assertEquals($beforeQueryCount + 2, $anotherQueryCount); + $this->assertQueryCount($beforeQueryCount + 2, 'the findAll() + 1 subselect loading both collections of the two returned $owners'); $this->assertCount(2, $owners[0]->children); $this->assertCount(3, $owners[1]->children); - // both collections are already initialized and count'ing them does not make a difference in total query count - $this->assertEquals($anotherQueryCount, count($this->getQueryLog()->queries)); + $this->assertQueryCount($beforeQueryCount + 2, 'both collections are already initialized and counting them does not make a difference in total query count'); } public function testEagerFetchModeWithDQL(): void From 4b2b4860fbb55c73f38fbf77a3de50e05dc4a21a Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 22 Oct 2023 20:11:36 +0200 Subject: [PATCH 041/128] Housekeeping: Revert change to AbstractExporter, not needed without subselect fetch. --- lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php index 15f218199be..cfaa4770654 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php @@ -211,8 +211,6 @@ protected function _getFetchModeString($mode) case ClassMetadataInfo::FETCH_LAZY: return 'LAZY'; } - - return 'LAZY'; } /** From ec74c83845231fa913b387a9cc1589d5586d0e0e Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 5 Nov 2023 19:26:35 +0100 Subject: [PATCH 042/128] Fix typos --- docs/en/reference/working-with-objects.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/reference/working-with-objects.rst b/docs/en/reference/working-with-objects.rst index ef48a9a14bc..d88b814e8c4 100644 --- a/docs/en/reference/working-with-objects.rst +++ b/docs/en/reference/working-with-objects.rst @@ -796,7 +796,7 @@ then the global batch size configuration is used to avoid IN(?) queries with too many arguments. The default batch size is 100 and can be changed with ``Configuration::setEagerFetchBatchSize()``. -For eagerly laoded Many-To-Many associations one query has to made for each +For eagerly loaded Many-To-Many associations one query has to be made for each collection. By Lazy Loading From 2a9390d426b73908610a90b9f773b7d73859e1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 26 Oct 2023 00:01:12 +0200 Subject: [PATCH 043/128] Make serialized SQL executors forward compatible The idea here is that instead of having a backward compatibility layer in the next major branch, we can have a forward compatibility layer in this branch. --- UPGRADE.md | 4 ++ .../ORM/Query/Exec/AbstractSqlExecutor.php | 45 +++++++++++++++--- .../Query/Exec/MultiTableDeleteExecutor.php | 8 ++-- .../Query/Exec/MultiTableUpdateExecutor.php | 6 ++- .../ORM/Query/Exec/SingleSelectExecutor.php | 6 ++- .../Exec/SingleTableDeleteUpdateExecutor.php | 8 ++-- psalm-baseline.xml | 33 ++++++++----- .../ParserResultSerializationTest.php | 26 ++++++++++ .../ParserResults/single_select_2_17_0.txt | Bin 0 -> 2369 bytes 9 files changed, 107 insertions(+), 29 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt diff --git a/UPGRADE.md b/UPGRADE.md index 1db52439499..4b8680a2bf6 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,9 @@ # Upgrade to 2.17 +## Deprecate `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::_sqlStatements` + +Use `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::sqlStatements` instead. + ## Undeprecate `Doctrine\ORM\Proxy\Autoloader` It will be a full-fledged class, no longer extending diff --git a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php index fc9660d1bb6..2374ad795e0 100644 --- a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php @@ -9,6 +9,10 @@ use Doctrine\DBAL\Result; use Doctrine\DBAL\Types\Type; +use function array_diff; +use function array_keys; +use function array_values; + /** * Base class for SQL statement executors. * @@ -18,12 +22,24 @@ */ abstract class AbstractSqlExecutor { - /** @var list|string */ + /** + * @deprecated use $sqlStatements instead + * + * @var list|string + */ protected $_sqlStatements; + /** @var list|string */ + protected $sqlStatements; + /** @var QueryCacheProfile */ protected $queryCacheProfile; + public function __construct() + { + $this->_sqlStatements = &$this->sqlStatements; + } + /** * Gets the SQL statements that are executed by the executor. * @@ -31,21 +47,18 @@ abstract class AbstractSqlExecutor */ public function getSqlStatements() { - return $this->_sqlStatements; + return $this->sqlStatements; } - /** @return void */ - public function setQueryCacheProfile(QueryCacheProfile $qcp) + public function setQueryCacheProfile(QueryCacheProfile $qcp): void { $this->queryCacheProfile = $qcp; } /** * Do not use query cache - * - * @return void */ - public function removeQueryCacheProfile() + public function removeQueryCacheProfile(): void { $this->queryCacheProfile = null; } @@ -60,4 +73,22 @@ public function removeQueryCacheProfile() * @return Result|int */ abstract public function execute(Connection $conn, array $params, array $types); + + /** @return list */ + public function __sleep(): array + { + /* Two reasons for this: + - we do not need to serialize the deprecated property, we can + rebuild the reference to the new property in __wakeup() + - not having the legacy property in the serialized data means the + serialized representation becomes compatible with 3.0.x, meaning + there will not be a deprecation warning about a missing property + when unserializing data */ + return array_values(array_diff(array_keys((array) $this), ["\0*\0_sqlStatements"])); + } + + public function __wakeup(): void + { + $this->_sqlStatements = &$this->sqlStatements; + } } diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index 79be7a09df5..bea246e2f5b 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -45,6 +45,8 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor */ public function __construct(AST\Node $AST, $sqlWalker) { + parent::__construct(); + $em = $sqlWalker->getEntityManager(); $conn = $em->getConnection(); $platform = $conn->getDatabasePlatform(); @@ -83,8 +85,8 @@ public function __construct(AST\Node $AST, $sqlWalker) // 3. Create and store DELETE statements $classNames = array_merge($primaryClass->parentClasses, [$primaryClass->name], $primaryClass->subClasses); foreach (array_reverse($classNames) as $className) { - $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform); - $this->_sqlStatements[] = 'DELETE FROM ' . $tableName + $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform); + $this->sqlStatements[] = 'DELETE FROM ' . $tableName . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; } @@ -117,7 +119,7 @@ public function execute(Connection $conn, array $params, array $types) $numDeleted = $conn->executeStatement($this->insertSql, $params, $types); // Execute DELETE statements - foreach ($this->_sqlStatements as $sql) { + foreach ($this->sqlStatements as $sql) { $conn->executeStatement($sql); } } catch (Throwable $exception) { diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index 12d690aab09..f1e491bd258 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -50,6 +50,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor */ public function __construct(AST\Node $AST, $sqlWalker) { + parent::__construct(); + $em = $sqlWalker->getEntityManager(); $conn = $em->getConnection(); $platform = $conn->getDatabasePlatform(); @@ -119,7 +121,7 @@ public function __construct(AST\Node $AST, $sqlWalker) } if ($affected) { - $this->_sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; + $this->sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; } } @@ -163,7 +165,7 @@ public function execute(Connection $conn, array $params, array $types) ); // Execute UPDATE statements - foreach ($this->_sqlStatements as $key => $statement) { + foreach ($this->sqlStatements as $key => $statement) { $paramValues = []; $paramTypes = []; diff --git a/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php b/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php index 11700a3f4f8..fbcab590e09 100644 --- a/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php @@ -18,7 +18,9 @@ class SingleSelectExecutor extends AbstractSqlExecutor { public function __construct(SelectStatement $AST, SqlWalker $sqlWalker) { - $this->_sqlStatements = $sqlWalker->walkSelectStatement($AST); + parent::__construct(); + + $this->sqlStatements = $sqlWalker->walkSelectStatement($AST); } /** @@ -28,6 +30,6 @@ public function __construct(SelectStatement $AST, SqlWalker $sqlWalker) */ public function execute(Connection $conn, array $params, array $types) { - return $conn->executeQuery($this->_sqlStatements, $params, $types, $this->queryCacheProfile); + return $conn->executeQuery($this->sqlStatements, $params, $types, $this->queryCacheProfile); } } diff --git a/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php index bf67d86d30b..7f7496e397a 100644 --- a/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php @@ -22,10 +22,12 @@ class SingleTableDeleteUpdateExecutor extends AbstractSqlExecutor /** @param SqlWalker $sqlWalker */ public function __construct(AST\Node $AST, $sqlWalker) { + parent::__construct(); + if ($AST instanceof AST\UpdateStatement) { - $this->_sqlStatements = $sqlWalker->walkUpdateStatement($AST); + $this->sqlStatements = $sqlWalker->walkUpdateStatement($AST); } elseif ($AST instanceof AST\DeleteStatement) { - $this->_sqlStatements = $sqlWalker->walkDeleteStatement($AST); + $this->sqlStatements = $sqlWalker->walkDeleteStatement($AST); } } @@ -40,6 +42,6 @@ public function execute(Connection $conn, array $params, array $types) $conn->ensureConnectedToPrimary(); } - return $conn->executeStatement($this->_sqlStatements, $params, $types); + return $conn->executeStatement($this->sqlStatements, $params, $types); } } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index bcb47d1a2be..809e541b90f 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1847,6 +1847,18 @@ null + + $_sqlStatements + $queryCacheProfile + $sqlStatements + + + sqlStatements]]> + + + _sqlStatements = &$this->sqlStatements]]> + _sqlStatements = &$this->sqlStatements]]> + @@ -1856,15 +1868,12 @@ int - _sqlStatements]]> + sqlStatements]]> MultiTableDeleteExecutor MultiTableDeleteExecutor - - _sqlStatements]]> - @@ -1874,40 +1883,40 @@ int - _sqlStatements]]> + sqlStatements]]> MultiTableUpdateExecutor MultiTableUpdateExecutor + MultiTableUpdateExecutor - _sqlStatements]]> + sqlStatements]]> - - _sqlStatements]]> - - _sqlStatements]]> + sqlStatements]]> SingleSelectExecutor + SingleSelectExecutor - executeStatement($this->_sqlStatements, $params, $types)]]> + executeStatement($this->sqlStatements, $params, $types)]]> int - _sqlStatements]]> + sqlStatements]]> SingleTableDeleteUpdateExecutor SingleTableDeleteUpdateExecutor + SingleTableDeleteUpdateExecutor diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php index a9d73fc7c98..5d69c4c9209 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -11,6 +11,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use Generator; use ReflectionMethod; +use ReflectionProperty; use function file_get_contents; use function rtrim; @@ -41,6 +42,30 @@ public function testSerializeParserResult(): void $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); } + public function testItSerializesParserResultWithAForwardCompatibleFormat(): void + { + $query = $this->_em + ->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u.name = :name'); + + $parserResult = self::parseQuery($query); + $serialized = serialize($parserResult); + $this->assertStringNotContainsString( + '_sqlStatements', + $serialized, + 'ParserResult should not contain any reference to _sqlStatements, which is a legacy property.' + ); + $unserialized = unserialize($serialized); + + $r = new ReflectionProperty($unserialized->getSqlExecutor(), '_sqlStatements'); + $r->setAccessible(true); + + $this->assertSame( + $r->getValue($unserialized->getSqlExecutor()), + $unserialized->getSqlExecutor()->getSqlStatements(), + 'The legacy property should be populated with the same value as the new one.' + ); + } + /** * @dataProvider provideSerializedSingleSelectResults */ @@ -59,6 +84,7 @@ public static function provideSerializedSingleSelectResults(): Generator { yield '2.14.3' => [rtrim(file_get_contents(__DIR__ . '/ParserResults/single_select_2_14_3.txt'), "\n")]; yield '2.15.0' => [rtrim(file_get_contents(__DIR__ . '/ParserResults/single_select_2_15_0.txt'), "\n")]; + yield '2.17.0' => [rtrim(file_get_contents(__DIR__ . '/ParserResults/single_select_2_17_0.txt'), "\n")]; } private static function parseQuery(Query $query): ParserResult diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt b/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa854bfab92d1b06105aeefae72af587f45e042d GIT binary patch literal 2369 zcmbW3TW{Jh6vz9#PZ8yDnkoYHGNWngDAhU**r3v0kSsSj?L6f|W1|*T{qFl8I|-r7 zZhb)5=h!~C-?1|ngGhwuMQlr*(`vq$uD))l+^)W;(one|vq^0z2IA3(;ZTGJe_489 z?$XHv#T#3c;b`vmbZp@ztEJ9wQ(96=v2FHwzSGpM!7ZN$cVuSyj@N{ zPsUe4+>?ho3C@;*PGs+mo98McmhiufAdBRoQK>4oEcGMV_wt0+svl6asPPvL7yiVSNj_> zm8)B9;z0IyATVtG_HnY9?DF|8c+a`-_gqcx7>}`vztfkpxX~$vquJ;QbiDlsI!edW zlI&Ei*C;2M4waBlv_FV0`x)*YT9 zEbnNO!MI2_Sw6qdiPOj+IGmB&8Uz%{0lLRQEqn$+E$*y;bq*uj)L0H(AeCyr+Vx@k zm8qrfm^xH>(mv){Is6V3g0BjfJe}!W;VBrq;2r+0ayaT57Px@er}Km!K5zv&M-^pA zNkTCQ1SsQF8AF||^n%uY-gf_gIsDR~FY=o7||0vI?Igc+#!w9sh9DZ1i!*?y=S^ pb%^j$AnS-9uO@)*&zu8X<9kMSyuuT{n%Q;mtMTmc@9F93)lWDO6tVyS literal 0 HcmV?d00001 From 300cffb9422647df83a9d9ee47df898b18afb205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 5 Nov 2023 18:54:57 +0100 Subject: [PATCH 044/128] Recommend SEQUENCE until doctrine/dbal 4 is released Using IDENTITY with doctrine/dbal 3 results in SERIAL, which is not recommended. --- UPGRADE.md | 17 +++++---- docs/en/reference/basic-mapping.rst | 14 ------- .../ORM/Mapping/ClassMetadataFactory.php | 37 +++++-------------- psalm-baseline.xml | 1 + .../ORM/Mapping/ClassMetadataFactoryTest.php | 22 +++++------ 5 files changed, 30 insertions(+), 61 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 1db52439499..f9bdc0ad9b8 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -9,16 +9,17 @@ It will be a full-fledged class, no longer extending When the `AUTO` identifier generation strategy was introduced, the best strategy at the time was selected for each database platform. -A lot of time has passed since then, and support for better strategies has been -added. +A lot of time has passed since then, and with ORM 3.0.0 and DBAL 4.0.0, support +for better strategies will be added. Because of that, it is now deprecated to rely on the historical defaults when -they differ from what we recommend now. +they differ from what we will be recommended in the future. Instead, you should pick a strategy for each database platform you use, and it will be used when using `AUTO`. As of now, only PostgreSQL is affected by this. -It is recommended that PostgreSQL user configure their new applications to use -`IDENTITY`: + +It is recommended that PostgreSQL users configure their existing and new +applications to use `SEQUENCE` until `doctrine/dbal` 4.0.0 is released: ```php use Doctrine\DBAL\Platforms\PostgreSQLPlatform; @@ -26,12 +27,12 @@ use Doctrine\ORM\Configuration; assert($configuration instanceof Configuration); $configuration->setIdentityGenerationPreferences([ - PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_IDENTITY, + PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE, ]); ``` -If migrating an existing application is too costly, the deprecation can be -addressed by configuring `SEQUENCE` as the default strategy. +When DBAL 4 is released, `AUTO` will result in `IDENTITY`, and the above +configuration should be removed to migrate to it. ## Deprecate `EntityManagerInterface::getPartialReference()` diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index 3bc4b5d33fe..66b552a1d87 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -427,20 +427,6 @@ defaults to the identifier generation mechanism your current database vendor preferred at the time that strategy was introduced: ``AUTO_INCREMENT`` with MySQL, sequences with PostgreSQL and Oracle and so on. -We now recommend using ``IDENTITY`` for PostgreSQL, and you can achieve -that while still using the ``AUTO`` strategy, by configuring what it -defaults to. - -.. code-block:: php - - setIdentityGenerationPreferences([ - PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]); .. _identifier-generation-strategies: diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 2ad71382e85..67ff0ef726e 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -34,7 +34,6 @@ use function assert; use function class_exists; -use function constant; use function count; use function end; use function explode; @@ -74,26 +73,10 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory /** @var mixed[] */ private $embeddablesActiveNesting = []; - private const LEGACY_DEFAULTS_FOR_ID_GENERATION = [ - 'Doctrine\DBAL\Platforms\MySqlPlatform' => ClassMetadata::GENERATOR_TYPE_IDENTITY, + private const NON_IDENTITY_DEFAULT_STRATEGY = [ 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => ClassMetadata::GENERATOR_TYPE_SEQUENCE, - Platforms\DB2Platform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - Platforms\MySQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, Platforms\OraclePlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, Platforms\PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, - Platforms\SQLServerPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - Platforms\SqlitePlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]; - - private const RECOMMENDED_STRATEGY = [ - 'Doctrine\DBAL\Platforms\MySqlPlatform' => 'IDENTITY', - 'Doctrine\DBAL\Platforms\PostgreSqlPlatform' => 'IDENTITY', - Platforms\DB2Platform::class => 'IDENTITY', - Platforms\MySQLPlatform::class => 'IDENTITY', - Platforms\OraclePlatform::class => 'SEQUENCE', - Platforms\PostgreSQLPlatform::class => 'IDENTITY', - Platforms\SQLServerPlatform::class => 'IDENTITY', - Platforms\SqlitePlatform::class => 'IDENTITY', ]; /** @return void */ @@ -657,7 +640,7 @@ private function completeIdGeneratorMapping(ClassMetadataInfo $class): void 'https://github.com/doctrine/orm/issues/8850', <<<'DEPRECATION' Context: Loading metadata for class %s -Problem: Using the IDENTITY generator strategy with platform "%s" is deprecated and will not be possible in Doctrine ORM 3.0. +Problem: Using identity columns emulated with a sequence is deprecated and will not be possible in Doctrine ORM 3.0. Solution: Use the SEQUENCE generator strategy instead. DEPRECATION , @@ -762,27 +745,25 @@ private function determineIdGeneratorStrategy(AbstractPlatform $platform): int } } - foreach (self::LEGACY_DEFAULTS_FOR_ID_GENERATION as $platformFamily => $strategy) { + foreach (self::NON_IDENTITY_DEFAULT_STRATEGY as $platformFamily => $strategy) { if (is_a($platform, $platformFamily)) { - $recommendedStrategyName = self::RECOMMENDED_STRATEGY[$platformFamily]; - if ($strategy !== constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $recommendedStrategyName)) { + if ($platform instanceof Platforms\PostgreSQLPlatform || is_a($platform, 'Doctrine\DBAL\Platforms\PostgreSqlPlatform')) { Deprecation::trigger( 'doctrine/orm', 'https://github.com/doctrine/orm/issues/8893', <<<'DEPRECATION' -Relying on non-optimal defaults for ID generation is deprecated. +Relying on non-optimal defaults for ID generation is deprecated, and IDENTITY +results in SERIAL, which is not recommended. Instead, configure identifier generation strategies explicitly through configuration. -We currently recommend "%s" for "%s", so you should use +We currently recommend "SEQUENCE" for "%s", so you should use $configuration->setIdentityGenerationPreferences([ - "%s" => ClassMetadata::GENERATOR_TYPE_%s, + "%s" => ClassMetadata::GENERATOR_TYPE_SEQUENCE, ]); DEPRECATION , - $recommendedStrategyName, - $platformFamily, $platformFamily, - $recommendedStrategyName + $platformFamily ); } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index bcb47d1a2be..95792770be8 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -537,6 +537,7 @@ $class $class $platformFamily + diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php index eae9e871192..bb9256a7768 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php @@ -170,37 +170,37 @@ private function setUpCmfForPlatform(AbstractPlatform $platform, array $preferen return $cmf; } - public function testRelyingOnLegacyIdGenerationDefaultsIsDeprecatedIfItResultsInASuboptimalDefault(): void + public function testRelyingOnLegacyIdGenerationDefaultsIsOKIfItResultsInTheCurrentlyRecommendedStrategyBeingUsed(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - - $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform()); + $cmf = $this->setUpCmfForPlatform(new OraclePlatform()); $cmf->setMetadataForClass($cm->name, $cm); - $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); $cmf->getMetadataFor($cm->name); } - public function testSpecifyingIdGenerationStrategyThroughConfigurationFixesTheDeprecation(): void + public function testRelyingOnLegacyIdGenerationDefaultsIsDeprecatedIfItResultsInADefaultThatWillChange(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform(), [ - PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY, - ]); + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform()); $cmf->setMetadataForClass($cm->name, $cm); - $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); $cmf->getMetadataFor($cm->name); } - public function testRelyingOnLegacyIdGenerationDefaultsIsOKIfItResultsInTheCurrentlyRecommendedStrategyBeingUsed(): void + public function testSpecifyingIdGenerationStrategyThroughConfigurationFixesTheDeprecation(): void { $cm = $this->createValidClassMetadata(); $cm->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO); - $cmf = $this->setUpCmfForPlatform(new OraclePlatform()); + + $cmf = $this->setUpCmfForPlatform(new PostgreSQLPlatform(), [ + PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_SEQUENCE, + ]); $cmf->setMetadataForClass($cm->name, $cm); $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/orm/issues/8893'); From c075154e1e4371a8a62199408b7cfd2406ecaa6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 6 Nov 2023 07:46:26 +0100 Subject: [PATCH 045/128] Restore backward compatibility with previous format When unserializing from a cache entry in the previous format, the sqlStatements need to be copied from the legacy property to the new property before the reference is created. --- lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php | 4 ++++ psalm-baseline.xml | 11 +++++++++++ .../ORM/Functional/ParserResultSerializationTest.php | 1 + 3 files changed, 16 insertions(+) diff --git a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php index 2374ad795e0..2ac9f7d59fe 100644 --- a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php @@ -89,6 +89,10 @@ public function __sleep(): array public function __wakeup(): void { + if ($this->_sqlStatements !== null && $this->sqlStatements === null) { + $this->sqlStatements = $this->_sqlStatements; + } + $this->_sqlStatements = &$this->sqlStatements; } } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 809e541b90f..d1a6cd27406 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1844,6 +1844,14 @@ + + _sqlStatements]]> + _sqlStatements]]> + + + _sqlStatements !== null && $this->sqlStatements === null]]> + sqlStatements === null]]> + null @@ -1852,6 +1860,9 @@ $queryCacheProfile $sqlStatements + + _sqlStatements !== null]]> + sqlStatements]]> diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php index 5d69c4c9209..55a9fc11b0b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -77,6 +77,7 @@ public function testUnserializeSingleSelectResult(string $serialized): void $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); $this->assertEquals(['name' => [0]], $unserialized->getParameterMappings()); $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); + $this->assertIsString($unserialized->getSqlExecutor()->getSqlStatements()); } /** @return Generator */ From 7613f25d577786621dcb05f2ebbcdcf0b1592d1c Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Fri, 3 Nov 2023 07:08:44 -0400 Subject: [PATCH 046/128] Adds metadata field type and enumType validation against Entity property type --- lib/Doctrine/ORM/Tools/SchemaValidator.php | 20 ++++++++ .../Functional/Ticket/GH11037/GH11037Test.php | 49 +++++++++++++++++++ .../Ticket/GH11037/IntEntityStatus.php | 11 +++++ .../GH11037/InvalidEntityWithTypedEnum.php | 31 ++++++++++++ .../Ticket/GH11037/StringEntityStatus.php | 11 +++++ .../GH11037/ValidEntityWithTypedEnum.php | 31 ++++++++++++ 6 files changed, 153 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index c6948aa85ff..3fd323c565a 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Tools; +use BackedEnum; use Doctrine\DBAL\Types\AsciiStringType; use Doctrine\DBAL\Types\BigIntType; use Doctrine\DBAL\Types\BooleanType; @@ -21,6 +22,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use ReflectionEnum; use ReflectionNamedType; use function array_diff; @@ -37,6 +39,7 @@ use function get_class; use function implode; use function in_array; +use function is_a; use function sprintf; use const PHP_VERSION_ID; @@ -386,6 +389,23 @@ function (array $fieldMapping) use ($class): ?string { return null; } + if ( + is_a($propertyType, BackedEnum::class, true) + && $metadataFieldType === (string) (new ReflectionEnum($propertyType))->getBackingType() + ) { + if (! isset($fieldMapping['enumType']) || $propertyType === $fieldMapping['enumType']) { + return null; + } + + return sprintf( + "The field '%s#%s' has the property type '%s' that differs from the metadata enumType '%s'.", + $class->name, + $fieldName, + $propertyType, + $fieldMapping['enumType'] + ); + } + return sprintf( "The field '%s#%s' has the property type '%s' that differs from the metadata field type '%s' returned by the '%s' DBAL type.", $class->name, diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php new file mode 100644 index 00000000000..bb173c2759c --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php @@ -0,0 +1,49 @@ += 8.1 + */ +final class GH11037Test extends OrmTestCase +{ + /** @var EntityManagerInterface */ + private $em; + + /** @var SchemaValidator */ + private $validator; + + protected function setUp(): void + { + $this->em = $this->getTestEntityManager(); + $this->validator = new SchemaValidator($this->em); + } + + public function testMetadataFieldTypeCoherentWithEntityPropertyType(): void + { + $class = $this->em->getClassMetadata(ValidEntityWithTypedEnum::class); + $ce = $this->validator->validateClass($class); + + self::assertEquals([], $ce); + } + + public function testMetadataFieldTypeNotCoherentWithEntityPropertyType(): void + { + $class = $this->em->getClassMetadata(InvalidEntityWithTypedEnum::class); + $ce = $this->validator->validateClass($class); + + self::assertEquals( + [ + "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status1' has the property type 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus' that differs from the metadata field type 'int' returned by the 'integer' DBAL type.", + "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\InvalidEntityWithTypedEnum#status2' has the property type 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\IntEntityStatus' that differs from the metadata enumType 'Doctrine\Tests\ORM\Functional\Ticket\GH11037\StringEntityStatus'.", + ], + $ce + ); + } +} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php new file mode 100644 index 00000000000..c9ac6df5a83 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php @@ -0,0 +1,11 @@ + Date: Thu, 9 Nov 2023 13:14:44 +0100 Subject: [PATCH 047/128] Deprecate annotation classes for named queries --- UPGRADE.md | 9 +++++++++ lib/Doctrine/ORM/Mapping/NamedNativeQueries.php | 2 ++ lib/Doctrine/ORM/Mapping/NamedNativeQuery.php | 2 ++ lib/Doctrine/ORM/Mapping/NamedQueries.php | 2 ++ lib/Doctrine/ORM/Mapping/NamedQuery.php | 2 ++ psalm.xml | 4 ++++ 6 files changed, 21 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index 0f5a668f4be..5ac1f28d7df 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,14 @@ # Upgrade to 2.17 +## Deprecate annotations classes for named queries + +The following classes have been deprecated: + +* `Doctrine\ORM\Mapping\NamedNativeQueries` +* `Doctrine\ORM\Mapping\NamedNativeQuery` +* `Doctrine\ORM\Mapping\NamedQueries` +* `Doctrine\ORM\Mapping\NamedQuery` + ## Deprecate `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::_sqlStatements` Use `Doctrine\ORM\Query\Exec\AbstractSqlExecutor::sqlStatements` instead. diff --git a/lib/Doctrine/ORM/Mapping/NamedNativeQueries.php b/lib/Doctrine/ORM/Mapping/NamedNativeQueries.php index bd474b4c39a..02ec6100b69 100644 --- a/lib/Doctrine/ORM/Mapping/NamedNativeQueries.php +++ b/lib/Doctrine/ORM/Mapping/NamedNativeQueries.php @@ -8,6 +8,8 @@ * Is used to specify an array of native SQL named queries. * The NamedNativeQueries annotation can be applied to an entity or mapped superclass. * + * @deprecated Named queries won't be supported in ORM 3. + * * @Annotation * @Target("CLASS") */ diff --git a/lib/Doctrine/ORM/Mapping/NamedNativeQuery.php b/lib/Doctrine/ORM/Mapping/NamedNativeQuery.php index 2970b266395..159b4962965 100644 --- a/lib/Doctrine/ORM/Mapping/NamedNativeQuery.php +++ b/lib/Doctrine/ORM/Mapping/NamedNativeQuery.php @@ -8,6 +8,8 @@ * Is used to specify a native SQL named query. * The NamedNativeQuery annotation can be applied to an entity or mapped superclass. * + * @deprecated Named queries won't be supported in ORM 3. + * * @Annotation * @Target("ANNOTATION") */ diff --git a/lib/Doctrine/ORM/Mapping/NamedQueries.php b/lib/Doctrine/ORM/Mapping/NamedQueries.php index a69810639c0..d844ab325d1 100644 --- a/lib/Doctrine/ORM/Mapping/NamedQueries.php +++ b/lib/Doctrine/ORM/Mapping/NamedQueries.php @@ -5,6 +5,8 @@ namespace Doctrine\ORM\Mapping; /** + * @deprecated Named queries won't be supported in ORM 3. + * * @Annotation * @Target("CLASS") */ diff --git a/lib/Doctrine/ORM/Mapping/NamedQuery.php b/lib/Doctrine/ORM/Mapping/NamedQuery.php index f57e8e8d80e..104cd95c7f9 100644 --- a/lib/Doctrine/ORM/Mapping/NamedQuery.php +++ b/lib/Doctrine/ORM/Mapping/NamedQuery.php @@ -5,6 +5,8 @@ namespace Doctrine\ORM\Mapping; /** + * @deprecated Named queries won't be supported in ORM 3. + * * @Annotation * @Target("ANNOTATION") */ diff --git a/psalm.xml b/psalm.xml index 8905a3c4086..a8a096c3ae4 100644 --- a/psalm.xml +++ b/psalm.xml @@ -38,6 +38,10 @@ + + + + From e8afa9f80ce66ac728f63325d102adda01cbd6ff Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 16 Nov 2023 00:04:41 +0100 Subject: [PATCH 048/128] Prepare 2.17.0 (#11059) --- .doctrine-project.json | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.doctrine-project.json b/.doctrine-project.json index e1f84c7b85d..1795e4513ac 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -11,21 +11,23 @@ "slug": "latest", "upcoming": true }, + { + "name": "2.18", + "branchName": "2.18.x", + "slug": "2.18", + "upcoming": true + }, { "name": "2.17", "branchName": "2.17.x", "slug": "2.17", - "upcoming": true + "current": true }, { "name": "2.16", "branchName": "2.16.x", "slug": "2.16", - "current": true, - "aliases": [ - "current", - "stable" - ] + "maintained": false }, { "name": "2.15", From 6be65ebc700dcf87d70811cb86110d1d1f94e3bc Mon Sep 17 00:00:00 2001 From: Albert Bakker Date: Thu, 16 Nov 2023 18:03:22 +0100 Subject: [PATCH 049/128] fix: return property names in AbstractSqlExecutor::__sleep Property names as returned by a cast to array are mangled, and that mangling is not documented. Returning unprefixed produces the same result, and is more likely to be supported by external tools relying on the documented possible return values of __sleep. For instance symfony/var-exporter does not support mangled names, which leads to issues when caching query parsing results in Symfony applications. --- .../ORM/Query/Exec/AbstractSqlExecutor.php | 6 +++- .../ParserResultSerializationTest.php | 34 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php index 2ac9f7d59fe..0348446a97c 100644 --- a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php @@ -11,7 +11,9 @@ use function array_diff; use function array_keys; +use function array_map; use function array_values; +use function str_replace; /** * Base class for SQL statement executors. @@ -84,7 +86,9 @@ public function __sleep(): array serialized representation becomes compatible with 3.0.x, meaning there will not be a deprecation warning about a missing property when unserializing data */ - return array_values(array_diff(array_keys((array) $this), ["\0*\0_sqlStatements"])); + return array_values(array_diff(array_map(static function (string $prop): string { + return str_replace("\0*\0", '', $prop); + }, array_keys((array) $this)), ['_sqlStatements'])); } public function __wakeup(): void diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php index 55a9fc11b0b..531ed5d71b6 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM\Functional; +use Closure; use Doctrine\ORM\Query; use Doctrine\ORM\Query\Exec\SingleSelectExecutor; use Doctrine\ORM\Query\ParserResult; @@ -12,6 +13,8 @@ use Generator; use ReflectionMethod; use ReflectionProperty; +use Symfony\Component\VarExporter\Instantiator; +use Symfony\Component\VarExporter\VarExporter; use function file_get_contents; use function rtrim; @@ -27,14 +30,18 @@ protected function setUp(): void parent::setUp(); } - public function testSerializeParserResult(): void + /** + * @param Closure(ParserResult): ParserResult $toSerializedAndBack + * + * @dataProvider provideToSerializedAndBack + */ + public function testSerializeParserResult(Closure $toSerializedAndBack): void { $query = $this->_em ->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u.name = :name'); $parserResult = self::parseQuery($query); - $serialized = serialize($parserResult); - $unserialized = unserialize($serialized); + $unserialized = $toSerializedAndBack($parserResult); $this->assertInstanceOf(ParserResult::class, $unserialized); $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); @@ -42,6 +49,27 @@ public function testSerializeParserResult(): void $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); } + /** @return Generator */ + public function provideToSerializedAndBack(): Generator + { + yield 'native serialization function' => [ + static function (ParserResult $parserResult): ParserResult { + return unserialize(serialize($parserResult)); + }, + ]; + + $instantiatorMethod = new ReflectionMethod(Instantiator::class, 'instantiate'); + if ($instantiatorMethod->getReturnType() === null) { + $this->markTestSkipped('symfony/var-exporter 5.4+ is required.'); + } + + yield 'symfony/var-exporter' => [ + static function (ParserResult $parserResult): ParserResult { + return eval('return ' . VarExporter::export($parserResult) . ';'); + }, + ]; + } + public function testItSerializesParserResultWithAForwardCompatibleFormat(): void { $query = $this->_em From 665ccf137632a3685901ac0ca68e3bddbabd9ca8 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Thu, 23 Nov 2023 12:42:38 +0100 Subject: [PATCH 050/128] Add failing test This test show that eager collections are broken when used in conjuction with iterating over a result. --- .../ORM/Functional/EagerFetchCollectionTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index 90cd1793a9d..cd76ee8b078 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -84,6 +84,18 @@ public function testSubselectFetchJoinWithNotAllowed(): void $query->getResult(); } + public function testEagerFetchWithIterable(): void + { + $this->createOwnerWithChildren(2); + $this->_em->flush(); + $this->_em->clear(); + + $iterable = $this->_em->getRepository(EagerFetchOwner::class)->createQueryBuilder('o')->getQuery()->toIterable(); + $owner = $iterable->current(); + + $this->assertCount(2, $owner->children); + } + protected function createOwnerWithChildren(int $children): EagerFetchOwner { $owner = new EagerFetchOwner(); From e5ab18ff802d25fe6ed20bc7011922e914d6ef38 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Thu, 23 Nov 2023 13:04:13 +0100 Subject: [PATCH 051/128] Do not defer eager loading when iterable hint is set --- lib/Doctrine/ORM/UnitOfWork.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index b1fef6d2012..0407c8455b9 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -3104,9 +3104,10 @@ public function createEntity($className, array $data, &$hints = []) $reflField->setValue($entity, $pColl); if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { - if ($assoc['type'] === ClassMetadata::ONE_TO_MANY) { + $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; + if (! $isIteration && $assoc['type'] === ClassMetadata::ONE_TO_MANY) { $this->scheduleCollectionForBatchLoading($pColl, $class); - } elseif ($assoc['type'] === ClassMetadata::MANY_TO_MANY) { + } elseif (($isIteration && $assoc['type'] === ClassMetadata::ONE_TO_MANY) || $assoc['type'] === ClassMetadata::MANY_TO_MANY) { $this->loadCollection($pColl); $pColl->takeSnapshot(); } From 212edaa80bf0669da6ccd7b4697d696e1ffceac8 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 29 Nov 2023 14:35:05 +0100 Subject: [PATCH 052/128] PHPStan 5.16.0, Symfony 7.0 (#11095) --- composer.json | 8 +++--- psalm-baseline.xml | 64 ++++++++-------------------------------------- 2 files changed, 15 insertions(+), 57 deletions(-) diff --git a/composer.json b/composer.json index eb9380419c4..7c57474aac6 100644 --- a/composer.json +++ b/composer.json @@ -46,10 +46,10 @@ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.15.0" + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "vimeo/psalm": "4.30.0 || 5.16.0" }, "conflict": { "doctrine/annotations": "<1.13 || >= 3.0" diff --git a/psalm-baseline.xml b/psalm-baseline.xml index ea6fcce0f6e..90cbc63a1c0 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + IterableResult @@ -590,7 +590,6 @@ table]]> - table]]> @@ -626,9 +625,6 @@ $quotedColumnNames namespace . '\\' . $className]]> - - __toString - FieldMapping class-string|null @@ -869,6 +865,9 @@ class-string + + $metadata + tables[$tableName]]]> tables[$tableName]]]> @@ -1730,11 +1729,6 @@ $sqlWalker - - - __toString - - $sqlWalker @@ -1942,36 +1936,15 @@ $parts - - - __toString - - - - - __toString - - - - __toString - $part - - - __toString - - arguments]]> - - __toString - ]]> @@ -1982,9 +1955,6 @@ - - __toString - conditionType]]> @@ -1994,16 +1964,6 @@ $parts - - - __toString - - - - - __toString - - $allowedClasses @@ -2017,9 +1977,6 @@ - - __toString - $value @@ -2127,9 +2084,6 @@ addNamedNativeQueryResultClassMapping addNamedNativeQueryResultSetMapping - - __toString - @@ -2192,12 +2146,18 @@ $expr + + queryComponents[$expression]]]> + string $query + + $expression + pathExpression]]> @@ -2293,9 +2253,6 @@ new ArrayCollection($parameters) - - __toString - $spacePos $spacePos @@ -2748,6 +2705,7 @@ $entityState $entityState + $object $value From 23d36c0d5293ac796f35850b4f082aef60c6fc52 Mon Sep 17 00:00:00 2001 From: Cliff Odijk Date: Fri, 1 Dec 2023 19:23:51 +0100 Subject: [PATCH 053/128] Add compatibility with the Symfony 4.4 VarExporter (#10948) --- lib/Doctrine/ORM/Query/ParserResult.php | 2 ++ .../ParserResultSerializationTest.php | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/Doctrine/ORM/Query/ParserResult.php b/lib/Doctrine/ORM/Query/ParserResult.php index e16b5ebc351..e5d36c9bbe3 100644 --- a/lib/Doctrine/ORM/Query/ParserResult.php +++ b/lib/Doctrine/ORM/Query/ParserResult.php @@ -141,7 +141,9 @@ public function __unserialize(array $data): void { foreach (self::LEGACY_PROPERTY_MAPPING as $property => $legacyProperty) { $this->$property = $data[sprintf("\0%s\0%s", self::class, $legacyProperty)] + ?? $data[self::class][$legacyProperty] ?? $data[sprintf("\0%s\0%s", self::class, $property)] + ?? $data[self::class][$property] ?? $this->$property ?? null; } diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php index 531ed5d71b6..0841c5ff3a0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php @@ -116,6 +116,25 @@ public static function provideSerializedSingleSelectResults(): Generator yield '2.17.0' => [rtrim(file_get_contents(__DIR__ . '/ParserResults/single_select_2_17_0.txt'), "\n")]; } + public function testSymfony44ProvidedData(): void + { + $sqlExecutor = $this->createMock(SingleSelectExecutor::class); + $resultSetMapping = $this->createMock(ResultSetMapping::class); + + $parserResult = new ParserResult(); + $parserResult->setSqlExecutor($sqlExecutor); + $parserResult->setResultSetMapping($resultSetMapping); + $parserResult->addParameterMapping('name', 0); + + $exported = VarExporter::export($parserResult); + $unserialized = eval('return ' . $exported . ';'); + + $this->assertInstanceOf(ParserResult::class, $unserialized); + $this->assertInstanceOf(ResultSetMapping::class, $unserialized->getResultSetMapping()); + $this->assertEquals(['name' => [0]], $unserialized->getParameterMappings()); + $this->assertInstanceOf(SingleSelectExecutor::class, $unserialized->getSqlExecutor()); + } + private static function parseQuery(Query $query): ParserResult { $r = new ReflectionMethod($query, 'parse'); From 44e943e10086255046faca106b1ac68d0a4ad238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20Nork=C5=ABnas?= Date: Sat, 2 Dec 2023 12:32:08 +0200 Subject: [PATCH 054/128] Fix JSON mapping linting against subset of builtin types (#11076) --- lib/Doctrine/ORM/Tools/SchemaValidator.php | 9 +++- .../Ticket/GH11072/GH11072EntityAdvanced.php | 26 ++++++++++++ .../Ticket/GH11072/GH11072EntityBasic.php | 39 +++++++++++++++++ .../Functional/Ticket/GH11072/GH11072Test.php | 42 +++++++++++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index 3fd323c565a..fbaf33bd01d 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -371,7 +371,7 @@ function (array $fieldMapping) use ($class): ?string { } // If the property type is not a named type, we cannot check it - if (! ($propertyType instanceof ReflectionNamedType)) { + if (! ($propertyType instanceof ReflectionNamedType) || $propertyType->getName() === 'mixed') { return null; } @@ -406,6 +406,13 @@ function (array $fieldMapping) use ($class): ?string { ); } + if ( + $fieldMapping['type'] === 'json' + && in_array($propertyType, ['string', 'int', 'float', 'bool', 'true', 'false', 'null'], true) + ) { + return null; + } + return sprintf( "The field '%s#%s' has the property type '%s' that differs from the metadata field type '%s' returned by the '%s' DBAL type.", $class->name, diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php new file mode 100644 index 00000000000..2495de40cf7 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php @@ -0,0 +1,26 @@ += 7.4 + */ +final class GH11072Test extends OrmFunctionalTestCase +{ + /** @var SchemaValidator */ + private $validator; + + protected function setUp(): void + { + $this->_em = $this->getTestEntityManager(); + $this->validator = new SchemaValidator($this->_em); + } + + public function testAcceptsSubsetOfBuiltinTypesWithoutErrors(): void + { + $class = $this->_em->getClassMetadata(GH11072EntityBasic::class); + $ce = $this->validator->validateClass($class); + + self::assertSame([], $ce); + } + + /** + * @requires PHP >= 8.2 + */ + public function testAcceptsAdvancedSubsetOfBuiltinTypesWithoutErrors(): void + { + $class = $this->_em->getClassMetadata(GH11072EntityAdvanced::class); + $ce = $this->validator->validateClass($class); + + self::assertSame([], $ce); + } +} From ed1df148c2c4a3b77bc857958c0d7a9f876a85fd Mon Sep 17 00:00:00 2001 From: flack Date: Mon, 4 Dec 2023 21:07:27 +0100 Subject: [PATCH 055/128] Fix method name in code example (#11104) --- docs/en/cookbook/resolve-target-entity-listener.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/cookbook/resolve-target-entity-listener.rst b/docs/en/cookbook/resolve-target-entity-listener.rst index e3c5550b102..04a50e56043 100644 --- a/docs/en/cookbook/resolve-target-entity-listener.rst +++ b/docs/en/cookbook/resolve-target-entity-listener.rst @@ -127,7 +127,7 @@ the targetEntity resolution will occur reliably: // Add the ResolveTargetEntityListener $evm->addEventListener(Doctrine\ORM\Events::loadClassMetadata, $rtel); - $connection = \Doctrine\DBAL\DriverManager::createConnection($connectionOptions, $config, $evm); + $connection = \Doctrine\DBAL\DriverManager::getConnection($connectionOptions, $config, $evm); $em = new \Doctrine\ORM\EntityManager($connection, $config, $evm); Final Thoughts From 46cb9a980bc9a202df09302dfa97ea03e37d7878 Mon Sep 17 00:00:00 2001 From: flaushi Date: Tue, 12 Dec 2023 14:51:31 +0100 Subject: [PATCH 056/128] Added a note parameter type for the INSTANCE OF DQL expression (#7963) Co-authored-by: flaushi --- docs/en/reference/dql-doctrine-query-language.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst index 669e74b509c..a9a7d6d3a1c 100644 --- a/docs/en/reference/dql-doctrine-query-language.rst +++ b/docs/en/reference/dql-doctrine-query-language.rst @@ -464,6 +464,11 @@ hierarchies: $query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee'); $query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1'); $query = $em->createQuery('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1'); + $query->setParameter(0, $em->getClassMetadata(CompanyEmployee::class)); + +.. note:: + To use a class as parameter, you have to bind its class metadata: + ``$query->setParameter(0, $em->getClassMetadata(CompanyEmployee::class);``. Get all users visible on a given website that have chosen certain gender: From 6af7f9f7bf6d07c8ed7332478d8fe634508a8d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=B6ller?= Date: Tue, 12 Dec 2023 16:33:54 +0100 Subject: [PATCH 057/128] Fix: Typo --- lib/Doctrine/ORM/EntityManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php index 21d2c7d3421..f7d47d7b12e 100644 --- a/lib/Doctrine/ORM/EntityManager.php +++ b/lib/Doctrine/ORM/EntityManager.php @@ -987,7 +987,7 @@ public static function create($connection, Configuration $config, ?EventManager Deprecation::trigger( 'doctrine/orm', 'https://github.com/doctrine/orm/pull/9961', - '%s() is deprecated. To boostrap a DBAL connection, call %s::getConnection() instead. Use the constructor to create an instance of %s.', + '%s() is deprecated. To bootstrap a DBAL connection, call %s::getConnection() instead. Use the constructor to create an instance of %s.', __METHOD__, DriverManager::class, self::class From 05ef1f4f967b6f6c5fa299853f0f17051c43dfdd Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Thu, 14 Dec 2023 15:21:32 -0500 Subject: [PATCH 058/128] Fixed enum mapping validation --- lib/Doctrine/ORM/Tools/SchemaValidator.php | 41 +++++++++++++++++-- .../Ticket/GH11037/EntityStatus.php | 9 ++++ .../Functional/Ticket/GH11037/GH11037Test.php | 3 +- .../GH11037/InvalidEntityWithTypedEnum.php | 5 +++ .../Ticket/GH11037/StringEntityStatus.php | 2 +- .../GH11037/ValidEntityWithTypedEnum.php | 5 +++ 6 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index fbaf33bd01d..c82e8da638a 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -39,6 +39,7 @@ use function get_class; use function implode; use function in_array; +use function interface_exists; use function is_a; use function sprintf; @@ -389,10 +390,20 @@ function (array $fieldMapping) use ($class): ?string { return null; } - if ( - is_a($propertyType, BackedEnum::class, true) - && $metadataFieldType === (string) (new ReflectionEnum($propertyType))->getBackingType() - ) { + if (is_a($propertyType, BackedEnum::class, true)) { + $backingType = (string) (new ReflectionEnum($propertyType))->getBackingType(); + + if ($metadataFieldType !== $backingType) { + return sprintf( + "The field '%s#%s' has the property type '%s' with a backing type of '%s' that differs from the metadata field type '%s'.", + $class->name, + $fieldName, + $propertyType, + $backingType, + $metadataFieldType + ); + } + if (! isset($fieldMapping['enumType']) || $propertyType === $fieldMapping['enumType']) { return null; } @@ -406,6 +417,28 @@ function (array $fieldMapping) use ($class): ?string { ); } + if ( + isset($fieldMapping['enumType']) + && $propertyType !== $fieldMapping['enumType'] + && interface_exists($propertyType) + && is_a($fieldMapping['enumType'], $propertyType, true) + ) { + $backingType = (string) (new ReflectionEnum($fieldMapping['enumType']))->getBackingType(); + + if ($metadataFieldType === $backingType) { + return null; + } + + return sprintf( + "The field '%s#%s' has the metadata enumType '%s' with a backing type of '%s' that differs from the metadata field type '%s'.", + $class->name, + $fieldName, + $fieldMapping['enumType'], + $backingType, + $metadataFieldType + ); + } + if ( $fieldMapping['type'] === 'json' && in_array($propertyType, ['string', 'int', 'float', 'bool', 'true', 'false', 'null'], true) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php new file mode 100644 index 00000000000..f94c44affe0 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php @@ -0,0 +1,9 @@ + Date: Wed, 20 Dec 2023 22:47:52 +0100 Subject: [PATCH 059/128] Allow to skip property type validation (#11130) --- .../Console/Command/ValidateSchemaCommand.php | 3 ++- lib/Doctrine/ORM/Tools/SchemaValidator.php | 10 ++++--- .../Functional/Ticket/GH10661/GH10661Test.php | 27 ++++++++++++------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php index 7c216445786..3807a81d58d 100644 --- a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php +++ b/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php @@ -31,6 +31,7 @@ protected function configure() ->addOption('em', null, InputOption::VALUE_REQUIRED, 'Name of the entity manager to operate on') ->addOption('skip-mapping', null, InputOption::VALUE_NONE, 'Skip the mapping validation check') ->addOption('skip-sync', null, InputOption::VALUE_NONE, 'Skip checking if the mapping is in sync with the database') + ->addOption('skip-property-types', null, InputOption::VALUE_NONE, 'Skip checking if property types match the Doctrine types') ->setHelp('Validate that the mapping files are correct and in sync with the database.'); } @@ -39,7 +40,7 @@ private function doExecute(InputInterface $input, OutputInterface $output): int $ui = (new SymfonyStyle($input, $output))->getErrorStyle(); $em = $this->getEntityManager($input); - $validator = new SchemaValidator($em); + $validator = new SchemaValidator($em, ! $input->getOption('skip-property-types')); $exit = 0; $ui->section('Mapping'); diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php index c82e8da638a..1ea5e688fab 100644 --- a/lib/Doctrine/ORM/Tools/SchemaValidator.php +++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php @@ -57,6 +57,9 @@ class SchemaValidator /** @var EntityManagerInterface */ private $em; + /** @var bool */ + private $validatePropertyTypes; + /** * It maps built-in Doctrine types to PHP types */ @@ -75,9 +78,10 @@ class SchemaValidator TextType::class => 'string', ]; - public function __construct(EntityManagerInterface $em) + public function __construct(EntityManagerInterface $em, bool $validatePropertyTypes = true) { - $this->em = $em; + $this->em = $em; + $this->validatePropertyTypes = $validatePropertyTypes; } /** @@ -137,7 +141,7 @@ public function validateClass(ClassMetadataInfo $class) } // PHP 7.4 introduces the ability to type properties, so we can't validate them in previous versions - if (PHP_VERSION_ID >= 70400) { + if (PHP_VERSION_ID >= 70400 && $this->validatePropertyTypes) { array_push($ce, ...$this->validatePropertiesTypes($class)); } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php index 6bc7f4a6124..04576aa2619 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php @@ -16,32 +16,36 @@ final class GH10661Test extends OrmTestCase /** @var EntityManagerInterface */ private $em; - /** @var SchemaValidator */ - private $validator; - protected function setUp(): void { - $this->em = $this->getTestEntityManager(); - $this->validator = new SchemaValidator($this->em); + $this->em = $this->getTestEntityManager(); } public function testMetadataFieldTypeNotCoherentWithEntityPropertyType(): void { $class = $this->em->getClassMetadata(InvalidEntity::class); - $ce = $this->validator->validateClass($class); + $ce = $this->bootstrapValidator()->validateClass($class); - self::assertEquals( + self::assertSame( ["The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidEntity#property1' has the property type 'float' that differs from the metadata field type 'string' returned by the 'decimal' DBAL type."], $ce ); } + public function testPropertyTypeErrorsCanBeSilenced(): void + { + $class = $this->em->getClassMetadata(InvalidEntity::class); + $ce = $this->bootstrapValidator(false)->validateClass($class); + + self::assertSame([], $ce); + } + public function testMetadataFieldTypeNotCoherentWithEntityPropertyTypeWithInheritance(): void { $class = $this->em->getClassMetadata(InvalidChildEntity::class); - $ce = $this->validator->validateClass($class); + $ce = $this->bootstrapValidator()->validateClass($class); - self::assertEquals( + self::assertSame( [ "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidChildEntity#property1' has the property type 'float' that differs from the metadata field type 'string' returned by the 'decimal' DBAL type.", "The field 'Doctrine\Tests\ORM\Functional\Ticket\GH10661\InvalidChildEntity#property2' has the property type 'int' that differs from the metadata field type 'string' returned by the 'string' DBAL type.", @@ -50,4 +54,9 @@ public function testMetadataFieldTypeNotCoherentWithEntityPropertyTypeWithInheri $ce ); } + + private function bootstrapValidator(bool $validatePropertyTypes = true): SchemaValidator + { + return new SchemaValidator($this->em, $validatePropertyTypes); + } } From 108fa30db295492f81f93545875c57c72a23061e Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 24 Nov 2023 19:31:15 +0100 Subject: [PATCH 060/128] Improve topological sort result order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR changes a detail in the commit order computation for depended-upon entities. We have a parent-child relationship between two entity classes. The association is parent one-to-many children, with the child entities containing the (owning side) back-reference. Cascade-persist is not used, so all entities have to be passed to `EntityManager::persist()`. Before v2.16.0, two child entities C1 and C2 will be inserted in the same order in which they are passed to `persist()`, and that is regardless of whether the parent entity was passed to `persist()` before or after the child entities. As of v2.16.0, passing the parent entity to `persist()` _after_ the child entities will lead to an insert order that is _reversed_ compared to the order of `persist()` calls. This PR makes the order consistent in both cases, as it was before v2.16.0. #### Cause When the parent is passed to `persist()` after the children, commit order computation has to re-arrange the entities. The parent must be inserted first since it is referred to by the children. The implementation of the topological sort from #10547 processed entities in reverse `persist()` order and unshifted finished nodes to an array to obtain the final result. That leads to dependencies (parent β†’ before c1, parent β†’ before c2) showing up in the result in the reverse order of which they were added. This PR changes the topological sort to produce a result in the opposite order ("all edges pointing left"), which helps to avoid the duplicate array order reversal. #### Discussion * This PR _does not_ change semantics of the `persist()` so that entities would (under all ciscumstances) be inserted in the order of `persist()` calls. * It fixes an unnecessary inconsistency between versions before 2.16.0 and after. In particular, it may be surprising that the insert order for the child entities depends on whether another referred-to entity (the parent) was added before or after them. * _Both_ orders (c1 before or after c2) are technically and logically correct with regard to the agreement that `commit()` is free to arrange entities in a way that allows for efficient insertion into the database. Fixes #11058. --- lib/Doctrine/ORM/Internal/TopologicalSort.php | 16 +- lib/Doctrine/ORM/UnitOfWork.php | 14 +- .../ORM/Functional/Ticket/GH11058Test.php | 146 ++++++++++++++++++ .../ORM/Internal/TopologicalSortTest.php | 76 +++++++-- 4 files changed, 223 insertions(+), 29 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php diff --git a/lib/Doctrine/ORM/Internal/TopologicalSort.php b/lib/Doctrine/ORM/Internal/TopologicalSort.php index 2bf1624ced8..aed71f3b206 100644 --- a/lib/Doctrine/ORM/Internal/TopologicalSort.php +++ b/lib/Doctrine/ORM/Internal/TopologicalSort.php @@ -7,8 +7,6 @@ use Doctrine\ORM\Internal\TopologicalSort\CycleDetectedException; use function array_keys; -use function array_reverse; -use function array_unshift; use function spl_object_id; /** @@ -93,18 +91,14 @@ public function addEdge($from, $to, bool $optional): void /** * Returns a topological sort of all nodes. When we have an edge A->B between two nodes - * A and B, then A will be listed before B in the result. + * A and B, then B will be listed before A in the result. Visually speaking, when ordering + * the nodes in the result order from left to right, all edges point to the left. * * @return list */ public function sort(): array { - /* - * When possible, keep objects in the result in the same order in which they were added as nodes. - * Since nodes are unshifted into $this->>sortResult (see the visit() method), that means we - * need to work them in array_reverse order here. - */ - foreach (array_reverse(array_keys($this->nodes)) as $oid) { + foreach (array_keys($this->nodes) as $oid) { if ($this->states[$oid] === self::NOT_VISITED) { $this->visit($oid); } @@ -147,7 +141,7 @@ private function visit(int $oid): void } // We have found a cycle and cannot break it at $edge. Best we can do - // is to retreat from the current vertex, hoping that somewhere up the + // is to backtrack from the current vertex, hoping that somewhere up the // stack this can be salvaged. $this->states[$oid] = self::NOT_VISITED; $exception->addToCycle($this->nodes[$oid]); @@ -160,6 +154,6 @@ private function visit(int $oid): void // So we're done with this vertex as well. $this->states[$oid] = self::VISITED; - array_unshift($this->sortResult, $this->nodes[$oid]); + $this->sortResult[] = $this->nodes[$oid]; } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index b1fef6d2012..b3285a8845c 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1378,9 +1378,10 @@ private function computeInsertExecutionOrder(): array $joinColumns = reset($assoc['joinColumns']); $isNullable = ! isset($joinColumns['nullable']) || $joinColumns['nullable']; - // Add dependency. The dependency direction implies that "$targetEntity has to go before $entity", - // so we can work through the topo sort result from left to right (with all edges pointing right). - $sort->addEdge($targetEntity, $entity, $isNullable); + // Add dependency. The dependency direction implies that "$entity depends on $targetEntity". The + // topological sort result will output the depended-upon nodes first, which means we can insert + // entities in that order. + $sort->addEdge($entity, $targetEntity, $isNullable); } } @@ -1432,9 +1433,10 @@ private function computeDeleteExecutionOrder(): array continue; } - // Add dependency. The dependency direction implies that "$entity has to be removed before $targetEntity", - // so we can work through the topo sort result from left to right (with all edges pointing right). - $sort->addEdge($entity, $targetEntity, false); + // Add dependency. The dependency direction implies that "$targetEntity depends on $entity + // being deleted first". The topological sort will output the depended-upon nodes first, + // so we can work through the result in the returned order. + $sort->addEdge($targetEntity, $entity, false); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php new file mode 100644 index 00000000000..a40ef8c2763 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php @@ -0,0 +1,146 @@ +setUpEntitySchema([ + GH11058Parent::class, + GH11058Child::class, + ]); + } + + public function testChildrenInsertedInOrderOfPersistCalls1WhenParentPersistedLast(): void + { + [$parent, $child1, $child2] = $this->createParentWithTwoChildEntities(); + + $this->_em->persist($child1); + $this->_em->persist($child2); + $this->_em->persist($parent); + $this->_em->flush(); + + self::assertTrue($child1->id < $child2->id); + } + + public function testChildrenInsertedInOrderOfPersistCalls2WhenParentPersistedLast(): void + { + [$parent, $child1, $child2] = $this->createParentWithTwoChildEntities(); + + $this->_em->persist($child2); + $this->_em->persist($child1); + $this->_em->persist($parent); + $this->_em->flush(); + + self::assertTrue($child2->id < $child1->id); + } + + public function testChildrenInsertedInOrderOfPersistCalls1WhenParentPersistedFirst(): void + { + [$parent, $child1, $child2] = $this->createParentWithTwoChildEntities(); + + $this->_em->persist($parent); + $this->_em->persist($child1); + $this->_em->persist($child2); + $this->_em->flush(); + + self::assertTrue($child1->id < $child2->id); + } + + public function testChildrenInsertedInOrderOfPersistCalls2WhenParentPersistedFirst(): void + { + [$parent, $child1, $child2] = $this->createParentWithTwoChildEntities(); + + $this->_em->persist($parent); + $this->_em->persist($child2); + $this->_em->persist($child1); + $this->_em->flush(); + + self::assertTrue($child2->id < $child1->id); + } + + private function createParentWithTwoChildEntities(): array + { + $parent = new GH11058Parent(); + $child1 = new GH11058Child(); + $child2 = new GH11058Child(); + + $parent->addChild($child1); + $parent->addChild($child2); + + return [$parent, $child1, $child2]; + } +} + +/** + * @ORM\Entity() + */ +class GH11058Parent +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\OneToMany(targetEntity="GH11058Child", mappedBy="parent") + * + * @var Collection + */ + public $children; + + public function __construct() + { + $this->children = new ArrayCollection(); + } + + public function addChild(GH11058Child $child): void + { + if (! $this->children->contains($child)) { + $this->children->add($child); + $child->setParent($this); + } + } +} + +/** + * @ORM\Entity() + */ +class GH11058Child +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\ManyToOne(targetEntity="GH11058Parent", inversedBy="children") + * + * @var GH11058Parent + */ + public $parent; + + public function setParent(GH11058Parent $parent): void + { + $this->parent = $parent; + $parent->addChild($this); + } +} diff --git a/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php b/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php index bba00d2d44e..d0dd9178c15 100644 --- a/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php +++ b/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php @@ -34,7 +34,7 @@ public function testSimpleOrdering(): void $this->addEdge('E', 'A'); // There is only 1 valid ordering for this constellation - self::assertSame(['E', 'A', 'B', 'C'], $this->computeResult()); + self::assertSame(['C', 'B', 'A', 'E'], $this->computeResult()); } public function testSkipOptionalEdgeToBreakCycle(): void @@ -44,7 +44,7 @@ public function testSkipOptionalEdgeToBreakCycle(): void $this->addEdge('A', 'B', true); $this->addEdge('B', 'A', false); - self::assertSame(['B', 'A'], $this->computeResult()); + self::assertSame(['A', 'B'], $this->computeResult()); } public function testBreakCycleByBacktracking(): void @@ -57,7 +57,7 @@ public function testBreakCycleByBacktracking(): void $this->addEdge('D', 'A'); // closes the cycle // We can only break B -> C, so the result must be C -> D -> A -> B - self::assertSame(['C', 'D', 'A', 'B'], $this->computeResult()); + self::assertSame(['B', 'A', 'D', 'C'], $this->computeResult()); } public function testCycleRemovedByEliminatingLastOptionalEdge(): void @@ -75,7 +75,7 @@ public function testCycleRemovedByEliminatingLastOptionalEdge(): void $this->addEdge('B', 'D', true); $this->addEdge('D', 'A'); - self::assertSame(['C', 'D', 'A', 'B'], $this->computeResult()); + self::assertSame(['B', 'A', 'C', 'D'], $this->computeResult()); } public function testGH7180Example(): void @@ -89,7 +89,7 @@ public function testGH7180Example(): void $this->addEdge('F', 'E'); $this->addEdge('E', 'D'); - self::assertSame(['F', 'E', 'D', 'G'], $this->computeResult()); + self::assertSame(['G', 'D', 'E', 'F'], $this->computeResult()); } public function testCommitOrderingFromGH7259Test(): void @@ -106,9 +106,9 @@ public function testCommitOrderingFromGH7259Test(): void // the D -> A -> B ordering is important to break the cycle // on the nullable link. $correctOrders = [ - ['D', 'A', 'B', 'C'], - ['D', 'A', 'C', 'B'], - ['D', 'C', 'A', 'B'], + ['C', 'B', 'A', 'D'], + ['B', 'C', 'A', 'D'], + ['B', 'A', 'C', 'D'], ]; self::assertContains($this->computeResult(), $correctOrders); @@ -124,12 +124,12 @@ public function testCommitOrderingFromGH8349Case1Test(): void $this->addEdge('B', 'C', true); $this->addEdge('C', 'D', true); - // Many orderings are possible here, but the bottom line is D must be before A (it's the only hard requirement). + // Many orderings are possible here, but the bottom line is A must be before D (it's the only hard requirement). $result = $this->computeResult(); $indexA = array_search('A', $result, true); $indexD = array_search('D', $result, true); - self::assertTrue($indexD < $indexA); + self::assertTrue($indexD > $indexA); } public function testCommitOrderingFromGH8349Case2Test(): void @@ -141,7 +141,7 @@ public function testCommitOrderingFromGH8349Case2Test(): void $this->addEdge('A', 'B', true); // The B -> A requirement determines the result here - self::assertSame(['B', 'A'], $this->computeResult()); + self::assertSame(['A', 'B'], $this->computeResult()); } public function testNodesMaintainOrderWhenNoDepencency(): void @@ -153,6 +153,58 @@ public function testNodesMaintainOrderWhenNoDepencency(): void self::assertSame(['A', 'B', 'C'], $this->computeResult()); } + public function testNodesReturnedInDepthFirstOrder(): void + { + $this->addNodes('A', 'B', 'C'); + $this->addEdge('A', 'B'); + $this->addEdge('A', 'C'); + + // We start on A and find that it has two dependencies on B and C, + // added (as dependencies) in that order. + // So, first we continue the DFS on B, because that edge was added first. + // This gives the result order B, C, A. + self::assertSame(['B', 'C', 'A'], $this->computeResult()); + } + + public function testNodesReturnedInDepthFirstOrderWithEdgesInDifferentOrderThanNodes(): void + { + $this->addNodes('A', 'B', 'C'); + $this->addEdge('A', 'C'); + $this->addEdge('A', 'B'); + + // This is like testNodesReturnedInDepthFirstOrder, but it shows that for the two + // nodes B and C that A depends upon, the result will follow the order in which + // the edges were added. + self::assertSame(['C', 'B', 'A'], $this->computeResult()); + } + + public function testNodesReturnedInDepthFirstOrderWithDependingNodeLast(): void + { + $this->addNodes('B', 'C', 'A'); + $this->addEdge('A', 'B'); + $this->addEdge('A', 'C'); + + // This again is like testNodesReturnedInDepthFirstOrder, but this + // time the node A that depends on B and C is added as the last node. + // That means processing can go over B and C in the order they were given. + // The order in which edges are added is not relevant (!), since at the time + // the edges are evaluated, the nodes they point to have already been finished. + self::assertSame(['B', 'C', 'A'], $this->computeResult()); + } + + public function testNodesReturnedInDepthFirstOrderWithDependingNodeLastAndEdgeOrderInversed(): void + { + $this->addNodes('B', 'C', 'A'); + $this->addEdge('A', 'C'); + $this->addEdge('A', 'B'); + + // This again is like testNodesReturnedInDepthFirstOrderWithDependingNodeLast, but adds + // the edges in the opposing order. Still, the result order is the same (!). + // This may be surprising when comparing with testNodesReturnedInDepthFirstOrderWithEdgesInDifferentOrderThanNodes, + // where the result order depends upon the _edge_ order. + self::assertSame(['B', 'C', 'A'], $this->computeResult()); + } + public function testDetectSmallCycle(): void { $this->addNodes('A', 'B'); @@ -205,7 +257,7 @@ public function testDetectLargerCycleNotIncludingStartNode(): void $this->computeResult(); } catch (CycleDetectedException $exception) { self::assertEquals( - [$this->nodes['D'], $this->nodes['B'], $this->nodes['C'], $this->nodes['D']], + [$this->nodes['B'], $this->nodes['C'], $this->nodes['D'], $this->nodes['B']], $exception->getCycle() ); } From 85d78f8b0d800be0cdae345893c1928c979b618e Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 22 Dec 2023 17:13:11 +0100 Subject: [PATCH 061/128] Mention in the limitations that private field names cannot be reused --- .../reference/limitations-and-known-issues.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/en/reference/limitations-and-known-issues.rst b/docs/en/reference/limitations-and-known-issues.rst index eb0b667ab60..09b6e0ee578 100644 --- a/docs/en/reference/limitations-and-known-issues.rst +++ b/docs/en/reference/limitations-and-known-issues.rst @@ -1,10 +1,10 @@ Limitations and Known Issues ============================ -We try to make using Doctrine2 a very pleasant experience. +We try to make using Doctrine ORM a very pleasant experience. Therefore we think it is very important to be honest about the current limitations to our users. Much like every other piece of -software Doctrine2 is not perfect and far from feature complete. +software the ORM is not perfect and far from feature complete. This section should give you an overview of current limitations of Doctrine ORM as well as critical known issues that you should know about. @@ -175,6 +175,18 @@ due to complexity. XML mapping configuration probably needs to completely re-configure or otherwise copy-and-paste configuration for fields used from traits. +Mapping multiple private fields of the same name +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When two classes, say a mapped superclass and an entity inheriting from it, +both contain a ``private`` field of the same name, this will lead to a ``MappingException``. + +Since the fields are ``private``, both are technically separate and can contain +different values at the same time. However, the ``ClassMetadata`` configuration used +internally by the ORM currently refers to fields by their name only, without taking the +class containing the field into consideration. This makes it impossible to keep separate +mapping configuration for both fields. + Known Issues ------------ From ebb101009c63f49614296df90235b26924255080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 28 Dec 2023 19:55:46 +0100 Subject: [PATCH 062/128] Remove inheritance Spotted while trying to merge https://github.com/doctrine/orm/pull/11076 (among other things) up into 3.0.x. On that branch, it is no longer possible for an entity to extend another entity without specifying an inheritance mapping type. I think the goal of that inheritance was just to reuse the identifier anyway, so let's just duplicate the identifier declaration instead. --- .../Ticket/GH11072/GH11072EntityAdvanced.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php index 2495de40cf7..4ca0dd0ef7f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php @@ -6,12 +6,22 @@ use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Id; /** * @Entity */ -class GH11072EntityAdvanced extends GH11072EntityBasic +class GH11072EntityAdvanced { + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + * @var int + */ + public $id; + /** @Column(type="json") */ public mixed $anything; From 073f2aa891249e582e63320cab34b035b591cf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 2 Jan 2024 19:28:09 +0100 Subject: [PATCH 063/128] Flatten directory tree It will make fuzzy matchers more efficient, and configuration files more readable. - lib/Doctrine/ORM becomes just src - tests/Doctrine/ becomes just tests --- CONTRIBUTING.md | 4 +- UPGRADE.md | 2 +- ci/github/phpunit/mysqli.xml | 2 +- ci/github/phpunit/pdo_mysql.xml | 2 +- ci/github/phpunit/pdo_pgsql.xml | 2 +- ci/github/phpunit/pdo_sqlite.xml | 2 +- ci/github/phpunit/pgsql.xml | 2 +- ci/github/phpunit/sqlite3.xml | 2 +- composer.json | 8 +- docs/en/reference/events.rst | 26 +- phpbench.json | 4 +- phpcs.xml.dist | 246 +++++------ phpstan-baseline.neon | 256 +++++------ phpstan-dbal2.neon | 30 +- phpstan-params.neon | 6 +- phpstan-persistence2.neon | 20 +- phpstan.neon | 26 +- phpunit.xml.dist | 4 +- psalm-baseline.xml | 408 +++++++++--------- psalm.xml | 88 ++-- {lib/Doctrine/ORM => src}/AbstractQuery.php | 0 {lib/Doctrine/ORM => src}/Cache.php | 0 .../Cache/AssociationCacheEntry.php | 0 .../ORM => src}/Cache/CacheConfiguration.php | 0 .../Doctrine/ORM => src}/Cache/CacheEntry.php | 0 .../ORM => src}/Cache/CacheException.php | 0 .../ORM => src}/Cache/CacheFactory.php | 0 {lib/Doctrine/ORM => src}/Cache/CacheKey.php | 0 .../Cache/CollectionCacheEntry.php | 0 .../ORM => src}/Cache/CollectionCacheKey.php | 0 .../ORM => src}/Cache/CollectionHydrator.php | 0 .../ORM => src}/Cache/ConcurrentRegion.php | 0 .../ORM => src}/Cache/DefaultCache.php | 0 .../ORM => src}/Cache/DefaultCacheFactory.php | 0 .../Cache/DefaultCollectionHydrator.php | 0 .../Cache/DefaultEntityHydrator.php | 0 .../ORM => src}/Cache/DefaultQueryCache.php | 0 .../ORM => src}/Cache/EntityCacheEntry.php | 0 .../ORM => src}/Cache/EntityCacheKey.php | 0 .../ORM => src}/Cache/EntityHydrator.php | 0 .../Cache/Exception/CacheException.php | 0 .../CannotUpdateReadOnlyCollection.php | 0 .../Exception/CannotUpdateReadOnlyEntity.php | 0 .../Cache/Exception/FeatureNotImplemented.php | 0 .../Exception/InvalidResultCacheDriver.php | 0 .../Exception/MetadataCacheNotConfigured.php | 0 .../MetadataCacheUsesNonPersistentCache.php | 0 .../Cache/Exception/NonCacheableEntity.php | 0 .../NonCacheableEntityAssociation.php | 0 .../Exception/QueryCacheNotConfigured.php | 0 .../QueryCacheUsesNonPersistentCache.php | 0 {lib/Doctrine/ORM => src}/Cache/Lock.php | 0 .../ORM => src}/Cache/LockException.php | 0 .../ORM => src}/Cache/Logging/CacheLogger.php | 0 .../Cache/Logging/CacheLoggerChain.php | 0 .../Cache/Logging/StatisticsCacheLogger.php | 0 .../ORM => src}/Cache/MultiGetRegion.php | 0 .../Cache/Persister/CachedPersister.php | 0 .../AbstractCollectionPersister.php | 0 .../Collection/CachedCollectionPersister.php | 0 ...rictReadWriteCachedCollectionPersister.php | 0 .../ReadOnlyCachedCollectionPersister.php | 0 .../ReadWriteCachedCollectionPersister.php | 0 .../Entity/AbstractEntityPersister.php | 0 .../Entity/CachedEntityPersister.php | 0 ...onStrictReadWriteCachedEntityPersister.php | 0 .../Entity/ReadOnlyCachedEntityPersister.php | 0 .../Entity/ReadWriteCachedEntityPersister.php | 0 .../Doctrine/ORM => src}/Cache/QueryCache.php | 0 .../ORM => src}/Cache/QueryCacheEntry.php | 0 .../ORM => src}/Cache/QueryCacheKey.php | 0 .../ORM => src}/Cache/QueryCacheValidator.php | 0 {lib/Doctrine/ORM => src}/Cache/Region.php | 0 .../Cache/Region/DefaultMultiGetRegion.php | 0 .../Cache/Region/DefaultRegion.php | 0 .../Cache/Region/FileLockRegion.php | 0 .../Cache/Region/UpdateTimestampCache.php | 0 .../Cache/RegionsConfiguration.php | 0 .../ORM => src}/Cache/TimestampCacheEntry.php | 0 .../ORM => src}/Cache/TimestampCacheKey.php | 0 .../Cache/TimestampQueryCacheValidator.php | 0 .../ORM => src}/Cache/TimestampRegion.php | 0 {lib/Doctrine/ORM => src}/Configuration.php | 0 .../Decorator/EntityManagerDecorator.php | 0 {lib/Doctrine/ORM => src}/EntityManager.php | 0 .../ORM => src}/EntityManagerInterface.php | 0 .../ORM => src}/EntityNotFoundException.php | 0 .../Doctrine/ORM => src}/EntityRepository.php | 0 .../ORM => src}/Event/LifecycleEventArgs.php | 0 .../ORM => src}/Event/ListenersInvoker.php | 0 .../Event/LoadClassMetadataEventArgs.php | 0 .../OnClassMetadataNotFoundEventArgs.php | 0 .../ORM => src}/Event/OnClearEventArgs.php | 0 .../ORM => src}/Event/OnFlushEventArgs.php | 0 .../ORM => src}/Event/PostFlushEventArgs.php | 0 .../ORM => src}/Event/PostLoadEventArgs.php | 0 .../Event/PostPersistEventArgs.php | 0 .../ORM => src}/Event/PostRemoveEventArgs.php | 0 .../ORM => src}/Event/PostUpdateEventArgs.php | 0 .../ORM => src}/Event/PreFlushEventArgs.php | 0 .../ORM => src}/Event/PrePersistEventArgs.php | 0 .../ORM => src}/Event/PreRemoveEventArgs.php | 0 .../ORM => src}/Event/PreUpdateEventArgs.php | 0 {lib/Doctrine/ORM => src}/Events.php | 0 .../Exception/ConfigurationException.php | 0 .../EntityIdentityCollisionException.php | 0 .../Exception/EntityManagerClosed.php | 0 .../Exception/EntityMissingAssignedId.php | 0 .../Exception/InvalidEntityRepository.php | 0 .../Exception/InvalidHydrationMode.php | 0 .../Exception/ManagerException.php | 0 .../Exception/MismatchedEventManager.php | 0 .../Exception/MissingIdentifierField.php | 0 .../MissingMappingDriverImplementation.php | 0 .../MultipleSelectorsFoundException.php | 0 .../Exception/NamedNativeQueryNotFound.php | 0 .../Exception/NamedQueryNotFound.php | 0 .../ORM => src}/Exception/NotSupported.php | 0 .../ORM => src}/Exception/ORMException.php | 0 .../Exception/PersisterException.php | 0 .../ProxyClassesAlwaysRegenerating.php | 0 .../Exception/RepositoryException.php | 0 .../Exception/SchemaToolException.php | 0 .../Exception/UnexpectedAssociationValue.php | 0 .../Exception/UnknownEntityNamespace.php | 0 .../UnrecognizedIdentifierFields.php | 0 .../ORM => src}/Id/AbstractIdGenerator.php | 0 .../ORM => src}/Id/AssignedGenerator.php | 0 .../Id/BigIntegerIdentityGenerator.php | 0 .../ORM => src}/Id/IdentityGenerator.php | 0 .../ORM => src}/Id/SequenceGenerator.php | 0 .../ORM => src}/Id/TableGenerator.php | 0 .../Doctrine/ORM => src}/Id/UuidGenerator.php | 0 .../Internal/Hydration/AbstractHydrator.php | 0 .../Internal/Hydration/ArrayHydrator.php | 0 .../Internal/Hydration/HydrationException.php | 0 .../Internal/Hydration/IterableResult.php | 0 .../Internal/Hydration/ObjectHydrator.php | 0 .../Hydration/ScalarColumnHydrator.php | 0 .../Internal/Hydration/ScalarHydrator.php | 0 .../Hydration/SimpleObjectHydrator.php | 0 .../Hydration/SingleScalarHydrator.php | 0 .../Internal/HydrationCompleteHandler.php | 0 .../ORM => src}/Internal/SQLResultCasing.php | 0 .../ORM => src}/Internal/TopologicalSort.php | 0 .../CycleDetectedException.php | 0 .../ORM => src}/LazyCriteriaCollection.php | 0 .../ORM => src}/Mapping/Annotation.php | 0 .../ORM => src}/Mapping/AnsiQuoteStrategy.php | 0 .../Mapping/AssociationOverride.php | 0 .../Mapping/AssociationOverrides.php | 0 .../ORM => src}/Mapping/AttributeOverride.php | 0 .../Mapping/AttributeOverrides.php | 0 .../Mapping/Builder/AssociationBuilder.php | 0 .../Mapping/Builder/ClassMetadataBuilder.php | 0 .../Mapping/Builder/EmbeddedBuilder.php | 0 .../Mapping/Builder/EntityListenerBuilder.php | 0 .../Mapping/Builder/FieldBuilder.php | 0 .../Builder/ManyToManyAssociationBuilder.php | 0 .../Builder/OneToManyAssociationBuilder.php | 0 {lib/Doctrine/ORM => src}/Mapping/Cache.php | 0 .../Mapping/ChainTypedFieldMapper.php | 0 .../Mapping/ChangeTrackingPolicy.php | 0 .../ORM => src}/Mapping/ClassMetadata.php | 0 .../Mapping/ClassMetadataFactory.php | 0 .../ORM => src}/Mapping/ClassMetadataInfo.php | 0 {lib/Doctrine/ORM => src}/Mapping/Column.php | 0 .../ORM => src}/Mapping/ColumnResult.php | 0 .../ORM => src}/Mapping/CustomIdGenerator.php | 0 .../Mapping/DefaultEntityListenerResolver.php | 0 .../Mapping/DefaultNamingStrategy.php | 0 .../Mapping/DefaultQuoteStrategy.php | 0 .../Mapping/DefaultTypedFieldMapper.php | 0 .../Mapping/DiscriminatorColumn.php | 0 .../ORM => src}/Mapping/DiscriminatorMap.php | 0 .../Mapping/Driver/AnnotationDriver.php | 0 .../Mapping/Driver/AttributeDriver.php | 0 .../Mapping/Driver/AttributeReader.php | 0 .../Driver/CompatibilityAnnotationDriver.php | 0 .../Mapping/Driver/DatabaseDriver.php | 0 .../Mapping/Driver/DriverChain.php | 0 .../ORM => src}/Mapping/Driver/PHPDriver.php | 0 .../Mapping/Driver/ReflectionBasedDriver.php | 0 .../Driver/RepeatableAttributeCollection.php | 0 .../Mapping/Driver/SimplifiedXmlDriver.php | 0 .../Mapping/Driver/SimplifiedYamlDriver.php | 0 .../Mapping/Driver/StaticPHPDriver.php | 0 .../ORM => src}/Mapping/Driver/XmlDriver.php | 2 +- .../ORM => src}/Mapping/Driver/YamlDriver.php | 0 .../ORM => src}/Mapping/Embeddable.php | 0 .../Doctrine/ORM => src}/Mapping/Embedded.php | 0 {lib/Doctrine/ORM => src}/Mapping/Entity.php | 0 .../Mapping/EntityListenerResolver.php | 0 .../ORM => src}/Mapping/EntityListeners.php | 0 .../ORM => src}/Mapping/EntityResult.php | 0 .../Mapping/Exception/CannotGenerateIds.php | 0 .../Exception/InvalidCustomGenerator.php | 0 .../Exception/UnknownGeneratorType.php | 0 .../ORM => src}/Mapping/FieldResult.php | 0 .../ORM => src}/Mapping/GeneratedValue.php | 0 .../Mapping/HasLifecycleCallbacks.php | 0 {lib/Doctrine/ORM => src}/Mapping/Id.php | 0 {lib/Doctrine/ORM => src}/Mapping/Index.php | 0 .../ORM => src}/Mapping/InheritanceType.php | 0 .../ORM => src}/Mapping/InverseJoinColumn.php | 0 .../ORM => src}/Mapping/JoinColumn.php | 0 .../Mapping/JoinColumnProperties.php | 0 .../ORM => src}/Mapping/JoinColumns.php | 0 .../ORM => src}/Mapping/JoinTable.php | 0 .../ORM => src}/Mapping/ManyToMany.php | 0 .../ORM => src}/Mapping/ManyToOne.php | 0 .../ORM => src}/Mapping/MappedSuperclass.php | 0 .../ORM => src}/Mapping/MappingAttribute.php | 0 .../ORM => src}/Mapping/MappingException.php | 0 .../Mapping/NamedNativeQueries.php | 0 .../ORM => src}/Mapping/NamedNativeQuery.php | 0 .../ORM => src}/Mapping/NamedQueries.php | 0 .../ORM => src}/Mapping/NamedQuery.php | 0 .../ORM => src}/Mapping/NamingStrategy.php | 0 .../ORM => src}/Mapping/OneToMany.php | 0 .../Doctrine/ORM => src}/Mapping/OneToOne.php | 0 {lib/Doctrine/ORM => src}/Mapping/OrderBy.php | 0 .../Doctrine/ORM => src}/Mapping/PostLoad.php | 0 .../ORM => src}/Mapping/PostPersist.php | 0 .../ORM => src}/Mapping/PostRemove.php | 0 .../ORM => src}/Mapping/PostUpdate.php | 0 .../Doctrine/ORM => src}/Mapping/PreFlush.php | 0 .../ORM => src}/Mapping/PrePersist.php | 0 .../ORM => src}/Mapping/PreRemove.php | 0 .../ORM => src}/Mapping/PreUpdate.php | 0 .../ORM => src}/Mapping/QuoteStrategy.php | 0 .../Reflection/ReflectionPropertiesGetter.php | 0 .../Mapping/ReflectionEmbeddedProperty.php | 0 .../Mapping/ReflectionEnumProperty.php | 0 .../Mapping/ReflectionReadonlyProperty.php | 0 .../ORM => src}/Mapping/SequenceGenerator.php | 0 .../Mapping/SqlResultSetMapping.php | 0 .../Mapping/SqlResultSetMappings.php | 0 {lib/Doctrine/ORM => src}/Mapping/Table.php | 0 .../ORM => src}/Mapping/TypedFieldMapper.php | 0 .../Mapping/UnderscoreNamingStrategy.php | 0 .../ORM => src}/Mapping/UniqueConstraint.php | 0 {lib/Doctrine/ORM => src}/Mapping/Version.php | 0 {lib/Doctrine/ORM => src}/NativeQuery.php | 0 .../ORM => src}/NoResultException.php | 0 .../ORM => src}/NonUniqueResultException.php | 0 {lib/Doctrine/ORM => src}/ORMException.php | 0 .../ORMInvalidArgumentException.php | 0 {lib/Doctrine/ORM => src}/ORMSetup.php | 0 .../ORM => src}/OptimisticLockException.php | 0 .../ORM => src}/PersistentCollection.php | 0 .../AbstractCollectionPersister.php | 0 .../Collection/CollectionPersister.php | 0 .../Collection/ManyToManyPersister.php | 0 .../Collection/OneToManyPersister.php | 0 .../AbstractEntityInheritancePersister.php | 0 .../Entity/BasicEntityPersister.php | 0 .../Entity/CachedPersisterContext.php | 0 .../Persisters/Entity/EntityPersister.php | 0 .../Entity/JoinedSubclassPersister.php | 0 .../Entity/SingleTablePersister.php | 0 .../CantUseInOperatorOnCompositeKeys.php | 0 .../Exception/InvalidOrientation.php | 0 .../Exception/UnrecognizedField.php | 0 ...MatchingAssociationFieldRequiresObject.php | 0 .../Persisters/PersisterException.php | 0 .../Persisters/SqlExpressionVisitor.php | 0 .../Persisters/SqlValueVisitor.php | 0 .../ORM => src}/PessimisticLockException.php | 0 .../Doctrine/ORM => src}/Proxy/Autoloader.php | 0 .../Proxy/DefaultProxyClassNameResolver.php | 0 .../ORM => src}/Proxy/InternalProxy.php | 0 {lib/Doctrine/ORM => src}/Proxy/Proxy.php | 0 .../ORM => src}/Proxy/ProxyFactory.php | 0 {lib/Doctrine/ORM => src}/Query.php | 0 .../ORM => src}/Query/AST/ASTException.php | 0 .../Query/AST/AggregateExpression.php | 0 .../Query/AST/ArithmeticExpression.php | 0 .../Query/AST/ArithmeticFactor.php | 0 .../ORM => src}/Query/AST/ArithmeticTerm.php | 0 .../Query/AST/BetweenExpression.php | 0 .../Query/AST/CoalesceExpression.php | 0 .../Query/AST/CollectionMemberExpression.php | 0 .../Query/AST/ComparisonExpression.php | 0 .../Query/AST/ConditionalExpression.php | 0 .../Query/AST/ConditionalFactor.php | 0 .../Query/AST/ConditionalPrimary.php | 0 .../ORM => src}/Query/AST/ConditionalTerm.php | 0 .../ORM => src}/Query/AST/DeleteClause.php | 0 .../ORM => src}/Query/AST/DeleteStatement.php | 0 .../EmptyCollectionComparisonExpression.php | 0 .../Query/AST/ExistsExpression.php | 0 .../ORM => src}/Query/AST/FromClause.php | 0 .../Query/AST/Functions/AbsFunction.php | 0 .../Query/AST/Functions/AvgFunction.php | 0 .../Query/AST/Functions/BitAndFunction.php | 0 .../Query/AST/Functions/BitOrFunction.php | 0 .../Query/AST/Functions/ConcatFunction.php | 0 .../Query/AST/Functions/CountFunction.php | 0 .../AST/Functions/CurrentDateFunction.php | 0 .../AST/Functions/CurrentTimeFunction.php | 0 .../Functions/CurrentTimestampFunction.php | 0 .../Query/AST/Functions/DateAddFunction.php | 0 .../Query/AST/Functions/DateDiffFunction.php | 0 .../Query/AST/Functions/DateSubFunction.php | 0 .../Query/AST/Functions/FunctionNode.php | 0 .../Query/AST/Functions/IdentityFunction.php | 0 .../Query/AST/Functions/LengthFunction.php | 0 .../Query/AST/Functions/LocateFunction.php | 0 .../Query/AST/Functions/LowerFunction.php | 0 .../Query/AST/Functions/MaxFunction.php | 0 .../Query/AST/Functions/MinFunction.php | 0 .../Query/AST/Functions/ModFunction.php | 0 .../Query/AST/Functions/SizeFunction.php | 0 .../Query/AST/Functions/SqrtFunction.php | 0 .../Query/AST/Functions/SubstringFunction.php | 0 .../Query/AST/Functions/SumFunction.php | 0 .../Query/AST/Functions/TrimFunction.php | 0 .../Query/AST/Functions/UpperFunction.php | 0 .../Query/AST/GeneralCaseExpression.php | 0 .../ORM => src}/Query/AST/GroupByClause.php | 0 .../ORM => src}/Query/AST/HavingClause.php | 0 .../AST/IdentificationVariableDeclaration.php | 0 .../ORM => src}/Query/AST/InExpression.php | 0 .../Query/AST/InListExpression.php | 0 .../Query/AST/InSubselectExpression.php | 0 .../ORM => src}/Query/AST/IndexBy.php | 0 .../ORM => src}/Query/AST/InputParameter.php | 0 .../Query/AST/InstanceOfExpression.php | 0 {lib/Doctrine/ORM => src}/Query/AST/Join.php | 0 .../Query/AST/JoinAssociationDeclaration.php | 0 .../AST/JoinAssociationPathExpression.php | 0 .../Query/AST/JoinClassPathExpression.php | 0 .../Query/AST/JoinVariableDeclaration.php | 0 .../ORM => src}/Query/AST/LikeExpression.php | 0 .../ORM => src}/Query/AST/Literal.php | 0 .../Query/AST/NewObjectExpression.php | 0 {lib/Doctrine/ORM => src}/Query/AST/Node.php | 0 .../Query/AST/NullComparisonExpression.php | 0 .../Query/AST/NullIfExpression.php | 0 .../ORM => src}/Query/AST/OrderByClause.php | 0 .../ORM => src}/Query/AST/OrderByItem.php | 0 .../Query/AST/ParenthesisExpression.php | 0 .../Query/AST/PartialObjectExpression.php | 0 .../ORM => src}/Query/AST/PathExpression.php | 0 .../AST/Phase2OptimizableConditional.php | 0 .../Query/AST/QuantifiedExpression.php | 0 .../Query/AST/RangeVariableDeclaration.php | 0 .../ORM => src}/Query/AST/SelectClause.php | 0 .../Query/AST/SelectExpression.php | 0 .../ORM => src}/Query/AST/SelectStatement.php | 0 .../Query/AST/SimpleArithmeticExpression.php | 0 .../Query/AST/SimpleCaseExpression.php | 0 .../Query/AST/SimpleSelectClause.php | 0 .../Query/AST/SimpleSelectExpression.php | 0 .../Query/AST/SimpleWhenClause.php | 0 .../ORM => src}/Query/AST/Subselect.php | 0 .../Query/AST/SubselectFromClause.php | 0 ...electIdentificationVariableDeclaration.php | 0 .../ORM => src}/Query/AST/TypedExpression.php | 0 .../ORM => src}/Query/AST/UpdateClause.php | 0 .../ORM => src}/Query/AST/UpdateItem.php | 0 .../ORM => src}/Query/AST/UpdateStatement.php | 0 .../ORM => src}/Query/AST/WhenClause.php | 0 .../ORM => src}/Query/AST/WhereClause.php | 0 .../Query/Exec/AbstractSqlExecutor.php | 0 .../Query/Exec/MultiTableDeleteExecutor.php | 0 .../Query/Exec/MultiTableUpdateExecutor.php | 0 .../Query/Exec/SingleSelectExecutor.php | 0 .../Exec/SingleTableDeleteUpdateExecutor.php | 0 {lib/Doctrine/ORM => src}/Query/Expr.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Andx.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Base.php | 0 .../ORM => src}/Query/Expr/Comparison.php | 0 .../ORM => src}/Query/Expr/Composite.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/From.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Func.php | 0 .../ORM => src}/Query/Expr/GroupBy.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Join.php | 0 .../ORM => src}/Query/Expr/Literal.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Math.php | 0 .../ORM => src}/Query/Expr/OrderBy.php | 0 {lib/Doctrine/ORM => src}/Query/Expr/Orx.php | 0 .../ORM => src}/Query/Expr/Select.php | 0 .../Query/Filter/FilterException.php | 0 .../ORM => src}/Query/Filter/SQLFilter.php | 0 .../ORM => src}/Query/FilterCollection.php | 0 {lib/Doctrine/ORM => src}/Query/Lexer.php | 0 {lib/Doctrine/ORM => src}/Query/Parameter.php | 0 .../Query/ParameterTypeInferer.php | 0 {lib/Doctrine/ORM => src}/Query/Parser.php | 0 .../ORM => src}/Query/ParserResult.php | 0 {lib/Doctrine/ORM => src}/Query/Printer.php | 0 .../ORM => src}/Query/QueryException.php | 0 .../Query/QueryExpressionVisitor.php | 0 .../ORM => src}/Query/ResultSetMapping.php | 0 .../Query/ResultSetMappingBuilder.php | 0 {lib/Doctrine/ORM => src}/Query/SqlWalker.php | 0 .../Doctrine/ORM => src}/Query/TreeWalker.php | 0 .../ORM => src}/Query/TreeWalkerAdapter.php | 0 .../ORM => src}/Query/TreeWalkerChain.php | 0 .../Query/TreeWalkerChainIterator.php | 0 {lib/Doctrine/ORM => src}/QueryBuilder.php | 0 .../Repository/DefaultRepositoryFactory.php | 0 .../Exception/InvalidFindByCall.php | 0 .../Exception/InvalidMagicMethodCall.php | 0 .../Repository/RepositoryFactory.php | 0 .../Tools/AttachEntityListenersListener.php | 0 .../Command/AbstractEntityManagerCommand.php | 0 .../ClearCache/CollectionRegionCommand.php | 0 .../ClearCache/EntityRegionCommand.php | 0 .../Command/ClearCache/MetadataCommand.php | 0 .../Command/ClearCache/QueryCommand.php | 0 .../Command/ClearCache/QueryRegionCommand.php | 0 .../Command/ClearCache/ResultCommand.php | 0 .../Command/ConvertDoctrine1SchemaCommand.php | 0 .../Console/Command/ConvertMappingCommand.php | 0 .../EnsureProductionSettingsCommand.php | 0 .../Command/GenerateEntitiesCommand.php | 0 .../Command/GenerateProxiesCommand.php | 0 .../Command/GenerateRepositoriesCommand.php | 0 .../Tools/Console/Command/InfoCommand.php | 0 .../Command/MappingDescribeCommand.php | 0 .../Tools/Console/Command/RunDqlCommand.php | 0 .../Command/SchemaTool/AbstractCommand.php | 0 .../Command/SchemaTool/CreateCommand.php | 0 .../Command/SchemaTool/DropCommand.php | 0 .../Command/SchemaTool/UpdateCommand.php | 0 .../Console/Command/ValidateSchemaCommand.php | 0 .../Tools/Console/CommandCompatibility.php | 0 .../Tools/Console/ConsoleRunner.php | 0 .../Tools/Console/EntityManagerProvider.php | 0 .../ConnectionFromManagerProvider.php | 0 .../HelperSetManagerProvider.php | 0 .../SingleManagerProvider.php | 0 .../UnknownManagerException.php | 0 .../Console/Helper/EntityManagerHelper.php | 0 .../Tools/Console/MetadataFilter.php | 0 .../Tools/ConvertDoctrine1Schema.php | 0 {lib/Doctrine/ORM => src}/Tools/Debug.php | 0 .../Tools/DebugUnitOfWorkListener.php | 0 .../DisconnectedClassMetadataFactory.php | 0 .../ORM => src}/Tools/EntityGenerator.php | 0 .../Tools/EntityRepositoryGenerator.php | 0 .../Tools/Event/GenerateSchemaEventArgs.php | 0 .../Event/GenerateSchemaTableEventArgs.php | 0 .../Exception/MissingColumnException.php | 0 .../Tools/Exception/NotSupported.php | 0 .../Tools/Export/ClassMetadataExporter.php | 0 .../Tools/Export/Driver/AbstractExporter.php | 0 .../Export/Driver/AnnotationExporter.php | 0 .../Tools/Export/Driver/PhpExporter.php | 0 .../Tools/Export/Driver/XmlExporter.php | 0 .../Tools/Export/Driver/YamlExporter.php | 0 .../Tools/Export/ExportException.php | 0 .../Tools/Pagination/CountOutputWalker.php | 0 .../Tools/Pagination/CountWalker.php | 0 .../RowNumberOverFunctionNotEnabled.php | 0 .../Pagination/LimitSubqueryOutputWalker.php | 0 .../Tools/Pagination/LimitSubqueryWalker.php | 0 .../Tools/Pagination/Paginator.php | 0 .../Tools/Pagination/RootTypeWalker.php | 0 .../Pagination/RowNumberOverFunction.php | 0 .../Tools/Pagination/WhereInWalker.php | 0 .../Tools/ResolveTargetEntityListener.php | 0 .../Doctrine/ORM => src}/Tools/SchemaTool.php | 0 .../ORM => src}/Tools/SchemaValidator.php | 0 {lib/Doctrine/ORM => src}/Tools/Setup.php | 0 .../Doctrine/ORM => src}/Tools/ToolEvents.php | 0 .../ORM => src}/Tools/ToolsException.php | 0 .../TransactionRequiredException.php | 0 .../ORM => src}/UnexpectedResultException.php | 0 {lib/Doctrine/ORM => src}/UnitOfWork.php | 0 .../HierarchyDiscriminatorResolver.php | 0 .../Utility/IdentifierFlattener.php | 0 .../ORM => src}/Utility/PersisterHelper.php | 0 {lib/Doctrine/ORM => src}/Version.php | 0 tests/.gitignore | 6 +- .../UnitOfWorkComputeChangesBench.php | 0 .../Performance/EntityManagerFactory.php | 0 ...etchJoinArrayHydrationPerformanceBench.php | 0 ...oinFullObjectHydrationPerformanceBench.php | 0 ...PartialObjectHydrationPerformanceBench.php | 0 .../Hydration/SimpleHydrationBench.php | 0 .../SimpleInsertPerformanceBench.php | 0 ...pleQueryArrayHydrationPerformanceBench.php | 0 ...eryFullObjectHydrationPerformanceBench.php | 0 ...PartialObjectHydrationPerformanceBench.php | 0 ...leQueryScalarHydrationPerformanceBench.php | 0 ...leInheritanceHydrationPerformanceBench.php | 0 ...TableInheritanceInsertPerformanceBench.php | 0 .../ProxyInitializationTimeBench.php | 0 .../ProxyInstantiationTimeBench.php | 0 .../Performance/Mock/NonLoadingPersister.php | 0 .../Mock/NonProxyLoadingEntityManager.php | 0 .../Mock/NonProxyLoadingUnitOfWork.php | 0 .../QueryBoundParameterProcessingBench.php | 0 .../Mapping/class-metadata-constructor.php | 0 .../Tools/Pagination/paginator-covariant.php | 0 .../StaticAnalysis/get-metadata.php | 0 .../Tests/DbalExtensions/Connection.php | 0 .../Tests/DbalExtensions/LegacySqlLogger.php | 0 .../Tests/DbalExtensions/QueryLog.php | 0 .../Tests/DbalExtensions/SqlLogger.php | 0 .../Tests/DbalTypes/CustomIdObject.php | 0 .../Tests/DbalTypes/CustomIdObjectType.php | 0 .../Tests/DbalTypes/CustomIntType.php | 0 .../DbalTypes/GH8565EmployeePayloadType.php | 0 .../DbalTypes/GH8565ManagerPayloadType.php | 0 .../DbalTypes/NegativeToPositiveType.php | 0 .../Tests/DbalTypes/Rot13Type.php | 0 .../Tests/DbalTypes/UpperCaseStringType.php | 0 .../{Doctrine => }/Tests/DoctrineTestCase.php | 0 .../EventListener/CacheMetadataListener.php | 0 tests/{Doctrine => }/Tests/IterableTester.php | 0 .../Tests/Mocks/ArrayResultFactory.php | 0 .../Tests/Mocks/CacheEntryMock.php | 0 .../Tests/Mocks/CacheKeyMock.php | 0 .../Tests/Mocks/CacheRegionMock.php | 0 .../Tests/Mocks/ConcurrentRegionMock.php | 0 .../Tests/Mocks/ConnectionMock.php | 0 .../Tests/Mocks/CustomTreeWalkerJoin.php | 0 .../Tests/Mocks/DatabasePlatformMock.php | 0 .../Tests/Mocks/DriverConnectionMock.php | 0 .../{Doctrine => }/Tests/Mocks/DriverMock.php | 0 .../Tests/Mocks/DriverResultMock.php | 0 .../Tests/Mocks/EntityManagerMock.php | 0 .../Tests/Mocks/EntityPersisterMock.php | 0 .../Tests/Mocks/ExceptionConverterMock.php | 0 .../Tests/Mocks/MetadataDriverMock.php | 0 .../Tests/Mocks/NullSqlWalker.php | 0 .../{Doctrine => }/Tests/Mocks/ResultMock.php | 0 .../Tests/Mocks/ResultStatement.php | 0 .../Tests/Mocks/SchemaManagerMock.php | 0 .../Tests/Mocks/StatementMock.php | 0 .../Tests/Mocks/TimestampRegionMock.php | 0 .../Tests/Mocks/UnitOfWorkMock.php | 0 .../Tests/Models/CMS/CmsAddress.php | 0 .../Tests/Models/CMS/CmsAddressDTO.php | 0 .../Tests/Models/CMS/CmsAddressListener.php | 0 .../Tests/Models/CMS/CmsArticle.php | 0 .../Tests/Models/CMS/CmsComment.php | 0 .../Tests/Models/CMS/CmsEmail.php | 0 .../Tests/Models/CMS/CmsEmployee.php | 0 .../Tests/Models/CMS/CmsGroup.php | 0 .../Tests/Models/CMS/CmsPhonenumber.php | 0 .../Tests/Models/CMS/CmsTag.php | 0 .../Tests/Models/CMS/CmsUser.php | 0 .../Tests/Models/CMS/CmsUserDTO.php | 0 .../Tests/Models/Cache/Action.php | 0 .../Tests/Models/Cache/Address.php | 0 .../Tests/Models/Cache/Attraction.php | 0 .../Models/Cache/AttractionContactInfo.php | 0 .../Tests/Models/Cache/AttractionInfo.php | 0 .../Models/Cache/AttractionLocationInfo.php | 0 .../{Doctrine => }/Tests/Models/Cache/Bar.php | 0 .../Tests/Models/Cache/Beach.php | 0 .../Tests/Models/Cache/City.php | 0 .../Tests/Models/Cache/Client.php | 0 .../Tests/Models/Cache/ComplexAction.php | 0 .../Tests/Models/Cache/Country.php | 0 .../Tests/Models/Cache/Flight.php | 0 .../Tests/Models/Cache/Login.php | 0 .../Tests/Models/Cache/Person.php | 0 .../Tests/Models/Cache/Restaurant.php | 0 .../Tests/Models/Cache/State.php | 0 .../Tests/Models/Cache/Token.php | 0 .../Tests/Models/Cache/Travel.php | 0 .../Tests/Models/Cache/Traveler.php | 0 .../Tests/Models/Cache/TravelerProfile.php | 0 .../Models/Cache/TravelerProfileInfo.php | 0 .../Tests/Models/Company/CompanyAuction.php | 0 .../Tests/Models/Company/CompanyCar.php | 0 .../Tests/Models/Company/CompanyContract.php | 0 .../Company/CompanyContractListener.php | 0 .../Tests/Models/Company/CompanyEmployee.php | 0 .../Tests/Models/Company/CompanyEvent.php | 0 .../Models/Company/CompanyFixContract.php | 0 .../Models/Company/CompanyFlexContract.php | 0 .../Company/CompanyFlexUltraContract.php | 0 .../CompanyFlexUltraContractListener.php | 0 .../Tests/Models/Company/CompanyManager.php | 0 .../Models/Company/CompanyOrganization.php | 0 .../Tests/Models/Company/CompanyPerson.php | 0 .../Tests/Models/Company/CompanyRaffle.php | 0 .../JoinedChildClass.php | 0 .../JoinedDerivedChildClass.php | 0 .../JoinedDerivedIdentityClass.php | 0 .../JoinedDerivedRootClass.php | 0 .../JoinedRootClass.php | 0 .../SingleChildClass.php | 0 .../SingleRootClass.php | 0 .../CustomType/CustomIdObjectTypeChild.php | 0 .../CustomType/CustomIdObjectTypeParent.php | 0 .../Models/CustomType/CustomTypeChild.php | 0 .../Models/CustomType/CustomTypeParent.php | 0 .../Models/CustomType/CustomTypeUpperCase.php | 0 .../Models/DDC117/DDC117ApproveChanges.php | 0 .../Tests/Models/DDC117/DDC117Article.php | 0 .../Models/DDC117/DDC117ArticleDetails.php | 0 .../Tests/Models/DDC117/DDC117Editor.php | 0 .../Tests/Models/DDC117/DDC117Link.php | 0 .../Tests/Models/DDC117/DDC117Reference.php | 0 .../Tests/Models/DDC117/DDC117Translation.php | 0 .../DDC1476EntityWithDefaultFieldType.php | 0 .../Tests/Models/DDC1590/DDC1590Entity.php | 0 .../Tests/Models/DDC1590/DDC1590User.php | 0 .../Tests/Models/DDC1872/DDC1872Bar.php | 0 .../DDC1872ExampleEntityWithOverride.php | 0 .../DDC1872ExampleEntityWithoutOverride.php | 0 .../Models/DDC1872/DDC1872ExampleTrait.php | 0 .../Tests/Models/DDC2372/DDC2372Address.php | 0 .../Tests/Models/DDC2372/DDC2372Admin.php | 0 .../Tests/Models/DDC2372/DDC2372User.php | 0 .../Traits/DDC2372AddressAndAccessors.php | 0 .../Models/DDC2504/DDC2504ChildClass.php | 0 .../Models/DDC2504/DDC2504OtherClass.php | 0 .../Tests/Models/DDC2504/DDC2504RootClass.php | 0 .../Models/DDC2825/ExplicitSchemaAndTable.php | 0 .../DDC2825/SchemaAndTableInTableName.php | 0 .../DDC3231/DDC3231EntityRepository.php | 0 .../Tests/Models/DDC3231/DDC3231User1.php | 0 .../DDC3231/DDC3231User1NoNamespace.php | 0 .../Tests/Models/DDC3231/DDC3231User2.php | 0 .../DDC3231/DDC3231User2NoNamespace.php | 0 .../Tests/Models/DDC3293/DDC3293Address.php | 0 .../Tests/Models/DDC3293/DDC3293User.php | 0 .../Models/DDC3293/DDC3293UserPrefixed.php | 0 .../Tests/Models/DDC3346/DDC3346Article.php | 0 .../Tests/Models/DDC3346/DDC3346Author.php | 0 .../Tests/Models/DDC3579/DDC3579Admin.php | 0 .../Tests/Models/DDC3579/DDC3579Group.php | 0 .../Tests/Models/DDC3579/DDC3579User.php | 0 .../Tests/Models/DDC3597/DDC3597Image.php | 0 .../Tests/Models/DDC3597/DDC3597Media.php | 0 .../Tests/Models/DDC3597/DDC3597Root.php | 0 .../DDC3597/Embeddable/DDC3597Dimension.php | 0 .../Tests/Models/DDC3699/DDC3699Child.php | 0 .../Tests/Models/DDC3699/DDC3699Parent.php | 0 .../Models/DDC3699/DDC3699RelationMany.php | 0 .../Models/DDC3699/DDC3699RelationOne.php | 0 .../Tests/Models/DDC3711/DDC3711EntityA.php | 0 .../Tests/Models/DDC3711/DDC3711EntityB.php | 0 .../Tests/Models/DDC3899/DDC3899Contract.php | 0 .../Models/DDC3899/DDC3899FixContract.php | 0 .../Models/DDC3899/DDC3899FlexContract.php | 0 .../Tests/Models/DDC3899/DDC3899User.php | 0 .../Tests/Models/DDC4006/DDC4006User.php | 0 .../Tests/Models/DDC4006/DDC4006UserId.php | 0 .../Models/DDC5934/DDC5934BaseContract.php | 0 .../Tests/Models/DDC5934/DDC5934Contract.php | 0 .../Tests/Models/DDC5934/DDC5934Member.php | 0 .../Tests/Models/DDC6412/DDC6412File.php | 0 .../Models/DDC753/DDC753CustomRepository.php | 0 .../Models/DDC753/DDC753DefaultRepository.php | 0 .../DDC753EntityWithCustomRepository.php | 0 ...DC753EntityWithDefaultCustomRepository.php | 0 .../DDC753EntityWithInvalidRepository.php | 0 .../Models/DDC753/DDC753InvalidRepository.php | 0 .../Models/DDC869/DDC869ChequePayment.php | 0 .../Models/DDC869/DDC869CreditCardPayment.php | 0 .../Tests/Models/DDC869/DDC869Payment.php | 0 .../Models/DDC869/DDC869PaymentRepository.php | 0 .../Tests/Models/DDC889/DDC889Class.php | 0 .../Tests/Models/DDC889/DDC889Entity.php | 0 .../Tests/Models/DDC889/DDC889SuperClass.php | 0 .../Tests/Models/DDC964/DDC964Address.php | 0 .../Tests/Models/DDC964/DDC964Admin.php | 0 .../Tests/Models/DDC964/DDC964Group.php | 0 .../Tests/Models/DDC964/DDC964Guest.php | 0 .../Tests/Models/DDC964/DDC964User.php | 0 .../DtoWithArrayOfEnums.php | 0 .../DataTransferObjects/DtoWithEnum.php | 0 .../DirectoryTree/AbstractContentItem.php | 0 .../Tests/Models/DirectoryTree/Directory.php | 0 .../Tests/Models/DirectoryTree/File.php | 0 .../Tests/Models/ECommerce/ECommerceCart.php | 0 .../Models/ECommerce/ECommerceCategory.php | 0 .../Models/ECommerce/ECommerceCustomer.php | 0 .../Models/ECommerce/ECommerceFeature.php | 0 .../Models/ECommerce/ECommerceProduct.php | 0 .../Models/ECommerce/ECommerceShipping.php | 0 .../Tests/Models/Enums/AccessLevel.php | 0 .../Tests/Models/Enums/Card.php | 0 .../Tests/Models/Enums/CardWithDefault.php | 0 .../Tests/Models/Enums/CardWithNullable.php | 0 .../Tests/Models/Enums/City.php | 0 .../Tests/Models/Enums/Product.php | 0 .../Tests/Models/Enums/Quantity.php | 0 .../Tests/Models/Enums/Scale.php | 0 .../Tests/Models/Enums/Suit.php | 0 .../Tests/Models/Enums/TypedCard.php | 0 .../Models/Enums/TypedCardEnumCompositeId.php | 0 .../Tests/Models/Enums/TypedCardEnumId.php | 0 .../Tests/Models/Enums/Unit.php | 0 .../Tests/Models/Enums/UserStatus.php | 0 .../Tests/Models/Forum/ForumAvatar.php | 0 .../Tests/Models/Forum/ForumBoard.php | 0 .../Tests/Models/Forum/ForumCategory.php | 0 .../Tests/Models/Forum/ForumEntry.php | 0 .../Tests/Models/Forum/ForumUser.php | 0 .../Tests/Models/GH10132/Complex.php | 0 .../Tests/Models/GH10132/ComplexChild.php | 0 .../Tests/Models/GH10288/GH10288People.php | 0 .../Tests/Models/GH10334/GH10334Foo.php | 0 .../Models/GH10334/GH10334FooCollection.php | 0 .../Tests/Models/GH10334/GH10334Product.php | 0 .../Models/GH10334/GH10334ProductType.php | 0 .../Models/GH10334/GH10334ProductTypeId.php | 0 .../Tests/Models/GH10336/GH10336Entity.php | 0 .../Tests/Models/GH10336/GH10336Relation.php | 0 .../Tests/Models/GH7141/GH7141Article.php | 0 .../Tests/Models/GH7316/GH7316Article.php | 0 .../Tests/Models/GH7717/GH7717Child.php | 0 .../Tests/Models/GH7717/GH7717Parent.php | 0 .../Tests/Models/GH8565/GH8565Employee.php | 0 .../Tests/Models/GH8565/GH8565Manager.php | 0 .../Tests/Models/GH8565/GH8565Person.php | 0 .../Tests/Models/Generic/BooleanModel.php | 0 .../Tests/Models/Generic/DateTimeModel.php | 0 .../Tests/Models/Generic/DecimalModel.php | 0 .../Models/Generic/NonAlphaColumnsEntity.php | 0 .../Models/Generic/SerializationModel.php | 0 .../Tests/Models/GeoNames/Admin1.php | 0 .../Models/GeoNames/Admin1AlternateName.php | 0 .../Tests/Models/GeoNames/City.php | 0 .../Tests/Models/GeoNames/Country.php | 0 .../Models/Global/GlobalNamespaceModel.php | 0 .../EntityWithArrayDefaultArrayValueM2M.php | 0 .../Tests/Models/Hydration/SimpleEntity.php | 0 .../Models/Issue5989/Issue5989Employee.php | 0 .../Models/Issue5989/Issue5989Manager.php | 0 .../Models/Issue5989/Issue5989Person.php | 0 .../Tests/Models/Issue9300/Issue9300Child.php | 0 .../Models/Issue9300/Issue9300Parent.php | 0 .../AnotherChildClass.php | 0 .../JoinedInheritanceType/ChildClass.php | 0 .../JoinedInheritanceType/RootClass.php | 0 .../Tests/Models/Legacy/LegacyArticle.php | 0 .../Tests/Models/Legacy/LegacyCar.php | 0 .../Tests/Models/Legacy/LegacyUser.php | 0 .../Models/Legacy/LegacyUserReference.php | 0 .../Models/ManyToManyPersister/ChildClass.php | 0 .../ManyToManyPersister/OtherParentClass.php | 0 .../ManyToManyPersister/ParentClass.php | 0 .../CompositeToOneKeyState.php | 0 .../Models/MixedToOneIdentity/Country.php | 0 .../Tests/Models/Navigation/NavCountry.php | 0 .../Tests/Models/Navigation/NavPhotos.php | 0 .../Models/Navigation/NavPointOfInterest.php | 0 .../Tests/Models/Navigation/NavTour.php | 0 .../Tests/Models/Navigation/NavUser.php | 0 .../Models/NonPublicSchemaJoins/User.php | 0 .../Models/NullDefault/NullDefaultColumn.php | 0 .../OneToOneInverseSideLoad/InverseSide.php | 0 .../OneToOneInverseSideLoad/OwningSide.php | 0 .../OneToOneSingleTableInheritance/Cat.php | 0 .../LitterBox.php | 0 .../OneToOneSingleTableInheritance/Pet.php | 0 .../Models/OrnementalOrphanRemoval/Person.php | 0 .../OrnementalOrphanRemoval/PhoneNumber.php | 0 .../Tests/Models/Pagination/Company.php | 0 .../Tests/Models/Pagination/Department.php | 0 .../Tests/Models/Pagination/Logo.php | 0 .../Tests/Models/Pagination/User.php | 0 .../Tests/Models/Pagination/User1.php | 0 .../PersistentCollectionContent.php | 0 .../PersistentCollectionHolder.php | 0 .../PersistentObject/PersistentEntity.php | 0 .../Tests/Models/Project/Project.php | 0 .../Tests/Models/Project/ProjectId.php | 0 .../Models/Project/ProjectInvalidMapping.php | 0 .../Tests/Models/Project/ProjectName.php | 0 .../Tests/Models/Quote/Address.php | 0 .../Tests/Models/Quote/City.php | 0 .../Tests/Models/Quote/FullAddress.php | 0 .../Tests/Models/Quote/Group.php | 0 .../Tests/Models/Quote/NumericEntity.php | 0 .../Tests/Models/Quote/Phone.php | 0 .../Tests/Models/Quote/User.php | 0 .../Models/ReadonlyProperties/Author.php | 0 .../Tests/Models/ReadonlyProperties/Book.php | 0 .../Models/ReadonlyProperties/SimpleBook.php | 0 .../Models/Reflection/AbstractEmbeddable.php | 0 .../Reflection/ArrayObjectExtendingClass.php | 0 .../Reflection/ClassWithMixedProperties.php | 0 .../Models/Reflection/ConcreteEmbeddable.php | 0 .../Tests/Models/Reflection/ParentClass.php | 0 .../Tests/Models/Routing/RoutingLeg.php | 0 .../Tests/Models/Routing/RoutingLocation.php | 0 .../Tests/Models/Routing/RoutingRoute.php | 0 .../Models/Routing/RoutingRouteBooking.php | 0 .../Tests/Models/StockExchange/Bond.php | 0 .../Tests/Models/StockExchange/Market.php | 0 .../Tests/Models/StockExchange/Stock.php | 0 .../{Doctrine => }/Tests/Models/Taxi/Car.php | 0 .../Tests/Models/Taxi/Driver.php | 0 .../Tests/Models/Taxi/PaidRide.php | 0 .../{Doctrine => }/Tests/Models/Taxi/Ride.php | 0 .../Tests/Models/Tweet/Tweet.php | 0 .../Tests/Models/Tweet/User.php | 0 .../Tests/Models/Tweet/UserList.php | 0 .../Tests/Models/TypedProperties/Contact.php | 0 .../Models/TypedProperties/UserTyped.php | 0 .../UserTypedWithCustomTypedField.php | 0 .../Tests/Models/Upsertable/Insertable.php | 0 .../Tests/Models/Upsertable/Updatable.php | 0 .../ValueConversionType/AuxiliaryEntity.php | 0 .../InversedManyToManyCompositeIdEntity.php | 0 ...dManyToManyCompositeIdForeignKeyEntity.php | 0 .../InversedManyToManyEntity.php | 0 .../InversedManyToManyExtraLazyEntity.php | 0 .../InversedOneToManyCompositeIdEntity.php | 0 ...edOneToManyCompositeIdForeignKeyEntity.php | 0 .../InversedOneToManyEntity.php | 0 .../InversedOneToManyExtraLazyEntity.php | 0 .../InversedOneToOneCompositeIdEntity.php | 0 ...sedOneToOneCompositeIdForeignKeyEntity.php | 0 .../InversedOneToOneEntity.php | 0 .../OwningManyToManyCompositeIdEntity.php | 0 ...gManyToManyCompositeIdForeignKeyEntity.php | 0 .../OwningManyToManyEntity.php | 0 .../OwningManyToManyExtraLazyEntity.php | 0 .../OwningManyToOneCompositeIdEntity.php | 0 ...ngManyToOneCompositeIdForeignKeyEntity.php | 0 .../OwningManyToOneEntity.php | 0 .../OwningManyToOneExtraLazyEntity.php | 0 .../OwningManyToOneIdForeignKeyEntity.php | 0 .../OwningOneToOneCompositeIdEntity.php | 0 ...ingOneToOneCompositeIdForeignKeyEntity.php | 0 .../OwningOneToOneEntity.php | 0 .../Tests/Models/ValueObjects/Name.php | 0 .../Tests/Models/ValueObjects/Person.php | 0 .../Models/VersionedManyToOne/Article.php | 0 .../Models/VersionedManyToOne/Category.php | 0 .../VersionedOneToOne/FirstRelatedEntity.php | 0 .../VersionedOneToOne/SecondRelatedEntity.php | 0 .../Tests/ORM/AbstractQueryTest.php | 0 .../Tests/ORM/Cache/CacheConfigTest.php | 0 .../Tests/ORM/Cache/CacheKeyTest.php | 0 .../Tests/ORM/Cache/CacheLoggerChainTest.php | 0 .../ORM/Cache/DefaultCacheFactoryTest.php | 0 .../Tests/ORM/Cache/DefaultCacheTest.php | 0 .../Cache/DefaultCollectionHydratorTest.php | 0 .../ORM/Cache/DefaultEntityHydratorTest.php | 0 .../Tests/ORM/Cache/DefaultQueryCacheTest.php | 0 .../ORM/Cache/DefaultRegionLegacyTest.php | 0 .../Tests/ORM/Cache/DefaultRegionTest.php | 0 .../Tests/ORM/Cache/FileLockRegionTest.php | 0 .../Tests/ORM/Cache/MultiGetRegionTest.php | 0 .../CollectionPersisterTestCase.php | 0 ...ReadWriteCachedCollectionPersisterTest.php | 0 .../ReadOnlyCachedCollectionPersisterTest.php | 0 ...ReadWriteCachedCollectionPersisterTest.php | 0 .../Entity/EntityPersisterTestCase.php | 0 ...rictReadWriteCachedEntityPersisterTest.php | 0 .../ReadOnlyCachedEntityPersisterTest.php | 0 .../ReadWriteCachedEntityPersisterTest.php | 0 .../Tests/ORM/Cache/RegionTestCase.php | 0 .../ORM/Cache/StatisticsCacheLoggerTest.php | 0 .../Tests/ORM/ConfigurationTest.php | 0 .../Decorator/EntityManagerDecoratorTest.php | 0 .../Tests/ORM/Entity/ConstructorTest.php | 0 .../Tests/ORM/EntityManagerTest.php | 0 .../Tests/ORM/EntityNotFoundExceptionTest.php | 0 .../OnClassMetadataNotFoundEventArgsTest.php | 0 .../AbstractManyToManyAssociationTestCase.php | 0 .../Functional/AdvancedAssociationTest.php | 0 .../ORM/Functional/AdvancedDqlQueryTest.php | 0 .../ORM/Functional/BasicFunctionalTest.php | 0 .../ORM/Functional/CascadeRemoveOrderTest.php | 0 .../ClassTableInheritanceSecondTest.php | 0 .../Functional/ClassTableInheritanceTest.php | 0 .../Tests/ORM/Functional/ClearEventTest.php | 0 .../Functional/CompositePrimaryKeyTest.php | 0 ...ompositePrimaryKeyWithAssociationsTest.php | 0 .../ORM/Functional/CustomFunctionsTest.php | 0 .../ORM/Functional/CustomIdObjectTypeTest.php | 0 .../ORM/Functional/CustomRepositoryTest.php | 0 .../ORM/Functional/DatabaseDriverTest.php | 0 .../ORM/Functional/DatabaseDriverTestCase.php | 0 .../ORM/Functional/DefaultValuesTest.php | 0 .../ORM/Functional/DetachedEntityTest.php | 0 .../Functional/EagerFetchCollectionTest.php | 0 .../ORM/Functional/EntityListenersTest.php | 0 .../EntityRepositoryCriteriaTest.php | 0 .../ORM/Functional/EntityRepositoryTest.php | 0 .../Tests/ORM/Functional/EnumTest.php | 0 .../Functional/ExtraLazyCollectionTest.php | 0 .../Tests/ORM/Functional/FlushEventTest.php | 0 .../Tests/ORM/Functional/GH7877Test.php | 0 .../ORM/Functional/HydrationCacheTest.php | 0 .../Tests/ORM/Functional/IdentityMapTest.php | 0 .../ORM/Functional/IndexByAssociationTest.php | 0 .../Functional/InsertableUpdatableTest.php | 0 .../JoinedTableCompositeKeyTest.php | 0 .../ORM/Functional/LifecycleCallbackTest.php | 0 .../Functional/Locking/GearmanLockTest.php | 0 .../Functional/Locking/LockAgentWorker.php | 0 .../Tests/ORM/Functional/Locking/LockTest.php | 0 .../ORM/Functional/Locking/OptimisticTest.php | 0 .../ManyToManyBasicAssociationTest.php | 0 ...ManyToManyBidirectionalAssociationTest.php | 0 .../ORM/Functional/ManyToManyEventTest.php | 0 ...nyToManySelfReferentialAssociationTest.php | 0 ...anyToManyUnidirectionalAssociationTest.php | 0 .../Functional/ManyToOneOrphanRemovalTest.php | 0 .../ORM/Functional/MappedSuperclassTest.php | 0 .../Functional/MergeCompositeToOneKeyTest.php | 0 .../Tests/ORM/Functional/MergeProxiesTest.php | 0 .../Functional/MergeSharedEntitiesTest.php | 0 .../MergeVersionedManyToOneTest.php | 0 .../Tests/ORM/Functional/NativeQueryTest.php | 0 .../Tests/ORM/Functional/NewOperatorTest.php | 0 .../Tests/ORM/Functional/NotifyPolicyTest.php | 0 .../OneToManyBidirectionalAssociationTest.php | 0 .../Functional/OneToManyOrphanRemovalTest.php | 0 ...neToManySelfReferentialAssociationTest.php | 0 ...OneToManyUnidirectionalAssociationTest.php | 0 .../OneToOneBidirectionalAssociationTest.php | 0 .../Functional/OneToOneEagerLoadingTest.php | 0 ...eToOneInverseSideLoadAfterDqlQueryTest.php | 0 .../Functional/OneToOneOrphanRemovalTest.php | 0 ...OneToOneSelfReferentialAssociationTest.php | 0 .../OneToOneSingleTableInheritanceTest.php | 0 .../OneToOneUnidirectionalAssociationTest.php | 0 .../ORM/Functional/OrderedCollectionTest.php | 0 ...edJoinedTableInheritanceCollectionTest.php | 0 .../Tests/ORM/Functional/PaginationTest.php | 0 .../ParserResultSerializationTest.php | 0 .../ParserResults/single_select_2_14_3.txt | Bin .../ParserResults/single_select_2_15_0.txt | Bin .../ParserResults/single_select_2_17_0.txt | Bin .../PersistentCollectionCriteriaTest.php | 0 .../Functional/PersistentCollectionTest.php | 0 .../ORM/Functional/PersistentObjectTest.php | 0 .../ORM/Functional/PostFlushEventTest.php | 0 .../ORM/Functional/PostLoadEventTest.php | 0 .../Functional/ProxiesLikeEntitiesTest.php | 0 .../QueryBuilderParenthesisTest.php | 0 .../Tests/ORM/Functional/QueryCacheTest.php | 0 .../ORM/Functional/QueryDqlFunctionTest.php | 0 .../ORM/Functional/QueryIterableTest.php | 0 .../Tests/ORM/Functional/QueryTest.php | 0 .../Tests/ORM/Functional/ReadOnlyTest.php | 0 .../ORM/Functional/ReadonlyPropertiesTest.php | 0 .../ORM/Functional/ReferenceProxyTest.php | 0 .../Tests/ORM/Functional/ResultCacheTest.php | 0 .../Tests/ORM/Functional/SQLFilterTest.php | 0 .../SchemaTool/CompanySchemaTest.php | 0 .../ORM/Functional/SchemaTool/DBAL483Test.php | 0 .../ORM/Functional/SchemaTool/DDC214Test.php | 0 .../SchemaTool/MySqlSchemaToolTest.php | 0 .../SchemaTool/PostgreSqlSchemaToolTest.php | 0 .../ORM/Functional/SchemaValidatorTest.php | 0 ...econdLevelCacheCompositePrimaryKeyTest.php | 0 ...ompositePrimaryKeyWithAssociationsTest.php | 0 .../SecondLevelCacheConcurrentTest.php | 0 .../SecondLevelCacheCriteriaTest.php | 0 ...econdLevelCacheExtraLazyCollectionTest.php | 0 .../SecondLevelCacheFunctionalTestCase.php | 0 ...condLevelCacheJoinTableInheritanceTest.php | 0 .../SecondLevelCacheManyToManyTest.php | 0 .../SecondLevelCacheManyToOneTest.php | 0 .../SecondLevelCacheOneToManyTest.php | 0 .../SecondLevelCacheOneToOneTest.php | 0 .../SecondLevelCacheQueryCacheTest.php | 0 .../SecondLevelCacheRepositoryTest.php | 0 ...ndLevelCacheSingleTableInheritanceTest.php | 0 .../ORM/Functional/SecondLevelCacheTest.php | 0 .../SequenceEmulatedIdentityStrategyTest.php | 0 .../ORM/Functional/SequenceGeneratorTest.php | 0 .../SingleTableCompositeKeyTest.php | 0 .../Functional/SingleTableInheritanceTest.php | 0 .../StandardEntityPersisterTest.php | 0 .../ORM/Functional/Ticket/DDC1040Test.php | 0 .../ORM/Functional/Ticket/DDC1041Test.php | 0 .../ORM/Functional/Ticket/DDC1043Test.php | 0 .../ORM/Functional/Ticket/DDC1080Test.php | 0 .../ORM/Functional/Ticket/DDC1113Test.php | 0 .../ORM/Functional/Ticket/DDC1129Test.php | 0 .../ORM/Functional/Ticket/DDC1163Test.php | 0 .../ORM/Functional/Ticket/DDC117Test.php | 0 .../ORM/Functional/Ticket/DDC1181Test.php | 0 .../ORM/Functional/Ticket/DDC1193Test.php | 0 .../ORM/Functional/Ticket/DDC1209Test.php | 0 .../ORM/Functional/Ticket/DDC1225Test.php | 0 .../ORM/Functional/Ticket/DDC1228Test.php | 0 .../ORM/Functional/Ticket/DDC1238Test.php | 0 .../ORM/Functional/Ticket/DDC1250Test.php | 0 .../ORM/Functional/Ticket/DDC1276Test.php | 0 .../ORM/Functional/Ticket/DDC1300Test.php | 0 .../ORM/Functional/Ticket/DDC1301Test.php | 0 .../ORM/Functional/Ticket/DDC1306Test.php | 0 .../ORM/Functional/Ticket/DDC1335Test.php | 0 .../ORM/Functional/Ticket/DDC1383Test.php | 0 .../ORM/Functional/Ticket/DDC1392Test.php | 0 .../ORM/Functional/Ticket/DDC1400Test.php | 0 .../ORM/Functional/Ticket/DDC1404Test.php | 0 .../ORM/Functional/Ticket/DDC142Test.php | 0 .../ORM/Functional/Ticket/DDC1430Test.php | 0 .../ORM/Functional/Ticket/DDC1436Test.php | 0 .../ORM/Functional/Ticket/DDC144Test.php | 0 .../ORM/Functional/Ticket/DDC1452Test.php | 0 .../ORM/Functional/Ticket/DDC1454Test.php | 0 .../ORM/Functional/Ticket/DDC1458Test.php | 0 .../ORM/Functional/Ticket/DDC1461Test.php | 0 .../ORM/Functional/Ticket/DDC1509Test.php | 0 .../ORM/Functional/Ticket/DDC1514Test.php | 0 .../ORM/Functional/Ticket/DDC1515Test.php | 0 .../ORM/Functional/Ticket/DDC1526Test.php | 0 .../ORM/Functional/Ticket/DDC1545Test.php | 0 .../ORM/Functional/Ticket/DDC1548Test.php | 0 .../ORM/Functional/Ticket/DDC1594Test.php | 0 .../ORM/Functional/Ticket/DDC1595Test.php | 0 .../ORM/Functional/Ticket/DDC163Test.php | 0 .../ORM/Functional/Ticket/DDC1643Test.php | 0 .../ORM/Functional/Ticket/DDC1654Test.php | 0 .../ORM/Functional/Ticket/DDC1655Test.php | 0 .../ORM/Functional/Ticket/DDC1666Test.php | 0 .../ORM/Functional/Ticket/DDC1685Test.php | 0 .../ORM/Functional/Ticket/DDC168Test.php | 0 .../ORM/Functional/Ticket/DDC1690Test.php | 0 .../ORM/Functional/Ticket/DDC1695Test.php | 0 .../ORM/Functional/Ticket/DDC1707Test.php | 0 .../ORM/Functional/Ticket/DDC1719Test.php | 0 .../ORM/Functional/Ticket/DDC1734Test.php | 0 .../ORM/Functional/Ticket/DDC1757Test.php | 0 .../ORM/Functional/Ticket/DDC1778Test.php | 0 .../ORM/Functional/Ticket/DDC1787Test.php | 0 .../ORM/Functional/Ticket/DDC1843Test.php | 0 .../ORM/Functional/Ticket/DDC1884Test.php | 0 .../ORM/Functional/Ticket/DDC1885Test.php | 0 .../ORM/Functional/Ticket/DDC1918Test.php | 0 .../ORM/Functional/Ticket/DDC1925Test.php | 0 .../ORM/Functional/Ticket/DDC192Test.php | 0 .../ORM/Functional/Ticket/DDC1995Test.php | 0 .../ORM/Functional/Ticket/DDC1998Test.php | 0 .../ORM/Functional/Ticket/DDC199Test.php | 0 .../ORM/Functional/Ticket/DDC2012Test.php | 0 .../ORM/Functional/Ticket/DDC2074Test.php | 0 .../ORM/Functional/Ticket/DDC2084Test.php | 0 .../ORM/Functional/Ticket/DDC2090Test.php | 0 .../ORM/Functional/Ticket/DDC2106Test.php | 0 .../ORM/Functional/Ticket/DDC211Test.php | 0 .../ORM/Functional/Ticket/DDC2138Test.php | 0 .../ORM/Functional/Ticket/DDC2175Test.php | 0 .../ORM/Functional/Ticket/DDC2182Test.php | 0 .../ORM/Functional/Ticket/DDC2214Test.php | 0 .../ORM/Functional/Ticket/DDC2224Test.php | 0 .../ORM/Functional/Ticket/DDC2230Test.php | 0 .../ORM/Functional/Ticket/DDC2231Test.php | 0 .../ORM/Functional/Ticket/DDC2252Test.php | 0 .../ORM/Functional/Ticket/DDC2256Test.php | 0 .../ORM/Functional/Ticket/DDC2306Test.php | 0 .../ORM/Functional/Ticket/DDC2346Test.php | 0 .../ORM/Functional/Ticket/DDC2350Test.php | 0 .../ORM/Functional/Ticket/DDC2359Test.php | 0 .../ORM/Functional/Ticket/DDC237Test.php | 0 .../ORM/Functional/Ticket/DDC2387Test.php | 0 .../ORM/Functional/Ticket/DDC2409Test.php | 0 .../ORM/Functional/Ticket/DDC2415Test.php | 0 .../ORM/Functional/Ticket/DDC2494Test.php | 0 .../ORM/Functional/Ticket/DDC2519Test.php | 0 .../ORM/Functional/Ticket/DDC2575Test.php | 0 .../ORM/Functional/Ticket/DDC2579Test.php | 0 .../ORM/Functional/Ticket/DDC258Test.php | 0 .../ORM/Functional/Ticket/DDC2602Test.php | 0 .../ORM/Functional/Ticket/DDC2645Test.php | 0 .../ORM/Functional/Ticket/DDC2655Test.php | 0 .../ORM/Functional/Ticket/DDC2660Test.php | 0 .../ORM/Functional/Ticket/DDC2692Test.php | 0 .../ORM/Functional/Ticket/DDC2759Test.php | 0 .../ORM/Functional/Ticket/DDC2775Test.php | 0 .../ORM/Functional/Ticket/DDC2780Test.php | 0 .../ORM/Functional/Ticket/DDC2790Test.php | 0 .../ORM/Functional/Ticket/DDC279Test.php | 0 .../ORM/Functional/Ticket/DDC2825Test.php | 0 .../ORM/Functional/Ticket/DDC2862Test.php | 0 .../ORM/Functional/Ticket/DDC2895Test.php | 0 .../ORM/Functional/Ticket/DDC2931Test.php | 0 .../ORM/Functional/Ticket/DDC2943Test.php | 0 .../ORM/Functional/Ticket/DDC2984Test.php | 0 .../ORM/Functional/Ticket/DDC2996Test.php | 0 .../ORM/Functional/Ticket/DDC3033Test.php | 0 .../ORM/Functional/Ticket/DDC3042Test.php | 0 .../ORM/Functional/Ticket/DDC3068Test.php | 0 .../ORM/Functional/Ticket/DDC309Test.php | 0 .../ORM/Functional/Ticket/DDC3103Test.php | 0 .../ORM/Functional/Ticket/DDC3123Test.php | 0 .../ORM/Functional/Ticket/DDC3160Test.php | 0 .../ORM/Functional/Ticket/DDC3170Test.php | 0 .../ORM/Functional/Ticket/DDC3192Test.php | 0 .../ORM/Functional/Ticket/DDC3223Test.php | 0 .../ORM/Functional/Ticket/DDC3300Test.php | 0 .../ORM/Functional/Ticket/DDC3303Test.php | 0 .../ORM/Functional/Ticket/DDC331Test.php | 0 .../ORM/Functional/Ticket/DDC3330Test.php | 0 .../ORM/Functional/Ticket/DDC3346Test.php | 0 .../ORM/Functional/Ticket/DDC345Test.php | 0 .../ORM/Functional/Ticket/DDC353Test.php | 0 .../ORM/Functional/Ticket/DDC3582Test.php | 0 .../ORM/Functional/Ticket/DDC3597Test.php | 0 .../ORM/Functional/Ticket/DDC3634Test.php | 0 .../ORM/Functional/Ticket/DDC3644Test.php | 0 .../ORM/Functional/Ticket/DDC3699Test.php | 0 .../ORM/Functional/Ticket/DDC3719Test.php | 0 .../ORM/Functional/Ticket/DDC371Test.php | 0 .../ORM/Functional/Ticket/DDC3785Test.php | 0 .../ORM/Functional/Ticket/DDC381Test.php | 0 .../ORM/Functional/Ticket/DDC3967Test.php | 0 .../ORM/Functional/Ticket/DDC4003Test.php | 0 .../ORM/Functional/Ticket/DDC4024Test.php | 0 .../ORM/Functional/Ticket/DDC422Test.php | 0 .../ORM/Functional/Ticket/DDC425Test.php | 0 .../ORM/Functional/Ticket/DDC440Test.php | 0 .../ORM/Functional/Ticket/DDC444Test.php | 0 .../ORM/Functional/Ticket/DDC448Test.php | 0 .../ORM/Functional/Ticket/DDC493Test.php | 0 .../ORM/Functional/Ticket/DDC501Test.php | 0 .../ORM/Functional/Ticket/DDC512Test.php | 0 .../ORM/Functional/Ticket/DDC513Test.php | 0 .../ORM/Functional/Ticket/DDC518Test.php | 0 .../ORM/Functional/Ticket/DDC522Test.php | 0 .../ORM/Functional/Ticket/DDC531Test.php | 0 .../ORM/Functional/Ticket/DDC5684Test.php | 0 .../ORM/Functional/Ticket/DDC588Test.php | 0 .../ORM/Functional/Ticket/DDC599Test.php | 0 .../ORM/Functional/Ticket/DDC618Test.php | 0 .../ORM/Functional/Ticket/DDC6303Test.php | 0 .../ORM/Functional/Ticket/DDC633Test.php | 0 .../ORM/Functional/Ticket/DDC6460Test.php | 0 .../ORM/Functional/Ticket/DDC6558Test.php | 0 .../ORM/Functional/Ticket/DDC656Test.php | 0 .../ORM/Functional/Ticket/DDC657Test.php | 0 .../ORM/Functional/Ticket/DDC698Test.php | 0 .../Tests/ORM/Functional/Ticket/DDC69Test.php | 0 .../ORM/Functional/Ticket/DDC719Test.php | 0 .../ORM/Functional/Ticket/DDC729Test.php | 0 .../ORM/Functional/Ticket/DDC735Test.php | 0 .../ORM/Functional/Ticket/DDC736Test.php | 0 .../ORM/Functional/Ticket/DDC742Test.php | 0 .../ORM/Functional/Ticket/DDC748Test.php | 0 .../ORM/Functional/Ticket/DDC758Test.php | 0 .../ORM/Functional/Ticket/DDC767Test.php | 0 .../ORM/Functional/Ticket/DDC7969Test.php | 0 .../ORM/Functional/Ticket/DDC809Test.php | 0 .../ORM/Functional/Ticket/DDC812Test.php | 0 .../ORM/Functional/Ticket/DDC832Test.php | 0 .../ORM/Functional/Ticket/DDC837Test.php | 0 .../ORM/Functional/Ticket/DDC849Test.php | 0 .../ORM/Functional/Ticket/DDC881Test.php | 0 .../ORM/Functional/Ticket/DDC933Test.php | 0 .../ORM/Functional/Ticket/DDC949Test.php | 0 .../ORM/Functional/Ticket/DDC960Test.php | 0 .../ORM/Functional/Ticket/DDC992Test.php | 0 .../Functional/Ticket/GH10049/GH10049Test.php | 0 .../GH10049/ReadOnlyPropertyInheritor.php | 0 .../Ticket/GH10049/ReadOnlyPropertyOwner.php | 0 .../ORM/Functional/Ticket/GH10132Test.php | 0 .../ORM/Functional/Ticket/GH10288Test.php | 0 .../ORM/Functional/Ticket/GH10334Test.php | 0 .../ORM/Functional/Ticket/GH10336Test.php | 0 .../ORM/Functional/Ticket/GH10348Test.php | 0 .../ORM/Functional/Ticket/GH10387Test.php | 0 .../ORM/Functional/Ticket/GH10450Test.php | 0 .../ORM/Functional/Ticket/GH10454Test.php | 0 .../ORM/Functional/Ticket/GH10462Test.php | 0 .../ORM/Functional/Ticket/GH10473Test.php | 0 .../ORM/Functional/Ticket/GH10531Test.php | 0 .../ORM/Functional/Ticket/GH10532Test.php | 0 .../ORM/Functional/Ticket/GH10566Test.php | 0 .../ORM/Functional/Ticket/GH10625Test.php | 0 .../Functional/Ticket/GH10661/GH10661Test.php | 0 .../Ticket/GH10661/InvalidChildEntity.php | 0 .../Ticket/GH10661/InvalidEntity.php | 0 .../ORM/Functional/Ticket/GH10747Test.php | 0 .../ORM/Functional/Ticket/GH10752Test.php | 0 .../ORM/Functional/Ticket/GH10808Test.php | 0 .../ORM/Functional/Ticket/GH10869Test.php | 0 .../ORM/Functional/Ticket/GH10880Test.php | 0 .../Ticket/GH11017/GH11017Entity.php | 0 .../Functional/Ticket/GH11017/GH11017Enum.php | 0 .../Functional/Ticket/GH11017/GH11017Test.php | 0 .../Ticket/GH11037/EntityStatus.php | 0 .../Functional/Ticket/GH11037/GH11037Test.php | 0 .../Ticket/GH11037/IntEntityStatus.php | 0 .../GH11037/InvalidEntityWithTypedEnum.php | 0 .../Ticket/GH11037/StringEntityStatus.php | 0 .../GH11037/ValidEntityWithTypedEnum.php | 0 .../ORM/Functional/Ticket/GH11058Test.php | 0 .../Ticket/GH11072/GH11072EntityAdvanced.php | 0 .../Ticket/GH11072/GH11072EntityBasic.php | 0 .../Functional/Ticket/GH11072/GH11072Test.php | 0 .../ORM/Functional/Ticket/GH2947Test.php | 0 .../ORM/Functional/Ticket/GH5562Test.php | 0 .../ORM/Functional/Ticket/GH5742Test.php | 0 .../ORM/Functional/Ticket/GH5762Test.php | 0 .../ORM/Functional/Ticket/GH5804Test.php | 0 .../ORM/Functional/Ticket/GH5887Test.php | 0 .../ORM/Functional/Ticket/GH5988Test.php | 0 .../ORM/Functional/Ticket/GH5998Test.php | 0 .../ORM/Functional/Ticket/GH6029Test.php | 0 .../ORM/Functional/Ticket/GH6141Test.php | 0 .../ORM/Functional/Ticket/GH6217Test.php | 0 .../ORM/Functional/Ticket/GH6362Test.php | 0 .../ORM/Functional/Ticket/GH6394Test.php | 0 .../ORM/Functional/Ticket/GH6402Test.php | 0 .../ORM/Functional/Ticket/GH6464Test.php | 0 .../GH6499OneToManyRelationshipTest.php | 0 .../Ticket/GH6499OneToOneRelationshipTest.php | 0 .../ORM/Functional/Ticket/GH6499Test.php | 0 .../ORM/Functional/Ticket/GH6531Test.php | 0 .../ORM/Functional/Ticket/GH6682Test.php | 0 .../ORM/Functional/Ticket/GH6699Test.php | 0 .../ORM/Functional/Ticket/GH6740Test.php | 0 .../ORM/Functional/Ticket/GH6823Test.php | 0 .../ORM/Functional/Ticket/GH6937Test.php | 0 .../ORM/Functional/Ticket/GH7006Test.php | 0 .../ORM/Functional/Ticket/GH7012Test.php | 0 .../ORM/Functional/Ticket/GH7062Test.php | 0 .../ORM/Functional/Ticket/GH7067Test.php | 0 .../ORM/Functional/Ticket/GH7068Test.php | 0 .../ORM/Functional/Ticket/GH7079Test.php | 0 .../ORM/Functional/Ticket/GH7180Test.php | 0 .../ORM/Functional/Ticket/GH7259Test.php | 0 .../ORM/Functional/Ticket/GH7286Test.php | 0 .../ORM/Functional/Ticket/GH7366Test.php | 0 .../ORM/Functional/Ticket/GH7407Test.php | 0 .../Ticket/GH7496WithToIterableTest.php | 0 .../ORM/Functional/Ticket/GH7505Test.php | 0 .../ORM/Functional/Ticket/GH7512Test.php | 0 .../ORM/Functional/Ticket/GH7629Test.php | 0 .../ORM/Functional/Ticket/GH7661Test.php | 0 .../ORM/Functional/Ticket/GH7684Test.php | 0 .../ORM/Functional/Ticket/GH7717Test.php | 0 .../ORM/Functional/Ticket/GH7735Test.php | 0 .../ORM/Functional/Ticket/GH7737Test.php | 0 .../ORM/Functional/Ticket/GH7761Test.php | 0 .../ORM/Functional/Ticket/GH7767Test.php | 0 .../ORM/Functional/Ticket/GH7820Test.php | 0 .../ORM/Functional/Ticket/GH7829Test.php | 0 .../ORM/Functional/Ticket/GH7836Test.php | 0 .../ORM/Functional/Ticket/GH7864Test.php | 0 .../ORM/Functional/Ticket/GH7869Test.php | 0 .../ORM/Functional/Ticket/GH7875Test.php | 0 .../ORM/Functional/Ticket/GH7941Test.php | 0 .../ORM/Functional/Ticket/GH8055Test.php | 0 .../ORM/Functional/Ticket/GH8061Test.php | 0 .../ORM/Functional/Ticket/GH8127Test.php | 0 .../ORM/Functional/Ticket/GH8217Test.php | 0 .../ORM/Functional/Ticket/GH8415Test.php | 0 .../Ticket/GH8415ToManyAssociationTest.php | 0 .../ORM/Functional/Ticket/GH8443Test.php | 0 .../ORM/Functional/Ticket/GH8499Test.php | 0 .../ORM/Functional/Ticket/GH8663Test.php | 0 .../ORM/Functional/Ticket/GH8914Test.php | 0 .../ORM/Functional/Ticket/GH9027Test.php | 0 .../ORM/Functional/Ticket/GH9109Test.php | 0 .../ORM/Functional/Ticket/GH9192Test.php | 0 .../ORM/Functional/Ticket/GH9230Test.php | 0 .../ORM/Functional/Ticket/GH9335Test.php | 0 .../Functional/Ticket/GH9467/GH9467Test.php | 0 .../Ticket/GH9467/JoinedInheritanceChild.php | 0 .../JoinedInheritanceNonInsertableColumn.php | 0 .../JoinedInheritanceNonUpdatableColumn.php | 0 .../JoinedInheritanceNonWritableColumn.php | 0 .../Ticket/GH9467/JoinedInheritanceRoot.php | 0 .../JoinedInheritanceWritableColumn.php | 0 .../ORM/Functional/Ticket/GH9516Test.php | 0 .../ORM/Functional/Ticket/GH9579Test.php | 0 .../ORM/Functional/Ticket/GH9807Test.php | 0 .../ORM/Functional/Ticket/Issue5989Test.php | 0 .../ORM/Functional/Ticket/Issue9300Test.php | 0 .../ORM/Functional/Ticket/Ticket2481Test.php | 0 .../Ticket4646InstanceOfAbstractTest.php | 0 .../Ticket4646InstanceOfMultiLevelTest.php | 0 .../Ticket4646InstanceOfParametricTest.php | 0 .../Ticket/Ticket4646InstanceOfTest.php | 0 ...46InstanceOfWithMultipleParametersTest.php | 0 .../Tests/ORM/Functional/TypeTest.php | 0 .../Tests/ORM/Functional/TypeValueSqlTest.php | 0 .../ORM/Functional/UUIDGeneratorTest.php | 0 .../Functional/UnitOfWorkLifecycleTest.php | 0 .../ManyToManyCompositeIdForeignKeyTest.php | 0 .../ManyToManyCompositeIdTest.php | 0 .../ManyToManyExtraLazyTest.php | 0 .../ValueConversionType/ManyToManyTest.php | 0 .../OneToManyCompositeIdForeignKeyTest.php | 0 .../OneToManyCompositeIdTest.php | 0 .../OneToManyExtraLazyTest.php | 0 .../ValueConversionType/OneToManyTest.php | 0 .../OneToOneCompositeIdForeignKeyTest.php | 0 .../OneToOneCompositeIdTest.php | 0 .../ValueConversionType/OneToOneTest.php | 0 .../Tests/ORM/Functional/ValueObjectsTest.php | 0 .../ORM/Functional/VersionedOneToOneTest.php | 0 ...els.OrnementalOrphanRemoval.Person.dcm.xml | 0 ...rnementalOrphanRemoval.PhoneNumber.dcm.xml | 0 .../ORM/Hydration/AbstractHydratorTest.php | 0 .../Tests/ORM/Hydration/ArrayHydratorTest.php | 0 .../ORM/Hydration/CustomHydratorTest.php | 0 .../Tests/ORM/Hydration/HydrationTestCase.php | 0 .../ORM/Hydration/ObjectHydratorTest.php | 0 .../ORM/Hydration/ResultSetMappingTest.php | 0 .../Hydration/ScalarColumnHydratorTest.php | 0 .../ORM/Hydration/ScalarHydratorTest.php | 0 .../Hydration/SimpleObjectHydratorTest.php | 0 .../Hydration/SingleScalarHydratorTest.php | 0 .../Tests/ORM/Id/AbstractIdGeneratorTest.php | 0 .../Tests/ORM/Id/AssignedGeneratorTest.php | 0 .../Tests/ORM/Id/SequenceGeneratorTest.php | 0 .../Internal/HydrationCompleteHandlerTest.php | 0 .../ORM/Internal/TopologicalSortTest.php | 0 .../Tests/ORM/LazyCriteriaCollectionTest.php | 0 .../ORM/Mapping/AnnotationDriverTest.php | 0 .../ORM/Mapping/AnsiQuoteStrategyTest.php | 0 .../Tests/ORM/Mapping/AttributeDriverTest.php | 0 .../Tests/ORM/Mapping/AttributeReaderTest.php | 0 .../Mapping/BasicInheritanceMappingTest.php | 0 .../ORM/Mapping/ClassMetadataBuilderTest.php | 0 .../ORM/Mapping/ClassMetadataFactoryTest.php | 0 .../Mapping/ClassMetadataLoadEventTest.php | 0 .../Tests/ORM/Mapping/ClassMetadataTest.php | 0 .../ORM/Mapping/DefaultQuoteStrategyTest.php | 0 .../Mapping/EntityListenerResolverTest.php | 0 .../Tests/ORM/Mapping/FieldBuilderTest.php | 0 .../AttributeEntityWithNestedJoinColumns.php | 0 .../ORM/Mapping/MappingDriverTestCase.php | 0 .../JoinColumnClassNamingStrategy.php | 0 .../Tests/ORM/Mapping/NamingStrategyTest.php | 0 .../ORM/Mapping/PHPMappingDriverTest.php | 0 .../Tests/ORM/Mapping/QuoteStrategyTest.php | 0 .../ReflectionPropertiesGetterTest.php | 0 .../ReflectionEmbeddedPropertyTest.php | 0 .../ReflectionReadonlyPropertyTest.php | 0 .../Mapping/StaticPHPMappingDriverTest.php | 0 .../ORM/Mapping/Symfony/DriverTestCase.php | 0 .../ORM/Mapping/Symfony/XmlDriverTest.php | 0 .../ORM/Mapping/Symfony/YamlDriverTest.php | 0 .../CustomIntAsStringTypedFieldMapper.php | 0 .../ORM/Mapping/TypedFieldMapperTest.php | 0 .../Mapping/UnderscoreNamingStrategyTest.php | 0 .../ORM/Mapping/XmlMappingDriverTest.php | 0 .../ORM/Mapping/YamlMappingDriverTest.php | 0 .../Doctrine.Tests.Models.CMS.CmsAddress.php | 0 .../php/Doctrine.Tests.Models.CMS.CmsUser.php | 0 .../php/Doctrine.Tests.Models.Cache.City.php | 0 ...e.Tests.Models.Company.CompanyContract.php | 0 ...ests.Models.Company.CompanyFixContract.php | 0 ...sts.Models.Company.CompanyFlexContract.php | 0 ...odels.Company.CompanyFlexUltraContract.php | 0 ...ine.Tests.Models.Company.CompanyPerson.php | 0 ...1476.DDC1476EntityWithDefaultFieldType.php | 0 ....Models.DDC2825.ExplicitSchemaAndTable.php | 0 ...dels.DDC2825.SchemaAndTableInTableName.php | 0 ...rine.Tests.Models.DDC3579.DDC3579Admin.php | 0 ...trine.Tests.Models.DDC3579.DDC3579User.php | 0 ...sts.Models.DDC5934.DDC5934BaseContract.php | 0 ...e.Tests.Models.DDC5934.DDC5934Contract.php | 0 ...ests.Models.DDC869.DDC869ChequePayment.php | 0 ....Models.DDC869.DDC869CreditCardPayment.php | 0 ...rine.Tests.Models.DDC869.DDC869Payment.php | 0 ...ctrine.Tests.Models.DDC889.DDC889Class.php | 0 ...trine.Tests.Models.DDC889.DDC889Entity.php | 0 ...e.Tests.Models.DDC889.DDC889SuperClass.php | 0 ...ctrine.Tests.Models.DDC964.DDC964Admin.php | 0 ...ctrine.Tests.Models.DDC964.DDC964Guest.php | 0 ...octrine.Tests.Models.DDC964.DDC964User.php | 0 .../php/Doctrine.Tests.Models.Enums.Card.php | 0 ...Tests.Models.TypedProperties.UserTyped.php | 0 ...operties.UserTypedWithCustomTypedField.php | 0 ...ine.Tests.Models.Upsertable.Insertable.php | 0 ...rine.Tests.Models.Upsertable.Updatable.php | 0 .../php/Doctrine.Tests.ORM.Mapping.Animal.php | 0 .../Doctrine.Tests.ORM.Mapping.Comment.php | 0 ...ctrine.Tests.ORM.Mapping.DDC1170Entity.php | 0 ...octrine.Tests.ORM.Mapping.DDC807Entity.php | 0 ...ests.ORM.Mapping.GH10288EnumTypePerson.php | 0 .../php/Doctrine.Tests.ORM.Mapping.PHPSLC.php | 0 ....ORM.Mapping.ReservedWordInTableColumn.php | 0 .../php/Doctrine.Tests.ORM.Mapping.User.php | 0 .../Tests/ORM/Mapping/xml/CatNoId.dcm.xml | 0 .../Tests/ORM/Mapping/xml/DDC2429Book.orm.xml | 0 .../ORM/Mapping/xml/DDC2429Novel.orm.xml | 0 ...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 0 .../Doctrine.Tests.Models.CMS.CmsUser.dcm.xml | 0 .../Doctrine.Tests.Models.Cache.City.dcm.xml | 0 ...sts.Models.Company.CompanyContract.dcm.xml | 0 ....Models.Company.CompanyFixContract.dcm.xml | 0 ...Models.Company.CompanyFlexContract.dcm.xml | 0 ...s.Company.CompanyFlexUltraContract.dcm.xml | 0 ...Tests.Models.Company.CompanyPerson.dcm.xml | 0 ...ts.Models.DDC117.DDC117Translation.dcm.xml | 0 ....DDC1476EntityWithDefaultFieldType.dcm.xml | 0 ...els.DDC2825.ExplicitSchemaAndTable.dcm.xml | 0 ....DDC2825.SchemaAndTableInTableName.dcm.xml | 0 ...ests.Models.DDC3293.DDC3293Address.dcm.xml | 0 ...e.Tests.Models.DDC3293.DDC3293User.dcm.xml | 0 ...Models.DDC3293.DDC3293UserPrefixed.dcm.xml | 0 ....Tests.Models.DDC3579.DDC3579Admin.dcm.xml | 0 ...e.Tests.Models.DDC3579.DDC3579User.dcm.xml | 0 ...Models.DDC5934.DDC5934BaseContract.dcm.xml | 0 ...sts.Models.DDC5934.DDC5934Contract.dcm.xml | 0 ....Models.DDC869.DDC869ChequePayment.dcm.xml | 0 ...els.DDC869.DDC869CreditCardPayment.dcm.xml | 0 ....Tests.Models.DDC869.DDC869Payment.dcm.xml | 0 ...ne.Tests.Models.DDC889.DDC889Class.dcm.xml | 0 ...e.Tests.Models.DDC889.DDC889Entity.dcm.xml | 0 ...sts.Models.DDC889.DDC889SuperClass.dcm.xml | 0 ...ne.Tests.Models.DDC964.DDC964Admin.dcm.xml | 0 ...ne.Tests.Models.DDC964.DDC964Guest.dcm.xml | 0 ...ine.Tests.Models.DDC964.DDC964User.dcm.xml | 0 .../Doctrine.Tests.Models.Enums.Card.dcm.xml | 0 ....Tests.Models.GH7141.GH7141Article.dcm.xml | 0 ....Tests.Models.GH7316.GH7316Article.dcm.xml | 0 ....Tests.Models.Generic.BooleanModel.dcm.xml | 0 ...trine.Tests.Models.Project.Project.dcm.xml | 0 ...dels.Project.ProjectInvalidMapping.dcm.xml | 0 ...s.Models.TypedProperties.UserTyped.dcm.xml | 0 ...ties.UserTypedWithCustomTypedField.dcm.xml | 0 ...Tests.Models.Upsertable.Insertable.dcm.xml | 0 ....Tests.Models.Upsertable.Updatable.dcm.xml | 0 ...ine.Tests.Models.ValueObjects.Name.dcm.xml | 0 ...e.Tests.Models.ValueObjects.Person.dcm.xml | 0 .../Doctrine.Tests.ORM.Mapping.Animal.dcm.xml | 0 .../Doctrine.Tests.ORM.Mapping.CTI.dcm.xml | 0 ...Doctrine.Tests.ORM.Mapping.Comment.dcm.xml | 0 ...ne.Tests.ORM.Mapping.DDC1170Entity.dcm.xml | 0 ...ine.Tests.ORM.Mapping.DDC807Entity.dcm.xml | 0 ....ORM.Mapping.GH10288EnumTypePerson.dcm.xml | 0 ....Mapping.ReservedWordInTableColumn.dcm.xml | 0 ...completeDiscriminatorColumnMapping.dcm.xml | 0 ...EntityNoDiscriminatorColumnMapping.dcm.xml | 0 .../Doctrine.Tests.ORM.Mapping.User.dcm.xml | 0 ...RM.Mapping.UserIncorrectAttributes.dcm.xml | 0 ...sts.ORM.Mapping.UserIncorrectIndex.dcm.xml | 0 ...ping.UserIncorrectUniqueConstraint.dcm.xml | 0 ....ORM.Mapping.UserMissingAttributes.dcm.xml | 0 .../Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml | 0 ...ctrine.Tests.Models.CMS.CmsAddress.dcm.yml | 0 .../Doctrine.Tests.Models.CMS.CmsUser.dcm.yml | 0 .../Doctrine.Tests.Models.Cache.City.dcm.yml | 0 ...sts.Models.Company.CompanyContract.dcm.yml | 0 ....Models.Company.CompanyFixContract.dcm.yml | 0 ...Models.Company.CompanyFlexContract.dcm.yml | 0 ...s.Company.CompanyFlexUltraContract.dcm.yml | 0 ...Tests.Models.Company.CompanyPerson.dcm.yml | 0 ....DDC1476EntityWithDefaultFieldType.dcm.yml | 0 ...els.DDC2825.ExplicitSchemaAndTable.dcm.yml | 0 ....DDC2825.SchemaAndTableInTableName.dcm.yml | 0 ....Tests.Models.DDC3579.DDC3579Admin.dcm.yml | 0 ...e.Tests.Models.DDC3579.DDC3579User.dcm.yml | 0 ...ests.Models.DDC3711.DDC3711EntityA.dcm.yml | 0 ...ests.Models.DDC3711.DDC3711EntityB.dcm.yml | 0 ...Models.DDC5934.DDC5934BaseContract.dcm.yml | 0 ...sts.Models.DDC5934.DDC5934Contract.dcm.yml | 0 ....Models.DDC869.DDC869ChequePayment.dcm.yml | 0 ...els.DDC869.DDC869CreditCardPayment.dcm.yml | 0 ....Tests.Models.DDC869.DDC869Payment.dcm.yml | 0 ...ne.Tests.Models.DDC889.DDC889Class.dcm.yml | 0 ...e.Tests.Models.DDC889.DDC889Entity.dcm.yml | 0 ...sts.Models.DDC889.DDC889SuperClass.dcm.yml | 0 ...ne.Tests.Models.DDC964.DDC964Admin.dcm.yml | 0 ...ne.Tests.Models.DDC964.DDC964Guest.dcm.yml | 0 ...ine.Tests.Models.DDC964.DDC964User.dcm.yml | 0 ....DirectoryTree.AbstractContentItem.dcm.yml | 0 ...sts.Models.DirectoryTree.Directory.dcm.yml | 0 ...ne.Tests.Models.DirectoryTree.File.dcm.yml | 0 .../Doctrine.Tests.Models.Enums.Card.dcm.yml | 0 ....Tests.Models.Generic.BooleanModel.dcm.yml | 0 ...s.Models.TypedProperties.UserTyped.dcm.yml | 0 ...ties.UserTypedWithCustomTypedField.dcm.yml | 0 ...Tests.Models.Upsertable.Insertable.dcm.yml | 0 ....Tests.Models.Upsertable.Updatable.dcm.yml | 0 .../Doctrine.Tests.ORM.Mapping.Animal.dcm.yml | 0 ...Doctrine.Tests.ORM.Mapping.Comment.dcm.yml | 0 ...ne.Tests.ORM.Mapping.DDC1170Entity.dcm.yml | 0 ...ne.Tests.ORM.Mapping.DDC2069Entity.dcm.yml | 0 ...ine.Tests.ORM.Mapping.DDC807Entity.dcm.yml | 0 ....ORM.Mapping.GH10288EnumTypePerson.dcm.yml | 0 ....Mapping.ReservedWordInTableColumn.dcm.yml | 0 ...completeDiscriminatorColumnMapping.dcm.yml | 0 ...EntityNoDiscriminatorColumnMapping.dcm.yml | 0 .../Doctrine.Tests.ORM.Mapping.User.dcm.yml | 0 ...sts.ORM.Mapping.UserIncorrectIndex.dcm.yml | 0 ...ping.UserIncorrectUniqueConstraint.dcm.yml | 0 .../ORM/ORMInvalidArgumentExceptionTest.php | 0 .../{Doctrine => }/Tests/ORM/ORMSetupTest.php | 0 .../ORM/Performance/SecondLevelCacheTest.php | 0 .../Tests/ORM/PersistentCollectionTest.php | 0 ...tyPersisterCompositeTypeParametersTest.php | 0 ...sicEntityPersisterCompositeTypeSqlTest.php | 0 .../BasicEntityPersisterTypeValueSqlTest.php | 0 .../Exception/UnrecognizedFieldTest.php | 0 .../Persisters/ManyToManyPersisterTest.php | 0 .../Tests/ORM/Proxy/ProxyFactoryTest.php | 0 .../Tests/ORM/Query/AST/InExpressionTest.php | 0 .../ORM/Query/CustomTreeWalkersJoinTest.php | 0 .../Tests/ORM/Query/CustomTreeWalkersTest.php | 0 .../ORM/Query/DeleteSqlGenerationTest.php | 0 .../Tests/ORM/Query/ExprTest.php | 0 .../Tests/ORM/Query/FilterCollectionTest.php | 0 .../ORM/Query/LanguageRecognitionTest.php | 0 .../Tests/ORM/Query/LexerTest.php | 0 .../ORM/Query/ParameterTypeInfererTest.php | 0 .../Tests/ORM/Query/ParserResultTest.php | 0 .../Tests/ORM/Query/ParserTest.php | 0 .../ORM/Query/QueryExpressionVisitorTest.php | 0 .../Tests/ORM/Query/QueryTest.php | 0 .../ORM/Query/SelectSqlGenerationTest.php | 0 .../ORM/Query/SqlExpressionVisitorTest.php | 0 .../Tests/ORM/Query/SqlWalkerTest.php | 0 .../Tests/ORM/Query/TreeWalkerAdapterTest.php | 0 .../ORM/Query/UpdateSqlGenerationTest.php | 0 .../Tests/ORM/QueryBuilderTest.php | 0 .../DefaultRepositoryFactoryTest.php | 0 .../AttachEntityListenersListenerTest.php | 0 .../ClearCacheCollectionRegionCommandTest.php | 0 .../ClearCacheEntityRegionCommandTest.php | 0 .../ClearCacheQueryRegionCommandTest.php | 0 .../ConvertDoctrine1SchemaCommandTest.php | 0 .../EnsureProductionSettingsCommandTest.php | 0 .../GenerateRepositoriesCommandTest.php | 0 .../Tools/Console/Command/InfoCommandTest.php | 0 .../Command/MappingDescribeCommandTest.php | 0 .../Console/Command/RunDqlCommandTest.php | 0 .../Command/SchemaTool/CommandTestCase.php | 0 .../Command/SchemaTool/CreateCommandTest.php | 0 .../Command/SchemaTool/DropCommandTest.php | 0 .../Command/SchemaTool/Models/Keyboard.php | 0 .../Command/SchemaTool/UpdateCommandTest.php | 0 .../Command/ValidateSchemaCommandTest.php | 0 .../ORM/Tools/Console/ConsoleRunnerTest.php | 0 .../ORM/Tools/Console/MetadataFilterTest.php | 0 .../ORM/Tools/ConvertDoctrine1SchemaTest.php | 0 .../Tests/ORM/Tools/DebugTest.php | 0 .../Tests/ORM/Tools/EntityGeneratorTest.php | 0 .../Tools/EntityRepositoryGeneratorTest.php | 0 .../AnnotationClassMetadataExporterTest.php | 0 .../Export/ClassMetadataExporterTestCase.php | 0 .../Export/PhpClassMetadataExporterTest.php | 0 .../Export/XmlClassMetadataExporterTest.php | 0 .../Export/YamlClassMetadataExporterTest.php | 0 .../Doctrine.Tests.ORM.Tools.Export.User.php | 0 .../Doctrine.Tests.ORM.Tools.Export.User.php | 0 ...ctrine.Tests.ORM.Tools.Export.User.dcm.xml | 0 ...ctrine.Tests.ORM.Tools.Export.User.dcm.yml | 0 .../Pagination/CountOutputWalkerTest.php | 0 .../ORM/Tools/Pagination/CountWalkerTest.php | 0 .../LimitSubqueryOutputWalkerTest.php | 0 .../Pagination/LimitSubqueryWalkerTest.php | 0 .../Tools/Pagination/PaginationTestCase.php | 0 .../ORM/Tools/Pagination/PaginatorTest.php | 0 .../Tools/Pagination/RootTypeWalkerTest.php | 0 .../Tools/Pagination/WhereInWalkerTest.php | 0 .../Tools/ResolveTargetEntityListenerTest.php | 0 .../Tests/ORM/Tools/SchemaToolTest.php | 0 .../Tests/ORM/Tools/SchemaValidatorTest.php | 0 .../Tests/ORM/Tools/SetupTest.php | 0 .../Tests/ORM/Tools/TestAsset/ChildClass.php | 0 .../ChildWithSameAttributesClass.php | 0 .../Tests/ORM/Tools/TestAsset/ParentClass.php | 0 .../ORM/Tools/doctrine1schema/schema.yml | 0 .../Tests/ORM/UnitOfWorkTest.php | 0 .../HierarchyDiscriminatorResolverTest.php | 0 .../Utility/IdentifierFlattenerEnumIdTest.php | 0 .../ORM/Utility/IdentifierFlattenerTest.php | 0 .../Tests/OrmFunctionalTestCase.php | 0 tests/{Doctrine => }/Tests/OrmTestCase.php | 0 .../MockBuilderCompatibilityTools.php | 0 tests/{Doctrine => }/Tests/TestInit.php | 8 +- tests/{Doctrine => }/Tests/TestUtil.php | 0 1573 files changed, 578 insertions(+), 578 deletions(-) rename {lib/Doctrine/ORM => src}/AbstractQuery.php (100%) rename {lib/Doctrine/ORM => src}/Cache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/AssociationCacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CacheConfiguration.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CacheException.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CacheFactory.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CacheKey.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CollectionCacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CollectionCacheKey.php (100%) rename {lib/Doctrine/ORM => src}/Cache/CollectionHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/ConcurrentRegion.php (100%) rename {lib/Doctrine/ORM => src}/Cache/DefaultCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/DefaultCacheFactory.php (100%) rename {lib/Doctrine/ORM => src}/Cache/DefaultCollectionHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/DefaultEntityHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/DefaultQueryCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/EntityCacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/EntityCacheKey.php (100%) rename {lib/Doctrine/ORM => src}/Cache/EntityHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/CacheException.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/CannotUpdateReadOnlyCollection.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/CannotUpdateReadOnlyEntity.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/FeatureNotImplemented.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/InvalidResultCacheDriver.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/MetadataCacheNotConfigured.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/MetadataCacheUsesNonPersistentCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/NonCacheableEntity.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/NonCacheableEntityAssociation.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/QueryCacheNotConfigured.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Exception/QueryCacheUsesNonPersistentCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Lock.php (100%) rename {lib/Doctrine/ORM => src}/Cache/LockException.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Logging/CacheLogger.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Logging/CacheLoggerChain.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Logging/StatisticsCacheLogger.php (100%) rename {lib/Doctrine/ORM => src}/Cache/MultiGetRegion.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/CachedPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Collection/AbstractCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Collection/CachedCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Entity/AbstractEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Entity/CachedEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Cache/QueryCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/QueryCacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/QueryCacheKey.php (100%) rename {lib/Doctrine/ORM => src}/Cache/QueryCacheValidator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Region.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Region/DefaultMultiGetRegion.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Region/DefaultRegion.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Region/FileLockRegion.php (100%) rename {lib/Doctrine/ORM => src}/Cache/Region/UpdateTimestampCache.php (100%) rename {lib/Doctrine/ORM => src}/Cache/RegionsConfiguration.php (100%) rename {lib/Doctrine/ORM => src}/Cache/TimestampCacheEntry.php (100%) rename {lib/Doctrine/ORM => src}/Cache/TimestampCacheKey.php (100%) rename {lib/Doctrine/ORM => src}/Cache/TimestampQueryCacheValidator.php (100%) rename {lib/Doctrine/ORM => src}/Cache/TimestampRegion.php (100%) rename {lib/Doctrine/ORM => src}/Configuration.php (100%) rename {lib/Doctrine/ORM => src}/Decorator/EntityManagerDecorator.php (100%) rename {lib/Doctrine/ORM => src}/EntityManager.php (100%) rename {lib/Doctrine/ORM => src}/EntityManagerInterface.php (100%) rename {lib/Doctrine/ORM => src}/EntityNotFoundException.php (100%) rename {lib/Doctrine/ORM => src}/EntityRepository.php (100%) rename {lib/Doctrine/ORM => src}/Event/LifecycleEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/ListenersInvoker.php (100%) rename {lib/Doctrine/ORM => src}/Event/LoadClassMetadataEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/OnClassMetadataNotFoundEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/OnClearEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/OnFlushEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PostFlushEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PostLoadEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PostPersistEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PostRemoveEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PostUpdateEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PreFlushEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PrePersistEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PreRemoveEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Event/PreUpdateEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Events.php (100%) rename {lib/Doctrine/ORM => src}/Exception/ConfigurationException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/EntityIdentityCollisionException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/EntityManagerClosed.php (100%) rename {lib/Doctrine/ORM => src}/Exception/EntityMissingAssignedId.php (100%) rename {lib/Doctrine/ORM => src}/Exception/InvalidEntityRepository.php (100%) rename {lib/Doctrine/ORM => src}/Exception/InvalidHydrationMode.php (100%) rename {lib/Doctrine/ORM => src}/Exception/ManagerException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/MismatchedEventManager.php (100%) rename {lib/Doctrine/ORM => src}/Exception/MissingIdentifierField.php (100%) rename {lib/Doctrine/ORM => src}/Exception/MissingMappingDriverImplementation.php (100%) rename {lib/Doctrine/ORM => src}/Exception/MultipleSelectorsFoundException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/NamedNativeQueryNotFound.php (100%) rename {lib/Doctrine/ORM => src}/Exception/NamedQueryNotFound.php (100%) rename {lib/Doctrine/ORM => src}/Exception/NotSupported.php (100%) rename {lib/Doctrine/ORM => src}/Exception/ORMException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/PersisterException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/ProxyClassesAlwaysRegenerating.php (100%) rename {lib/Doctrine/ORM => src}/Exception/RepositoryException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/SchemaToolException.php (100%) rename {lib/Doctrine/ORM => src}/Exception/UnexpectedAssociationValue.php (100%) rename {lib/Doctrine/ORM => src}/Exception/UnknownEntityNamespace.php (100%) rename {lib/Doctrine/ORM => src}/Exception/UnrecognizedIdentifierFields.php (100%) rename {lib/Doctrine/ORM => src}/Id/AbstractIdGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/AssignedGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/BigIntegerIdentityGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/IdentityGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/SequenceGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/TableGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Id/UuidGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/AbstractHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/ArrayHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/HydrationException.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/IterableResult.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/ObjectHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/ScalarColumnHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/ScalarHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/SimpleObjectHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/Hydration/SingleScalarHydrator.php (100%) rename {lib/Doctrine/ORM => src}/Internal/HydrationCompleteHandler.php (100%) rename {lib/Doctrine/ORM => src}/Internal/SQLResultCasing.php (100%) rename {lib/Doctrine/ORM => src}/Internal/TopologicalSort.php (100%) rename {lib/Doctrine/ORM => src}/Internal/TopologicalSort/CycleDetectedException.php (100%) rename {lib/Doctrine/ORM => src}/LazyCriteriaCollection.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Annotation.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/AnsiQuoteStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/AssociationOverride.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/AssociationOverrides.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/AttributeOverride.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/AttributeOverrides.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/AssociationBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/ClassMetadataBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/EmbeddedBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/EntityListenerBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/FieldBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/ManyToManyAssociationBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Builder/OneToManyAssociationBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Cache.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ChainTypedFieldMapper.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ChangeTrackingPolicy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ClassMetadata.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ClassMetadataFactory.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ClassMetadataInfo.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Column.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ColumnResult.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/CustomIdGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DefaultEntityListenerResolver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DefaultNamingStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DefaultQuoteStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DefaultTypedFieldMapper.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DiscriminatorColumn.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/DiscriminatorMap.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/AnnotationDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/AttributeDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/AttributeReader.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/CompatibilityAnnotationDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/DatabaseDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/DriverChain.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/PHPDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/ReflectionBasedDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/RepeatableAttributeCollection.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/SimplifiedXmlDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/SimplifiedYamlDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/StaticPHPDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/XmlDriver.php (99%) rename {lib/Doctrine/ORM => src}/Mapping/Driver/YamlDriver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Embeddable.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Embedded.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Entity.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/EntityListenerResolver.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/EntityListeners.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/EntityResult.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Exception/CannotGenerateIds.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Exception/InvalidCustomGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Exception/UnknownGeneratorType.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/FieldResult.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/GeneratedValue.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/HasLifecycleCallbacks.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Id.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Index.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/InheritanceType.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/InverseJoinColumn.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/JoinColumn.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/JoinColumnProperties.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/JoinColumns.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/JoinTable.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ManyToMany.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ManyToOne.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/MappedSuperclass.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/MappingAttribute.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/MappingException.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/NamedNativeQueries.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/NamedNativeQuery.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/NamedQueries.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/NamedQuery.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/NamingStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/OneToMany.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/OneToOne.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/OrderBy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PostLoad.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PostPersist.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PostRemove.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PostUpdate.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PreFlush.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PrePersist.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PreRemove.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/PreUpdate.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/QuoteStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Reflection/ReflectionPropertiesGetter.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ReflectionEmbeddedProperty.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ReflectionEnumProperty.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/ReflectionReadonlyProperty.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/SequenceGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/SqlResultSetMapping.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/SqlResultSetMappings.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Table.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/TypedFieldMapper.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/UnderscoreNamingStrategy.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/UniqueConstraint.php (100%) rename {lib/Doctrine/ORM => src}/Mapping/Version.php (100%) rename {lib/Doctrine/ORM => src}/NativeQuery.php (100%) rename {lib/Doctrine/ORM => src}/NoResultException.php (100%) rename {lib/Doctrine/ORM => src}/NonUniqueResultException.php (100%) rename {lib/Doctrine/ORM => src}/ORMException.php (100%) rename {lib/Doctrine/ORM => src}/ORMInvalidArgumentException.php (100%) rename {lib/Doctrine/ORM => src}/ORMSetup.php (100%) rename {lib/Doctrine/ORM => src}/OptimisticLockException.php (100%) rename {lib/Doctrine/ORM => src}/PersistentCollection.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Collection/AbstractCollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Collection/CollectionPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Collection/ManyToManyPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Collection/OneToManyPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/AbstractEntityInheritancePersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/BasicEntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/CachedPersisterContext.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/EntityPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/JoinedSubclassPersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Entity/SingleTablePersister.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Exception/CantUseInOperatorOnCompositeKeys.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Exception/InvalidOrientation.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/Exception/UnrecognizedField.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/MatchingAssociationFieldRequiresObject.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/PersisterException.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/SqlExpressionVisitor.php (100%) rename {lib/Doctrine/ORM => src}/Persisters/SqlValueVisitor.php (100%) rename {lib/Doctrine/ORM => src}/PessimisticLockException.php (100%) rename {lib/Doctrine/ORM => src}/Proxy/Autoloader.php (100%) rename {lib/Doctrine/ORM => src}/Proxy/DefaultProxyClassNameResolver.php (100%) rename {lib/Doctrine/ORM => src}/Proxy/InternalProxy.php (100%) rename {lib/Doctrine/ORM => src}/Proxy/Proxy.php (100%) rename {lib/Doctrine/ORM => src}/Proxy/ProxyFactory.php (100%) rename {lib/Doctrine/ORM => src}/Query.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ASTException.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/AggregateExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ArithmeticExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ArithmeticFactor.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ArithmeticTerm.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/BetweenExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/CoalesceExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/CollectionMemberExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ComparisonExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ConditionalExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ConditionalFactor.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ConditionalPrimary.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ConditionalTerm.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/DeleteClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/DeleteStatement.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/EmptyCollectionComparisonExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ExistsExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/FromClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/AbsFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/AvgFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/BitAndFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/BitOrFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/ConcatFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/CountFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/CurrentDateFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/CurrentTimeFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/CurrentTimestampFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/DateAddFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/DateDiffFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/DateSubFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/FunctionNode.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/IdentityFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/LengthFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/LocateFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/LowerFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/MaxFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/MinFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/ModFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/SizeFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/SqrtFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/SubstringFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/SumFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/TrimFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Functions/UpperFunction.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/GeneralCaseExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/GroupByClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/HavingClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/IdentificationVariableDeclaration.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/InExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/InListExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/InSubselectExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/IndexBy.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/InputParameter.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/InstanceOfExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Join.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/JoinAssociationDeclaration.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/JoinAssociationPathExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/JoinClassPathExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/JoinVariableDeclaration.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/LikeExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Literal.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/NewObjectExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Node.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/NullComparisonExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/NullIfExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/OrderByClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/OrderByItem.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/ParenthesisExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/PartialObjectExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/PathExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Phase2OptimizableConditional.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/QuantifiedExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/RangeVariableDeclaration.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SelectClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SelectExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SelectStatement.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SimpleArithmeticExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SimpleCaseExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SimpleSelectClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SimpleSelectExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SimpleWhenClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/Subselect.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SubselectFromClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/SubselectIdentificationVariableDeclaration.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/TypedExpression.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/UpdateClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/UpdateItem.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/UpdateStatement.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/WhenClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/AST/WhereClause.php (100%) rename {lib/Doctrine/ORM => src}/Query/Exec/AbstractSqlExecutor.php (100%) rename {lib/Doctrine/ORM => src}/Query/Exec/MultiTableDeleteExecutor.php (100%) rename {lib/Doctrine/ORM => src}/Query/Exec/MultiTableUpdateExecutor.php (100%) rename {lib/Doctrine/ORM => src}/Query/Exec/SingleSelectExecutor.php (100%) rename {lib/Doctrine/ORM => src}/Query/Exec/SingleTableDeleteUpdateExecutor.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Andx.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Base.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Comparison.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Composite.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/From.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Func.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/GroupBy.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Join.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Literal.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Math.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/OrderBy.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Orx.php (100%) rename {lib/Doctrine/ORM => src}/Query/Expr/Select.php (100%) rename {lib/Doctrine/ORM => src}/Query/Filter/FilterException.php (100%) rename {lib/Doctrine/ORM => src}/Query/Filter/SQLFilter.php (100%) rename {lib/Doctrine/ORM => src}/Query/FilterCollection.php (100%) rename {lib/Doctrine/ORM => src}/Query/Lexer.php (100%) rename {lib/Doctrine/ORM => src}/Query/Parameter.php (100%) rename {lib/Doctrine/ORM => src}/Query/ParameterTypeInferer.php (100%) rename {lib/Doctrine/ORM => src}/Query/Parser.php (100%) rename {lib/Doctrine/ORM => src}/Query/ParserResult.php (100%) rename {lib/Doctrine/ORM => src}/Query/Printer.php (100%) rename {lib/Doctrine/ORM => src}/Query/QueryException.php (100%) rename {lib/Doctrine/ORM => src}/Query/QueryExpressionVisitor.php (100%) rename {lib/Doctrine/ORM => src}/Query/ResultSetMapping.php (100%) rename {lib/Doctrine/ORM => src}/Query/ResultSetMappingBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Query/SqlWalker.php (100%) rename {lib/Doctrine/ORM => src}/Query/TreeWalker.php (100%) rename {lib/Doctrine/ORM => src}/Query/TreeWalkerAdapter.php (100%) rename {lib/Doctrine/ORM => src}/Query/TreeWalkerChain.php (100%) rename {lib/Doctrine/ORM => src}/Query/TreeWalkerChainIterator.php (100%) rename {lib/Doctrine/ORM => src}/QueryBuilder.php (100%) rename {lib/Doctrine/ORM => src}/Repository/DefaultRepositoryFactory.php (100%) rename {lib/Doctrine/ORM => src}/Repository/Exception/InvalidFindByCall.php (100%) rename {lib/Doctrine/ORM => src}/Repository/Exception/InvalidMagicMethodCall.php (100%) rename {lib/Doctrine/ORM => src}/Repository/RepositoryFactory.php (100%) rename {lib/Doctrine/ORM => src}/Tools/AttachEntityListenersListener.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/AbstractEntityManagerCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/CollectionRegionCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/EntityRegionCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/MetadataCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/QueryCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/QueryRegionCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ClearCache/ResultCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ConvertMappingCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/EnsureProductionSettingsCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/GenerateEntitiesCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/GenerateProxiesCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/GenerateRepositoriesCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/InfoCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/MappingDescribeCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/RunDqlCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/SchemaTool/AbstractCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/SchemaTool/CreateCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/SchemaTool/DropCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/SchemaTool/UpdateCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Command/ValidateSchemaCommand.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/CommandCompatibility.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/ConsoleRunner.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/EntityManagerProvider.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/EntityManagerProvider/HelperSetManagerProvider.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/EntityManagerProvider/SingleManagerProvider.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/EntityManagerProvider/UnknownManagerException.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/Helper/EntityManagerHelper.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Console/MetadataFilter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/ConvertDoctrine1Schema.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Debug.php (100%) rename {lib/Doctrine/ORM => src}/Tools/DebugUnitOfWorkListener.php (100%) rename {lib/Doctrine/ORM => src}/Tools/DisconnectedClassMetadataFactory.php (100%) rename {lib/Doctrine/ORM => src}/Tools/EntityGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Tools/EntityRepositoryGenerator.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Event/GenerateSchemaEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Event/GenerateSchemaTableEventArgs.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Exception/MissingColumnException.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Exception/NotSupported.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/ClassMetadataExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/Driver/AbstractExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/Driver/AnnotationExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/Driver/PhpExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/Driver/XmlExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/Driver/YamlExporter.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Export/ExportException.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/CountOutputWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/CountWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/Exception/RowNumberOverFunctionNotEnabled.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/LimitSubqueryOutputWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/LimitSubqueryWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/Paginator.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/RootTypeWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/RowNumberOverFunction.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Pagination/WhereInWalker.php (100%) rename {lib/Doctrine/ORM => src}/Tools/ResolveTargetEntityListener.php (100%) rename {lib/Doctrine/ORM => src}/Tools/SchemaTool.php (100%) rename {lib/Doctrine/ORM => src}/Tools/SchemaValidator.php (100%) rename {lib/Doctrine/ORM => src}/Tools/Setup.php (100%) rename {lib/Doctrine/ORM => src}/Tools/ToolEvents.php (100%) rename {lib/Doctrine/ORM => src}/Tools/ToolsException.php (100%) rename {lib/Doctrine/ORM => src}/TransactionRequiredException.php (100%) rename {lib/Doctrine/ORM => src}/UnexpectedResultException.php (100%) rename {lib/Doctrine/ORM => src}/UnitOfWork.php (100%) rename {lib/Doctrine/ORM => src}/Utility/HierarchyDiscriminatorResolver.php (100%) rename {lib/Doctrine/ORM => src}/Utility/IdentifierFlattener.php (100%) rename {lib/Doctrine/ORM => src}/Utility/PersisterHelper.php (100%) rename {lib/Doctrine/ORM => src}/Version.php (100%) rename tests/{Doctrine => }/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php (100%) rename tests/{Doctrine => }/Performance/EntityManagerFactory.php (100%) rename tests/{Doctrine => }/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleHydrationBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleInsertPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php (100%) rename tests/{Doctrine => }/Performance/LazyLoading/ProxyInitializationTimeBench.php (100%) rename tests/{Doctrine => }/Performance/LazyLoading/ProxyInstantiationTimeBench.php (100%) rename tests/{Doctrine => }/Performance/Mock/NonLoadingPersister.php (100%) rename tests/{Doctrine => }/Performance/Mock/NonProxyLoadingEntityManager.php (100%) rename tests/{Doctrine => }/Performance/Mock/NonProxyLoadingUnitOfWork.php (100%) rename tests/{Doctrine => }/Performance/Query/QueryBoundParameterProcessingBench.php (100%) rename tests/{Doctrine => }/StaticAnalysis/Mapping/class-metadata-constructor.php (100%) rename tests/{Doctrine => }/StaticAnalysis/Tools/Pagination/paginator-covariant.php (100%) rename tests/{Doctrine => }/StaticAnalysis/get-metadata.php (100%) rename tests/{Doctrine => }/Tests/DbalExtensions/Connection.php (100%) rename tests/{Doctrine => }/Tests/DbalExtensions/LegacySqlLogger.php (100%) rename tests/{Doctrine => }/Tests/DbalExtensions/QueryLog.php (100%) rename tests/{Doctrine => }/Tests/DbalExtensions/SqlLogger.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/CustomIdObject.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/CustomIdObjectType.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/CustomIntType.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/GH8565EmployeePayloadType.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/GH8565ManagerPayloadType.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/NegativeToPositiveType.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/Rot13Type.php (100%) rename tests/{Doctrine => }/Tests/DbalTypes/UpperCaseStringType.php (100%) rename tests/{Doctrine => }/Tests/DoctrineTestCase.php (100%) rename tests/{Doctrine => }/Tests/EventListener/CacheMetadataListener.php (100%) rename tests/{Doctrine => }/Tests/IterableTester.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ArrayResultFactory.php (100%) rename tests/{Doctrine => }/Tests/Mocks/CacheEntryMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/CacheKeyMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/CacheRegionMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ConcurrentRegionMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ConnectionMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/CustomTreeWalkerJoin.php (100%) rename tests/{Doctrine => }/Tests/Mocks/DatabasePlatformMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/DriverConnectionMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/DriverMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/DriverResultMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/EntityManagerMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/EntityPersisterMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ExceptionConverterMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/MetadataDriverMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/NullSqlWalker.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ResultMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/ResultStatement.php (100%) rename tests/{Doctrine => }/Tests/Mocks/SchemaManagerMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/StatementMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/TimestampRegionMock.php (100%) rename tests/{Doctrine => }/Tests/Mocks/UnitOfWorkMock.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsAddress.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsAddressDTO.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsAddressListener.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsArticle.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsComment.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsEmail.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsEmployee.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsGroup.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsPhonenumber.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsTag.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsUser.php (100%) rename tests/{Doctrine => }/Tests/Models/CMS/CmsUserDTO.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Action.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Address.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Attraction.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/AttractionContactInfo.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/AttractionInfo.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/AttractionLocationInfo.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Bar.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Beach.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/City.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Client.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/ComplexAction.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Country.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Flight.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Login.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Person.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Restaurant.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/State.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Token.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Travel.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/Traveler.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/TravelerProfile.php (100%) rename tests/{Doctrine => }/Tests/Models/Cache/TravelerProfileInfo.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyAuction.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyCar.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyContract.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyContractListener.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyEmployee.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyEvent.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyFixContract.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyFlexContract.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyFlexUltraContract.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyFlexUltraContractListener.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyManager.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyOrganization.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyPerson.php (100%) rename tests/{Doctrine => }/Tests/Models/Company/CompanyRaffle.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/JoinedDerivedChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/JoinedDerivedIdentityClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/JoinedDerivedRootClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/SingleChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CompositeKeyInheritance/SingleRootClass.php (100%) rename tests/{Doctrine => }/Tests/Models/CustomType/CustomIdObjectTypeChild.php (100%) rename tests/{Doctrine => }/Tests/Models/CustomType/CustomIdObjectTypeParent.php (100%) rename tests/{Doctrine => }/Tests/Models/CustomType/CustomTypeChild.php (100%) rename tests/{Doctrine => }/Tests/Models/CustomType/CustomTypeParent.php (100%) rename tests/{Doctrine => }/Tests/Models/CustomType/CustomTypeUpperCase.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117ApproveChanges.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117Article.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117ArticleDetails.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117Editor.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117Link.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117Reference.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC117/DDC117Translation.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1476/DDC1476EntityWithDefaultFieldType.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1590/DDC1590Entity.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1590/DDC1590User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1872/DDC1872Bar.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1872/DDC1872ExampleEntityWithOverride.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1872/DDC1872ExampleEntityWithoutOverride.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC1872/DDC1872ExampleTrait.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2372/DDC2372Address.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2372/DDC2372Admin.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2372/DDC2372User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2372/Traits/DDC2372AddressAndAccessors.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2504/DDC2504ChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2504/DDC2504OtherClass.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2504/DDC2504RootClass.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2825/ExplicitSchemaAndTable.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC2825/SchemaAndTableInTableName.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3231/DDC3231EntityRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3231/DDC3231User1.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3231/DDC3231User1NoNamespace.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3231/DDC3231User2.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3231/DDC3231User2NoNamespace.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3293/DDC3293Address.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3293/DDC3293User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3293/DDC3293UserPrefixed.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3346/DDC3346Article.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3346/DDC3346Author.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3579/DDC3579Admin.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3579/DDC3579Group.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3579/DDC3579User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3597/DDC3597Image.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3597/DDC3597Media.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3597/DDC3597Root.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3597/Embeddable/DDC3597Dimension.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3699/DDC3699Child.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3699/DDC3699Parent.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3699/DDC3699RelationMany.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3699/DDC3699RelationOne.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3711/DDC3711EntityA.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3711/DDC3711EntityB.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3899/DDC3899Contract.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3899/DDC3899FixContract.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3899/DDC3899FlexContract.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC3899/DDC3899User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC4006/DDC4006User.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC4006/DDC4006UserId.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC5934/DDC5934BaseContract.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC5934/DDC5934Contract.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC5934/DDC5934Member.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC6412/DDC6412File.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753CustomRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753DefaultRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753EntityWithCustomRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753EntityWithDefaultCustomRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753EntityWithInvalidRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC753/DDC753InvalidRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC869/DDC869ChequePayment.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC869/DDC869CreditCardPayment.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC869/DDC869Payment.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC869/DDC869PaymentRepository.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC889/DDC889Class.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC889/DDC889Entity.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC889/DDC889SuperClass.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC964/DDC964Address.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC964/DDC964Admin.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC964/DDC964Group.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC964/DDC964Guest.php (100%) rename tests/{Doctrine => }/Tests/Models/DDC964/DDC964User.php (100%) rename tests/{Doctrine => }/Tests/Models/DataTransferObjects/DtoWithArrayOfEnums.php (100%) rename tests/{Doctrine => }/Tests/Models/DataTransferObjects/DtoWithEnum.php (100%) rename tests/{Doctrine => }/Tests/Models/DirectoryTree/AbstractContentItem.php (100%) rename tests/{Doctrine => }/Tests/Models/DirectoryTree/Directory.php (100%) rename tests/{Doctrine => }/Tests/Models/DirectoryTree/File.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceCart.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceCategory.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceCustomer.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceFeature.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceProduct.php (100%) rename tests/{Doctrine => }/Tests/Models/ECommerce/ECommerceShipping.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/AccessLevel.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Card.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/CardWithDefault.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/CardWithNullable.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/City.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Product.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Quantity.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Scale.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Suit.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/TypedCard.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/TypedCardEnumCompositeId.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/TypedCardEnumId.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/Unit.php (100%) rename tests/{Doctrine => }/Tests/Models/Enums/UserStatus.php (100%) rename tests/{Doctrine => }/Tests/Models/Forum/ForumAvatar.php (100%) rename tests/{Doctrine => }/Tests/Models/Forum/ForumBoard.php (100%) rename tests/{Doctrine => }/Tests/Models/Forum/ForumCategory.php (100%) rename tests/{Doctrine => }/Tests/Models/Forum/ForumEntry.php (100%) rename tests/{Doctrine => }/Tests/Models/Forum/ForumUser.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10132/Complex.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10132/ComplexChild.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10288/GH10288People.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10334/GH10334Foo.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10334/GH10334FooCollection.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10334/GH10334Product.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10334/GH10334ProductType.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10334/GH10334ProductTypeId.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10336/GH10336Entity.php (100%) rename tests/{Doctrine => }/Tests/Models/GH10336/GH10336Relation.php (100%) rename tests/{Doctrine => }/Tests/Models/GH7141/GH7141Article.php (100%) rename tests/{Doctrine => }/Tests/Models/GH7316/GH7316Article.php (100%) rename tests/{Doctrine => }/Tests/Models/GH7717/GH7717Child.php (100%) rename tests/{Doctrine => }/Tests/Models/GH7717/GH7717Parent.php (100%) rename tests/{Doctrine => }/Tests/Models/GH8565/GH8565Employee.php (100%) rename tests/{Doctrine => }/Tests/Models/GH8565/GH8565Manager.php (100%) rename tests/{Doctrine => }/Tests/Models/GH8565/GH8565Person.php (100%) rename tests/{Doctrine => }/Tests/Models/Generic/BooleanModel.php (100%) rename tests/{Doctrine => }/Tests/Models/Generic/DateTimeModel.php (100%) rename tests/{Doctrine => }/Tests/Models/Generic/DecimalModel.php (100%) rename tests/{Doctrine => }/Tests/Models/Generic/NonAlphaColumnsEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/Generic/SerializationModel.php (100%) rename tests/{Doctrine => }/Tests/Models/GeoNames/Admin1.php (100%) rename tests/{Doctrine => }/Tests/Models/GeoNames/Admin1AlternateName.php (100%) rename tests/{Doctrine => }/Tests/Models/GeoNames/City.php (100%) rename tests/{Doctrine => }/Tests/Models/GeoNames/Country.php (100%) rename tests/{Doctrine => }/Tests/Models/Global/GlobalNamespaceModel.php (100%) rename tests/{Doctrine => }/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php (100%) rename tests/{Doctrine => }/Tests/Models/Hydration/SimpleEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/Issue5989/Issue5989Employee.php (100%) rename tests/{Doctrine => }/Tests/Models/Issue5989/Issue5989Manager.php (100%) rename tests/{Doctrine => }/Tests/Models/Issue5989/Issue5989Person.php (100%) rename tests/{Doctrine => }/Tests/Models/Issue9300/Issue9300Child.php (100%) rename tests/{Doctrine => }/Tests/Models/Issue9300/Issue9300Parent.php (100%) rename tests/{Doctrine => }/Tests/Models/JoinedInheritanceType/AnotherChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/JoinedInheritanceType/ChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/JoinedInheritanceType/RootClass.php (100%) rename tests/{Doctrine => }/Tests/Models/Legacy/LegacyArticle.php (100%) rename tests/{Doctrine => }/Tests/Models/Legacy/LegacyCar.php (100%) rename tests/{Doctrine => }/Tests/Models/Legacy/LegacyUser.php (100%) rename tests/{Doctrine => }/Tests/Models/Legacy/LegacyUserReference.php (100%) rename tests/{Doctrine => }/Tests/Models/ManyToManyPersister/ChildClass.php (100%) rename tests/{Doctrine => }/Tests/Models/ManyToManyPersister/OtherParentClass.php (100%) rename tests/{Doctrine => }/Tests/Models/ManyToManyPersister/ParentClass.php (100%) rename tests/{Doctrine => }/Tests/Models/MixedToOneIdentity/CompositeToOneKeyState.php (100%) rename tests/{Doctrine => }/Tests/Models/MixedToOneIdentity/Country.php (100%) rename tests/{Doctrine => }/Tests/Models/Navigation/NavCountry.php (100%) rename tests/{Doctrine => }/Tests/Models/Navigation/NavPhotos.php (100%) rename tests/{Doctrine => }/Tests/Models/Navigation/NavPointOfInterest.php (100%) rename tests/{Doctrine => }/Tests/Models/Navigation/NavTour.php (100%) rename tests/{Doctrine => }/Tests/Models/Navigation/NavUser.php (100%) rename tests/{Doctrine => }/Tests/Models/NonPublicSchemaJoins/User.php (100%) rename tests/{Doctrine => }/Tests/Models/NullDefault/NullDefaultColumn.php (100%) rename tests/{Doctrine => }/Tests/Models/OneToOneInverseSideLoad/InverseSide.php (100%) rename tests/{Doctrine => }/Tests/Models/OneToOneInverseSideLoad/OwningSide.php (100%) rename tests/{Doctrine => }/Tests/Models/OneToOneSingleTableInheritance/Cat.php (100%) rename tests/{Doctrine => }/Tests/Models/OneToOneSingleTableInheritance/LitterBox.php (100%) rename tests/{Doctrine => }/Tests/Models/OneToOneSingleTableInheritance/Pet.php (100%) rename tests/{Doctrine => }/Tests/Models/OrnementalOrphanRemoval/Person.php (100%) rename tests/{Doctrine => }/Tests/Models/OrnementalOrphanRemoval/PhoneNumber.php (100%) rename tests/{Doctrine => }/Tests/Models/Pagination/Company.php (100%) rename tests/{Doctrine => }/Tests/Models/Pagination/Department.php (100%) rename tests/{Doctrine => }/Tests/Models/Pagination/Logo.php (100%) rename tests/{Doctrine => }/Tests/Models/Pagination/User.php (100%) rename tests/{Doctrine => }/Tests/Models/Pagination/User1.php (100%) rename tests/{Doctrine => }/Tests/Models/PersistentObject/PersistentCollectionContent.php (100%) rename tests/{Doctrine => }/Tests/Models/PersistentObject/PersistentCollectionHolder.php (100%) rename tests/{Doctrine => }/Tests/Models/PersistentObject/PersistentEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/Project/Project.php (100%) rename tests/{Doctrine => }/Tests/Models/Project/ProjectId.php (100%) rename tests/{Doctrine => }/Tests/Models/Project/ProjectInvalidMapping.php (100%) rename tests/{Doctrine => }/Tests/Models/Project/ProjectName.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/Address.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/City.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/FullAddress.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/Group.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/NumericEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/Phone.php (100%) rename tests/{Doctrine => }/Tests/Models/Quote/User.php (100%) rename tests/{Doctrine => }/Tests/Models/ReadonlyProperties/Author.php (100%) rename tests/{Doctrine => }/Tests/Models/ReadonlyProperties/Book.php (100%) rename tests/{Doctrine => }/Tests/Models/ReadonlyProperties/SimpleBook.php (100%) rename tests/{Doctrine => }/Tests/Models/Reflection/AbstractEmbeddable.php (100%) rename tests/{Doctrine => }/Tests/Models/Reflection/ArrayObjectExtendingClass.php (100%) rename tests/{Doctrine => }/Tests/Models/Reflection/ClassWithMixedProperties.php (100%) rename tests/{Doctrine => }/Tests/Models/Reflection/ConcreteEmbeddable.php (100%) rename tests/{Doctrine => }/Tests/Models/Reflection/ParentClass.php (100%) rename tests/{Doctrine => }/Tests/Models/Routing/RoutingLeg.php (100%) rename tests/{Doctrine => }/Tests/Models/Routing/RoutingLocation.php (100%) rename tests/{Doctrine => }/Tests/Models/Routing/RoutingRoute.php (100%) rename tests/{Doctrine => }/Tests/Models/Routing/RoutingRouteBooking.php (100%) rename tests/{Doctrine => }/Tests/Models/StockExchange/Bond.php (100%) rename tests/{Doctrine => }/Tests/Models/StockExchange/Market.php (100%) rename tests/{Doctrine => }/Tests/Models/StockExchange/Stock.php (100%) rename tests/{Doctrine => }/Tests/Models/Taxi/Car.php (100%) rename tests/{Doctrine => }/Tests/Models/Taxi/Driver.php (100%) rename tests/{Doctrine => }/Tests/Models/Taxi/PaidRide.php (100%) rename tests/{Doctrine => }/Tests/Models/Taxi/Ride.php (100%) rename tests/{Doctrine => }/Tests/Models/Tweet/Tweet.php (100%) rename tests/{Doctrine => }/Tests/Models/Tweet/User.php (100%) rename tests/{Doctrine => }/Tests/Models/Tweet/UserList.php (100%) rename tests/{Doctrine => }/Tests/Models/TypedProperties/Contact.php (100%) rename tests/{Doctrine => }/Tests/Models/TypedProperties/UserTyped.php (100%) rename tests/{Doctrine => }/Tests/Models/TypedProperties/UserTypedWithCustomTypedField.php (100%) rename tests/{Doctrine => }/Tests/Models/Upsertable/Insertable.php (100%) rename tests/{Doctrine => }/Tests/Models/Upsertable/Updatable.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/AuxiliaryEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedManyToManyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedManyToManyExtraLazyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToManyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToManyExtraLazyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/InversedOneToOneEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToManyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToManyExtraLazyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToOneEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToOneExtraLazyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningManyToOneIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueConversionType/OwningOneToOneEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueObjects/Name.php (100%) rename tests/{Doctrine => }/Tests/Models/ValueObjects/Person.php (100%) rename tests/{Doctrine => }/Tests/Models/VersionedManyToOne/Article.php (100%) rename tests/{Doctrine => }/Tests/Models/VersionedManyToOne/Category.php (100%) rename tests/{Doctrine => }/Tests/Models/VersionedOneToOne/FirstRelatedEntity.php (100%) rename tests/{Doctrine => }/Tests/Models/VersionedOneToOne/SecondRelatedEntity.php (100%) rename tests/{Doctrine => }/Tests/ORM/AbstractQueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/CacheConfigTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/CacheKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/CacheLoggerChainTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultCacheFactoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultCollectionHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultEntityHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultQueryCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultRegionLegacyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/DefaultRegionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/FileLockRegionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/MultiGetRegionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/RegionTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Cache/StatisticsCacheLoggerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/ConfigurationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Decorator/EntityManagerDecoratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Entity/ConstructorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/EntityManagerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/EntityNotFoundExceptionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Event/OnClassMetadataNotFoundEventArgsTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/AbstractManyToManyAssociationTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/AdvancedAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/AdvancedDqlQueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/BasicFunctionalTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CascadeRemoveOrderTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ClassTableInheritanceTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ClearEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CompositePrimaryKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CompositePrimaryKeyWithAssociationsTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CustomFunctionsTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CustomIdObjectTypeTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/CustomRepositoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/DatabaseDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/DatabaseDriverTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/DefaultValuesTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/DetachedEntityTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/EagerFetchCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/EntityListenersTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/EntityRepositoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/EnumTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ExtraLazyCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/FlushEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/GH7877Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/HydrationCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/IdentityMapTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/IndexByAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/InsertableUpdatableTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/LifecycleCallbackTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Locking/GearmanLockTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Locking/LockAgentWorker.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Locking/LockTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Locking/OptimisticTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToManyEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToManySelfReferentialAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToManyUnidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ManyToOneOrphanRemovalTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/MappedSuperclassTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/MergeCompositeToOneKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/MergeProxiesTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/MergeSharedEntitiesTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/MergeVersionedManyToOneTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/NativeQueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/NewOperatorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/NotifyPolicyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToManyUnidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneEagerLoadingTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneOrphanRemovalTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneSingleTableInheritanceTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OneToOneUnidirectionalAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OrderedCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/OrderedJoinedTableInheritanceCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PaginationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ParserResultSerializationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PersistentCollectionCriteriaTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PersistentCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PersistentObjectTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PostFlushEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/PostLoadEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/QueryBuilderParenthesisTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/QueryCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/QueryDqlFunctionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/QueryIterableTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/QueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ReadOnlyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ReadonlyPropertiesTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ReferenceProxyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ResultCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SQLFilterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaTool/DBAL483Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaTool/DDC214Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SchemaValidatorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyWithAssociationsTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SecondLevelCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SequenceEmulatedIdentityStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SequenceGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SingleTableCompositeKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/SingleTableInheritanceTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/StandardEntityPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1040Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1041Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1043Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1080Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1113Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1129Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1163Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC117Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1181Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1193Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1209Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1225Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1228Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1238Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1250Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1276Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1300Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1301Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1306Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1335Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1383Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1392Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1400Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1404Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC142Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1430Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1436Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC144Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1452Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1454Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1458Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1461Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1509Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1514Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1515Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1526Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1545Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1548Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1594Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1595Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC163Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1643Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1654Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1655Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1666Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1685Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC168Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1690Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1695Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1707Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1719Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1734Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1757Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1778Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1787Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1843Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1884Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1885Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1918Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1925Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC192Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1995Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC1998Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC199Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2012Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2074Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2084Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2090Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2106Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC211Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2138Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2175Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2182Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2214Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2224Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2230Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2231Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2252Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2256Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2306Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2346Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2350Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2359Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC237Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2387Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2409Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2415Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2494Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2519Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2575Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2579Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC258Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2602Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2645Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2655Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2660Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2692Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2759Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2775Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2780Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2790Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC279Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2825Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2862Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2895Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2931Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2943Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2984Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC2996Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3033Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3042Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3068Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC309Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3103Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3123Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3160Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3170Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3192Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3223Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3300Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3303Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC331Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3330Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3346Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC345Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC353Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3582Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3597Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3634Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3644Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3699Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3719Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC371Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3785Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC381Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC3967Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC4003Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC4024Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC422Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC425Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC440Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC444Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC448Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC493Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC501Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC512Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC513Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC518Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC522Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC531Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC5684Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC588Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC599Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC618Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC6303Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC633Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC6460Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC6558Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC656Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC657Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC698Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC69Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC719Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC729Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC735Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC736Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC742Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC748Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC758Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC767Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC7969Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC809Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC812Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC832Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC837Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC849Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC881Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC933Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC949Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC960Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/DDC992Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10049/GH10049Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyInheritor.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyOwner.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10132Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10288Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10334Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10336Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10348Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10387Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10450Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10454Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10462Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10473Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10531Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10532Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10566Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10625Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10747Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10752Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10808Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10869Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH10880Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11058Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH2947Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5562Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5742Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5762Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5804Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5887Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5988Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH5998Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6029Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6141Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6217Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6362Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6394Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6402Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6464Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6499OneToManyRelationshipTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6499OneToOneRelationshipTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6499Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6531Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6682Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6699Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6740Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6823Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH6937Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7006Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7012Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7062Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7067Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7068Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7079Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7180Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7259Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7286Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7366Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7407Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7496WithToIterableTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7505Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7512Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7629Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7661Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7684Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7717Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7735Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7737Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7761Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7767Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7820Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7829Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7836Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7864Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7869Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7875Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH7941Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8055Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8061Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8127Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8217Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8415Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8415ToManyAssociationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8443Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8499Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8663Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH8914Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9027Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9109Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9192Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9230Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9335Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/GH9467Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceChild.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonInsertableColumn.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonUpdatableColumn.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonWritableColumn.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceRoot.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceWritableColumn.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9516Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9579Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/GH9807Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Issue5989Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Issue9300Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket2481Test.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfAbstractTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfMultiLevelTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfParametricTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfWithMultipleParametersTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/TypeTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/TypeValueSqlTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/UUIDGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/UnitOfWorkLifecycleTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/ManyToManyExtraLazyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/ValueObjectsTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/VersionedOneToOneTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.Person.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.PhoneNumber.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/AbstractHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/ArrayHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/CustomHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/HydrationTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/ObjectHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/ResultSetMappingTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/ScalarColumnHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/ScalarHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/SimpleObjectHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Hydration/SingleScalarHydratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Id/AbstractIdGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Id/AssignedGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Id/SequenceGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Internal/HydrationCompleteHandlerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Internal/TopologicalSortTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/LazyCriteriaCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/AnnotationDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/AttributeDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/AttributeReaderTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/BasicInheritanceMappingTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ClassMetadataBuilderTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ClassMetadataFactoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ClassMetadataTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/EntityListenerResolverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/FieldBuilderTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/Fixtures/AttributeEntityWithNestedJoinColumns.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/MappingDriverTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/NamingStrategy/JoinColumnClassNamingStrategy.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/NamingStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/PHPMappingDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/QuoteStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/Reflection/ReflectionPropertiesGetterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ReflectionEmbeddedPropertyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/ReflectionReadonlyPropertyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/Symfony/DriverTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/Symfony/XmlDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/Symfony/YamlDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/TypedFieldMapper/CustomIntAsStringTypedFieldMapper.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/TypedFieldMapperTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/UnderscoreNamingStrategyTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/XmlMappingDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/YamlMappingDriverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsUser.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Cache.City.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyPerson.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579Admin.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579User.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Class.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Entity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889SuperClass.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Enums.Card.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTyped.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Insertable.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Updatable.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Animal.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Comment.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC1170Entity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC807Entity.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.PHPSLC.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/CatNoId.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Cache.City.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293Address.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293User.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293UserPrefixed.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Enums.Card.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7141.GH7141Article.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7316.GH7316Article.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.Project.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.ProjectInvalidMapping.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Name.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Person.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Comment.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectAttributes.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserMissingAttributes.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsUser.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Cache.City.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityA.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityB.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.AbstractContentItem.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.Directory.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.File.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Enums.Card.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Animal.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Comment.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC2069Entity.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/ORMInvalidArgumentExceptionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/ORMSetupTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Performance/SecondLevelCacheTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/PersistentCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeParametersTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeSqlTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Persisters/Exception/UnrecognizedFieldTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Persisters/ManyToManyPersisterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Proxy/ProxyFactoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/AST/InExpressionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/CustomTreeWalkersJoinTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/CustomTreeWalkersTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/DeleteSqlGenerationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/ExprTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/FilterCollectionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/LanguageRecognitionTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/LexerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/ParameterTypeInfererTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/ParserResultTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/ParserTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/QueryExpressionVisitorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/QueryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/SelectSqlGenerationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/SqlExpressionVisitorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/SqlWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/TreeWalkerAdapterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Query/UpdateSqlGenerationTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/QueryBuilderTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/AttachEntityListenersListenerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/EnsureProductionSettingsCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/InfoCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/MappingDescribeCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/SchemaTool/CreateCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/SchemaTool/DropCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/SchemaTool/Models/Keyboard.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/SchemaTool/UpdateCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/Command/ValidateSchemaCommandTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/ConsoleRunnerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Console/MetadataFilterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/DebugTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/EntityGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/EntityRepositoryGeneratorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/AnnotationClassMetadataExporterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/ClassMetadataExporterTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/PhpClassMetadataExporterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/XmlClassMetadataExporterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/YamlClassMetadataExporterTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/php/Doctrine.Tests.ORM.Tools.Export.User.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/xml/Doctrine.Tests.ORM.Tools.Export.User.dcm.xml (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Export/yaml/Doctrine.Tests.ORM.Tools.Export.User.dcm.yml (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/CountWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/PaginationTestCase.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/PaginatorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/RootTypeWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/ResolveTargetEntityListenerTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/SchemaToolTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/SchemaValidatorTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/SetupTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/TestAsset/ChildClass.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/TestAsset/ParentClass.php (100%) rename tests/{Doctrine => }/Tests/ORM/Tools/doctrine1schema/schema.yml (100%) rename tests/{Doctrine => }/Tests/ORM/UnitOfWorkTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Utility/IdentifierFlattenerEnumIdTest.php (100%) rename tests/{Doctrine => }/Tests/ORM/Utility/IdentifierFlattenerTest.php (100%) rename tests/{Doctrine => }/Tests/OrmFunctionalTestCase.php (100%) rename tests/{Doctrine => }/Tests/OrmTestCase.php (100%) rename tests/{Doctrine => }/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php (100%) rename tests/{Doctrine => }/Tests/TestInit.php (79%) rename tests/{Doctrine => }/Tests/TestUtil.php (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30f5fb5c6ad..10390f15c65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ You may fix many some of the issues with `vendor/bin/phpcbf`. Please try to add a test for your pull-request. * If you want to fix a bug or provide a reproduce case, create a test file in - ``tests/Doctrine/Tests/ORM/Functional/Ticket`` with the name of the ticket, + ``tests/Tests/ORM/Functional/Ticket`` with the name of the ticket, ``DDC1234Test.php`` for example. * If you want to contribute new functionality add unit- or functional tests depending on the scope of the feature. @@ -57,7 +57,7 @@ sqlite database. Tips for creating unit tests: 1. If you put a test into the `Ticket` namespace as described above, put the testcase and all entities into the same class. - See `https://github.com/doctrine/orm/tree/2.8.x/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2306Test.php` for an + See `https://github.com/doctrine/orm/tree/2.8.x/tests/Tests/ORM/Functional/Ticket/DDC2306Test.php` for an example. ## Getting merged diff --git a/UPGRADE.md b/UPGRADE.md index 5ac1f28d7df..df40b151d24 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1235,7 +1235,7 @@ The EntityRepository now has an interface Doctrine\Persistence\ObjectRepository. The annotation reader was heavily refactored between 2.0 and 2.1-RC1. In theory the operation of the new reader should be backwards compatible, but it has to be setup differently to work that way: // new call to the AnnotationRegistry - \Doctrine\Common\Annotations\AnnotationRegistry::registerFile('/doctrine-src/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php'); + \Doctrine\Common\Annotations\AnnotationRegistry::registerFile('/doctrine-src/src/Mapping/Driver/DoctrineAnnotations.php'); $reader = new \Doctrine\Common\Annotations\AnnotationReader(); $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\'); diff --git a/ci/github/phpunit/mysqli.xml b/ci/github/phpunit/mysqli.xml index b0605067dfd..97aa45af2f4 100644 --- a/ci/github/phpunit/mysqli.xml +++ b/ci/github/phpunit/mysqli.xml @@ -27,7 +27,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/ci/github/phpunit/pdo_mysql.xml b/ci/github/phpunit/pdo_mysql.xml index b74b05555eb..23cd676a9db 100644 --- a/ci/github/phpunit/pdo_mysql.xml +++ b/ci/github/phpunit/pdo_mysql.xml @@ -27,7 +27,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/ci/github/phpunit/pdo_pgsql.xml b/ci/github/phpunit/pdo_pgsql.xml index 2c53e3c93cb..0360be046f5 100644 --- a/ci/github/phpunit/pdo_pgsql.xml +++ b/ci/github/phpunit/pdo_pgsql.xml @@ -27,7 +27,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/ci/github/phpunit/pdo_sqlite.xml b/ci/github/phpunit/pdo_sqlite.xml index 69e74128110..35de869baf2 100644 --- a/ci/github/phpunit/pdo_sqlite.xml +++ b/ci/github/phpunit/pdo_sqlite.xml @@ -25,7 +25,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/ci/github/phpunit/pgsql.xml b/ci/github/phpunit/pgsql.xml index bccfccf4b6f..b547f47b488 100644 --- a/ci/github/phpunit/pgsql.xml +++ b/ci/github/phpunit/pgsql.xml @@ -27,7 +27,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/ci/github/phpunit/sqlite3.xml b/ci/github/phpunit/sqlite3.xml index b9ae8b43ed7..4b5ed70e6dd 100644 --- a/ci/github/phpunit/sqlite3.xml +++ b/ci/github/phpunit/sqlite3.xml @@ -25,7 +25,7 @@ - ../../../lib/Doctrine + ../../../src diff --git a/composer.json b/composer.json index 7c57474aac6..1404346847a 100644 --- a/composer.json +++ b/composer.json @@ -60,13 +60,13 @@ "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" }, "autoload": { - "psr-4": { "Doctrine\\ORM\\": "lib/Doctrine/ORM" } + "psr-4": { "Doctrine\\ORM\\": "src" } }, "autoload-dev": { "psr-4": { - "Doctrine\\Tests\\": "tests/Doctrine/Tests", - "Doctrine\\StaticAnalysis\\": "tests/Doctrine/StaticAnalysis", - "Doctrine\\Performance\\": "tests/Doctrine/Performance" + "Doctrine\\Tests\\": "tests/Tests", + "Doctrine\\StaticAnalysis\\": "tests/StaticAnalysis", + "Doctrine\\Performance\\": "tests/Performance" } }, "bin": ["bin/doctrine"], diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index 40dea522329..3240623dc22 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -1140,16 +1140,16 @@ and the EntityManager. } } -.. _PrePersistEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PrePersistEventArgs.php -.. _PreRemoveEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreRemoveEventArgs.php -.. _PreUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php -.. _PostPersistEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostPersistEventArgs.php -.. _PostRemoveEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostRemoveEventArgs.php -.. _PostUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostUpdateEventArgs.php -.. _PostLoadEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostLoadEventArgs.php -.. _PreFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PreFlushEventArgs.php -.. _PostFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/PostFlushEventArgs.php -.. _OnFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnFlushEventArgs.php -.. _OnClearEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClearEventArgs.php -.. _LoadClassMetadataEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php -.. _OnClassMetadataNotFoundEventArgs: https://github.com/doctrine/orm/blob/HEAD/lib/Doctrine/ORM/Event/OnClassMetadataNotFoundEventArgs.php +.. _PrePersistEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PrePersistEventArgs.php +.. _PreRemoveEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PreRemoveEventArgs.php +.. _PreUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PreUpdateEventArgs.php +.. _PostPersistEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PostPersistEventArgs.php +.. _PostRemoveEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PostRemoveEventArgs.php +.. _PostUpdateEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PostUpdateEventArgs.php +.. _PostLoadEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PostLoadEventArgs.php +.. _PreFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PreFlushEventArgs.php +.. _PostFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/PostFlushEventArgs.php +.. _OnFlushEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/OnFlushEventArgs.php +.. _OnClearEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/OnClearEventArgs.php +.. _LoadClassMetadataEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/LoadClassMetadataEventArgs.php +.. _OnClassMetadataNotFoundEventArgs: https://github.com/doctrine/orm/blob/HEAD/src/Event/OnClassMetadataNotFoundEventArgs.php diff --git a/phpbench.json b/phpbench.json index 64989be5d6f..c6de1cebaaf 100644 --- a/phpbench.json +++ b/phpbench.json @@ -1,6 +1,6 @@ { - "runner.bootstrap": "tests/Doctrine/Tests/TestInit.php", - "runner.path": "tests/Doctrine/Performance", + "runner.bootstrap": "tests/Tests/TestInit.php", + "runner.path": "tests/Performance", "runner.file_pattern": "*Bench.php", "core.extensions": [ diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 9f7dba86050..3fa9a3f13f1 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -11,12 +11,12 @@ - lib + src tests - */lib/Doctrine/ORM/Mapping/InverseJoinColumn.php - */tests/Doctrine/Tests/Proxies/__CG__* - */tests/Doctrine/Tests/ORM/Tools/Export/export/* + */src/Mapping/InverseJoinColumn.php + */tests/Tests/Proxies/__CG__* + */tests/Tests/ORM/Tools/Export/export/* @@ -34,119 +34,119 @@ - */lib/* + */src/* - tests/Doctrine/Tests/Mocks/HydratorMockStatement.php + tests/Tests/Mocks/HydratorMockStatement.php - */lib/* + */src/* - lib/Doctrine/ORM/Mapping/Driver/CompatibilityAnnotationDriver.php - lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php - lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php + src/Mapping/Driver/CompatibilityAnnotationDriver.php + src/Tools/Console/CommandCompatibility.php + src/Tools/Console/Helper/EntityManagerHelper.php tests/* - lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php + src/Tools/Console/Helper/EntityManagerHelper.php tests/* - lib/Doctrine/ORM/Tools/Debug.php - tests/Doctrine/Tests/ORM/Tools/DebugTest.php + src/Tools/Debug.php + tests/Tests/ORM/Tools/DebugTest.php - lib/Doctrine/ORM/Events.php - lib/Doctrine/ORM/Tools/ToolEvents.php + src/Events.php + src/Tools/ToolEvents.php - lib/Doctrine/ORM/Mapping/Column.php - lib/Doctrine/ORM/Mapping/Index.php - lib/Doctrine/ORM/Mapping/Table.php - lib/Doctrine/ORM/Mapping/UniqueConstraint.php + src/Mapping/Column.php + src/Mapping/Index.php + src/Mapping/Table.php + src/Mapping/UniqueConstraint.php - lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + src/Internal/Hydration/AbstractHydrator.php - lib/Doctrine/ORM/Query/Parser.php + src/Query/Parser.php - lib/Doctrine/ORM/Mapping/AssociationOverride.php - lib/Doctrine/ORM/Mapping/AssociationOverrides.php - lib/Doctrine/ORM/Mapping/AttributeOverride.php - lib/Doctrine/ORM/Mapping/AttributeOverrides.php - lib/Doctrine/ORM/Mapping/Cache.php - lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php - lib/Doctrine/ORM/Mapping/Column.php - lib/Doctrine/ORM/Mapping/ColumnResult.php - lib/Doctrine/ORM/Mapping/CustomIdGenerator.php - lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php - lib/Doctrine/ORM/Mapping/DiscriminatorMap.php - lib/Doctrine/ORM/Mapping/Embeddable.php - lib/Doctrine/ORM/Mapping/Embedded.php - lib/Doctrine/ORM/Mapping/Entity.php - lib/Doctrine/ORM/Mapping/EntityListeners.php - lib/Doctrine/ORM/Mapping/EntityResult.php - lib/Doctrine/ORM/Mapping/FieldResult.php - lib/Doctrine/ORM/Mapping/GeneratedValue.php - lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php - lib/Doctrine/ORM/Mapping/Id.php - lib/Doctrine/ORM/Mapping/Index.php - lib/Doctrine/ORM/Mapping/InheritanceType.php - lib/Doctrine/ORM/Mapping/JoinColumn.php - lib/Doctrine/ORM/Mapping/JoinColumns.php - lib/Doctrine/ORM/Mapping/JoinTable.php - lib/Doctrine/ORM/Mapping/ManyToMany.php - lib/Doctrine/ORM/Mapping/ManyToOne.php - lib/Doctrine/ORM/Mapping/MappedSuperclass.php - lib/Doctrine/ORM/Mapping/NamedNativeQueries.php - lib/Doctrine/ORM/Mapping/NamedNativeQuery.php - lib/Doctrine/ORM/Mapping/NamedQueries.php - lib/Doctrine/ORM/Mapping/NamedQuery.php - lib/Doctrine/ORM/Mapping/OneToMany.php - lib/Doctrine/ORM/Mapping/OneToOne.php - lib/Doctrine/ORM/Mapping/OrderBy.php - lib/Doctrine/ORM/Mapping/PostLoad.php - lib/Doctrine/ORM/Mapping/PostPersist.php - lib/Doctrine/ORM/Mapping/PostRemove.php - lib/Doctrine/ORM/Mapping/PostUpdate.php - lib/Doctrine/ORM/Mapping/PreFlush.php - lib/Doctrine/ORM/Mapping/PrePersist.php - lib/Doctrine/ORM/Mapping/PreRemove.php - lib/Doctrine/ORM/Mapping/PreUpdate.php - lib/Doctrine/ORM/Mapping/SequenceGenerator.php - lib/Doctrine/ORM/Mapping/SqlResultSetMapping.php - lib/Doctrine/ORM/Mapping/SqlResultSetMappings.php - lib/Doctrine/ORM/Mapping/Table.php - lib/Doctrine/ORM/Mapping/UniqueConstraint.php - lib/Doctrine/ORM/Mapping/Version.php + src/Mapping/AssociationOverride.php + src/Mapping/AssociationOverrides.php + src/Mapping/AttributeOverride.php + src/Mapping/AttributeOverrides.php + src/Mapping/Cache.php + src/Mapping/ChangeTrackingPolicy.php + src/Mapping/Column.php + src/Mapping/ColumnResult.php + src/Mapping/CustomIdGenerator.php + src/Mapping/DiscriminatorColumn.php + src/Mapping/DiscriminatorMap.php + src/Mapping/Embeddable.php + src/Mapping/Embedded.php + src/Mapping/Entity.php + src/Mapping/EntityListeners.php + src/Mapping/EntityResult.php + src/Mapping/FieldResult.php + src/Mapping/GeneratedValue.php + src/Mapping/HasLifecycleCallbacks.php + src/Mapping/Id.php + src/Mapping/Index.php + src/Mapping/InheritanceType.php + src/Mapping/JoinColumn.php + src/Mapping/JoinColumns.php + src/Mapping/JoinTable.php + src/Mapping/ManyToMany.php + src/Mapping/ManyToOne.php + src/Mapping/MappedSuperclass.php + src/Mapping/NamedNativeQueries.php + src/Mapping/NamedNativeQuery.php + src/Mapping/NamedQueries.php + src/Mapping/NamedQuery.php + src/Mapping/OneToMany.php + src/Mapping/OneToOne.php + src/Mapping/OrderBy.php + src/Mapping/PostLoad.php + src/Mapping/PostPersist.php + src/Mapping/PostRemove.php + src/Mapping/PostUpdate.php + src/Mapping/PreFlush.php + src/Mapping/PrePersist.php + src/Mapping/PreRemove.php + src/Mapping/PreUpdate.php + src/Mapping/SequenceGenerator.php + src/Mapping/SqlResultSetMapping.php + src/Mapping/SqlResultSetMappings.php + src/Mapping/Table.php + src/Mapping/UniqueConstraint.php + src/Mapping/Version.php - lib/Doctrine/ORM/Cache/DefaultQueryCache.php + src/Cache/DefaultQueryCache.php - lib/Doctrine/ORM/EntityManagerInterface.php + src/EntityManagerInterface.php - tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleTrait.php + tests/Tests/Models/DDC1872/DDC1872ExampleTrait.php @@ -167,25 +167,25 @@ - tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php - tests/Doctrine/Tests/Models/DDC3231/DDC3231User1NoNamespace.php - tests/Doctrine/Tests/Models/DDC3231/DDC3231User2NoNamespace.php + tests/Tests/Models/Global/GlobalNamespaceModel.php + tests/Tests/Models/DDC3231/DDC3231User1NoNamespace.php + tests/Tests/Models/DDC3231/DDC3231User2NoNamespace.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2084Test.php + tests/Tests/ORM/Functional/Ticket/DDC2084Test.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2084Test.php + tests/Tests/ORM/Functional/Ticket/DDC2084Test.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1301Test.php - tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php + tests/Tests/ORM/Functional/Ticket/DDC1301Test.php + tests/Tests/ORM/Functional/ExtraLazyCollectionTest.php - tests/Doctrine/Tests/Models/DDC1590/DDC1590User.php + tests/Tests/Models/DDC1590/DDC1590User.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php + tests/Tests/ORM/Functional/Ticket/DDC832Test.php - tests/Doctrine/Tests/Proxy/DefaultProxyClassNameResolverTest.php + tests/Tests/Proxy/DefaultProxyClassNameResolverTest.php - tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php - tests/Doctrine/Tests/Mocks/DriverMock.php - tests/Doctrine/Tests/ORM/UnitOfWorkTest.php - tests/Doctrine/Tests/ORM/Query/DeleteSqlGenerationTest.php + tests/Tests/Mocks/DatabasePlatformMock.php + tests/Tests/Mocks/DriverMock.php + tests/Tests/ORM/UnitOfWorkTest.php + tests/Tests/ORM/Query/DeleteSqlGenerationTest.php - lib/Doctrine/ORM/Query/AST/Node.php + src/Query/AST/Node.php - tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests* + tests/Tests/ORM/Mapping/php/Doctrine.Tests* - lib/Doctrine/ORM/AbstractQuery.php - lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php - lib/Doctrine/ORM/NativeQuery.php - lib/Doctrine/ORM/Query.php - lib/Doctrine/ORM/Query/TreeWalkerAdapter.php - lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php + src/AbstractQuery.php + src/Mapping/ClassMetadataInfo.php + src/NativeQuery.php + src/Query.php + src/Query/TreeWalkerAdapter.php + src/Tools/Export/Driver/AbstractExporter.php + src/Tools/Export/Driver/AnnotationExporter.php + src/Tools/Export/Driver/PhpExporter.php - tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php - tests/Doctrine/Tests/Mocks/SchemaManagerMock.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php + tests/Tests/Mocks/DatabasePlatformMock.php + tests/Tests/Mocks/SchemaManagerMock.php + tests/Tests/ORM/Functional/Ticket/DDC3634Test.php - lib/Doctrine/ORM/AbstractQuery.php - lib/Doctrine/ORM/Configuration.php - lib/Doctrine/ORM/EntityRepository.php - lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php - lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php - lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php - lib/Doctrine/ORM/Query/Printer.php - lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php - lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php - lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php - lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php + src/AbstractQuery.php + src/Configuration.php + src/EntityRepository.php + src/Internal/Hydration/AbstractHydrator.php + src/Query/Exec/AbstractSqlExecutor.php + src/Query/Exec/AbstractSqlExecutor.php + src/Query/Printer.php + src/Tools/EntityRepositoryGenerator.php + src/Tools/Console/Helper/EntityManagerHelper.php + src/Tools/Export/Driver/AbstractExporter.php + src/Tools/Export/Driver/AnnotationExporter.php + src/Tools/Export/Driver/PhpExporter.php + src/Tools/Export/Driver/XmlExporter.php + src/Tools/Export/Driver/YamlExporter.php - tests/Doctrine/Tests/OrmFunctionalTestCase.php + tests/Tests/OrmFunctionalTestCase.php - lib/Doctrine/ORM/Proxy/ProxyFactory.php + src/Proxy/ProxyFactory.php - tests/Doctrine/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php + tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php - tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1843Test.php + tests/Tests/ORM/Functional/Ticket/DDC1885Test.php + tests/Tests/ORM/Functional/Ticket/DDC1843Test.php - lib/Doctrine/ORM/Id/TableGenerator.php + src/Id/TableGenerator.php - lib/Doctrine/ORM/Id/TableGenerator.php + src/Id/TableGenerator.php - lib/Doctrine/ORM/QueryBuilder.php + src/QueryBuilder.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 007049439c1..e824e0ad896 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -3,639 +3,639 @@ parameters: - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Persisters\\\\Entity\\\\EntityPersister\\:\\:getCacheRegion\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php + path: src/Cache/DefaultEntityHydrator.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Cache\\\\CacheEntry\\:\\:\\$class\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Cache\\\\CacheEntry\\:\\:resolveAssociationEntries\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Persisters\\\\Entity\\\\EntityPersister\\:\\:getCacheRegion\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Persisters\\\\Entity\\\\EntityPersister\\:\\:storeEntityCache\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Parameter \\#2 \\$key of method Doctrine\\\\ORM\\\\Cache\\\\Logging\\\\CacheLogger\\:\\:entityCacheHit\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheKey, Doctrine\\\\ORM\\\\Cache\\\\CacheKey given\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Parameter \\#2 \\$key of method Doctrine\\\\ORM\\\\Cache\\\\Logging\\\\CacheLogger\\:\\:entityCacheMiss\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheKey, Doctrine\\\\ORM\\\\Cache\\\\CacheKey given\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/DefaultQueryCache.php + path: src/Cache/DefaultQueryCache.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Cache\\\\CacheEntry\\:\\:\\$identifiers\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php + path: src/Cache/Persister/Collection/AbstractCollectionPersister.php - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php + path: src/Cache/Persister/Collection/AbstractCollectionPersister.php - message: "#^Parameter \\#2 \\$key of method Doctrine\\\\ORM\\\\Cache\\\\EntityHydrator\\:\\:buildCacheEntry\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheKey, Doctrine\\\\ORM\\\\Cache\\\\CacheKey given\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php + path: src/Cache/Persister/Collection/AbstractCollectionPersister.php - message: "#^Parameter \\#3 \\$entry of method Doctrine\\\\ORM\\\\Cache\\\\CollectionHydrator\\:\\:loadCacheEntry\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\CollectionCacheEntry, Doctrine\\\\ORM\\\\Cache\\\\CacheEntry given\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php + path: src/Cache/Persister/Collection/AbstractCollectionPersister.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Cache\\\\Region\\:\\:lock\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php + path: src/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Cache\\\\CacheEntry\\:\\:\\$class\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php + path: src/Cache/Persister/Entity/AbstractEntityPersister.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Cache\\\\Persister\\\\CachedPersister&Doctrine\\\\ORM\\\\Persisters\\\\Collection\\\\CollectionPersister\\:\\:loadCollectionCache\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php + path: src/Cache/Persister/Entity/AbstractEntityPersister.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Cache\\\\Persister\\\\CachedPersister&Doctrine\\\\ORM\\\\Persisters\\\\Collection\\\\CollectionPersister\\:\\:storeCollectionCache\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php + path: src/Cache/Persister/Entity/AbstractEntityPersister.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Persisters\\\\Entity\\\\EntityPersister\\:\\:storeEntityCache\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php + path: src/Cache/Persister/Entity/AbstractEntityPersister.php - message: "#^Parameter \\#3 \\$entry of method Doctrine\\\\ORM\\\\Cache\\\\EntityHydrator\\:\\:loadCacheEntry\\(\\) expects Doctrine\\\\ORM\\\\Cache\\\\EntityCacheEntry, Doctrine\\\\ORM\\\\Cache\\\\CacheEntry given\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php + path: src/Cache/Persister/Entity/AbstractEntityPersister.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Cache\\\\Region\\:\\:lock\\(\\)\\.$#" count: 2 - path: lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php + path: src/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php - message: "#^If condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php + path: src/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php - message: "#^Method Doctrine\\\\ORM\\\\Cache\\\\Region\\\\DefaultRegion\\:\\:getCache\\(\\) should return Doctrine\\\\Common\\\\Cache\\\\CacheProvider but returns Doctrine\\\\Common\\\\Cache\\\\Cache\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/Region/DefaultRegion.php + path: src/Cache/Region/DefaultRegion.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Cache\\\\CacheEntry\\:\\:\\$time\\.$#" count: 1 - path: lib/Doctrine/ORM/Cache/TimestampQueryCacheValidator.php + path: src/Cache/TimestampQueryCacheValidator.php - message: "#^Class Doctrine\\\\Common\\\\Cache\\\\ArrayCache not found\\.$#" count: 2 - path: lib/Doctrine/ORM/Configuration.php + path: src/Configuration.php - message: "#^Method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:find\\(\\) invoked with 4 parameters, 2 required\\.$#" count: 1 - path: lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php + path: src/Decorator/EntityManagerDecorator.php - message: "#^Method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:flush\\(\\) invoked with 1 parameter, 0 required\\.$#" count: 1 - path: lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php + path: src/Decorator/EntityManagerDecorator.php - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/EntityManager.php + path: src/EntityManager.php - message: "#^Result of && is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/EntityManager.php + path: src/EntityManager.php - message: "#^Return type \\(Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataFactory\\) of method Doctrine\\\\ORM\\\\EntityManager\\:\\:getMetadataFactory\\(\\) should be compatible with return type \\(Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadataFactory\\\\>\\) of method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:getMetadataFactory\\(\\)$#" count: 2 - path: lib/Doctrine/ORM/EntityManager.php + path: src/EntityManager.php - message: "#^Template type T of method Doctrine\\\\ORM\\\\EntityManagerInterface\\:\\:getClassMetadata\\(\\) is not referenced in a parameter\\.$#" count: 1 - path: lib/Doctrine/ORM/EntityManagerInterface.php + path: src/EntityManagerInterface.php - message: "#^Method Doctrine\\\\ORM\\\\EntityRepository\\:\\:matching\\(\\) should return Doctrine\\\\Common\\\\Collections\\\\AbstractLazyCollection\\&Doctrine\\\\Common\\\\Collections\\\\Selectable\\ but returns Doctrine\\\\ORM\\\\LazyCriteriaCollection\\<\\(int\\|string\\), object\\>\\.$#" count: 1 - path: lib/Doctrine/ORM/EntityRepository.php + path: src/EntityRepository.php - message: "#^Method Doctrine\\\\Persistence\\\\ObjectManager\\:\\:find\\(\\) invoked with 4 parameters, 2 required\\.$#" count: 1 - path: lib/Doctrine/ORM/EntityRepository.php + path: src/EntityRepository.php - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Platforms\\\\AbstractPlatform\\:\\:getTableHiLoCurrentValSql\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Id/TableGenerator.php + path: src/Id/TableGenerator.php - message: "#^Call to an undefined method Doctrine\\\\DBAL\\\\Platforms\\\\AbstractPlatform\\:\\:getTableHiLoUpdateNextValSql\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Id/TableGenerator.php + path: src/Id/TableGenerator.php - message: "#^If condition is always true\\.$#" count: 2 - path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php + path: src/Mapping/ClassMetadataFactory.php - message: "#^Parameter \\#2 \\$class of method Doctrine\\\\ORM\\\\Mapping\\\\QuoteStrategy\\:\\:getSequenceName\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo given\\.$#" count: 2 - path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php + path: src/Mapping/ClassMetadataFactory.php - message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\:\\:fullyQualifiedClassName\\(\\) should return class\\-string\\|null but returns string\\|null\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php + path: src/Mapping/ClassMetadataInfo.php - message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\NamingStrategy\\:\\:joinColumnName\\(\\) invoked with 2 parameters, 1 required\\.$#" count: 2 - path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php + path: src/Mapping/ClassMetadataInfo.php - message: "#^Negated boolean expression is always false\\.$#" count: 2 - path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php + path: src/Mapping/ClassMetadataInfo.php - message: "#^Result of && is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php + path: src/Mapping/ClassMetadataInfo.php - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapEmbedded\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapManyToMany\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapManyToOne\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapOneToMany\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Call to an undefined method Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:mapOneToOne\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php + path: src/Mapping/Driver/AnnotationDriver.php - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php + path: src/Mapping/Driver/AttributeDriver.php - message: "#^Parameter \\#4 \\.\\.\\.\\$args of static method Doctrine\\\\Deprecations\\\\Deprecation\\:\\:trigger\\(\\) expects float\\|int\\|string, false given\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php + path: src/Mapping/Driver/DatabaseDriver.php - message: "#^Empty array passed to foreach\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: "#^Offset 'version' on \\*NEVER\\* in isset\\(\\) always exists and is always null\\.$#" count: 1 - path: lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: "#^Call to function is_int\\(\\) with string will always evaluate to false\\.$#" count: 1 - path: lib/Doctrine/ORM/NativeQuery.php + path: src/NativeQuery.php - message: "#^Result of && is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/NativeQuery.php + path: src/NativeQuery.php - message: "#^Method Doctrine\\\\ORM\\\\Persisters\\\\Collection\\\\OneToManyPersister\\:\\:delete\\(\\) should return int\\|null but empty return statement found\\.$#" count: 1 - path: lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php + path: src/Persisters/Collection/OneToManyPersister.php - message: "#^Parameter \\#3 \\$hints of method Doctrine\\\\ORM\\\\Internal\\\\Hydration\\\\AbstractHydrator\\:\\:hydrateAll\\(\\) expects array\\, array\\ given\\.$#" count: 1 - path: lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php + path: src/Persisters/Entity/BasicEntityPersister.php - message: "#^Parameter \\#3 \\$hints of method Doctrine\\\\ORM\\\\Internal\\\\Hydration\\\\AbstractHydrator\\:\\:hydrateAll\\(\\) expects array\\, array\\ given\\.$#" count: 4 - path: lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php + path: src/Persisters/Entity/BasicEntityPersister.php - message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" count: 1 - path: lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php + path: src/Persisters/Entity/BasicEntityPersister.php - message: "#^Property Doctrine\\\\ORM\\\\Persisters\\\\Entity\\\\CachedPersisterContext\\:\\:\\$class \\(Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata\\) does not accept Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\.$#" count: 1 - path: lib/Doctrine/ORM/Persisters/Entity/CachedPersisterContext.php + path: src/Persisters/Entity/CachedPersisterContext.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$isEmbeddedClass\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$isMappedSuperclass\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Call to an undefined method Doctrine\\\\Common\\\\Proxy\\\\Proxy\\:\\:__wakeup\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Call to an undefined static method Doctrine\\\\ORM\\\\Proxy\\\\ProxyFactory\\:\\:createLazyGhost\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Comparison operation \"\\<\" between 0\\|1\\|2\\|3\\|4 and 0 is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Comparison operation \"\\>\" between 0\\|1\\|2\\|3\\|4 and 4 is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Parameter \\#1 \\$class of method Doctrine\\\\ORM\\\\Utility\\\\IdentifierFlattener\\:\\:flattenIdentifier\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata given\\.$#" count: 3 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Result of \\|\\| is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Proxy/ProxyFactory.php + path: src/Proxy/ProxyFactory.php - message: "#^Parameter \\#2 \\$sqlParams of method Doctrine\\\\ORM\\\\Query\\:\\:evictResultSetCache\\(\\) expects array\\, array\\ given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query.php + path: src/Query.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node\\:\\:\\$value\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php + path: src/Query/AST/Functions/DateAddFunction.php - message: "#^Access to an undefined property Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node\\:\\:\\$value\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php + path: src/Query/AST/Functions/DateSubFunction.php - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php + path: src/Query/AST/Functions/LengthFunction.php - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php + path: src/Query/AST/Functions/LowerFunction.php - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php + path: src/Query/AST/Functions/UpperFunction.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\AST\\\\IndexBy\\:\\:dispatch\\(\\) should return string but returns void\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/IndexBy.php + path: src/Query/AST/IndexBy.php - message: "#^Result of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkIndexBy\\(\\) \\(void\\) is used\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/IndexBy.php + path: src/Query/AST/IndexBy.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkJoinPathExpression\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/JoinClassPathExpression.php + path: src/Query/AST/JoinClassPathExpression.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkJoinVariableDeclaration\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php + path: src/Query/AST/JoinVariableDeclaration.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkWhenClauseExpression\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php + path: src/Query/AST/SimpleWhenClause.php - message: "#^Call to an undefined method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkWhenClauseExpression\\(\\)\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/WhenClause.php + path: src/Query/AST/WhenClause.php - message: "#^Property Doctrine\\\\ORM\\\\Query\\\\Exec\\\\AbstractSqlExecutor\\:\\:\\$queryCacheProfile \\(Doctrine\\\\DBAL\\\\Cache\\\\QueryCacheProfile\\) does not accept null\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php + path: src/Query/Exec/AbstractSqlExecutor.php - message: "#^PHPDoc type array\\ of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Andx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\ of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Expr/Andx.php + path: src/Query/Expr/Andx.php - message: "#^PHPDoc type array\\ of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Orx\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\ of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Expr/Orx.php + path: src/Query/Expr/Orx.php - message: "#^PHPDoc type array\\ of property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Select\\:\\:\\$allowedClasses is not covariant with PHPDoc type array\\ of overridden property Doctrine\\\\ORM\\\\Query\\\\Expr\\\\Base\\:\\:\\$allowedClasses\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Expr/Select.php + path: src/Query/Expr/Select.php - message: "#^Comparison operation \"\\<\" between null and 102 is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\Parser\\:\\:ArithmeticFactor\\(\\) should return Doctrine\\\\ORM\\\\Query\\\\AST\\\\ArithmeticFactor but returns Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node\\|string\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\Parser\\:\\:ArithmeticTerm\\(\\) should return Doctrine\\\\ORM\\\\Query\\\\AST\\\\ArithmeticTerm but returns Doctrine\\\\ORM\\\\Query\\\\AST\\\\ArithmeticFactor\\|string\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Parameter \\#2 \\$stringPattern of class Doctrine\\\\ORM\\\\Query\\\\AST\\\\LikeExpression constructor expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\Functions\\\\FunctionNode\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\InputParameter\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\Literal\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\PathExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Result of && is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 4 - path: lib/Doctrine/ORM/Query/Parser.php + path: src/Query/Parser.php - message: "#^Offset 'columns' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php + path: src/Query/ResultSetMappingBuilder.php - message: "#^Offset 'entities' on array\\{name\\: string, entities\\: array, columns\\: array\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php + path: src/Query/ResultSetMappingBuilder.php - message: "#^Parameter \\#2 \\$class of static method Doctrine\\\\ORM\\\\Utility\\\\PersisterHelper\\:\\:getTypeOfColumn\\(\\) expects Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadata, Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php + path: src/Query/ResultSetMappingBuilder.php - message: "#^Call to function is_string\\(\\) with Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node will always evaluate to false\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php + path: src/Query/SqlWalker.php - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php + path: src/Query/SqlWalker.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkConditionalPrimary\\(\\) should return string but return statement is missing\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php + path: src/Query/SqlWalker.php - message: "#^Parameter \\#1 \\$condTerm of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkConditionalTerm\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalFactor\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalPrimary\\|Doctrine\\\\ORM\\\\Query\\\\AST\\\\ConditionalTerm, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Phase2OptimizableConditional given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php + path: src/Query/SqlWalker.php - message: "#^Result of && is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/SqlWalker.php + path: src/Query/SqlWalker.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\TreeWalkerAdapter\\:\\:getExecutor\\(\\) should return Doctrine\\\\ORM\\\\Query\\\\Exec\\\\AbstractSqlExecutor but returns null\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/TreeWalkerAdapter.php + path: src/Query/TreeWalkerAdapter.php - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\TreeWalkerChain\\:\\:getExecutor\\(\\) should return Doctrine\\\\ORM\\\\Query\\\\Exec\\\\AbstractSqlExecutor but returns null\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/TreeWalkerChain.php + path: src/Query/TreeWalkerChain.php - message: "#^Parameter \\#2 \\$value \\(string\\) of method Doctrine\\\\ORM\\\\Query\\\\TreeWalkerChainIterator\\:\\:offsetSet\\(\\) should be compatible with parameter \\$value \\(Doctrine\\\\ORM\\\\Query\\\\TreeWalker\\) of method ArrayAccess\\\\:\\:offsetSet\\(\\)$#" count: 1 - path: lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php + path: src/Query/TreeWalkerChainIterator.php - message: "#^PHPDoc tag @param references unknown parameter\\: \\$where$#" count: 2 - path: lib/Doctrine/ORM/QueryBuilder.php + path: src/QueryBuilder.php - message: "#^Parameter \\#2 \\$dqlPart of method Doctrine\\\\ORM\\\\QueryBuilder\\:\\:add\\(\\) expects array\\<'join'\\|int, array\\\\|string\\>\\|object\\|string, non\\-empty\\-array\\ given\\.$#" count: 2 - path: lib/Doctrine/ORM/QueryBuilder.php + path: src/QueryBuilder.php - message: "#^Class Doctrine\\\\Common\\\\Cache\\\\ApcCache not found\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php + path: src/Tools/Console/Command/ClearCache/QueryCommand.php - message: "#^Class Doctrine\\\\Common\\\\Cache\\\\XcacheCache not found\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php + path: src/Tools/Console/Command/ClearCache/QueryCommand.php - message: "#^Class Doctrine\\\\Common\\\\Cache\\\\ApcCache not found\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php + path: src/Tools/Console/Command/ClearCache/ResultCommand.php - message: "#^Class Doctrine\\\\Common\\\\Cache\\\\XcacheCache not found\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php + path: src/Tools/Console/Command/ClearCache/ResultCommand.php - message: "#^Parameter \\#1 \\$metadata of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:setMetadata\\(\\) expects array\\, array\\ given\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php + path: src/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$name\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php + path: src/Tools/Console/Command/ConvertMappingCommand.php - message: "#^Parameter \\#1 \\$metadata of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:setMetadata\\(\\) expects array\\, array\\ given\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php + path: src/Tools/Console/Command/ConvertMappingCommand.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$name\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php + path: src/Tools/Console/Command/GenerateEntitiesCommand.php - message: "#^Parameter \\#1 \\$metadatas of method Doctrine\\\\ORM\\\\Tools\\\\EntityGenerator\\:\\:generate\\(\\) expects array\\, array\\ given\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php + path: src/Tools/Console/Command/GenerateEntitiesCommand.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$name\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php + path: src/Tools/Console/Command/GenerateProxiesCommand.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$customRepositoryClassName\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php + path: src/Tools/Console/Command/GenerateRepositoriesCommand.php - message: "#^Parameter \\#1 \\$entityListeners of method Doctrine\\\\ORM\\\\Tools\\\\Console\\\\Command\\\\MappingDescribeCommand\\:\\:formatEntityListeners\\(\\) expects array\\, array\\\\>\\> given\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php + path: src/Tools/Console/Command/MappingDescribeCommand.php - message: "#^Offset 'allocationSize' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/EntityGenerator.php + path: src/Tools/EntityGenerator.php - message: "#^Offset 'initialValue' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/EntityGenerator.php + path: src/Tools/EntityGenerator.php - message: "#^Offset 'name' on array\\{name\\: string, schema\\?\\: string, indexes\\?\\: array, uniqueConstraints\\?\\: array, options\\?\\: array\\, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/EntityGenerator.php + path: src/Tools/EntityGenerator.php - message: "#^Offset 'sequenceName' on array\\{sequenceName\\: string, allocationSize\\: string, initialValue\\: string, quoted\\?\\: mixed\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/EntityGenerator.php + path: src/Tools/EntityGenerator.php - message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\\\:\\:\\$lifecycleCallbacks \\(array\\\\>\\) in isset\\(\\) is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/EntityGenerator.php + path: src/Tools/EntityGenerator.php - message: "#^Method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:_getIdGeneratorTypeString\\(\\) should return string but return statement is missing\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php + path: src/Tools/Export/Driver/AbstractExporter.php - message: "#^If condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php + path: src/Tools/Export/Driver/PhpExporter.php - message: "#^Offset 'name' on array\\{name\\: string, schema\\?\\: string, indexes\\?\\: array, uniqueConstraints\\?\\: array, options\\?\\: array\\, quoted\\?\\: bool\\} in isset\\(\\) always exists and is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php + path: src/Tools/Export/Driver/XmlExporter.php - message: "#^Parameter \\#1 \\$policy of method Doctrine\\\\ORM\\\\Tools\\\\Export\\\\Driver\\\\AbstractExporter\\:\\:_getChangeTrackingPolicyString\\(\\) expects 1\\|2\\|3, int given\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php + path: src/Tools/Export/Driver/XmlExporter.php - message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\\\:\\:\\$lifecycleCallbacks \\(array\\\\>\\) in isset\\(\\) is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php + path: src/Tools/Export/Driver/XmlExporter.php - message: "#^Right side of && is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php + path: src/Tools/Export/Driver/XmlExporter.php - message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\\\:\\:\\$lifecycleCallbacks \\(array\\\\>\\) in isset\\(\\) is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php + path: src/Tools/Export/Driver/YamlExporter.php - message: "#^Property Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\\\:\\:\\$table \\(array\\\\) on left side of \\?\\? is not nullable\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php + path: src/Tools/Export/Driver/YamlExporter.php - message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/SchemaTool.php + path: src/Tools/SchemaTool.php - message: "#^Negated boolean expression is always false\\.$#" count: 1 - path: lib/Doctrine/ORM/Tools/SchemaTool.php + path: src/Tools/SchemaTool.php - message: "#^Parameter \\#3 \\$changeSet of class Doctrine\\\\ORM\\\\Event\\\\PreUpdateEventArgs constructor is passed by reference, so it expects variables only$#" count: 1 - path: lib/Doctrine/ORM/UnitOfWork.php + path: src/UnitOfWork.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$name\\.$#" count: 1 - path: lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php + path: src/Utility/HierarchyDiscriminatorResolver.php - message: "#^Access to an undefined property Doctrine\\\\Persistence\\\\Mapping\\\\ClassMetadata\\:\\:\\$subClasses\\.$#" count: 1 - path: lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php + path: src/Utility/HierarchyDiscriminatorResolver.php diff --git a/phpstan-dbal2.neon b/phpstan-dbal2.neon index c2a8bcb4476..47c7a5457ca 100644 --- a/phpstan-dbal2.neon +++ b/phpstan-dbal2.neon @@ -12,7 +12,7 @@ parameters: - '/^Class Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform not found\.$/' - message: '/Doctrine\\DBAL\\Platforms\\MyS(ql|QL)Platform/' - path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php + path: src/Mapping/ClassMetadataFactory.php # Forward compatibility for DBAL 3.5 - '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getAlterSchemaSQL\(\).$/' @@ -20,44 +20,44 @@ parameters: # Forward compatibility for DBAL 3.4 - '/^Call to an undefined method Doctrine\\DBAL\\Cache\\QueryCacheProfile::[gs]etResultCache\(\)\.$/' - - message: '/^Call to an undefined static method Doctrine\\DBAL\\Configuration::[gs]etResultCache\(\)\.$/' - path: lib/Doctrine/ORM/Configuration.php + message: '/^Call to an undefined static method Doctrine\\DBAL\\Configuration::[gs]etResultCache\(\)\.$/' + path: src/Configuration.php - - message: '/^Parameter #3 \$resultCache of class Doctrine\\DBAL\\Cache\\QueryCacheProfile constructor/' - path: lib/Doctrine/ORM/AbstractQuery.php + message: '/^Parameter #3 \$resultCache of class Doctrine\\DBAL\\Cache\\QueryCacheProfile constructor/' + path: src/AbstractQuery.php - message: '/^Parameter #2 \$\w+ of method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getDateAdd\w+Expression\(\) expects int, string given\.$/' - path: lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php + path: src/Query/AST/Functions/DateAddFunction.php - message: '/^Parameter #2 \$\w+ of method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getDateSub\w+Expression\(\) expects int, string given\.$/' - path: lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php + path: src/Query/AST/Functions/DateSubFunction.php # False positive - message: '/^Call to an undefined method Doctrine\\Common\\Cache\\Cache::deleteAll\(\)\.$/' count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php + path: src/Tools/Console/Command/ClearCache/ResultCommand.php # See https://github.com/doctrine/dbal/pull/5129 - message: '/^Parameter #3 \$startPos of method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getLocateExpression\(\) expects int\|false, string given\.$/' count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php + path: src/Query/AST/Functions/LocateFunction.php # Won't get fixed in DBAL 2 - message: "#^Parameter \\#2 \\$start of method Doctrine\\\\DBAL\\\\Platforms\\\\AbstractPlatform\\:\\:getSubstringExpression\\(\\) expects int, string given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php + path: src/Query/AST/Functions/SubstringFunction.php - message: "#^Parameter \\#3 \\$length of method Doctrine\\\\DBAL\\\\Platforms\\\\AbstractPlatform\\:\\:getSubstringExpression\\(\\) expects int\\|null, string\\|null given\\.$#" count: 1 - path: lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php + path: src/Query/AST/Functions/SubstringFunction.php - message: '#^Class Doctrine\\DBAL\\Platforms\\MySQLPlatform not found\.$#' count: 2 - path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php + path: src/Mapping/ClassMetadataFactory.php # Symfony cache supports passing a key prefix to the clear method. - '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/' @@ -65,10 +65,10 @@ parameters: # Persistence 2 support - message: '/clear.*invoked with 1 parameter/' - path: lib/Doctrine/ORM/EntityRepository.php + path: src/EntityRepository.php - message: '#^Class Doctrine\\Persistence\\ObjectManagerAware not found\.$#' - path: lib/Doctrine/ORM/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Call to method injectObjectManager\(\) on an unknown class Doctrine\\Persistence\\ObjectManagerAware\.$#' - path: lib/Doctrine/ORM/UnitOfWork.php + path: src/UnitOfWork.php diff --git a/phpstan-params.neon b/phpstan-params.neon index cdc1e7cd511..8f0a4cc2333 100644 --- a/phpstan-params.neon +++ b/phpstan-params.neon @@ -1,10 +1,10 @@ parameters: level: 5 paths: - - lib - - tests/Doctrine/StaticAnalysis + - src + - tests/StaticAnalysis excludePaths: - - lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php + - src/Mapping/Driver/AttributeReader.php earlyTerminatingMethodCalls: Doctrine\ORM\Query\Parser: - syntaxError diff --git a/phpstan-persistence2.neon b/phpstan-persistence2.neon index 41d9db7a30c..7da96fb7d4c 100644 --- a/phpstan-persistence2.neon +++ b/phpstan-persistence2.neon @@ -10,29 +10,29 @@ parameters: # Fallback logic for DBAL 2 - message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/' - path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php + path: src/Tools/Console/ConsoleRunner.php - '/^Class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform not found\.$/' - '/^Call to method \w+\(\) on an unknown class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform\.$/' - - message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/' - path: lib/Doctrine/ORM/Internal/SQLResultCasing.php + message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/' + path: src/Internal/SQLResultCasing.php - - message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/' + path: src/Internal/Hydration/AbstractHydrator.php - - message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/' + path: src/Internal/Hydration/AbstractHydrator.php - - message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' + path: src/Internal/Hydration/AbstractHydrator.php # False positive - message: '/^Call to an undefined method Doctrine\\Common\\Cache\\Cache::deleteAll\(\)\.$/' count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php + path: src/Tools/Console/Command/ClearCache/ResultCommand.php # Symfony cache supports passing a key prefix to the clear method. - '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/' diff --git a/phpstan.neon b/phpstan.neon index c80418eede6..073376e99f6 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,29 +10,29 @@ parameters: # Fallback logic for DBAL 2 - message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/' - path: lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php + path: src/Tools/Console/ConsoleRunner.php - '/^Class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform not found\.$/' - '/^Call to method \w+\(\) on an unknown class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform\.$/' - - message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/' - path: lib/Doctrine/ORM/Internal/SQLResultCasing.php + message: '/^Call to an undefined method Doctrine\\DBAL\\Platforms\\AbstractPlatform::getSQLResultCasing\(\)\.$/' + path: src/Internal/SQLResultCasing.php - - message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Parameter \$stmt of method .* has invalid type Doctrine\\DBAL\\Driver\\ResultStatement\.$/' + path: src/Internal/Hydration/AbstractHydrator.php - - message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Class Doctrine\\DBAL\\Driver\\ResultStatement not found\.$/' + path: src/Internal/Hydration/AbstractHydrator.php - - message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' - path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' + path: src/Internal/Hydration/AbstractHydrator.php # False positive - message: '/^Call to an undefined method Doctrine\\Common\\Cache\\Cache::deleteAll\(\)\.$/' count: 1 - path: lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php + path: src/Tools/Console/Command/ClearCache/ResultCommand.php # Symfony cache supports passing a key prefix to the clear method. - '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/' @@ -40,10 +40,10 @@ parameters: # Persistence 2 support - message: '/clear.*invoked with 1 parameter/' - path: lib/Doctrine/ORM/EntityRepository.php + path: src/EntityRepository.php - message: '#^Class Doctrine\\Persistence\\ObjectManagerAware not found\.$#' - path: lib/Doctrine/ORM/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Call to method injectObjectManager\(\) on an unknown class Doctrine\\Persistence\\ObjectManagerAware\.$#' - path: lib/Doctrine/ORM/UnitOfWork.php + path: src/UnitOfWork.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ab844d2480a..f596eb473c8 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -17,11 +17,11 @@ verbose="false" failOnRisky="true" convertDeprecationsToExceptions="true" - bootstrap="./tests/Doctrine/Tests/TestInit.php" + bootstrap="./tests/Tests/TestInit.php" > - ./tests/Doctrine/Tests/ORM + ./tests/Tests/ORM diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 90cbc63a1c0..2521ceb9193 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,6 +1,6 @@ - + IterableResult @@ -43,18 +43,18 @@ (string) $cacheRegion - + getTimestampRegion - + (string) $association (string) $entityClass - + @@ -67,7 +67,7 @@ getCacheFactory - + string @@ -78,7 +78,7 @@ (string) $fileLockRegionDirectory - + getMetadataFactory()]]> @@ -94,7 +94,7 @@ getCacheRegion - + identifiers[$assocIndex]]]> identifiers[$assocIndex]]]> @@ -122,7 +122,7 @@ storeEntityCache - + $cache $entityKey @@ -139,18 +139,18 @@ getCacheFactory - + getOwner()]]> getOwner()]]> - + getOwner()]]> - + getOwner()]]> getOwner()]]> @@ -160,7 +160,7 @@ lock - + $cacheEntry @@ -196,7 +196,7 @@ storeEntityCache - + $isChanged @@ -205,7 +205,7 @@ lock - + cache]]> @@ -213,7 +213,7 @@ CacheProvider - + (int) $defaultLifetime (int) $defaultLifetime @@ -223,22 +223,22 @@ (int) $lifetime - + (float) $time - + (string) $space - + time]]> - + $className @@ -250,7 +250,7 @@ (bool) $flag - + copy getHydrator @@ -279,7 +279,7 @@ flush - + $className $connection @@ -352,7 +352,7 @@ new $class($this) - + addNamedNativeQueryMapping @@ -368,28 +368,28 @@ find - + (string) $className - + BaseORMException - + $entity - + serialize unserialize - + $currentLevel nextValue]]> @@ -400,7 +400,7 @@ getTableHiLoUpdateNextValSql - + IterableResult new IterableResult($this) @@ -414,7 +414,7 @@ return $rowData; - + $index @@ -439,7 +439,7 @@ resultPointers[$dqlAlias] =& $coll[key($coll)]]]> - + mixed[]|false @@ -454,7 +454,7 @@ current !== false]]> - + $element @@ -489,17 +489,17 @@ - + $class - + - + $repositoryClassName @@ -507,12 +507,12 @@ addNamedQuery - + $class - + $generatedValue $sequenceDef @@ -524,7 +524,7 @@ (string) $customIdGenerator - + ClassMetadata ClassMetadata @@ -532,7 +532,7 @@ ClassMetadata - + $class $class @@ -573,7 +573,7 @@ getConnection - + $mapping @@ -698,12 +698,12 @@ joinColumnName - + $name - + is_object($object) @@ -714,12 +714,12 @@ instances]]> - + - + canEmulateSchemas canEmulateSchemas @@ -735,7 +735,7 @@ associationMappings[$fieldName]['joinColumns']]]> - + $mapping @@ -746,7 +746,7 @@ array_merge(self::DEFAULT_TYPED_FIELD_MAPPINGS, $typedFieldMappings) - + addNamedNativeQuery addNamedQuery @@ -803,7 +803,7 @@ mapOneToOne - + $columnDef @@ -851,7 +851,7 @@ name)]]> - + $metadata instanceof ClassMetadata @@ -878,24 +878,24 @@ getIndexes - + PHPDriver - + $fileExtension $prefixes - + $fileExtension $prefixes - + @@ -959,7 +959,7 @@ getName() === 'mapped-superclass']]> - + isset($discrColumn['name']) ? (string) $discrColumn['name'] : null, @@ -1022,35 +1022,35 @@ $element - + $columnPrefix - + $discriminatorColumn $entityClass - + $column $name - + $value - + $inverseJoinColumns $joinColumns - + $className $className @@ -1058,7 +1058,7 @@ $indexName - + $name $query @@ -1066,18 +1066,18 @@ $resultSetMapping - + $value - + $name $query - + embeddedClass]]> @@ -1094,34 +1094,34 @@ (string) $embeddedClass - + ReflectionEnumProperty ReflectionEnumProperty - + ReflectionReadonlyProperty ReflectionReadonlyProperty - + $name - + - + $sql - + ]]> object|null @@ -1163,7 +1163,7 @@ unwrap(), 'add']]]> - + $collection->getOwner(), $mapping['indexBy'] => $index]]]> @@ -1214,7 +1214,7 @@ - + int|null @@ -1240,7 +1240,7 @@ associationMappings[$mapping['mappedBy']]['joinColumns']]]> - + $assoc $association @@ -1335,7 +1335,7 @@ currentPersisterContext->sqlTableAliases]]> - + $selectJoinSql @@ -1346,19 +1346,19 @@ (bool) $handlesLimits - + loadAll - + - + @@ -1366,7 +1366,7 @@ $columnList - + $className substr($className, $pos + Proxy::MARKER_LENGTH + 2) @@ -1375,7 +1375,7 @@ string - + $classMetadata $classMetadata @@ -1435,7 +1435,7 @@ require $fileName - + IterableResult @@ -1461,94 +1461,94 @@ $parserResult - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + SimpleArithmeticExpression()]]> - + ArithmeticPrimary()]]> ArithmeticPrimary()]]> - + ArithmeticPrimary()]]> ArithmeticPrimary()]]> - + intervalExpression->dispatch($sqlWalker)]]> intervalExpression->dispatch($sqlWalker)]]> @@ -1571,13 +1571,13 @@ unit->value]]> - + ArithmeticPrimary()]]> ArithmeticPrimary()]]> - + intervalExpression->dispatch($sqlWalker)]]> intervalExpression->dispatch($sqlWalker)]]> @@ -1591,22 +1591,22 @@ unit->value]]> - + $sqlWalker - + - + stringPrimary]]> - + simpleArithmeticExpression]]> @@ -1614,18 +1614,18 @@ SimpleArithmeticExpression()]]> - + stringPrimary]]> - + SimpleArithmeticExpression()]]> SimpleArithmeticExpression()]]> - + associationMappings]]> associationMappings]]> @@ -1635,48 +1635,48 @@ - + SimpleArithmeticExpression()]]> - + SimpleArithmeticExpression()]]> SimpleArithmeticExpression()]]> - + stringPrimary]]> - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + simpleStateFieldPathExpression]]> @@ -1694,87 +1694,87 @@ null - + $sqlWalker - + $sqlWalker - + $sqlWalker - + walkJoinPathExpression - + walkJoinVariableDeclaration - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker @@ -1782,17 +1782,17 @@ null - + $sqlWalker - + $sqlWalker - + $sqlWalker @@ -1800,32 +1800,32 @@ walkWhenClauseExpression - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker - + $sqlWalker @@ -1833,12 +1833,12 @@ walkWhenClauseExpression - + $sqlWalker - + _sqlStatements]]> _sqlStatements]]> @@ -1866,7 +1866,7 @@ _sqlStatements = &$this->sqlStatements]]> - + $numDeleted @@ -1881,7 +1881,7 @@ MultiTableDeleteExecutor - + $numUpdated @@ -1900,7 +1900,7 @@ sqlStatements]]> - + sqlStatements]]> @@ -1909,7 +1909,7 @@ SingleSelectExecutor - + executeStatement($this->sqlStatements, $params, $types)]]> @@ -1925,23 +1925,23 @@ SingleTableDeleteUpdateExecutor - + $y - + $allowedClasses $parts - + $part - + arguments]]> @@ -1949,34 +1949,34 @@ ]]> - + $parts - + conditionType]]> - + $parts - + $allowedClasses $parts - + $allowedClasses $parts - + $value @@ -1987,13 +1987,13 @@ parameters]]> - + Connection::PARAM_INT_ARRAY Connection::PARAM_STR_ARRAY - + $stringPattern @@ -2058,12 +2058,12 @@ $token === Lexer::T_IDENTIFIER - + $sqlExecutor - + parameters)]]> @@ -2074,7 +2074,7 @@ Comparison::EQ - + $class @@ -2090,7 +2090,7 @@ - + is_string($expression) @@ -2197,7 +2197,7 @@ $whereClause !== null - + getExecutor @@ -2205,7 +2205,7 @@ null - + getExecutor @@ -2219,7 +2219,7 @@ $condPrimary - + $value @@ -2235,7 +2235,7 @@ walkers]]> - + $join]]]> $join]]]> @@ -2272,7 +2272,7 @@ self::SELECT - + repositoryList[$repositoryHash]]]> repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName)]]> @@ -2287,22 +2287,22 @@ new $repositoryClassName($entityManager, $metadata) - + evictAll - + evictAll - + getQueryCacheImpl - + $fromPaths $metadata @@ -2321,7 +2321,7 @@ private $metadataExporter = null; - + $metadata @@ -2335,12 +2335,12 @@ name]]> - + connect - + $metadatas @@ -2352,7 +2352,7 @@ name]]> - + name]]> @@ -2360,7 +2360,7 @@ getConfiguration()->getProxyDir()]]> - + new EntityRepositoryGenerator() @@ -2368,12 +2368,12 @@ customRepositoryClassName]]> - + getAllClassNames - + entityListeners]]> @@ -2381,7 +2381,7 @@ getAllClassNames - + int @@ -2389,13 +2389,13 @@ executeSchemaCommand($input, $output, new SchemaTool($em), $metadatas, $ui)]]> - + $metadatas $metadatas - + $metadatas $metadatas @@ -2406,7 +2406,7 @@ getName()]]> - + $metadatas @@ -2415,7 +2415,7 @@ getName()]]> - + new ArrayIterator($metadatas) @@ -2423,17 +2423,17 @@ MetadataFilter - + - + $state === UnitOfWork::STATE_DETACHED - + getClassToExtend()]]> getClassToExtend() ?: $metadata->name]]> @@ -2460,7 +2460,7 @@ lifecycleCallbacks)]]> - + $fullClassName $fullClassName @@ -2473,7 +2473,7 @@ $repositoryName - + Driver\AbstractExporter Driver\AnnotationExporter::class @@ -2493,7 +2493,7 @@ Driver\AbstractExporter - + ExportException::attemptOverwriteExistingFile($path) @@ -2504,7 +2504,7 @@ _outputDir]]> - + AbstractExporter EntityGenerator @@ -2514,7 +2514,7 @@ $_extension - + changeTrackingPolicy]]> @@ -2532,7 +2532,7 @@ table]]> - + changeTrackingPolicy]]> asXML()]]> @@ -2551,7 +2551,7 @@ lifecycleCallbacks)]]> - + changeTrackingPolicy]]> @@ -2583,7 +2583,7 @@ lifecycleCallbacks)]]> - + $query @@ -2591,7 +2591,7 @@ associationMappings[$property]['joinColumns']]]> - + $query @@ -2612,7 +2612,7 @@ associationMappings[$property]['joinColumns']]]> - + $parameters @@ -2620,12 +2620,12 @@ (bool) $fetchJoinCollection - + $orderByClause - + $classes @@ -2658,7 +2658,7 @@ $indexName - + @@ -2670,7 +2670,7 @@ - + $paths @@ -2683,7 +2683,7 @@ - + ! is_object($object) is_object($object) @@ -2774,18 +2774,18 @@ $visited - + name]]> subClasses]]> - + associationMappings[$field]['joinColumns']]]> - + diff --git a/psalm.xml b/psalm.xml index a8a096c3ae4..d88c41393a6 100644 --- a/psalm.xml +++ b/psalm.xml @@ -11,11 +11,11 @@ errorBaseline="psalm-baseline.xml" > - - + + - + @@ -54,15 +54,15 @@ - - - - - - - - - + + + + + + + + + @@ -75,7 +75,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,24 +114,24 @@ - + - - + + - + - - + + - + @@ -145,13 +145,13 @@ - + - + @@ -163,48 +163,48 @@ - + - + - + - - - + + + - - - + + + - - + + - + @@ -213,31 +213,31 @@ - + - + - - + + - + - + @@ -254,8 +254,8 @@ - - + + @@ -294,7 +294,7 @@ - + diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/src/AbstractQuery.php similarity index 100% rename from lib/Doctrine/ORM/AbstractQuery.php rename to src/AbstractQuery.php diff --git a/lib/Doctrine/ORM/Cache.php b/src/Cache.php similarity index 100% rename from lib/Doctrine/ORM/Cache.php rename to src/Cache.php diff --git a/lib/Doctrine/ORM/Cache/AssociationCacheEntry.php b/src/Cache/AssociationCacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/AssociationCacheEntry.php rename to src/Cache/AssociationCacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/CacheConfiguration.php b/src/Cache/CacheConfiguration.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CacheConfiguration.php rename to src/Cache/CacheConfiguration.php diff --git a/lib/Doctrine/ORM/Cache/CacheEntry.php b/src/Cache/CacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CacheEntry.php rename to src/Cache/CacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/CacheException.php b/src/Cache/CacheException.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CacheException.php rename to src/Cache/CacheException.php diff --git a/lib/Doctrine/ORM/Cache/CacheFactory.php b/src/Cache/CacheFactory.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CacheFactory.php rename to src/Cache/CacheFactory.php diff --git a/lib/Doctrine/ORM/Cache/CacheKey.php b/src/Cache/CacheKey.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CacheKey.php rename to src/Cache/CacheKey.php diff --git a/lib/Doctrine/ORM/Cache/CollectionCacheEntry.php b/src/Cache/CollectionCacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CollectionCacheEntry.php rename to src/Cache/CollectionCacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/CollectionCacheKey.php b/src/Cache/CollectionCacheKey.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CollectionCacheKey.php rename to src/Cache/CollectionCacheKey.php diff --git a/lib/Doctrine/ORM/Cache/CollectionHydrator.php b/src/Cache/CollectionHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/CollectionHydrator.php rename to src/Cache/CollectionHydrator.php diff --git a/lib/Doctrine/ORM/Cache/ConcurrentRegion.php b/src/Cache/ConcurrentRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/ConcurrentRegion.php rename to src/Cache/ConcurrentRegion.php diff --git a/lib/Doctrine/ORM/Cache/DefaultCache.php b/src/Cache/DefaultCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/DefaultCache.php rename to src/Cache/DefaultCache.php diff --git a/lib/Doctrine/ORM/Cache/DefaultCacheFactory.php b/src/Cache/DefaultCacheFactory.php similarity index 100% rename from lib/Doctrine/ORM/Cache/DefaultCacheFactory.php rename to src/Cache/DefaultCacheFactory.php diff --git a/lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php b/src/Cache/DefaultCollectionHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/DefaultCollectionHydrator.php rename to src/Cache/DefaultCollectionHydrator.php diff --git a/lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php b/src/Cache/DefaultEntityHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/DefaultEntityHydrator.php rename to src/Cache/DefaultEntityHydrator.php diff --git a/lib/Doctrine/ORM/Cache/DefaultQueryCache.php b/src/Cache/DefaultQueryCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/DefaultQueryCache.php rename to src/Cache/DefaultQueryCache.php diff --git a/lib/Doctrine/ORM/Cache/EntityCacheEntry.php b/src/Cache/EntityCacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/EntityCacheEntry.php rename to src/Cache/EntityCacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/EntityCacheKey.php b/src/Cache/EntityCacheKey.php similarity index 100% rename from lib/Doctrine/ORM/Cache/EntityCacheKey.php rename to src/Cache/EntityCacheKey.php diff --git a/lib/Doctrine/ORM/Cache/EntityHydrator.php b/src/Cache/EntityHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/EntityHydrator.php rename to src/Cache/EntityHydrator.php diff --git a/lib/Doctrine/ORM/Cache/Exception/CacheException.php b/src/Cache/Exception/CacheException.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/CacheException.php rename to src/Cache/Exception/CacheException.php diff --git a/lib/Doctrine/ORM/Cache/Exception/CannotUpdateReadOnlyCollection.php b/src/Cache/Exception/CannotUpdateReadOnlyCollection.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/CannotUpdateReadOnlyCollection.php rename to src/Cache/Exception/CannotUpdateReadOnlyCollection.php diff --git a/lib/Doctrine/ORM/Cache/Exception/CannotUpdateReadOnlyEntity.php b/src/Cache/Exception/CannotUpdateReadOnlyEntity.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/CannotUpdateReadOnlyEntity.php rename to src/Cache/Exception/CannotUpdateReadOnlyEntity.php diff --git a/lib/Doctrine/ORM/Cache/Exception/FeatureNotImplemented.php b/src/Cache/Exception/FeatureNotImplemented.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/FeatureNotImplemented.php rename to src/Cache/Exception/FeatureNotImplemented.php diff --git a/lib/Doctrine/ORM/Cache/Exception/InvalidResultCacheDriver.php b/src/Cache/Exception/InvalidResultCacheDriver.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/InvalidResultCacheDriver.php rename to src/Cache/Exception/InvalidResultCacheDriver.php diff --git a/lib/Doctrine/ORM/Cache/Exception/MetadataCacheNotConfigured.php b/src/Cache/Exception/MetadataCacheNotConfigured.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/MetadataCacheNotConfigured.php rename to src/Cache/Exception/MetadataCacheNotConfigured.php diff --git a/lib/Doctrine/ORM/Cache/Exception/MetadataCacheUsesNonPersistentCache.php b/src/Cache/Exception/MetadataCacheUsesNonPersistentCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/MetadataCacheUsesNonPersistentCache.php rename to src/Cache/Exception/MetadataCacheUsesNonPersistentCache.php diff --git a/lib/Doctrine/ORM/Cache/Exception/NonCacheableEntity.php b/src/Cache/Exception/NonCacheableEntity.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/NonCacheableEntity.php rename to src/Cache/Exception/NonCacheableEntity.php diff --git a/lib/Doctrine/ORM/Cache/Exception/NonCacheableEntityAssociation.php b/src/Cache/Exception/NonCacheableEntityAssociation.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/NonCacheableEntityAssociation.php rename to src/Cache/Exception/NonCacheableEntityAssociation.php diff --git a/lib/Doctrine/ORM/Cache/Exception/QueryCacheNotConfigured.php b/src/Cache/Exception/QueryCacheNotConfigured.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/QueryCacheNotConfigured.php rename to src/Cache/Exception/QueryCacheNotConfigured.php diff --git a/lib/Doctrine/ORM/Cache/Exception/QueryCacheUsesNonPersistentCache.php b/src/Cache/Exception/QueryCacheUsesNonPersistentCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Exception/QueryCacheUsesNonPersistentCache.php rename to src/Cache/Exception/QueryCacheUsesNonPersistentCache.php diff --git a/lib/Doctrine/ORM/Cache/Lock.php b/src/Cache/Lock.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Lock.php rename to src/Cache/Lock.php diff --git a/lib/Doctrine/ORM/Cache/LockException.php b/src/Cache/LockException.php similarity index 100% rename from lib/Doctrine/ORM/Cache/LockException.php rename to src/Cache/LockException.php diff --git a/lib/Doctrine/ORM/Cache/Logging/CacheLogger.php b/src/Cache/Logging/CacheLogger.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Logging/CacheLogger.php rename to src/Cache/Logging/CacheLogger.php diff --git a/lib/Doctrine/ORM/Cache/Logging/CacheLoggerChain.php b/src/Cache/Logging/CacheLoggerChain.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Logging/CacheLoggerChain.php rename to src/Cache/Logging/CacheLoggerChain.php diff --git a/lib/Doctrine/ORM/Cache/Logging/StatisticsCacheLogger.php b/src/Cache/Logging/StatisticsCacheLogger.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Logging/StatisticsCacheLogger.php rename to src/Cache/Logging/StatisticsCacheLogger.php diff --git a/lib/Doctrine/ORM/Cache/MultiGetRegion.php b/src/Cache/MultiGetRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/MultiGetRegion.php rename to src/Cache/MultiGetRegion.php diff --git a/lib/Doctrine/ORM/Cache/Persister/CachedPersister.php b/src/Cache/Persister/CachedPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/CachedPersister.php rename to src/Cache/Persister/CachedPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php b/src/Cache/Persister/Collection/AbstractCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Collection/AbstractCollectionPersister.php rename to src/Cache/Persister/Collection/AbstractCollectionPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/CachedCollectionPersister.php b/src/Cache/Persister/Collection/CachedCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Collection/CachedCollectionPersister.php rename to src/Cache/Persister/Collection/CachedCollectionPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersister.php b/src/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersister.php rename to src/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php b/src/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php rename to src/Cache/Persister/Collection/ReadOnlyCachedCollectionPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php b/src/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php rename to src/Cache/Persister/Collection/ReadWriteCachedCollectionPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php b/src/Cache/Persister/Entity/AbstractEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Entity/AbstractEntityPersister.php rename to src/Cache/Persister/Entity/AbstractEntityPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/CachedEntityPersister.php b/src/Cache/Persister/Entity/CachedEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Entity/CachedEntityPersister.php rename to src/Cache/Persister/Entity/CachedEntityPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersister.php b/src/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersister.php rename to src/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php b/src/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php rename to src/Cache/Persister/Entity/ReadOnlyCachedEntityPersister.php diff --git a/lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php b/src/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php rename to src/Cache/Persister/Entity/ReadWriteCachedEntityPersister.php diff --git a/lib/Doctrine/ORM/Cache/QueryCache.php b/src/Cache/QueryCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/QueryCache.php rename to src/Cache/QueryCache.php diff --git a/lib/Doctrine/ORM/Cache/QueryCacheEntry.php b/src/Cache/QueryCacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/QueryCacheEntry.php rename to src/Cache/QueryCacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/QueryCacheKey.php b/src/Cache/QueryCacheKey.php similarity index 100% rename from lib/Doctrine/ORM/Cache/QueryCacheKey.php rename to src/Cache/QueryCacheKey.php diff --git a/lib/Doctrine/ORM/Cache/QueryCacheValidator.php b/src/Cache/QueryCacheValidator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/QueryCacheValidator.php rename to src/Cache/QueryCacheValidator.php diff --git a/lib/Doctrine/ORM/Cache/Region.php b/src/Cache/Region.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Region.php rename to src/Cache/Region.php diff --git a/lib/Doctrine/ORM/Cache/Region/DefaultMultiGetRegion.php b/src/Cache/Region/DefaultMultiGetRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Region/DefaultMultiGetRegion.php rename to src/Cache/Region/DefaultMultiGetRegion.php diff --git a/lib/Doctrine/ORM/Cache/Region/DefaultRegion.php b/src/Cache/Region/DefaultRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Region/DefaultRegion.php rename to src/Cache/Region/DefaultRegion.php diff --git a/lib/Doctrine/ORM/Cache/Region/FileLockRegion.php b/src/Cache/Region/FileLockRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Region/FileLockRegion.php rename to src/Cache/Region/FileLockRegion.php diff --git a/lib/Doctrine/ORM/Cache/Region/UpdateTimestampCache.php b/src/Cache/Region/UpdateTimestampCache.php similarity index 100% rename from lib/Doctrine/ORM/Cache/Region/UpdateTimestampCache.php rename to src/Cache/Region/UpdateTimestampCache.php diff --git a/lib/Doctrine/ORM/Cache/RegionsConfiguration.php b/src/Cache/RegionsConfiguration.php similarity index 100% rename from lib/Doctrine/ORM/Cache/RegionsConfiguration.php rename to src/Cache/RegionsConfiguration.php diff --git a/lib/Doctrine/ORM/Cache/TimestampCacheEntry.php b/src/Cache/TimestampCacheEntry.php similarity index 100% rename from lib/Doctrine/ORM/Cache/TimestampCacheEntry.php rename to src/Cache/TimestampCacheEntry.php diff --git a/lib/Doctrine/ORM/Cache/TimestampCacheKey.php b/src/Cache/TimestampCacheKey.php similarity index 100% rename from lib/Doctrine/ORM/Cache/TimestampCacheKey.php rename to src/Cache/TimestampCacheKey.php diff --git a/lib/Doctrine/ORM/Cache/TimestampQueryCacheValidator.php b/src/Cache/TimestampQueryCacheValidator.php similarity index 100% rename from lib/Doctrine/ORM/Cache/TimestampQueryCacheValidator.php rename to src/Cache/TimestampQueryCacheValidator.php diff --git a/lib/Doctrine/ORM/Cache/TimestampRegion.php b/src/Cache/TimestampRegion.php similarity index 100% rename from lib/Doctrine/ORM/Cache/TimestampRegion.php rename to src/Cache/TimestampRegion.php diff --git a/lib/Doctrine/ORM/Configuration.php b/src/Configuration.php similarity index 100% rename from lib/Doctrine/ORM/Configuration.php rename to src/Configuration.php diff --git a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php b/src/Decorator/EntityManagerDecorator.php similarity index 100% rename from lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php rename to src/Decorator/EntityManagerDecorator.php diff --git a/lib/Doctrine/ORM/EntityManager.php b/src/EntityManager.php similarity index 100% rename from lib/Doctrine/ORM/EntityManager.php rename to src/EntityManager.php diff --git a/lib/Doctrine/ORM/EntityManagerInterface.php b/src/EntityManagerInterface.php similarity index 100% rename from lib/Doctrine/ORM/EntityManagerInterface.php rename to src/EntityManagerInterface.php diff --git a/lib/Doctrine/ORM/EntityNotFoundException.php b/src/EntityNotFoundException.php similarity index 100% rename from lib/Doctrine/ORM/EntityNotFoundException.php rename to src/EntityNotFoundException.php diff --git a/lib/Doctrine/ORM/EntityRepository.php b/src/EntityRepository.php similarity index 100% rename from lib/Doctrine/ORM/EntityRepository.php rename to src/EntityRepository.php diff --git a/lib/Doctrine/ORM/Event/LifecycleEventArgs.php b/src/Event/LifecycleEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/LifecycleEventArgs.php rename to src/Event/LifecycleEventArgs.php diff --git a/lib/Doctrine/ORM/Event/ListenersInvoker.php b/src/Event/ListenersInvoker.php similarity index 100% rename from lib/Doctrine/ORM/Event/ListenersInvoker.php rename to src/Event/ListenersInvoker.php diff --git a/lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php b/src/Event/LoadClassMetadataEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/LoadClassMetadataEventArgs.php rename to src/Event/LoadClassMetadataEventArgs.php diff --git a/lib/Doctrine/ORM/Event/OnClassMetadataNotFoundEventArgs.php b/src/Event/OnClassMetadataNotFoundEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/OnClassMetadataNotFoundEventArgs.php rename to src/Event/OnClassMetadataNotFoundEventArgs.php diff --git a/lib/Doctrine/ORM/Event/OnClearEventArgs.php b/src/Event/OnClearEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/OnClearEventArgs.php rename to src/Event/OnClearEventArgs.php diff --git a/lib/Doctrine/ORM/Event/OnFlushEventArgs.php b/src/Event/OnFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/OnFlushEventArgs.php rename to src/Event/OnFlushEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PostFlushEventArgs.php b/src/Event/PostFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PostFlushEventArgs.php rename to src/Event/PostFlushEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PostLoadEventArgs.php b/src/Event/PostLoadEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PostLoadEventArgs.php rename to src/Event/PostLoadEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PostPersistEventArgs.php b/src/Event/PostPersistEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PostPersistEventArgs.php rename to src/Event/PostPersistEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PostRemoveEventArgs.php b/src/Event/PostRemoveEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PostRemoveEventArgs.php rename to src/Event/PostRemoveEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PostUpdateEventArgs.php b/src/Event/PostUpdateEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PostUpdateEventArgs.php rename to src/Event/PostUpdateEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PreFlushEventArgs.php b/src/Event/PreFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PreFlushEventArgs.php rename to src/Event/PreFlushEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PrePersistEventArgs.php b/src/Event/PrePersistEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PrePersistEventArgs.php rename to src/Event/PrePersistEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PreRemoveEventArgs.php b/src/Event/PreRemoveEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PreRemoveEventArgs.php rename to src/Event/PreRemoveEventArgs.php diff --git a/lib/Doctrine/ORM/Event/PreUpdateEventArgs.php b/src/Event/PreUpdateEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Event/PreUpdateEventArgs.php rename to src/Event/PreUpdateEventArgs.php diff --git a/lib/Doctrine/ORM/Events.php b/src/Events.php similarity index 100% rename from lib/Doctrine/ORM/Events.php rename to src/Events.php diff --git a/lib/Doctrine/ORM/Exception/ConfigurationException.php b/src/Exception/ConfigurationException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/ConfigurationException.php rename to src/Exception/ConfigurationException.php diff --git a/lib/Doctrine/ORM/Exception/EntityIdentityCollisionException.php b/src/Exception/EntityIdentityCollisionException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/EntityIdentityCollisionException.php rename to src/Exception/EntityIdentityCollisionException.php diff --git a/lib/Doctrine/ORM/Exception/EntityManagerClosed.php b/src/Exception/EntityManagerClosed.php similarity index 100% rename from lib/Doctrine/ORM/Exception/EntityManagerClosed.php rename to src/Exception/EntityManagerClosed.php diff --git a/lib/Doctrine/ORM/Exception/EntityMissingAssignedId.php b/src/Exception/EntityMissingAssignedId.php similarity index 100% rename from lib/Doctrine/ORM/Exception/EntityMissingAssignedId.php rename to src/Exception/EntityMissingAssignedId.php diff --git a/lib/Doctrine/ORM/Exception/InvalidEntityRepository.php b/src/Exception/InvalidEntityRepository.php similarity index 100% rename from lib/Doctrine/ORM/Exception/InvalidEntityRepository.php rename to src/Exception/InvalidEntityRepository.php diff --git a/lib/Doctrine/ORM/Exception/InvalidHydrationMode.php b/src/Exception/InvalidHydrationMode.php similarity index 100% rename from lib/Doctrine/ORM/Exception/InvalidHydrationMode.php rename to src/Exception/InvalidHydrationMode.php diff --git a/lib/Doctrine/ORM/Exception/ManagerException.php b/src/Exception/ManagerException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/ManagerException.php rename to src/Exception/ManagerException.php diff --git a/lib/Doctrine/ORM/Exception/MismatchedEventManager.php b/src/Exception/MismatchedEventManager.php similarity index 100% rename from lib/Doctrine/ORM/Exception/MismatchedEventManager.php rename to src/Exception/MismatchedEventManager.php diff --git a/lib/Doctrine/ORM/Exception/MissingIdentifierField.php b/src/Exception/MissingIdentifierField.php similarity index 100% rename from lib/Doctrine/ORM/Exception/MissingIdentifierField.php rename to src/Exception/MissingIdentifierField.php diff --git a/lib/Doctrine/ORM/Exception/MissingMappingDriverImplementation.php b/src/Exception/MissingMappingDriverImplementation.php similarity index 100% rename from lib/Doctrine/ORM/Exception/MissingMappingDriverImplementation.php rename to src/Exception/MissingMappingDriverImplementation.php diff --git a/lib/Doctrine/ORM/Exception/MultipleSelectorsFoundException.php b/src/Exception/MultipleSelectorsFoundException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/MultipleSelectorsFoundException.php rename to src/Exception/MultipleSelectorsFoundException.php diff --git a/lib/Doctrine/ORM/Exception/NamedNativeQueryNotFound.php b/src/Exception/NamedNativeQueryNotFound.php similarity index 100% rename from lib/Doctrine/ORM/Exception/NamedNativeQueryNotFound.php rename to src/Exception/NamedNativeQueryNotFound.php diff --git a/lib/Doctrine/ORM/Exception/NamedQueryNotFound.php b/src/Exception/NamedQueryNotFound.php similarity index 100% rename from lib/Doctrine/ORM/Exception/NamedQueryNotFound.php rename to src/Exception/NamedQueryNotFound.php diff --git a/lib/Doctrine/ORM/Exception/NotSupported.php b/src/Exception/NotSupported.php similarity index 100% rename from lib/Doctrine/ORM/Exception/NotSupported.php rename to src/Exception/NotSupported.php diff --git a/lib/Doctrine/ORM/Exception/ORMException.php b/src/Exception/ORMException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/ORMException.php rename to src/Exception/ORMException.php diff --git a/lib/Doctrine/ORM/Exception/PersisterException.php b/src/Exception/PersisterException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/PersisterException.php rename to src/Exception/PersisterException.php diff --git a/lib/Doctrine/ORM/Exception/ProxyClassesAlwaysRegenerating.php b/src/Exception/ProxyClassesAlwaysRegenerating.php similarity index 100% rename from lib/Doctrine/ORM/Exception/ProxyClassesAlwaysRegenerating.php rename to src/Exception/ProxyClassesAlwaysRegenerating.php diff --git a/lib/Doctrine/ORM/Exception/RepositoryException.php b/src/Exception/RepositoryException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/RepositoryException.php rename to src/Exception/RepositoryException.php diff --git a/lib/Doctrine/ORM/Exception/SchemaToolException.php b/src/Exception/SchemaToolException.php similarity index 100% rename from lib/Doctrine/ORM/Exception/SchemaToolException.php rename to src/Exception/SchemaToolException.php diff --git a/lib/Doctrine/ORM/Exception/UnexpectedAssociationValue.php b/src/Exception/UnexpectedAssociationValue.php similarity index 100% rename from lib/Doctrine/ORM/Exception/UnexpectedAssociationValue.php rename to src/Exception/UnexpectedAssociationValue.php diff --git a/lib/Doctrine/ORM/Exception/UnknownEntityNamespace.php b/src/Exception/UnknownEntityNamespace.php similarity index 100% rename from lib/Doctrine/ORM/Exception/UnknownEntityNamespace.php rename to src/Exception/UnknownEntityNamespace.php diff --git a/lib/Doctrine/ORM/Exception/UnrecognizedIdentifierFields.php b/src/Exception/UnrecognizedIdentifierFields.php similarity index 100% rename from lib/Doctrine/ORM/Exception/UnrecognizedIdentifierFields.php rename to src/Exception/UnrecognizedIdentifierFields.php diff --git a/lib/Doctrine/ORM/Id/AbstractIdGenerator.php b/src/Id/AbstractIdGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/AbstractIdGenerator.php rename to src/Id/AbstractIdGenerator.php diff --git a/lib/Doctrine/ORM/Id/AssignedGenerator.php b/src/Id/AssignedGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/AssignedGenerator.php rename to src/Id/AssignedGenerator.php diff --git a/lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php b/src/Id/BigIntegerIdentityGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php rename to src/Id/BigIntegerIdentityGenerator.php diff --git a/lib/Doctrine/ORM/Id/IdentityGenerator.php b/src/Id/IdentityGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/IdentityGenerator.php rename to src/Id/IdentityGenerator.php diff --git a/lib/Doctrine/ORM/Id/SequenceGenerator.php b/src/Id/SequenceGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/SequenceGenerator.php rename to src/Id/SequenceGenerator.php diff --git a/lib/Doctrine/ORM/Id/TableGenerator.php b/src/Id/TableGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/TableGenerator.php rename to src/Id/TableGenerator.php diff --git a/lib/Doctrine/ORM/Id/UuidGenerator.php b/src/Id/UuidGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Id/UuidGenerator.php rename to src/Id/UuidGenerator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/src/Internal/Hydration/AbstractHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php rename to src/Internal/Hydration/AbstractHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php b/src/Internal/Hydration/ArrayHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/ArrayHydrator.php rename to src/Internal/Hydration/ArrayHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php b/src/Internal/Hydration/HydrationException.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/HydrationException.php rename to src/Internal/Hydration/HydrationException.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/IterableResult.php b/src/Internal/Hydration/IterableResult.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/IterableResult.php rename to src/Internal/Hydration/IterableResult.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/src/Internal/Hydration/ObjectHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php rename to src/Internal/Hydration/ObjectHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/ScalarColumnHydrator.php b/src/Internal/Hydration/ScalarColumnHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/ScalarColumnHydrator.php rename to src/Internal/Hydration/ScalarColumnHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php b/src/Internal/Hydration/ScalarHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/ScalarHydrator.php rename to src/Internal/Hydration/ScalarHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/src/Internal/Hydration/SimpleObjectHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php rename to src/Internal/Hydration/SimpleObjectHydrator.php diff --git a/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php b/src/Internal/Hydration/SingleScalarHydrator.php similarity index 100% rename from lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php rename to src/Internal/Hydration/SingleScalarHydrator.php diff --git a/lib/Doctrine/ORM/Internal/HydrationCompleteHandler.php b/src/Internal/HydrationCompleteHandler.php similarity index 100% rename from lib/Doctrine/ORM/Internal/HydrationCompleteHandler.php rename to src/Internal/HydrationCompleteHandler.php diff --git a/lib/Doctrine/ORM/Internal/SQLResultCasing.php b/src/Internal/SQLResultCasing.php similarity index 100% rename from lib/Doctrine/ORM/Internal/SQLResultCasing.php rename to src/Internal/SQLResultCasing.php diff --git a/lib/Doctrine/ORM/Internal/TopologicalSort.php b/src/Internal/TopologicalSort.php similarity index 100% rename from lib/Doctrine/ORM/Internal/TopologicalSort.php rename to src/Internal/TopologicalSort.php diff --git a/lib/Doctrine/ORM/Internal/TopologicalSort/CycleDetectedException.php b/src/Internal/TopologicalSort/CycleDetectedException.php similarity index 100% rename from lib/Doctrine/ORM/Internal/TopologicalSort/CycleDetectedException.php rename to src/Internal/TopologicalSort/CycleDetectedException.php diff --git a/lib/Doctrine/ORM/LazyCriteriaCollection.php b/src/LazyCriteriaCollection.php similarity index 100% rename from lib/Doctrine/ORM/LazyCriteriaCollection.php rename to src/LazyCriteriaCollection.php diff --git a/lib/Doctrine/ORM/Mapping/Annotation.php b/src/Mapping/Annotation.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Annotation.php rename to src/Mapping/Annotation.php diff --git a/lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php b/src/Mapping/AnsiQuoteStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php rename to src/Mapping/AnsiQuoteStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/AssociationOverride.php b/src/Mapping/AssociationOverride.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/AssociationOverride.php rename to src/Mapping/AssociationOverride.php diff --git a/lib/Doctrine/ORM/Mapping/AssociationOverrides.php b/src/Mapping/AssociationOverrides.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/AssociationOverrides.php rename to src/Mapping/AssociationOverrides.php diff --git a/lib/Doctrine/ORM/Mapping/AttributeOverride.php b/src/Mapping/AttributeOverride.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/AttributeOverride.php rename to src/Mapping/AttributeOverride.php diff --git a/lib/Doctrine/ORM/Mapping/AttributeOverrides.php b/src/Mapping/AttributeOverrides.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/AttributeOverrides.php rename to src/Mapping/AttributeOverrides.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php b/src/Mapping/Builder/AssociationBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php rename to src/Mapping/Builder/AssociationBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php b/src/Mapping/Builder/ClassMetadataBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php rename to src/Mapping/Builder/ClassMetadataBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/EmbeddedBuilder.php b/src/Mapping/Builder/EmbeddedBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/EmbeddedBuilder.php rename to src/Mapping/Builder/EmbeddedBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php b/src/Mapping/Builder/EntityListenerBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/EntityListenerBuilder.php rename to src/Mapping/Builder/EntityListenerBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php b/src/Mapping/Builder/FieldBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/FieldBuilder.php rename to src/Mapping/Builder/FieldBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php b/src/Mapping/Builder/ManyToManyAssociationBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/ManyToManyAssociationBuilder.php rename to src/Mapping/Builder/ManyToManyAssociationBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php b/src/Mapping/Builder/OneToManyAssociationBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Builder/OneToManyAssociationBuilder.php rename to src/Mapping/Builder/OneToManyAssociationBuilder.php diff --git a/lib/Doctrine/ORM/Mapping/Cache.php b/src/Mapping/Cache.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Cache.php rename to src/Mapping/Cache.php diff --git a/lib/Doctrine/ORM/Mapping/ChainTypedFieldMapper.php b/src/Mapping/ChainTypedFieldMapper.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ChainTypedFieldMapper.php rename to src/Mapping/ChainTypedFieldMapper.php diff --git a/lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php b/src/Mapping/ChangeTrackingPolicy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ChangeTrackingPolicy.php rename to src/Mapping/ChangeTrackingPolicy.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ClassMetadata.php rename to src/Mapping/ClassMetadata.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php rename to src/Mapping/ClassMetadataFactory.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/src/Mapping/ClassMetadataInfo.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php rename to src/Mapping/ClassMetadataInfo.php diff --git a/lib/Doctrine/ORM/Mapping/Column.php b/src/Mapping/Column.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Column.php rename to src/Mapping/Column.php diff --git a/lib/Doctrine/ORM/Mapping/ColumnResult.php b/src/Mapping/ColumnResult.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ColumnResult.php rename to src/Mapping/ColumnResult.php diff --git a/lib/Doctrine/ORM/Mapping/CustomIdGenerator.php b/src/Mapping/CustomIdGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/CustomIdGenerator.php rename to src/Mapping/CustomIdGenerator.php diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/src/Mapping/DefaultEntityListenerResolver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php rename to src/Mapping/DefaultEntityListenerResolver.php diff --git a/lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php b/src/Mapping/DefaultNamingStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DefaultNamingStrategy.php rename to src/Mapping/DefaultNamingStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php b/src/Mapping/DefaultQuoteStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php rename to src/Mapping/DefaultQuoteStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php b/src/Mapping/DefaultTypedFieldMapper.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php rename to src/Mapping/DefaultTypedFieldMapper.php diff --git a/lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php b/src/Mapping/DiscriminatorColumn.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DiscriminatorColumn.php rename to src/Mapping/DiscriminatorColumn.php diff --git a/lib/Doctrine/ORM/Mapping/DiscriminatorMap.php b/src/Mapping/DiscriminatorMap.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/DiscriminatorMap.php rename to src/Mapping/DiscriminatorMap.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/src/Mapping/Driver/AnnotationDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php rename to src/Mapping/Driver/AnnotationDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php rename to src/Mapping/Driver/AttributeDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php b/src/Mapping/Driver/AttributeReader.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/AttributeReader.php rename to src/Mapping/Driver/AttributeReader.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/CompatibilityAnnotationDriver.php b/src/Mapping/Driver/CompatibilityAnnotationDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/CompatibilityAnnotationDriver.php rename to src/Mapping/Driver/CompatibilityAnnotationDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/src/Mapping/Driver/DatabaseDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php rename to src/Mapping/Driver/DatabaseDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/DriverChain.php b/src/Mapping/Driver/DriverChain.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/DriverChain.php rename to src/Mapping/Driver/DriverChain.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php b/src/Mapping/Driver/PHPDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/PHPDriver.php rename to src/Mapping/Driver/PHPDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/ReflectionBasedDriver.php b/src/Mapping/Driver/ReflectionBasedDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/ReflectionBasedDriver.php rename to src/Mapping/Driver/ReflectionBasedDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/RepeatableAttributeCollection.php b/src/Mapping/Driver/RepeatableAttributeCollection.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/RepeatableAttributeCollection.php rename to src/Mapping/Driver/RepeatableAttributeCollection.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php b/src/Mapping/Driver/SimplifiedXmlDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/SimplifiedXmlDriver.php rename to src/Mapping/Driver/SimplifiedXmlDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php b/src/Mapping/Driver/SimplifiedYamlDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/SimplifiedYamlDriver.php rename to src/Mapping/Driver/SimplifiedYamlDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php b/src/Mapping/Driver/StaticPHPDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/StaticPHPDriver.php rename to src/Mapping/Driver/StaticPHPDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/src/Mapping/Driver/XmlDriver.php similarity index 99% rename from lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php rename to src/Mapping/Driver/XmlDriver.php index 82ad11a2981..5d05cbc2cf7 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/src/Mapping/Driver/XmlDriver.php @@ -1003,7 +1003,7 @@ private function validateMapping(string $file): void $document = new DOMDocument(); $document->load($file); - if (! $document->schemaValidate(__DIR__ . '/../../../../../doctrine-mapping.xsd')) { + if (! $document->schemaValidate(__DIR__ . '/../../../doctrine-mapping.xsd')) { throw MappingException::fromLibXmlErrors(libxml_get_errors()); } } finally { diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/src/Mapping/Driver/YamlDriver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php rename to src/Mapping/Driver/YamlDriver.php diff --git a/lib/Doctrine/ORM/Mapping/Embeddable.php b/src/Mapping/Embeddable.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Embeddable.php rename to src/Mapping/Embeddable.php diff --git a/lib/Doctrine/ORM/Mapping/Embedded.php b/src/Mapping/Embedded.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Embedded.php rename to src/Mapping/Embedded.php diff --git a/lib/Doctrine/ORM/Mapping/Entity.php b/src/Mapping/Entity.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Entity.php rename to src/Mapping/Entity.php diff --git a/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php b/src/Mapping/EntityListenerResolver.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/EntityListenerResolver.php rename to src/Mapping/EntityListenerResolver.php diff --git a/lib/Doctrine/ORM/Mapping/EntityListeners.php b/src/Mapping/EntityListeners.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/EntityListeners.php rename to src/Mapping/EntityListeners.php diff --git a/lib/Doctrine/ORM/Mapping/EntityResult.php b/src/Mapping/EntityResult.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/EntityResult.php rename to src/Mapping/EntityResult.php diff --git a/lib/Doctrine/ORM/Mapping/Exception/CannotGenerateIds.php b/src/Mapping/Exception/CannotGenerateIds.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Exception/CannotGenerateIds.php rename to src/Mapping/Exception/CannotGenerateIds.php diff --git a/lib/Doctrine/ORM/Mapping/Exception/InvalidCustomGenerator.php b/src/Mapping/Exception/InvalidCustomGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Exception/InvalidCustomGenerator.php rename to src/Mapping/Exception/InvalidCustomGenerator.php diff --git a/lib/Doctrine/ORM/Mapping/Exception/UnknownGeneratorType.php b/src/Mapping/Exception/UnknownGeneratorType.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Exception/UnknownGeneratorType.php rename to src/Mapping/Exception/UnknownGeneratorType.php diff --git a/lib/Doctrine/ORM/Mapping/FieldResult.php b/src/Mapping/FieldResult.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/FieldResult.php rename to src/Mapping/FieldResult.php diff --git a/lib/Doctrine/ORM/Mapping/GeneratedValue.php b/src/Mapping/GeneratedValue.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/GeneratedValue.php rename to src/Mapping/GeneratedValue.php diff --git a/lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php b/src/Mapping/HasLifecycleCallbacks.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/HasLifecycleCallbacks.php rename to src/Mapping/HasLifecycleCallbacks.php diff --git a/lib/Doctrine/ORM/Mapping/Id.php b/src/Mapping/Id.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Id.php rename to src/Mapping/Id.php diff --git a/lib/Doctrine/ORM/Mapping/Index.php b/src/Mapping/Index.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Index.php rename to src/Mapping/Index.php diff --git a/lib/Doctrine/ORM/Mapping/InheritanceType.php b/src/Mapping/InheritanceType.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/InheritanceType.php rename to src/Mapping/InheritanceType.php diff --git a/lib/Doctrine/ORM/Mapping/InverseJoinColumn.php b/src/Mapping/InverseJoinColumn.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/InverseJoinColumn.php rename to src/Mapping/InverseJoinColumn.php diff --git a/lib/Doctrine/ORM/Mapping/JoinColumn.php b/src/Mapping/JoinColumn.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/JoinColumn.php rename to src/Mapping/JoinColumn.php diff --git a/lib/Doctrine/ORM/Mapping/JoinColumnProperties.php b/src/Mapping/JoinColumnProperties.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/JoinColumnProperties.php rename to src/Mapping/JoinColumnProperties.php diff --git a/lib/Doctrine/ORM/Mapping/JoinColumns.php b/src/Mapping/JoinColumns.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/JoinColumns.php rename to src/Mapping/JoinColumns.php diff --git a/lib/Doctrine/ORM/Mapping/JoinTable.php b/src/Mapping/JoinTable.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/JoinTable.php rename to src/Mapping/JoinTable.php diff --git a/lib/Doctrine/ORM/Mapping/ManyToMany.php b/src/Mapping/ManyToMany.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ManyToMany.php rename to src/Mapping/ManyToMany.php diff --git a/lib/Doctrine/ORM/Mapping/ManyToOne.php b/src/Mapping/ManyToOne.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ManyToOne.php rename to src/Mapping/ManyToOne.php diff --git a/lib/Doctrine/ORM/Mapping/MappedSuperclass.php b/src/Mapping/MappedSuperclass.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/MappedSuperclass.php rename to src/Mapping/MappedSuperclass.php diff --git a/lib/Doctrine/ORM/Mapping/MappingAttribute.php b/src/Mapping/MappingAttribute.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/MappingAttribute.php rename to src/Mapping/MappingAttribute.php diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/src/Mapping/MappingException.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/MappingException.php rename to src/Mapping/MappingException.php diff --git a/lib/Doctrine/ORM/Mapping/NamedNativeQueries.php b/src/Mapping/NamedNativeQueries.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/NamedNativeQueries.php rename to src/Mapping/NamedNativeQueries.php diff --git a/lib/Doctrine/ORM/Mapping/NamedNativeQuery.php b/src/Mapping/NamedNativeQuery.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/NamedNativeQuery.php rename to src/Mapping/NamedNativeQuery.php diff --git a/lib/Doctrine/ORM/Mapping/NamedQueries.php b/src/Mapping/NamedQueries.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/NamedQueries.php rename to src/Mapping/NamedQueries.php diff --git a/lib/Doctrine/ORM/Mapping/NamedQuery.php b/src/Mapping/NamedQuery.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/NamedQuery.php rename to src/Mapping/NamedQuery.php diff --git a/lib/Doctrine/ORM/Mapping/NamingStrategy.php b/src/Mapping/NamingStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/NamingStrategy.php rename to src/Mapping/NamingStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/OneToMany.php b/src/Mapping/OneToMany.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/OneToMany.php rename to src/Mapping/OneToMany.php diff --git a/lib/Doctrine/ORM/Mapping/OneToOne.php b/src/Mapping/OneToOne.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/OneToOne.php rename to src/Mapping/OneToOne.php diff --git a/lib/Doctrine/ORM/Mapping/OrderBy.php b/src/Mapping/OrderBy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/OrderBy.php rename to src/Mapping/OrderBy.php diff --git a/lib/Doctrine/ORM/Mapping/PostLoad.php b/src/Mapping/PostLoad.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PostLoad.php rename to src/Mapping/PostLoad.php diff --git a/lib/Doctrine/ORM/Mapping/PostPersist.php b/src/Mapping/PostPersist.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PostPersist.php rename to src/Mapping/PostPersist.php diff --git a/lib/Doctrine/ORM/Mapping/PostRemove.php b/src/Mapping/PostRemove.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PostRemove.php rename to src/Mapping/PostRemove.php diff --git a/lib/Doctrine/ORM/Mapping/PostUpdate.php b/src/Mapping/PostUpdate.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PostUpdate.php rename to src/Mapping/PostUpdate.php diff --git a/lib/Doctrine/ORM/Mapping/PreFlush.php b/src/Mapping/PreFlush.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PreFlush.php rename to src/Mapping/PreFlush.php diff --git a/lib/Doctrine/ORM/Mapping/PrePersist.php b/src/Mapping/PrePersist.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PrePersist.php rename to src/Mapping/PrePersist.php diff --git a/lib/Doctrine/ORM/Mapping/PreRemove.php b/src/Mapping/PreRemove.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PreRemove.php rename to src/Mapping/PreRemove.php diff --git a/lib/Doctrine/ORM/Mapping/PreUpdate.php b/src/Mapping/PreUpdate.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/PreUpdate.php rename to src/Mapping/PreUpdate.php diff --git a/lib/Doctrine/ORM/Mapping/QuoteStrategy.php b/src/Mapping/QuoteStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/QuoteStrategy.php rename to src/Mapping/QuoteStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/Reflection/ReflectionPropertiesGetter.php b/src/Mapping/Reflection/ReflectionPropertiesGetter.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Reflection/ReflectionPropertiesGetter.php rename to src/Mapping/Reflection/ReflectionPropertiesGetter.php diff --git a/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php b/src/Mapping/ReflectionEmbeddedProperty.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php rename to src/Mapping/ReflectionEmbeddedProperty.php diff --git a/lib/Doctrine/ORM/Mapping/ReflectionEnumProperty.php b/src/Mapping/ReflectionEnumProperty.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ReflectionEnumProperty.php rename to src/Mapping/ReflectionEnumProperty.php diff --git a/lib/Doctrine/ORM/Mapping/ReflectionReadonlyProperty.php b/src/Mapping/ReflectionReadonlyProperty.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/ReflectionReadonlyProperty.php rename to src/Mapping/ReflectionReadonlyProperty.php diff --git a/lib/Doctrine/ORM/Mapping/SequenceGenerator.php b/src/Mapping/SequenceGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/SequenceGenerator.php rename to src/Mapping/SequenceGenerator.php diff --git a/lib/Doctrine/ORM/Mapping/SqlResultSetMapping.php b/src/Mapping/SqlResultSetMapping.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/SqlResultSetMapping.php rename to src/Mapping/SqlResultSetMapping.php diff --git a/lib/Doctrine/ORM/Mapping/SqlResultSetMappings.php b/src/Mapping/SqlResultSetMappings.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/SqlResultSetMappings.php rename to src/Mapping/SqlResultSetMappings.php diff --git a/lib/Doctrine/ORM/Mapping/Table.php b/src/Mapping/Table.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Table.php rename to src/Mapping/Table.php diff --git a/lib/Doctrine/ORM/Mapping/TypedFieldMapper.php b/src/Mapping/TypedFieldMapper.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/TypedFieldMapper.php rename to src/Mapping/TypedFieldMapper.php diff --git a/lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php b/src/Mapping/UnderscoreNamingStrategy.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/UnderscoreNamingStrategy.php rename to src/Mapping/UnderscoreNamingStrategy.php diff --git a/lib/Doctrine/ORM/Mapping/UniqueConstraint.php b/src/Mapping/UniqueConstraint.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/UniqueConstraint.php rename to src/Mapping/UniqueConstraint.php diff --git a/lib/Doctrine/ORM/Mapping/Version.php b/src/Mapping/Version.php similarity index 100% rename from lib/Doctrine/ORM/Mapping/Version.php rename to src/Mapping/Version.php diff --git a/lib/Doctrine/ORM/NativeQuery.php b/src/NativeQuery.php similarity index 100% rename from lib/Doctrine/ORM/NativeQuery.php rename to src/NativeQuery.php diff --git a/lib/Doctrine/ORM/NoResultException.php b/src/NoResultException.php similarity index 100% rename from lib/Doctrine/ORM/NoResultException.php rename to src/NoResultException.php diff --git a/lib/Doctrine/ORM/NonUniqueResultException.php b/src/NonUniqueResultException.php similarity index 100% rename from lib/Doctrine/ORM/NonUniqueResultException.php rename to src/NonUniqueResultException.php diff --git a/lib/Doctrine/ORM/ORMException.php b/src/ORMException.php similarity index 100% rename from lib/Doctrine/ORM/ORMException.php rename to src/ORMException.php diff --git a/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/src/ORMInvalidArgumentException.php similarity index 100% rename from lib/Doctrine/ORM/ORMInvalidArgumentException.php rename to src/ORMInvalidArgumentException.php diff --git a/lib/Doctrine/ORM/ORMSetup.php b/src/ORMSetup.php similarity index 100% rename from lib/Doctrine/ORM/ORMSetup.php rename to src/ORMSetup.php diff --git a/lib/Doctrine/ORM/OptimisticLockException.php b/src/OptimisticLockException.php similarity index 100% rename from lib/Doctrine/ORM/OptimisticLockException.php rename to src/OptimisticLockException.php diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/src/PersistentCollection.php similarity index 100% rename from lib/Doctrine/ORM/PersistentCollection.php rename to src/PersistentCollection.php diff --git a/lib/Doctrine/ORM/Persisters/Collection/AbstractCollectionPersister.php b/src/Persisters/Collection/AbstractCollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Collection/AbstractCollectionPersister.php rename to src/Persisters/Collection/AbstractCollectionPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Collection/CollectionPersister.php b/src/Persisters/Collection/CollectionPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Collection/CollectionPersister.php rename to src/Persisters/Collection/CollectionPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php b/src/Persisters/Collection/ManyToManyPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Collection/ManyToManyPersister.php rename to src/Persisters/Collection/ManyToManyPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php b/src/Persisters/Collection/OneToManyPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php rename to src/Persisters/Collection/OneToManyPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/AbstractEntityInheritancePersister.php b/src/Persisters/Entity/AbstractEntityInheritancePersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/AbstractEntityInheritancePersister.php rename to src/Persisters/Entity/AbstractEntityInheritancePersister.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/src/Persisters/Entity/BasicEntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php rename to src/Persisters/Entity/BasicEntityPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/CachedPersisterContext.php b/src/Persisters/Entity/CachedPersisterContext.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/CachedPersisterContext.php rename to src/Persisters/Entity/CachedPersisterContext.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/EntityPersister.php b/src/Persisters/Entity/EntityPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/EntityPersister.php rename to src/Persisters/Entity/EntityPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php b/src/Persisters/Entity/JoinedSubclassPersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php rename to src/Persisters/Entity/JoinedSubclassPersister.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/SingleTablePersister.php b/src/Persisters/Entity/SingleTablePersister.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Entity/SingleTablePersister.php rename to src/Persisters/Entity/SingleTablePersister.php diff --git a/lib/Doctrine/ORM/Persisters/Exception/CantUseInOperatorOnCompositeKeys.php b/src/Persisters/Exception/CantUseInOperatorOnCompositeKeys.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Exception/CantUseInOperatorOnCompositeKeys.php rename to src/Persisters/Exception/CantUseInOperatorOnCompositeKeys.php diff --git a/lib/Doctrine/ORM/Persisters/Exception/InvalidOrientation.php b/src/Persisters/Exception/InvalidOrientation.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Exception/InvalidOrientation.php rename to src/Persisters/Exception/InvalidOrientation.php diff --git a/lib/Doctrine/ORM/Persisters/Exception/UnrecognizedField.php b/src/Persisters/Exception/UnrecognizedField.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/Exception/UnrecognizedField.php rename to src/Persisters/Exception/UnrecognizedField.php diff --git a/lib/Doctrine/ORM/Persisters/MatchingAssociationFieldRequiresObject.php b/src/Persisters/MatchingAssociationFieldRequiresObject.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/MatchingAssociationFieldRequiresObject.php rename to src/Persisters/MatchingAssociationFieldRequiresObject.php diff --git a/lib/Doctrine/ORM/Persisters/PersisterException.php b/src/Persisters/PersisterException.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/PersisterException.php rename to src/Persisters/PersisterException.php diff --git a/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php b/src/Persisters/SqlExpressionVisitor.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php rename to src/Persisters/SqlExpressionVisitor.php diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/src/Persisters/SqlValueVisitor.php similarity index 100% rename from lib/Doctrine/ORM/Persisters/SqlValueVisitor.php rename to src/Persisters/SqlValueVisitor.php diff --git a/lib/Doctrine/ORM/PessimisticLockException.php b/src/PessimisticLockException.php similarity index 100% rename from lib/Doctrine/ORM/PessimisticLockException.php rename to src/PessimisticLockException.php diff --git a/lib/Doctrine/ORM/Proxy/Autoloader.php b/src/Proxy/Autoloader.php similarity index 100% rename from lib/Doctrine/ORM/Proxy/Autoloader.php rename to src/Proxy/Autoloader.php diff --git a/lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php b/src/Proxy/DefaultProxyClassNameResolver.php similarity index 100% rename from lib/Doctrine/ORM/Proxy/DefaultProxyClassNameResolver.php rename to src/Proxy/DefaultProxyClassNameResolver.php diff --git a/lib/Doctrine/ORM/Proxy/InternalProxy.php b/src/Proxy/InternalProxy.php similarity index 100% rename from lib/Doctrine/ORM/Proxy/InternalProxy.php rename to src/Proxy/InternalProxy.php diff --git a/lib/Doctrine/ORM/Proxy/Proxy.php b/src/Proxy/Proxy.php similarity index 100% rename from lib/Doctrine/ORM/Proxy/Proxy.php rename to src/Proxy/Proxy.php diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/src/Proxy/ProxyFactory.php similarity index 100% rename from lib/Doctrine/ORM/Proxy/ProxyFactory.php rename to src/Proxy/ProxyFactory.php diff --git a/lib/Doctrine/ORM/Query.php b/src/Query.php similarity index 100% rename from lib/Doctrine/ORM/Query.php rename to src/Query.php diff --git a/lib/Doctrine/ORM/Query/AST/ASTException.php b/src/Query/AST/ASTException.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ASTException.php rename to src/Query/AST/ASTException.php diff --git a/lib/Doctrine/ORM/Query/AST/AggregateExpression.php b/src/Query/AST/AggregateExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/AggregateExpression.php rename to src/Query/AST/AggregateExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php b/src/Query/AST/ArithmeticExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ArithmeticExpression.php rename to src/Query/AST/ArithmeticExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php b/src/Query/AST/ArithmeticFactor.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ArithmeticFactor.php rename to src/Query/AST/ArithmeticFactor.php diff --git a/lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php b/src/Query/AST/ArithmeticTerm.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ArithmeticTerm.php rename to src/Query/AST/ArithmeticTerm.php diff --git a/lib/Doctrine/ORM/Query/AST/BetweenExpression.php b/src/Query/AST/BetweenExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/BetweenExpression.php rename to src/Query/AST/BetweenExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/CoalesceExpression.php b/src/Query/AST/CoalesceExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/CoalesceExpression.php rename to src/Query/AST/CoalesceExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php b/src/Query/AST/CollectionMemberExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/CollectionMemberExpression.php rename to src/Query/AST/CollectionMemberExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ComparisonExpression.php b/src/Query/AST/ComparisonExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ComparisonExpression.php rename to src/Query/AST/ComparisonExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalExpression.php b/src/Query/AST/ConditionalExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ConditionalExpression.php rename to src/Query/AST/ConditionalExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalFactor.php b/src/Query/AST/ConditionalFactor.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ConditionalFactor.php rename to src/Query/AST/ConditionalFactor.php diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php b/src/Query/AST/ConditionalPrimary.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ConditionalPrimary.php rename to src/Query/AST/ConditionalPrimary.php diff --git a/lib/Doctrine/ORM/Query/AST/ConditionalTerm.php b/src/Query/AST/ConditionalTerm.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ConditionalTerm.php rename to src/Query/AST/ConditionalTerm.php diff --git a/lib/Doctrine/ORM/Query/AST/DeleteClause.php b/src/Query/AST/DeleteClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/DeleteClause.php rename to src/Query/AST/DeleteClause.php diff --git a/lib/Doctrine/ORM/Query/AST/DeleteStatement.php b/src/Query/AST/DeleteStatement.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/DeleteStatement.php rename to src/Query/AST/DeleteStatement.php diff --git a/lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php b/src/Query/AST/EmptyCollectionComparisonExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/EmptyCollectionComparisonExpression.php rename to src/Query/AST/EmptyCollectionComparisonExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/ExistsExpression.php b/src/Query/AST/ExistsExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ExistsExpression.php rename to src/Query/AST/ExistsExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/FromClause.php b/src/Query/AST/FromClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/FromClause.php rename to src/Query/AST/FromClause.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php b/src/Query/AST/Functions/AbsFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/AbsFunction.php rename to src/Query/AST/Functions/AbsFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/AvgFunction.php b/src/Query/AST/Functions/AvgFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/AvgFunction.php rename to src/Query/AST/Functions/AvgFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php b/src/Query/AST/Functions/BitAndFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/BitAndFunction.php rename to src/Query/AST/Functions/BitAndFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php b/src/Query/AST/Functions/BitOrFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/BitOrFunction.php rename to src/Query/AST/Functions/BitOrFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php b/src/Query/AST/Functions/ConcatFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/ConcatFunction.php rename to src/Query/AST/Functions/ConcatFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CountFunction.php b/src/Query/AST/Functions/CountFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/CountFunction.php rename to src/Query/AST/Functions/CountFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php b/src/Query/AST/Functions/CurrentDateFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php rename to src/Query/AST/Functions/CurrentDateFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php b/src/Query/AST/Functions/CurrentTimeFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php rename to src/Query/AST/Functions/CurrentTimeFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php b/src/Query/AST/Functions/CurrentTimestampFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php rename to src/Query/AST/Functions/CurrentTimestampFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php b/src/Query/AST/Functions/DateAddFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/DateAddFunction.php rename to src/Query/AST/Functions/DateAddFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php b/src/Query/AST/Functions/DateDiffFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/DateDiffFunction.php rename to src/Query/AST/Functions/DateDiffFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php b/src/Query/AST/Functions/DateSubFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/DateSubFunction.php rename to src/Query/AST/Functions/DateSubFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php b/src/Query/AST/Functions/FunctionNode.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php rename to src/Query/AST/Functions/FunctionNode.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php b/src/Query/AST/Functions/IdentityFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php rename to src/Query/AST/Functions/IdentityFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php b/src/Query/AST/Functions/LengthFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/LengthFunction.php rename to src/Query/AST/Functions/LengthFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php b/src/Query/AST/Functions/LocateFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/LocateFunction.php rename to src/Query/AST/Functions/LocateFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php b/src/Query/AST/Functions/LowerFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/LowerFunction.php rename to src/Query/AST/Functions/LowerFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/MaxFunction.php b/src/Query/AST/Functions/MaxFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/MaxFunction.php rename to src/Query/AST/Functions/MaxFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/MinFunction.php b/src/Query/AST/Functions/MinFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/MinFunction.php rename to src/Query/AST/Functions/MinFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php b/src/Query/AST/Functions/ModFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/ModFunction.php rename to src/Query/AST/Functions/ModFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php b/src/Query/AST/Functions/SizeFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/SizeFunction.php rename to src/Query/AST/Functions/SizeFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php b/src/Query/AST/Functions/SqrtFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/SqrtFunction.php rename to src/Query/AST/Functions/SqrtFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php b/src/Query/AST/Functions/SubstringFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/SubstringFunction.php rename to src/Query/AST/Functions/SubstringFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/SumFunction.php b/src/Query/AST/Functions/SumFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/SumFunction.php rename to src/Query/AST/Functions/SumFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php b/src/Query/AST/Functions/TrimFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/TrimFunction.php rename to src/Query/AST/Functions/TrimFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php b/src/Query/AST/Functions/UpperFunction.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Functions/UpperFunction.php rename to src/Query/AST/Functions/UpperFunction.php diff --git a/lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php b/src/Query/AST/GeneralCaseExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php rename to src/Query/AST/GeneralCaseExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/GroupByClause.php b/src/Query/AST/GroupByClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/GroupByClause.php rename to src/Query/AST/GroupByClause.php diff --git a/lib/Doctrine/ORM/Query/AST/HavingClause.php b/src/Query/AST/HavingClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/HavingClause.php rename to src/Query/AST/HavingClause.php diff --git a/lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php b/src/Query/AST/IdentificationVariableDeclaration.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/IdentificationVariableDeclaration.php rename to src/Query/AST/IdentificationVariableDeclaration.php diff --git a/lib/Doctrine/ORM/Query/AST/InExpression.php b/src/Query/AST/InExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/InExpression.php rename to src/Query/AST/InExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/InListExpression.php b/src/Query/AST/InListExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/InListExpression.php rename to src/Query/AST/InListExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/InSubselectExpression.php b/src/Query/AST/InSubselectExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/InSubselectExpression.php rename to src/Query/AST/InSubselectExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/IndexBy.php b/src/Query/AST/IndexBy.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/IndexBy.php rename to src/Query/AST/IndexBy.php diff --git a/lib/Doctrine/ORM/Query/AST/InputParameter.php b/src/Query/AST/InputParameter.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/InputParameter.php rename to src/Query/AST/InputParameter.php diff --git a/lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php b/src/Query/AST/InstanceOfExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/InstanceOfExpression.php rename to src/Query/AST/InstanceOfExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/Join.php b/src/Query/AST/Join.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Join.php rename to src/Query/AST/Join.php diff --git a/lib/Doctrine/ORM/Query/AST/JoinAssociationDeclaration.php b/src/Query/AST/JoinAssociationDeclaration.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/JoinAssociationDeclaration.php rename to src/Query/AST/JoinAssociationDeclaration.php diff --git a/lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php b/src/Query/AST/JoinAssociationPathExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/JoinAssociationPathExpression.php rename to src/Query/AST/JoinAssociationPathExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/JoinClassPathExpression.php b/src/Query/AST/JoinClassPathExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/JoinClassPathExpression.php rename to src/Query/AST/JoinClassPathExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php b/src/Query/AST/JoinVariableDeclaration.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/JoinVariableDeclaration.php rename to src/Query/AST/JoinVariableDeclaration.php diff --git a/lib/Doctrine/ORM/Query/AST/LikeExpression.php b/src/Query/AST/LikeExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/LikeExpression.php rename to src/Query/AST/LikeExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/Literal.php b/src/Query/AST/Literal.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Literal.php rename to src/Query/AST/Literal.php diff --git a/lib/Doctrine/ORM/Query/AST/NewObjectExpression.php b/src/Query/AST/NewObjectExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/NewObjectExpression.php rename to src/Query/AST/NewObjectExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/Node.php b/src/Query/AST/Node.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Node.php rename to src/Query/AST/Node.php diff --git a/lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php b/src/Query/AST/NullComparisonExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/NullComparisonExpression.php rename to src/Query/AST/NullComparisonExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/NullIfExpression.php b/src/Query/AST/NullIfExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/NullIfExpression.php rename to src/Query/AST/NullIfExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/OrderByClause.php b/src/Query/AST/OrderByClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/OrderByClause.php rename to src/Query/AST/OrderByClause.php diff --git a/lib/Doctrine/ORM/Query/AST/OrderByItem.php b/src/Query/AST/OrderByItem.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/OrderByItem.php rename to src/Query/AST/OrderByItem.php diff --git a/lib/Doctrine/ORM/Query/AST/ParenthesisExpression.php b/src/Query/AST/ParenthesisExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/ParenthesisExpression.php rename to src/Query/AST/ParenthesisExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php b/src/Query/AST/PartialObjectExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/PartialObjectExpression.php rename to src/Query/AST/PartialObjectExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/PathExpression.php b/src/Query/AST/PathExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/PathExpression.php rename to src/Query/AST/PathExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php b/src/Query/AST/Phase2OptimizableConditional.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Phase2OptimizableConditional.php rename to src/Query/AST/Phase2OptimizableConditional.php diff --git a/lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php b/src/Query/AST/QuantifiedExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/QuantifiedExpression.php rename to src/Query/AST/QuantifiedExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php b/src/Query/AST/RangeVariableDeclaration.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/RangeVariableDeclaration.php rename to src/Query/AST/RangeVariableDeclaration.php diff --git a/lib/Doctrine/ORM/Query/AST/SelectClause.php b/src/Query/AST/SelectClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SelectClause.php rename to src/Query/AST/SelectClause.php diff --git a/lib/Doctrine/ORM/Query/AST/SelectExpression.php b/src/Query/AST/SelectExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SelectExpression.php rename to src/Query/AST/SelectExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/SelectStatement.php b/src/Query/AST/SelectStatement.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SelectStatement.php rename to src/Query/AST/SelectStatement.php diff --git a/lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php b/src/Query/AST/SimpleArithmeticExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SimpleArithmeticExpression.php rename to src/Query/AST/SimpleArithmeticExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php b/src/Query/AST/SimpleCaseExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php rename to src/Query/AST/SimpleCaseExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php b/src/Query/AST/SimpleSelectClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SimpleSelectClause.php rename to src/Query/AST/SimpleSelectClause.php diff --git a/lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php b/src/Query/AST/SimpleSelectExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SimpleSelectExpression.php rename to src/Query/AST/SimpleSelectExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php b/src/Query/AST/SimpleWhenClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php rename to src/Query/AST/SimpleWhenClause.php diff --git a/lib/Doctrine/ORM/Query/AST/Subselect.php b/src/Query/AST/Subselect.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/Subselect.php rename to src/Query/AST/Subselect.php diff --git a/lib/Doctrine/ORM/Query/AST/SubselectFromClause.php b/src/Query/AST/SubselectFromClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SubselectFromClause.php rename to src/Query/AST/SubselectFromClause.php diff --git a/lib/Doctrine/ORM/Query/AST/SubselectIdentificationVariableDeclaration.php b/src/Query/AST/SubselectIdentificationVariableDeclaration.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/SubselectIdentificationVariableDeclaration.php rename to src/Query/AST/SubselectIdentificationVariableDeclaration.php diff --git a/lib/Doctrine/ORM/Query/AST/TypedExpression.php b/src/Query/AST/TypedExpression.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/TypedExpression.php rename to src/Query/AST/TypedExpression.php diff --git a/lib/Doctrine/ORM/Query/AST/UpdateClause.php b/src/Query/AST/UpdateClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/UpdateClause.php rename to src/Query/AST/UpdateClause.php diff --git a/lib/Doctrine/ORM/Query/AST/UpdateItem.php b/src/Query/AST/UpdateItem.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/UpdateItem.php rename to src/Query/AST/UpdateItem.php diff --git a/lib/Doctrine/ORM/Query/AST/UpdateStatement.php b/src/Query/AST/UpdateStatement.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/UpdateStatement.php rename to src/Query/AST/UpdateStatement.php diff --git a/lib/Doctrine/ORM/Query/AST/WhenClause.php b/src/Query/AST/WhenClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/WhenClause.php rename to src/Query/AST/WhenClause.php diff --git a/lib/Doctrine/ORM/Query/AST/WhereClause.php b/src/Query/AST/WhereClause.php similarity index 100% rename from lib/Doctrine/ORM/Query/AST/WhereClause.php rename to src/Query/AST/WhereClause.php diff --git a/lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php b/src/Query/Exec/AbstractSqlExecutor.php similarity index 100% rename from lib/Doctrine/ORM/Query/Exec/AbstractSqlExecutor.php rename to src/Query/Exec/AbstractSqlExecutor.php diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/src/Query/Exec/MultiTableDeleteExecutor.php similarity index 100% rename from lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php rename to src/Query/Exec/MultiTableDeleteExecutor.php diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/src/Query/Exec/MultiTableUpdateExecutor.php similarity index 100% rename from lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php rename to src/Query/Exec/MultiTableUpdateExecutor.php diff --git a/lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php b/src/Query/Exec/SingleSelectExecutor.php similarity index 100% rename from lib/Doctrine/ORM/Query/Exec/SingleSelectExecutor.php rename to src/Query/Exec/SingleSelectExecutor.php diff --git a/lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php b/src/Query/Exec/SingleTableDeleteUpdateExecutor.php similarity index 100% rename from lib/Doctrine/ORM/Query/Exec/SingleTableDeleteUpdateExecutor.php rename to src/Query/Exec/SingleTableDeleteUpdateExecutor.php diff --git a/lib/Doctrine/ORM/Query/Expr.php b/src/Query/Expr.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr.php rename to src/Query/Expr.php diff --git a/lib/Doctrine/ORM/Query/Expr/Andx.php b/src/Query/Expr/Andx.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Andx.php rename to src/Query/Expr/Andx.php diff --git a/lib/Doctrine/ORM/Query/Expr/Base.php b/src/Query/Expr/Base.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Base.php rename to src/Query/Expr/Base.php diff --git a/lib/Doctrine/ORM/Query/Expr/Comparison.php b/src/Query/Expr/Comparison.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Comparison.php rename to src/Query/Expr/Comparison.php diff --git a/lib/Doctrine/ORM/Query/Expr/Composite.php b/src/Query/Expr/Composite.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Composite.php rename to src/Query/Expr/Composite.php diff --git a/lib/Doctrine/ORM/Query/Expr/From.php b/src/Query/Expr/From.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/From.php rename to src/Query/Expr/From.php diff --git a/lib/Doctrine/ORM/Query/Expr/Func.php b/src/Query/Expr/Func.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Func.php rename to src/Query/Expr/Func.php diff --git a/lib/Doctrine/ORM/Query/Expr/GroupBy.php b/src/Query/Expr/GroupBy.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/GroupBy.php rename to src/Query/Expr/GroupBy.php diff --git a/lib/Doctrine/ORM/Query/Expr/Join.php b/src/Query/Expr/Join.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Join.php rename to src/Query/Expr/Join.php diff --git a/lib/Doctrine/ORM/Query/Expr/Literal.php b/src/Query/Expr/Literal.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Literal.php rename to src/Query/Expr/Literal.php diff --git a/lib/Doctrine/ORM/Query/Expr/Math.php b/src/Query/Expr/Math.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Math.php rename to src/Query/Expr/Math.php diff --git a/lib/Doctrine/ORM/Query/Expr/OrderBy.php b/src/Query/Expr/OrderBy.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/OrderBy.php rename to src/Query/Expr/OrderBy.php diff --git a/lib/Doctrine/ORM/Query/Expr/Orx.php b/src/Query/Expr/Orx.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Orx.php rename to src/Query/Expr/Orx.php diff --git a/lib/Doctrine/ORM/Query/Expr/Select.php b/src/Query/Expr/Select.php similarity index 100% rename from lib/Doctrine/ORM/Query/Expr/Select.php rename to src/Query/Expr/Select.php diff --git a/lib/Doctrine/ORM/Query/Filter/FilterException.php b/src/Query/Filter/FilterException.php similarity index 100% rename from lib/Doctrine/ORM/Query/Filter/FilterException.php rename to src/Query/Filter/FilterException.php diff --git a/lib/Doctrine/ORM/Query/Filter/SQLFilter.php b/src/Query/Filter/SQLFilter.php similarity index 100% rename from lib/Doctrine/ORM/Query/Filter/SQLFilter.php rename to src/Query/Filter/SQLFilter.php diff --git a/lib/Doctrine/ORM/Query/FilterCollection.php b/src/Query/FilterCollection.php similarity index 100% rename from lib/Doctrine/ORM/Query/FilterCollection.php rename to src/Query/FilterCollection.php diff --git a/lib/Doctrine/ORM/Query/Lexer.php b/src/Query/Lexer.php similarity index 100% rename from lib/Doctrine/ORM/Query/Lexer.php rename to src/Query/Lexer.php diff --git a/lib/Doctrine/ORM/Query/Parameter.php b/src/Query/Parameter.php similarity index 100% rename from lib/Doctrine/ORM/Query/Parameter.php rename to src/Query/Parameter.php diff --git a/lib/Doctrine/ORM/Query/ParameterTypeInferer.php b/src/Query/ParameterTypeInferer.php similarity index 100% rename from lib/Doctrine/ORM/Query/ParameterTypeInferer.php rename to src/Query/ParameterTypeInferer.php diff --git a/lib/Doctrine/ORM/Query/Parser.php b/src/Query/Parser.php similarity index 100% rename from lib/Doctrine/ORM/Query/Parser.php rename to src/Query/Parser.php diff --git a/lib/Doctrine/ORM/Query/ParserResult.php b/src/Query/ParserResult.php similarity index 100% rename from lib/Doctrine/ORM/Query/ParserResult.php rename to src/Query/ParserResult.php diff --git a/lib/Doctrine/ORM/Query/Printer.php b/src/Query/Printer.php similarity index 100% rename from lib/Doctrine/ORM/Query/Printer.php rename to src/Query/Printer.php diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/src/Query/QueryException.php similarity index 100% rename from lib/Doctrine/ORM/Query/QueryException.php rename to src/Query/QueryException.php diff --git a/lib/Doctrine/ORM/Query/QueryExpressionVisitor.php b/src/Query/QueryExpressionVisitor.php similarity index 100% rename from lib/Doctrine/ORM/Query/QueryExpressionVisitor.php rename to src/Query/QueryExpressionVisitor.php diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/src/Query/ResultSetMapping.php similarity index 100% rename from lib/Doctrine/ORM/Query/ResultSetMapping.php rename to src/Query/ResultSetMapping.php diff --git a/lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php b/src/Query/ResultSetMappingBuilder.php similarity index 100% rename from lib/Doctrine/ORM/Query/ResultSetMappingBuilder.php rename to src/Query/ResultSetMappingBuilder.php diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/src/Query/SqlWalker.php similarity index 100% rename from lib/Doctrine/ORM/Query/SqlWalker.php rename to src/Query/SqlWalker.php diff --git a/lib/Doctrine/ORM/Query/TreeWalker.php b/src/Query/TreeWalker.php similarity index 100% rename from lib/Doctrine/ORM/Query/TreeWalker.php rename to src/Query/TreeWalker.php diff --git a/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php b/src/Query/TreeWalkerAdapter.php similarity index 100% rename from lib/Doctrine/ORM/Query/TreeWalkerAdapter.php rename to src/Query/TreeWalkerAdapter.php diff --git a/lib/Doctrine/ORM/Query/TreeWalkerChain.php b/src/Query/TreeWalkerChain.php similarity index 100% rename from lib/Doctrine/ORM/Query/TreeWalkerChain.php rename to src/Query/TreeWalkerChain.php diff --git a/lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php b/src/Query/TreeWalkerChainIterator.php similarity index 100% rename from lib/Doctrine/ORM/Query/TreeWalkerChainIterator.php rename to src/Query/TreeWalkerChainIterator.php diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/src/QueryBuilder.php similarity index 100% rename from lib/Doctrine/ORM/QueryBuilder.php rename to src/QueryBuilder.php diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/src/Repository/DefaultRepositoryFactory.php similarity index 100% rename from lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php rename to src/Repository/DefaultRepositoryFactory.php diff --git a/lib/Doctrine/ORM/Repository/Exception/InvalidFindByCall.php b/src/Repository/Exception/InvalidFindByCall.php similarity index 100% rename from lib/Doctrine/ORM/Repository/Exception/InvalidFindByCall.php rename to src/Repository/Exception/InvalidFindByCall.php diff --git a/lib/Doctrine/ORM/Repository/Exception/InvalidMagicMethodCall.php b/src/Repository/Exception/InvalidMagicMethodCall.php similarity index 100% rename from lib/Doctrine/ORM/Repository/Exception/InvalidMagicMethodCall.php rename to src/Repository/Exception/InvalidMagicMethodCall.php diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/src/Repository/RepositoryFactory.php similarity index 100% rename from lib/Doctrine/ORM/Repository/RepositoryFactory.php rename to src/Repository/RepositoryFactory.php diff --git a/lib/Doctrine/ORM/Tools/AttachEntityListenersListener.php b/src/Tools/AttachEntityListenersListener.php similarity index 100% rename from lib/Doctrine/ORM/Tools/AttachEntityListenersListener.php rename to src/Tools/AttachEntityListenersListener.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/AbstractEntityManagerCommand.php b/src/Tools/Console/Command/AbstractEntityManagerCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/AbstractEntityManagerCommand.php rename to src/Tools/Console/Command/AbstractEntityManagerCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php b/src/Tools/Console/Command/ClearCache/CollectionRegionCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/CollectionRegionCommand.php rename to src/Tools/Console/Command/ClearCache/CollectionRegionCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php b/src/Tools/Console/Command/ClearCache/EntityRegionCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/EntityRegionCommand.php rename to src/Tools/Console/Command/ClearCache/EntityRegionCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php b/src/Tools/Console/Command/ClearCache/MetadataCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/MetadataCommand.php rename to src/Tools/Console/Command/ClearCache/MetadataCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php b/src/Tools/Console/Command/ClearCache/QueryCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryCommand.php rename to src/Tools/Console/Command/ClearCache/QueryCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php b/src/Tools/Console/Command/ClearCache/QueryRegionCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/QueryRegionCommand.php rename to src/Tools/Console/Command/ClearCache/QueryRegionCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php b/src/Tools/Console/Command/ClearCache/ResultCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ClearCache/ResultCommand.php rename to src/Tools/Console/Command/ClearCache/ResultCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php b/src/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php rename to src/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/src/Tools/Console/Command/ConvertMappingCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php rename to src/Tools/Console/Command/ConvertMappingCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php b/src/Tools/Console/Command/EnsureProductionSettingsCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/EnsureProductionSettingsCommand.php rename to src/Tools/Console/Command/EnsureProductionSettingsCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/src/Tools/Console/Command/GenerateEntitiesCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php rename to src/Tools/Console/Command/GenerateEntitiesCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/src/Tools/Console/Command/GenerateProxiesCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php rename to src/Tools/Console/Command/GenerateProxiesCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/src/Tools/Console/Command/GenerateRepositoriesCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php rename to src/Tools/Console/Command/GenerateRepositoriesCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php b/src/Tools/Console/Command/InfoCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/InfoCommand.php rename to src/Tools/Console/Command/InfoCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php b/src/Tools/Console/Command/MappingDescribeCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/MappingDescribeCommand.php rename to src/Tools/Console/Command/MappingDescribeCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php b/src/Tools/Console/Command/RunDqlCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/RunDqlCommand.php rename to src/Tools/Console/Command/RunDqlCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php b/src/Tools/Console/Command/SchemaTool/AbstractCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/AbstractCommand.php rename to src/Tools/Console/Command/SchemaTool/AbstractCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php b/src/Tools/Console/Command/SchemaTool/CreateCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php rename to src/Tools/Console/Command/SchemaTool/CreateCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/src/Tools/Console/Command/SchemaTool/DropCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php rename to src/Tools/Console/Command/SchemaTool/DropCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/src/Tools/Console/Command/SchemaTool/UpdateCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php rename to src/Tools/Console/Command/SchemaTool/UpdateCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php b/src/Tools/Console/Command/ValidateSchemaCommand.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Command/ValidateSchemaCommand.php rename to src/Tools/Console/Command/ValidateSchemaCommand.php diff --git a/lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php b/src/Tools/Console/CommandCompatibility.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/CommandCompatibility.php rename to src/Tools/Console/CommandCompatibility.php diff --git a/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php b/src/Tools/Console/ConsoleRunner.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php rename to src/Tools/Console/ConsoleRunner.php diff --git a/lib/Doctrine/ORM/Tools/Console/EntityManagerProvider.php b/src/Tools/Console/EntityManagerProvider.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/EntityManagerProvider.php rename to src/Tools/Console/EntityManagerProvider.php diff --git a/lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php b/src/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php rename to src/Tools/Console/EntityManagerProvider/ConnectionFromManagerProvider.php diff --git a/lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/HelperSetManagerProvider.php b/src/Tools/Console/EntityManagerProvider/HelperSetManagerProvider.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/HelperSetManagerProvider.php rename to src/Tools/Console/EntityManagerProvider/HelperSetManagerProvider.php diff --git a/lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/SingleManagerProvider.php b/src/Tools/Console/EntityManagerProvider/SingleManagerProvider.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/SingleManagerProvider.php rename to src/Tools/Console/EntityManagerProvider/SingleManagerProvider.php diff --git a/lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/UnknownManagerException.php b/src/Tools/Console/EntityManagerProvider/UnknownManagerException.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/EntityManagerProvider/UnknownManagerException.php rename to src/Tools/Console/EntityManagerProvider/UnknownManagerException.php diff --git a/lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php b/src/Tools/Console/Helper/EntityManagerHelper.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/Helper/EntityManagerHelper.php rename to src/Tools/Console/Helper/EntityManagerHelper.php diff --git a/lib/Doctrine/ORM/Tools/Console/MetadataFilter.php b/src/Tools/Console/MetadataFilter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Console/MetadataFilter.php rename to src/Tools/Console/MetadataFilter.php diff --git a/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php b/src/Tools/ConvertDoctrine1Schema.php similarity index 100% rename from lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php rename to src/Tools/ConvertDoctrine1Schema.php diff --git a/lib/Doctrine/ORM/Tools/Debug.php b/src/Tools/Debug.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Debug.php rename to src/Tools/Debug.php diff --git a/lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php b/src/Tools/DebugUnitOfWorkListener.php similarity index 100% rename from lib/Doctrine/ORM/Tools/DebugUnitOfWorkListener.php rename to src/Tools/DebugUnitOfWorkListener.php diff --git a/lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php b/src/Tools/DisconnectedClassMetadataFactory.php similarity index 100% rename from lib/Doctrine/ORM/Tools/DisconnectedClassMetadataFactory.php rename to src/Tools/DisconnectedClassMetadataFactory.php diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/src/Tools/EntityGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Tools/EntityGenerator.php rename to src/Tools/EntityGenerator.php diff --git a/lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php b/src/Tools/EntityRepositoryGenerator.php similarity index 100% rename from lib/Doctrine/ORM/Tools/EntityRepositoryGenerator.php rename to src/Tools/EntityRepositoryGenerator.php diff --git a/lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php b/src/Tools/Event/GenerateSchemaEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Event/GenerateSchemaEventArgs.php rename to src/Tools/Event/GenerateSchemaEventArgs.php diff --git a/lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php b/src/Tools/Event/GenerateSchemaTableEventArgs.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Event/GenerateSchemaTableEventArgs.php rename to src/Tools/Event/GenerateSchemaTableEventArgs.php diff --git a/lib/Doctrine/ORM/Tools/Exception/MissingColumnException.php b/src/Tools/Exception/MissingColumnException.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Exception/MissingColumnException.php rename to src/Tools/Exception/MissingColumnException.php diff --git a/lib/Doctrine/ORM/Tools/Exception/NotSupported.php b/src/Tools/Exception/NotSupported.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Exception/NotSupported.php rename to src/Tools/Exception/NotSupported.php diff --git a/lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php b/src/Tools/Export/ClassMetadataExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/ClassMetadataExporter.php rename to src/Tools/Export/ClassMetadataExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/src/Tools/Export/Driver/AbstractExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php rename to src/Tools/Export/Driver/AbstractExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php b/src/Tools/Export/Driver/AnnotationExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/Driver/AnnotationExporter.php rename to src/Tools/Export/Driver/AnnotationExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php b/src/Tools/Export/Driver/PhpExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/Driver/PhpExporter.php rename to src/Tools/Export/Driver/PhpExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/src/Tools/Export/Driver/XmlExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php rename to src/Tools/Export/Driver/XmlExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php b/src/Tools/Export/Driver/YamlExporter.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php rename to src/Tools/Export/Driver/YamlExporter.php diff --git a/lib/Doctrine/ORM/Tools/Export/ExportException.php b/src/Tools/Export/ExportException.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Export/ExportException.php rename to src/Tools/Export/ExportException.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php b/src/Tools/Pagination/CountOutputWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/CountOutputWalker.php rename to src/Tools/Pagination/CountOutputWalker.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/CountWalker.php b/src/Tools/Pagination/CountWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/CountWalker.php rename to src/Tools/Pagination/CountWalker.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/Exception/RowNumberOverFunctionNotEnabled.php b/src/Tools/Pagination/Exception/RowNumberOverFunctionNotEnabled.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/Exception/RowNumberOverFunctionNotEnabled.php rename to src/Tools/Pagination/Exception/RowNumberOverFunctionNotEnabled.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/src/Tools/Pagination/LimitSubqueryOutputWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php rename to src/Tools/Pagination/LimitSubqueryOutputWalker.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php b/src/Tools/Pagination/LimitSubqueryWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryWalker.php rename to src/Tools/Pagination/LimitSubqueryWalker.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/src/Tools/Pagination/Paginator.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/Paginator.php rename to src/Tools/Pagination/Paginator.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/RootTypeWalker.php b/src/Tools/Pagination/RootTypeWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/RootTypeWalker.php rename to src/Tools/Pagination/RootTypeWalker.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/RowNumberOverFunction.php b/src/Tools/Pagination/RowNumberOverFunction.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/RowNumberOverFunction.php rename to src/Tools/Pagination/RowNumberOverFunction.php diff --git a/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php b/src/Tools/Pagination/WhereInWalker.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php rename to src/Tools/Pagination/WhereInWalker.php diff --git a/lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php b/src/Tools/ResolveTargetEntityListener.php similarity index 100% rename from lib/Doctrine/ORM/Tools/ResolveTargetEntityListener.php rename to src/Tools/ResolveTargetEntityListener.php diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/src/Tools/SchemaTool.php similarity index 100% rename from lib/Doctrine/ORM/Tools/SchemaTool.php rename to src/Tools/SchemaTool.php diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/src/Tools/SchemaValidator.php similarity index 100% rename from lib/Doctrine/ORM/Tools/SchemaValidator.php rename to src/Tools/SchemaValidator.php diff --git a/lib/Doctrine/ORM/Tools/Setup.php b/src/Tools/Setup.php similarity index 100% rename from lib/Doctrine/ORM/Tools/Setup.php rename to src/Tools/Setup.php diff --git a/lib/Doctrine/ORM/Tools/ToolEvents.php b/src/Tools/ToolEvents.php similarity index 100% rename from lib/Doctrine/ORM/Tools/ToolEvents.php rename to src/Tools/ToolEvents.php diff --git a/lib/Doctrine/ORM/Tools/ToolsException.php b/src/Tools/ToolsException.php similarity index 100% rename from lib/Doctrine/ORM/Tools/ToolsException.php rename to src/Tools/ToolsException.php diff --git a/lib/Doctrine/ORM/TransactionRequiredException.php b/src/TransactionRequiredException.php similarity index 100% rename from lib/Doctrine/ORM/TransactionRequiredException.php rename to src/TransactionRequiredException.php diff --git a/lib/Doctrine/ORM/UnexpectedResultException.php b/src/UnexpectedResultException.php similarity index 100% rename from lib/Doctrine/ORM/UnexpectedResultException.php rename to src/UnexpectedResultException.php diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/src/UnitOfWork.php similarity index 100% rename from lib/Doctrine/ORM/UnitOfWork.php rename to src/UnitOfWork.php diff --git a/lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php b/src/Utility/HierarchyDiscriminatorResolver.php similarity index 100% rename from lib/Doctrine/ORM/Utility/HierarchyDiscriminatorResolver.php rename to src/Utility/HierarchyDiscriminatorResolver.php diff --git a/lib/Doctrine/ORM/Utility/IdentifierFlattener.php b/src/Utility/IdentifierFlattener.php similarity index 100% rename from lib/Doctrine/ORM/Utility/IdentifierFlattener.php rename to src/Utility/IdentifierFlattener.php diff --git a/lib/Doctrine/ORM/Utility/PersisterHelper.php b/src/Utility/PersisterHelper.php similarity index 100% rename from lib/Doctrine/ORM/Utility/PersisterHelper.php rename to src/Utility/PersisterHelper.php diff --git a/lib/Doctrine/ORM/Version.php b/src/Version.php similarity index 100% rename from lib/Doctrine/ORM/Version.php rename to src/Version.php diff --git a/tests/.gitignore b/tests/.gitignore index 7210405266d..7575448eba5 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,3 +1,3 @@ -Doctrine/Tests/Proxies/ -Doctrine/Tests/ORM/Proxy/generated/ -Doctrine/Tests/ORM/Tools/Export/export +Tests/Proxies/ +Tests/ORM/Proxy/generated/ +Tests/ORM/Tools/Export/export diff --git a/tests/Doctrine/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php b/tests/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php similarity index 100% rename from tests/Doctrine/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php rename to tests/Performance/ChangeSet/UnitOfWorkComputeChangesBench.php diff --git a/tests/Doctrine/Performance/EntityManagerFactory.php b/tests/Performance/EntityManagerFactory.php similarity index 100% rename from tests/Doctrine/Performance/EntityManagerFactory.php rename to tests/Performance/EntityManagerFactory.php diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php b/tests/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php rename to tests/Performance/Hydration/MixedQueryFetchJoinArrayHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php b/tests/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php rename to tests/Performance/Hydration/MixedQueryFetchJoinFullObjectHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php b/tests/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php rename to tests/Performance/Hydration/MixedQueryFetchJoinPartialObjectHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleHydrationBench.php b/tests/Performance/Hydration/SimpleHydrationBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleHydrationBench.php rename to tests/Performance/Hydration/SimpleHydrationBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php b/tests/Performance/Hydration/SimpleInsertPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleInsertPerformanceBench.php rename to tests/Performance/Hydration/SimpleInsertPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php b/tests/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php rename to tests/Performance/Hydration/SimpleQueryArrayHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php b/tests/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php rename to tests/Performance/Hydration/SimpleQueryFullObjectHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php b/tests/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php rename to tests/Performance/Hydration/SimpleQueryPartialObjectHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php b/tests/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php rename to tests/Performance/Hydration/SimpleQueryScalarHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php b/tests/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php rename to tests/Performance/Hydration/SingleTableInheritanceHydrationPerformanceBench.php diff --git a/tests/Doctrine/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php b/tests/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php similarity index 100% rename from tests/Doctrine/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php rename to tests/Performance/Hydration/SingleTableInheritanceInsertPerformanceBench.php diff --git a/tests/Doctrine/Performance/LazyLoading/ProxyInitializationTimeBench.php b/tests/Performance/LazyLoading/ProxyInitializationTimeBench.php similarity index 100% rename from tests/Doctrine/Performance/LazyLoading/ProxyInitializationTimeBench.php rename to tests/Performance/LazyLoading/ProxyInitializationTimeBench.php diff --git a/tests/Doctrine/Performance/LazyLoading/ProxyInstantiationTimeBench.php b/tests/Performance/LazyLoading/ProxyInstantiationTimeBench.php similarity index 100% rename from tests/Doctrine/Performance/LazyLoading/ProxyInstantiationTimeBench.php rename to tests/Performance/LazyLoading/ProxyInstantiationTimeBench.php diff --git a/tests/Doctrine/Performance/Mock/NonLoadingPersister.php b/tests/Performance/Mock/NonLoadingPersister.php similarity index 100% rename from tests/Doctrine/Performance/Mock/NonLoadingPersister.php rename to tests/Performance/Mock/NonLoadingPersister.php diff --git a/tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php b/tests/Performance/Mock/NonProxyLoadingEntityManager.php similarity index 100% rename from tests/Doctrine/Performance/Mock/NonProxyLoadingEntityManager.php rename to tests/Performance/Mock/NonProxyLoadingEntityManager.php diff --git a/tests/Doctrine/Performance/Mock/NonProxyLoadingUnitOfWork.php b/tests/Performance/Mock/NonProxyLoadingUnitOfWork.php similarity index 100% rename from tests/Doctrine/Performance/Mock/NonProxyLoadingUnitOfWork.php rename to tests/Performance/Mock/NonProxyLoadingUnitOfWork.php diff --git a/tests/Doctrine/Performance/Query/QueryBoundParameterProcessingBench.php b/tests/Performance/Query/QueryBoundParameterProcessingBench.php similarity index 100% rename from tests/Doctrine/Performance/Query/QueryBoundParameterProcessingBench.php rename to tests/Performance/Query/QueryBoundParameterProcessingBench.php diff --git a/tests/Doctrine/StaticAnalysis/Mapping/class-metadata-constructor.php b/tests/StaticAnalysis/Mapping/class-metadata-constructor.php similarity index 100% rename from tests/Doctrine/StaticAnalysis/Mapping/class-metadata-constructor.php rename to tests/StaticAnalysis/Mapping/class-metadata-constructor.php diff --git a/tests/Doctrine/StaticAnalysis/Tools/Pagination/paginator-covariant.php b/tests/StaticAnalysis/Tools/Pagination/paginator-covariant.php similarity index 100% rename from tests/Doctrine/StaticAnalysis/Tools/Pagination/paginator-covariant.php rename to tests/StaticAnalysis/Tools/Pagination/paginator-covariant.php diff --git a/tests/Doctrine/StaticAnalysis/get-metadata.php b/tests/StaticAnalysis/get-metadata.php similarity index 100% rename from tests/Doctrine/StaticAnalysis/get-metadata.php rename to tests/StaticAnalysis/get-metadata.php diff --git a/tests/Doctrine/Tests/DbalExtensions/Connection.php b/tests/Tests/DbalExtensions/Connection.php similarity index 100% rename from tests/Doctrine/Tests/DbalExtensions/Connection.php rename to tests/Tests/DbalExtensions/Connection.php diff --git a/tests/Doctrine/Tests/DbalExtensions/LegacySqlLogger.php b/tests/Tests/DbalExtensions/LegacySqlLogger.php similarity index 100% rename from tests/Doctrine/Tests/DbalExtensions/LegacySqlLogger.php rename to tests/Tests/DbalExtensions/LegacySqlLogger.php diff --git a/tests/Doctrine/Tests/DbalExtensions/QueryLog.php b/tests/Tests/DbalExtensions/QueryLog.php similarity index 100% rename from tests/Doctrine/Tests/DbalExtensions/QueryLog.php rename to tests/Tests/DbalExtensions/QueryLog.php diff --git a/tests/Doctrine/Tests/DbalExtensions/SqlLogger.php b/tests/Tests/DbalExtensions/SqlLogger.php similarity index 100% rename from tests/Doctrine/Tests/DbalExtensions/SqlLogger.php rename to tests/Tests/DbalExtensions/SqlLogger.php diff --git a/tests/Doctrine/Tests/DbalTypes/CustomIdObject.php b/tests/Tests/DbalTypes/CustomIdObject.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/CustomIdObject.php rename to tests/Tests/DbalTypes/CustomIdObject.php diff --git a/tests/Doctrine/Tests/DbalTypes/CustomIdObjectType.php b/tests/Tests/DbalTypes/CustomIdObjectType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/CustomIdObjectType.php rename to tests/Tests/DbalTypes/CustomIdObjectType.php diff --git a/tests/Doctrine/Tests/DbalTypes/CustomIntType.php b/tests/Tests/DbalTypes/CustomIntType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/CustomIntType.php rename to tests/Tests/DbalTypes/CustomIntType.php diff --git a/tests/Doctrine/Tests/DbalTypes/GH8565EmployeePayloadType.php b/tests/Tests/DbalTypes/GH8565EmployeePayloadType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/GH8565EmployeePayloadType.php rename to tests/Tests/DbalTypes/GH8565EmployeePayloadType.php diff --git a/tests/Doctrine/Tests/DbalTypes/GH8565ManagerPayloadType.php b/tests/Tests/DbalTypes/GH8565ManagerPayloadType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/GH8565ManagerPayloadType.php rename to tests/Tests/DbalTypes/GH8565ManagerPayloadType.php diff --git a/tests/Doctrine/Tests/DbalTypes/NegativeToPositiveType.php b/tests/Tests/DbalTypes/NegativeToPositiveType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/NegativeToPositiveType.php rename to tests/Tests/DbalTypes/NegativeToPositiveType.php diff --git a/tests/Doctrine/Tests/DbalTypes/Rot13Type.php b/tests/Tests/DbalTypes/Rot13Type.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/Rot13Type.php rename to tests/Tests/DbalTypes/Rot13Type.php diff --git a/tests/Doctrine/Tests/DbalTypes/UpperCaseStringType.php b/tests/Tests/DbalTypes/UpperCaseStringType.php similarity index 100% rename from tests/Doctrine/Tests/DbalTypes/UpperCaseStringType.php rename to tests/Tests/DbalTypes/UpperCaseStringType.php diff --git a/tests/Doctrine/Tests/DoctrineTestCase.php b/tests/Tests/DoctrineTestCase.php similarity index 100% rename from tests/Doctrine/Tests/DoctrineTestCase.php rename to tests/Tests/DoctrineTestCase.php diff --git a/tests/Doctrine/Tests/EventListener/CacheMetadataListener.php b/tests/Tests/EventListener/CacheMetadataListener.php similarity index 100% rename from tests/Doctrine/Tests/EventListener/CacheMetadataListener.php rename to tests/Tests/EventListener/CacheMetadataListener.php diff --git a/tests/Doctrine/Tests/IterableTester.php b/tests/Tests/IterableTester.php similarity index 100% rename from tests/Doctrine/Tests/IterableTester.php rename to tests/Tests/IterableTester.php diff --git a/tests/Doctrine/Tests/Mocks/ArrayResultFactory.php b/tests/Tests/Mocks/ArrayResultFactory.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ArrayResultFactory.php rename to tests/Tests/Mocks/ArrayResultFactory.php diff --git a/tests/Doctrine/Tests/Mocks/CacheEntryMock.php b/tests/Tests/Mocks/CacheEntryMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/CacheEntryMock.php rename to tests/Tests/Mocks/CacheEntryMock.php diff --git a/tests/Doctrine/Tests/Mocks/CacheKeyMock.php b/tests/Tests/Mocks/CacheKeyMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/CacheKeyMock.php rename to tests/Tests/Mocks/CacheKeyMock.php diff --git a/tests/Doctrine/Tests/Mocks/CacheRegionMock.php b/tests/Tests/Mocks/CacheRegionMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/CacheRegionMock.php rename to tests/Tests/Mocks/CacheRegionMock.php diff --git a/tests/Doctrine/Tests/Mocks/ConcurrentRegionMock.php b/tests/Tests/Mocks/ConcurrentRegionMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ConcurrentRegionMock.php rename to tests/Tests/Mocks/ConcurrentRegionMock.php diff --git a/tests/Doctrine/Tests/Mocks/ConnectionMock.php b/tests/Tests/Mocks/ConnectionMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ConnectionMock.php rename to tests/Tests/Mocks/ConnectionMock.php diff --git a/tests/Doctrine/Tests/Mocks/CustomTreeWalkerJoin.php b/tests/Tests/Mocks/CustomTreeWalkerJoin.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/CustomTreeWalkerJoin.php rename to tests/Tests/Mocks/CustomTreeWalkerJoin.php diff --git a/tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php b/tests/Tests/Mocks/DatabasePlatformMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/DatabasePlatformMock.php rename to tests/Tests/Mocks/DatabasePlatformMock.php diff --git a/tests/Doctrine/Tests/Mocks/DriverConnectionMock.php b/tests/Tests/Mocks/DriverConnectionMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/DriverConnectionMock.php rename to tests/Tests/Mocks/DriverConnectionMock.php diff --git a/tests/Doctrine/Tests/Mocks/DriverMock.php b/tests/Tests/Mocks/DriverMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/DriverMock.php rename to tests/Tests/Mocks/DriverMock.php diff --git a/tests/Doctrine/Tests/Mocks/DriverResultMock.php b/tests/Tests/Mocks/DriverResultMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/DriverResultMock.php rename to tests/Tests/Mocks/DriverResultMock.php diff --git a/tests/Doctrine/Tests/Mocks/EntityManagerMock.php b/tests/Tests/Mocks/EntityManagerMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/EntityManagerMock.php rename to tests/Tests/Mocks/EntityManagerMock.php diff --git a/tests/Doctrine/Tests/Mocks/EntityPersisterMock.php b/tests/Tests/Mocks/EntityPersisterMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/EntityPersisterMock.php rename to tests/Tests/Mocks/EntityPersisterMock.php diff --git a/tests/Doctrine/Tests/Mocks/ExceptionConverterMock.php b/tests/Tests/Mocks/ExceptionConverterMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ExceptionConverterMock.php rename to tests/Tests/Mocks/ExceptionConverterMock.php diff --git a/tests/Doctrine/Tests/Mocks/MetadataDriverMock.php b/tests/Tests/Mocks/MetadataDriverMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/MetadataDriverMock.php rename to tests/Tests/Mocks/MetadataDriverMock.php diff --git a/tests/Doctrine/Tests/Mocks/NullSqlWalker.php b/tests/Tests/Mocks/NullSqlWalker.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/NullSqlWalker.php rename to tests/Tests/Mocks/NullSqlWalker.php diff --git a/tests/Doctrine/Tests/Mocks/ResultMock.php b/tests/Tests/Mocks/ResultMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ResultMock.php rename to tests/Tests/Mocks/ResultMock.php diff --git a/tests/Doctrine/Tests/Mocks/ResultStatement.php b/tests/Tests/Mocks/ResultStatement.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/ResultStatement.php rename to tests/Tests/Mocks/ResultStatement.php diff --git a/tests/Doctrine/Tests/Mocks/SchemaManagerMock.php b/tests/Tests/Mocks/SchemaManagerMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/SchemaManagerMock.php rename to tests/Tests/Mocks/SchemaManagerMock.php diff --git a/tests/Doctrine/Tests/Mocks/StatementMock.php b/tests/Tests/Mocks/StatementMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/StatementMock.php rename to tests/Tests/Mocks/StatementMock.php diff --git a/tests/Doctrine/Tests/Mocks/TimestampRegionMock.php b/tests/Tests/Mocks/TimestampRegionMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/TimestampRegionMock.php rename to tests/Tests/Mocks/TimestampRegionMock.php diff --git a/tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php b/tests/Tests/Mocks/UnitOfWorkMock.php similarity index 100% rename from tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php rename to tests/Tests/Mocks/UnitOfWorkMock.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddress.php b/tests/Tests/Models/CMS/CmsAddress.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsAddress.php rename to tests/Tests/Models/CMS/CmsAddress.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddressDTO.php b/tests/Tests/Models/CMS/CmsAddressDTO.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsAddressDTO.php rename to tests/Tests/Models/CMS/CmsAddressDTO.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php b/tests/Tests/Models/CMS/CmsAddressListener.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsAddressListener.php rename to tests/Tests/Models/CMS/CmsAddressListener.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsArticle.php b/tests/Tests/Models/CMS/CmsArticle.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsArticle.php rename to tests/Tests/Models/CMS/CmsArticle.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsComment.php b/tests/Tests/Models/CMS/CmsComment.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsComment.php rename to tests/Tests/Models/CMS/CmsComment.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsEmail.php b/tests/Tests/Models/CMS/CmsEmail.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsEmail.php rename to tests/Tests/Models/CMS/CmsEmail.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsEmployee.php b/tests/Tests/Models/CMS/CmsEmployee.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsEmployee.php rename to tests/Tests/Models/CMS/CmsEmployee.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsGroup.php b/tests/Tests/Models/CMS/CmsGroup.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsGroup.php rename to tests/Tests/Models/CMS/CmsGroup.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsPhonenumber.php b/tests/Tests/Models/CMS/CmsPhonenumber.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsPhonenumber.php rename to tests/Tests/Models/CMS/CmsPhonenumber.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsTag.php b/tests/Tests/Models/CMS/CmsTag.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsTag.php rename to tests/Tests/Models/CMS/CmsTag.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsUser.php b/tests/Tests/Models/CMS/CmsUser.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsUser.php rename to tests/Tests/Models/CMS/CmsUser.php diff --git a/tests/Doctrine/Tests/Models/CMS/CmsUserDTO.php b/tests/Tests/Models/CMS/CmsUserDTO.php similarity index 100% rename from tests/Doctrine/Tests/Models/CMS/CmsUserDTO.php rename to tests/Tests/Models/CMS/CmsUserDTO.php diff --git a/tests/Doctrine/Tests/Models/Cache/Action.php b/tests/Tests/Models/Cache/Action.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Action.php rename to tests/Tests/Models/Cache/Action.php diff --git a/tests/Doctrine/Tests/Models/Cache/Address.php b/tests/Tests/Models/Cache/Address.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Address.php rename to tests/Tests/Models/Cache/Address.php diff --git a/tests/Doctrine/Tests/Models/Cache/Attraction.php b/tests/Tests/Models/Cache/Attraction.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Attraction.php rename to tests/Tests/Models/Cache/Attraction.php diff --git a/tests/Doctrine/Tests/Models/Cache/AttractionContactInfo.php b/tests/Tests/Models/Cache/AttractionContactInfo.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/AttractionContactInfo.php rename to tests/Tests/Models/Cache/AttractionContactInfo.php diff --git a/tests/Doctrine/Tests/Models/Cache/AttractionInfo.php b/tests/Tests/Models/Cache/AttractionInfo.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/AttractionInfo.php rename to tests/Tests/Models/Cache/AttractionInfo.php diff --git a/tests/Doctrine/Tests/Models/Cache/AttractionLocationInfo.php b/tests/Tests/Models/Cache/AttractionLocationInfo.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/AttractionLocationInfo.php rename to tests/Tests/Models/Cache/AttractionLocationInfo.php diff --git a/tests/Doctrine/Tests/Models/Cache/Bar.php b/tests/Tests/Models/Cache/Bar.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Bar.php rename to tests/Tests/Models/Cache/Bar.php diff --git a/tests/Doctrine/Tests/Models/Cache/Beach.php b/tests/Tests/Models/Cache/Beach.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Beach.php rename to tests/Tests/Models/Cache/Beach.php diff --git a/tests/Doctrine/Tests/Models/Cache/City.php b/tests/Tests/Models/Cache/City.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/City.php rename to tests/Tests/Models/Cache/City.php diff --git a/tests/Doctrine/Tests/Models/Cache/Client.php b/tests/Tests/Models/Cache/Client.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Client.php rename to tests/Tests/Models/Cache/Client.php diff --git a/tests/Doctrine/Tests/Models/Cache/ComplexAction.php b/tests/Tests/Models/Cache/ComplexAction.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/ComplexAction.php rename to tests/Tests/Models/Cache/ComplexAction.php diff --git a/tests/Doctrine/Tests/Models/Cache/Country.php b/tests/Tests/Models/Cache/Country.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Country.php rename to tests/Tests/Models/Cache/Country.php diff --git a/tests/Doctrine/Tests/Models/Cache/Flight.php b/tests/Tests/Models/Cache/Flight.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Flight.php rename to tests/Tests/Models/Cache/Flight.php diff --git a/tests/Doctrine/Tests/Models/Cache/Login.php b/tests/Tests/Models/Cache/Login.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Login.php rename to tests/Tests/Models/Cache/Login.php diff --git a/tests/Doctrine/Tests/Models/Cache/Person.php b/tests/Tests/Models/Cache/Person.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Person.php rename to tests/Tests/Models/Cache/Person.php diff --git a/tests/Doctrine/Tests/Models/Cache/Restaurant.php b/tests/Tests/Models/Cache/Restaurant.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Restaurant.php rename to tests/Tests/Models/Cache/Restaurant.php diff --git a/tests/Doctrine/Tests/Models/Cache/State.php b/tests/Tests/Models/Cache/State.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/State.php rename to tests/Tests/Models/Cache/State.php diff --git a/tests/Doctrine/Tests/Models/Cache/Token.php b/tests/Tests/Models/Cache/Token.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Token.php rename to tests/Tests/Models/Cache/Token.php diff --git a/tests/Doctrine/Tests/Models/Cache/Travel.php b/tests/Tests/Models/Cache/Travel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Travel.php rename to tests/Tests/Models/Cache/Travel.php diff --git a/tests/Doctrine/Tests/Models/Cache/Traveler.php b/tests/Tests/Models/Cache/Traveler.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/Traveler.php rename to tests/Tests/Models/Cache/Traveler.php diff --git a/tests/Doctrine/Tests/Models/Cache/TravelerProfile.php b/tests/Tests/Models/Cache/TravelerProfile.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/TravelerProfile.php rename to tests/Tests/Models/Cache/TravelerProfile.php diff --git a/tests/Doctrine/Tests/Models/Cache/TravelerProfileInfo.php b/tests/Tests/Models/Cache/TravelerProfileInfo.php similarity index 100% rename from tests/Doctrine/Tests/Models/Cache/TravelerProfileInfo.php rename to tests/Tests/Models/Cache/TravelerProfileInfo.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyAuction.php b/tests/Tests/Models/Company/CompanyAuction.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyAuction.php rename to tests/Tests/Models/Company/CompanyAuction.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyCar.php b/tests/Tests/Models/Company/CompanyCar.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyCar.php rename to tests/Tests/Models/Company/CompanyCar.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContract.php b/tests/Tests/Models/Company/CompanyContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyContract.php rename to tests/Tests/Models/Company/CompanyContract.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyContractListener.php b/tests/Tests/Models/Company/CompanyContractListener.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyContractListener.php rename to tests/Tests/Models/Company/CompanyContractListener.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyEmployee.php b/tests/Tests/Models/Company/CompanyEmployee.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyEmployee.php rename to tests/Tests/Models/Company/CompanyEmployee.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyEvent.php b/tests/Tests/Models/Company/CompanyEvent.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyEvent.php rename to tests/Tests/Models/Company/CompanyEvent.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFixContract.php b/tests/Tests/Models/Company/CompanyFixContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyFixContract.php rename to tests/Tests/Models/Company/CompanyFixContract.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php b/tests/Tests/Models/Company/CompanyFlexContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyFlexContract.php rename to tests/Tests/Models/Company/CompanyFlexContract.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php b/tests/Tests/Models/Company/CompanyFlexUltraContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContract.php rename to tests/Tests/Models/Company/CompanyFlexUltraContract.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php b/tests/Tests/Models/Company/CompanyFlexUltraContractListener.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyFlexUltraContractListener.php rename to tests/Tests/Models/Company/CompanyFlexUltraContractListener.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyManager.php b/tests/Tests/Models/Company/CompanyManager.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyManager.php rename to tests/Tests/Models/Company/CompanyManager.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyOrganization.php b/tests/Tests/Models/Company/CompanyOrganization.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyOrganization.php rename to tests/Tests/Models/Company/CompanyOrganization.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyPerson.php b/tests/Tests/Models/Company/CompanyPerson.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyPerson.php rename to tests/Tests/Models/Company/CompanyPerson.php diff --git a/tests/Doctrine/Tests/Models/Company/CompanyRaffle.php b/tests/Tests/Models/Company/CompanyRaffle.php similarity index 100% rename from tests/Doctrine/Tests/Models/Company/CompanyRaffle.php rename to tests/Tests/Models/Company/CompanyRaffle.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php b/tests/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php rename to tests/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedChildClass.php b/tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedChildClass.php rename to tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedChildClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedIdentityClass.php b/tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedIdentityClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedIdentityClass.php rename to tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedIdentityClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedRootClass.php b/tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedRootClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedDerivedRootClass.php rename to tests/Tests/Models/CompositeKeyInheritance/JoinedDerivedRootClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php b/tests/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php rename to tests/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php b/tests/Tests/Models/CompositeKeyInheritance/SingleChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php rename to tests/Tests/Models/CompositeKeyInheritance/SingleChildClass.php diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleRootClass.php b/tests/Tests/Models/CompositeKeyInheritance/SingleRootClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleRootClass.php rename to tests/Tests/Models/CompositeKeyInheritance/SingleRootClass.php diff --git a/tests/Doctrine/Tests/Models/CustomType/CustomIdObjectTypeChild.php b/tests/Tests/Models/CustomType/CustomIdObjectTypeChild.php similarity index 100% rename from tests/Doctrine/Tests/Models/CustomType/CustomIdObjectTypeChild.php rename to tests/Tests/Models/CustomType/CustomIdObjectTypeChild.php diff --git a/tests/Doctrine/Tests/Models/CustomType/CustomIdObjectTypeParent.php b/tests/Tests/Models/CustomType/CustomIdObjectTypeParent.php similarity index 100% rename from tests/Doctrine/Tests/Models/CustomType/CustomIdObjectTypeParent.php rename to tests/Tests/Models/CustomType/CustomIdObjectTypeParent.php diff --git a/tests/Doctrine/Tests/Models/CustomType/CustomTypeChild.php b/tests/Tests/Models/CustomType/CustomTypeChild.php similarity index 100% rename from tests/Doctrine/Tests/Models/CustomType/CustomTypeChild.php rename to tests/Tests/Models/CustomType/CustomTypeChild.php diff --git a/tests/Doctrine/Tests/Models/CustomType/CustomTypeParent.php b/tests/Tests/Models/CustomType/CustomTypeParent.php similarity index 100% rename from tests/Doctrine/Tests/Models/CustomType/CustomTypeParent.php rename to tests/Tests/Models/CustomType/CustomTypeParent.php diff --git a/tests/Doctrine/Tests/Models/CustomType/CustomTypeUpperCase.php b/tests/Tests/Models/CustomType/CustomTypeUpperCase.php similarity index 100% rename from tests/Doctrine/Tests/Models/CustomType/CustomTypeUpperCase.php rename to tests/Tests/Models/CustomType/CustomTypeUpperCase.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117ApproveChanges.php b/tests/Tests/Models/DDC117/DDC117ApproveChanges.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117ApproveChanges.php rename to tests/Tests/Models/DDC117/DDC117ApproveChanges.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php b/tests/Tests/Models/DDC117/DDC117Article.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117Article.php rename to tests/Tests/Models/DDC117/DDC117Article.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117ArticleDetails.php b/tests/Tests/Models/DDC117/DDC117ArticleDetails.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117ArticleDetails.php rename to tests/Tests/Models/DDC117/DDC117ArticleDetails.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Editor.php b/tests/Tests/Models/DDC117/DDC117Editor.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117Editor.php rename to tests/Tests/Models/DDC117/DDC117Editor.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Link.php b/tests/Tests/Models/DDC117/DDC117Link.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117Link.php rename to tests/Tests/Models/DDC117/DDC117Link.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Reference.php b/tests/Tests/Models/DDC117/DDC117Reference.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117Reference.php rename to tests/Tests/Models/DDC117/DDC117Reference.php diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Translation.php b/tests/Tests/Models/DDC117/DDC117Translation.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC117/DDC117Translation.php rename to tests/Tests/Models/DDC117/DDC117Translation.php diff --git a/tests/Doctrine/Tests/Models/DDC1476/DDC1476EntityWithDefaultFieldType.php b/tests/Tests/Models/DDC1476/DDC1476EntityWithDefaultFieldType.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1476/DDC1476EntityWithDefaultFieldType.php rename to tests/Tests/Models/DDC1476/DDC1476EntityWithDefaultFieldType.php diff --git a/tests/Doctrine/Tests/Models/DDC1590/DDC1590Entity.php b/tests/Tests/Models/DDC1590/DDC1590Entity.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1590/DDC1590Entity.php rename to tests/Tests/Models/DDC1590/DDC1590Entity.php diff --git a/tests/Doctrine/Tests/Models/DDC1590/DDC1590User.php b/tests/Tests/Models/DDC1590/DDC1590User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1590/DDC1590User.php rename to tests/Tests/Models/DDC1590/DDC1590User.php diff --git a/tests/Doctrine/Tests/Models/DDC1872/DDC1872Bar.php b/tests/Tests/Models/DDC1872/DDC1872Bar.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1872/DDC1872Bar.php rename to tests/Tests/Models/DDC1872/DDC1872Bar.php diff --git a/tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleEntityWithOverride.php b/tests/Tests/Models/DDC1872/DDC1872ExampleEntityWithOverride.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleEntityWithOverride.php rename to tests/Tests/Models/DDC1872/DDC1872ExampleEntityWithOverride.php diff --git a/tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleEntityWithoutOverride.php b/tests/Tests/Models/DDC1872/DDC1872ExampleEntityWithoutOverride.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleEntityWithoutOverride.php rename to tests/Tests/Models/DDC1872/DDC1872ExampleEntityWithoutOverride.php diff --git a/tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleTrait.php b/tests/Tests/Models/DDC1872/DDC1872ExampleTrait.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC1872/DDC1872ExampleTrait.php rename to tests/Tests/Models/DDC1872/DDC1872ExampleTrait.php diff --git a/tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php b/tests/Tests/Models/DDC2372/DDC2372Address.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php rename to tests/Tests/Models/DDC2372/DDC2372Address.php diff --git a/tests/Doctrine/Tests/Models/DDC2372/DDC2372Admin.php b/tests/Tests/Models/DDC2372/DDC2372Admin.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2372/DDC2372Admin.php rename to tests/Tests/Models/DDC2372/DDC2372Admin.php diff --git a/tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php b/tests/Tests/Models/DDC2372/DDC2372User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php rename to tests/Tests/Models/DDC2372/DDC2372User.php diff --git a/tests/Doctrine/Tests/Models/DDC2372/Traits/DDC2372AddressAndAccessors.php b/tests/Tests/Models/DDC2372/Traits/DDC2372AddressAndAccessors.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2372/Traits/DDC2372AddressAndAccessors.php rename to tests/Tests/Models/DDC2372/Traits/DDC2372AddressAndAccessors.php diff --git a/tests/Doctrine/Tests/Models/DDC2504/DDC2504ChildClass.php b/tests/Tests/Models/DDC2504/DDC2504ChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2504/DDC2504ChildClass.php rename to tests/Tests/Models/DDC2504/DDC2504ChildClass.php diff --git a/tests/Doctrine/Tests/Models/DDC2504/DDC2504OtherClass.php b/tests/Tests/Models/DDC2504/DDC2504OtherClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2504/DDC2504OtherClass.php rename to tests/Tests/Models/DDC2504/DDC2504OtherClass.php diff --git a/tests/Doctrine/Tests/Models/DDC2504/DDC2504RootClass.php b/tests/Tests/Models/DDC2504/DDC2504RootClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2504/DDC2504RootClass.php rename to tests/Tests/Models/DDC2504/DDC2504RootClass.php diff --git a/tests/Doctrine/Tests/Models/DDC2825/ExplicitSchemaAndTable.php b/tests/Tests/Models/DDC2825/ExplicitSchemaAndTable.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2825/ExplicitSchemaAndTable.php rename to tests/Tests/Models/DDC2825/ExplicitSchemaAndTable.php diff --git a/tests/Doctrine/Tests/Models/DDC2825/SchemaAndTableInTableName.php b/tests/Tests/Models/DDC2825/SchemaAndTableInTableName.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC2825/SchemaAndTableInTableName.php rename to tests/Tests/Models/DDC2825/SchemaAndTableInTableName.php diff --git a/tests/Doctrine/Tests/Models/DDC3231/DDC3231EntityRepository.php b/tests/Tests/Models/DDC3231/DDC3231EntityRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3231/DDC3231EntityRepository.php rename to tests/Tests/Models/DDC3231/DDC3231EntityRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC3231/DDC3231User1.php b/tests/Tests/Models/DDC3231/DDC3231User1.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3231/DDC3231User1.php rename to tests/Tests/Models/DDC3231/DDC3231User1.php diff --git a/tests/Doctrine/Tests/Models/DDC3231/DDC3231User1NoNamespace.php b/tests/Tests/Models/DDC3231/DDC3231User1NoNamespace.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3231/DDC3231User1NoNamespace.php rename to tests/Tests/Models/DDC3231/DDC3231User1NoNamespace.php diff --git a/tests/Doctrine/Tests/Models/DDC3231/DDC3231User2.php b/tests/Tests/Models/DDC3231/DDC3231User2.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3231/DDC3231User2.php rename to tests/Tests/Models/DDC3231/DDC3231User2.php diff --git a/tests/Doctrine/Tests/Models/DDC3231/DDC3231User2NoNamespace.php b/tests/Tests/Models/DDC3231/DDC3231User2NoNamespace.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3231/DDC3231User2NoNamespace.php rename to tests/Tests/Models/DDC3231/DDC3231User2NoNamespace.php diff --git a/tests/Doctrine/Tests/Models/DDC3293/DDC3293Address.php b/tests/Tests/Models/DDC3293/DDC3293Address.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3293/DDC3293Address.php rename to tests/Tests/Models/DDC3293/DDC3293Address.php diff --git a/tests/Doctrine/Tests/Models/DDC3293/DDC3293User.php b/tests/Tests/Models/DDC3293/DDC3293User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3293/DDC3293User.php rename to tests/Tests/Models/DDC3293/DDC3293User.php diff --git a/tests/Doctrine/Tests/Models/DDC3293/DDC3293UserPrefixed.php b/tests/Tests/Models/DDC3293/DDC3293UserPrefixed.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3293/DDC3293UserPrefixed.php rename to tests/Tests/Models/DDC3293/DDC3293UserPrefixed.php diff --git a/tests/Doctrine/Tests/Models/DDC3346/DDC3346Article.php b/tests/Tests/Models/DDC3346/DDC3346Article.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3346/DDC3346Article.php rename to tests/Tests/Models/DDC3346/DDC3346Article.php diff --git a/tests/Doctrine/Tests/Models/DDC3346/DDC3346Author.php b/tests/Tests/Models/DDC3346/DDC3346Author.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3346/DDC3346Author.php rename to tests/Tests/Models/DDC3346/DDC3346Author.php diff --git a/tests/Doctrine/Tests/Models/DDC3579/DDC3579Admin.php b/tests/Tests/Models/DDC3579/DDC3579Admin.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3579/DDC3579Admin.php rename to tests/Tests/Models/DDC3579/DDC3579Admin.php diff --git a/tests/Doctrine/Tests/Models/DDC3579/DDC3579Group.php b/tests/Tests/Models/DDC3579/DDC3579Group.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3579/DDC3579Group.php rename to tests/Tests/Models/DDC3579/DDC3579Group.php diff --git a/tests/Doctrine/Tests/Models/DDC3579/DDC3579User.php b/tests/Tests/Models/DDC3579/DDC3579User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3579/DDC3579User.php rename to tests/Tests/Models/DDC3579/DDC3579User.php diff --git a/tests/Doctrine/Tests/Models/DDC3597/DDC3597Image.php b/tests/Tests/Models/DDC3597/DDC3597Image.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3597/DDC3597Image.php rename to tests/Tests/Models/DDC3597/DDC3597Image.php diff --git a/tests/Doctrine/Tests/Models/DDC3597/DDC3597Media.php b/tests/Tests/Models/DDC3597/DDC3597Media.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3597/DDC3597Media.php rename to tests/Tests/Models/DDC3597/DDC3597Media.php diff --git a/tests/Doctrine/Tests/Models/DDC3597/DDC3597Root.php b/tests/Tests/Models/DDC3597/DDC3597Root.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3597/DDC3597Root.php rename to tests/Tests/Models/DDC3597/DDC3597Root.php diff --git a/tests/Doctrine/Tests/Models/DDC3597/Embeddable/DDC3597Dimension.php b/tests/Tests/Models/DDC3597/Embeddable/DDC3597Dimension.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3597/Embeddable/DDC3597Dimension.php rename to tests/Tests/Models/DDC3597/Embeddable/DDC3597Dimension.php diff --git a/tests/Doctrine/Tests/Models/DDC3699/DDC3699Child.php b/tests/Tests/Models/DDC3699/DDC3699Child.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3699/DDC3699Child.php rename to tests/Tests/Models/DDC3699/DDC3699Child.php diff --git a/tests/Doctrine/Tests/Models/DDC3699/DDC3699Parent.php b/tests/Tests/Models/DDC3699/DDC3699Parent.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3699/DDC3699Parent.php rename to tests/Tests/Models/DDC3699/DDC3699Parent.php diff --git a/tests/Doctrine/Tests/Models/DDC3699/DDC3699RelationMany.php b/tests/Tests/Models/DDC3699/DDC3699RelationMany.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3699/DDC3699RelationMany.php rename to tests/Tests/Models/DDC3699/DDC3699RelationMany.php diff --git a/tests/Doctrine/Tests/Models/DDC3699/DDC3699RelationOne.php b/tests/Tests/Models/DDC3699/DDC3699RelationOne.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3699/DDC3699RelationOne.php rename to tests/Tests/Models/DDC3699/DDC3699RelationOne.php diff --git a/tests/Doctrine/Tests/Models/DDC3711/DDC3711EntityA.php b/tests/Tests/Models/DDC3711/DDC3711EntityA.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3711/DDC3711EntityA.php rename to tests/Tests/Models/DDC3711/DDC3711EntityA.php diff --git a/tests/Doctrine/Tests/Models/DDC3711/DDC3711EntityB.php b/tests/Tests/Models/DDC3711/DDC3711EntityB.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3711/DDC3711EntityB.php rename to tests/Tests/Models/DDC3711/DDC3711EntityB.php diff --git a/tests/Doctrine/Tests/Models/DDC3899/DDC3899Contract.php b/tests/Tests/Models/DDC3899/DDC3899Contract.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3899/DDC3899Contract.php rename to tests/Tests/Models/DDC3899/DDC3899Contract.php diff --git a/tests/Doctrine/Tests/Models/DDC3899/DDC3899FixContract.php b/tests/Tests/Models/DDC3899/DDC3899FixContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3899/DDC3899FixContract.php rename to tests/Tests/Models/DDC3899/DDC3899FixContract.php diff --git a/tests/Doctrine/Tests/Models/DDC3899/DDC3899FlexContract.php b/tests/Tests/Models/DDC3899/DDC3899FlexContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3899/DDC3899FlexContract.php rename to tests/Tests/Models/DDC3899/DDC3899FlexContract.php diff --git a/tests/Doctrine/Tests/Models/DDC3899/DDC3899User.php b/tests/Tests/Models/DDC3899/DDC3899User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC3899/DDC3899User.php rename to tests/Tests/Models/DDC3899/DDC3899User.php diff --git a/tests/Doctrine/Tests/Models/DDC4006/DDC4006User.php b/tests/Tests/Models/DDC4006/DDC4006User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC4006/DDC4006User.php rename to tests/Tests/Models/DDC4006/DDC4006User.php diff --git a/tests/Doctrine/Tests/Models/DDC4006/DDC4006UserId.php b/tests/Tests/Models/DDC4006/DDC4006UserId.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC4006/DDC4006UserId.php rename to tests/Tests/Models/DDC4006/DDC4006UserId.php diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php b/tests/Tests/Models/DDC5934/DDC5934BaseContract.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC5934/DDC5934BaseContract.php rename to tests/Tests/Models/DDC5934/DDC5934BaseContract.php diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php b/tests/Tests/Models/DDC5934/DDC5934Contract.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC5934/DDC5934Contract.php rename to tests/Tests/Models/DDC5934/DDC5934Contract.php diff --git a/tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php b/tests/Tests/Models/DDC5934/DDC5934Member.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC5934/DDC5934Member.php rename to tests/Tests/Models/DDC5934/DDC5934Member.php diff --git a/tests/Doctrine/Tests/Models/DDC6412/DDC6412File.php b/tests/Tests/Models/DDC6412/DDC6412File.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC6412/DDC6412File.php rename to tests/Tests/Models/DDC6412/DDC6412File.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753CustomRepository.php b/tests/Tests/Models/DDC753/DDC753CustomRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753CustomRepository.php rename to tests/Tests/Models/DDC753/DDC753CustomRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753DefaultRepository.php b/tests/Tests/Models/DDC753/DDC753DefaultRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753DefaultRepository.php rename to tests/Tests/Models/DDC753/DDC753DefaultRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithCustomRepository.php b/tests/Tests/Models/DDC753/DDC753EntityWithCustomRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithCustomRepository.php rename to tests/Tests/Models/DDC753/DDC753EntityWithCustomRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithDefaultCustomRepository.php b/tests/Tests/Models/DDC753/DDC753EntityWithDefaultCustomRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithDefaultCustomRepository.php rename to tests/Tests/Models/DDC753/DDC753EntityWithDefaultCustomRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithInvalidRepository.php b/tests/Tests/Models/DDC753/DDC753EntityWithInvalidRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753EntityWithInvalidRepository.php rename to tests/Tests/Models/DDC753/DDC753EntityWithInvalidRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC753/DDC753InvalidRepository.php b/tests/Tests/Models/DDC753/DDC753InvalidRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC753/DDC753InvalidRepository.php rename to tests/Tests/Models/DDC753/DDC753InvalidRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869ChequePayment.php b/tests/Tests/Models/DDC869/DDC869ChequePayment.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC869/DDC869ChequePayment.php rename to tests/Tests/Models/DDC869/DDC869ChequePayment.php diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869CreditCardPayment.php b/tests/Tests/Models/DDC869/DDC869CreditCardPayment.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC869/DDC869CreditCardPayment.php rename to tests/Tests/Models/DDC869/DDC869CreditCardPayment.php diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869Payment.php b/tests/Tests/Models/DDC869/DDC869Payment.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC869/DDC869Payment.php rename to tests/Tests/Models/DDC869/DDC869Payment.php diff --git a/tests/Doctrine/Tests/Models/DDC869/DDC869PaymentRepository.php b/tests/Tests/Models/DDC869/DDC869PaymentRepository.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC869/DDC869PaymentRepository.php rename to tests/Tests/Models/DDC869/DDC869PaymentRepository.php diff --git a/tests/Doctrine/Tests/Models/DDC889/DDC889Class.php b/tests/Tests/Models/DDC889/DDC889Class.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC889/DDC889Class.php rename to tests/Tests/Models/DDC889/DDC889Class.php diff --git a/tests/Doctrine/Tests/Models/DDC889/DDC889Entity.php b/tests/Tests/Models/DDC889/DDC889Entity.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC889/DDC889Entity.php rename to tests/Tests/Models/DDC889/DDC889Entity.php diff --git a/tests/Doctrine/Tests/Models/DDC889/DDC889SuperClass.php b/tests/Tests/Models/DDC889/DDC889SuperClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC889/DDC889SuperClass.php rename to tests/Tests/Models/DDC889/DDC889SuperClass.php diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964Address.php b/tests/Tests/Models/DDC964/DDC964Address.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC964/DDC964Address.php rename to tests/Tests/Models/DDC964/DDC964Address.php diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964Admin.php b/tests/Tests/Models/DDC964/DDC964Admin.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC964/DDC964Admin.php rename to tests/Tests/Models/DDC964/DDC964Admin.php diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964Group.php b/tests/Tests/Models/DDC964/DDC964Group.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC964/DDC964Group.php rename to tests/Tests/Models/DDC964/DDC964Group.php diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php b/tests/Tests/Models/DDC964/DDC964Guest.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC964/DDC964Guest.php rename to tests/Tests/Models/DDC964/DDC964Guest.php diff --git a/tests/Doctrine/Tests/Models/DDC964/DDC964User.php b/tests/Tests/Models/DDC964/DDC964User.php similarity index 100% rename from tests/Doctrine/Tests/Models/DDC964/DDC964User.php rename to tests/Tests/Models/DDC964/DDC964User.php diff --git a/tests/Doctrine/Tests/Models/DataTransferObjects/DtoWithArrayOfEnums.php b/tests/Tests/Models/DataTransferObjects/DtoWithArrayOfEnums.php similarity index 100% rename from tests/Doctrine/Tests/Models/DataTransferObjects/DtoWithArrayOfEnums.php rename to tests/Tests/Models/DataTransferObjects/DtoWithArrayOfEnums.php diff --git a/tests/Doctrine/Tests/Models/DataTransferObjects/DtoWithEnum.php b/tests/Tests/Models/DataTransferObjects/DtoWithEnum.php similarity index 100% rename from tests/Doctrine/Tests/Models/DataTransferObjects/DtoWithEnum.php rename to tests/Tests/Models/DataTransferObjects/DtoWithEnum.php diff --git a/tests/Doctrine/Tests/Models/DirectoryTree/AbstractContentItem.php b/tests/Tests/Models/DirectoryTree/AbstractContentItem.php similarity index 100% rename from tests/Doctrine/Tests/Models/DirectoryTree/AbstractContentItem.php rename to tests/Tests/Models/DirectoryTree/AbstractContentItem.php diff --git a/tests/Doctrine/Tests/Models/DirectoryTree/Directory.php b/tests/Tests/Models/DirectoryTree/Directory.php similarity index 100% rename from tests/Doctrine/Tests/Models/DirectoryTree/Directory.php rename to tests/Tests/Models/DirectoryTree/Directory.php diff --git a/tests/Doctrine/Tests/Models/DirectoryTree/File.php b/tests/Tests/Models/DirectoryTree/File.php similarity index 100% rename from tests/Doctrine/Tests/Models/DirectoryTree/File.php rename to tests/Tests/Models/DirectoryTree/File.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceCart.php b/tests/Tests/Models/ECommerce/ECommerceCart.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceCart.php rename to tests/Tests/Models/ECommerce/ECommerceCart.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php b/tests/Tests/Models/ECommerce/ECommerceCategory.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceCategory.php rename to tests/Tests/Models/ECommerce/ECommerceCategory.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceCustomer.php b/tests/Tests/Models/ECommerce/ECommerceCustomer.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceCustomer.php rename to tests/Tests/Models/ECommerce/ECommerceCustomer.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php b/tests/Tests/Models/ECommerce/ECommerceFeature.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceFeature.php rename to tests/Tests/Models/ECommerce/ECommerceFeature.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php b/tests/Tests/Models/ECommerce/ECommerceProduct.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceProduct.php rename to tests/Tests/Models/ECommerce/ECommerceProduct.php diff --git a/tests/Doctrine/Tests/Models/ECommerce/ECommerceShipping.php b/tests/Tests/Models/ECommerce/ECommerceShipping.php similarity index 100% rename from tests/Doctrine/Tests/Models/ECommerce/ECommerceShipping.php rename to tests/Tests/Models/ECommerce/ECommerceShipping.php diff --git a/tests/Doctrine/Tests/Models/Enums/AccessLevel.php b/tests/Tests/Models/Enums/AccessLevel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/AccessLevel.php rename to tests/Tests/Models/Enums/AccessLevel.php diff --git a/tests/Doctrine/Tests/Models/Enums/Card.php b/tests/Tests/Models/Enums/Card.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Card.php rename to tests/Tests/Models/Enums/Card.php diff --git a/tests/Doctrine/Tests/Models/Enums/CardWithDefault.php b/tests/Tests/Models/Enums/CardWithDefault.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/CardWithDefault.php rename to tests/Tests/Models/Enums/CardWithDefault.php diff --git a/tests/Doctrine/Tests/Models/Enums/CardWithNullable.php b/tests/Tests/Models/Enums/CardWithNullable.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/CardWithNullable.php rename to tests/Tests/Models/Enums/CardWithNullable.php diff --git a/tests/Doctrine/Tests/Models/Enums/City.php b/tests/Tests/Models/Enums/City.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/City.php rename to tests/Tests/Models/Enums/City.php diff --git a/tests/Doctrine/Tests/Models/Enums/Product.php b/tests/Tests/Models/Enums/Product.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Product.php rename to tests/Tests/Models/Enums/Product.php diff --git a/tests/Doctrine/Tests/Models/Enums/Quantity.php b/tests/Tests/Models/Enums/Quantity.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Quantity.php rename to tests/Tests/Models/Enums/Quantity.php diff --git a/tests/Doctrine/Tests/Models/Enums/Scale.php b/tests/Tests/Models/Enums/Scale.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Scale.php rename to tests/Tests/Models/Enums/Scale.php diff --git a/tests/Doctrine/Tests/Models/Enums/Suit.php b/tests/Tests/Models/Enums/Suit.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Suit.php rename to tests/Tests/Models/Enums/Suit.php diff --git a/tests/Doctrine/Tests/Models/Enums/TypedCard.php b/tests/Tests/Models/Enums/TypedCard.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/TypedCard.php rename to tests/Tests/Models/Enums/TypedCard.php diff --git a/tests/Doctrine/Tests/Models/Enums/TypedCardEnumCompositeId.php b/tests/Tests/Models/Enums/TypedCardEnumCompositeId.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/TypedCardEnumCompositeId.php rename to tests/Tests/Models/Enums/TypedCardEnumCompositeId.php diff --git a/tests/Doctrine/Tests/Models/Enums/TypedCardEnumId.php b/tests/Tests/Models/Enums/TypedCardEnumId.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/TypedCardEnumId.php rename to tests/Tests/Models/Enums/TypedCardEnumId.php diff --git a/tests/Doctrine/Tests/Models/Enums/Unit.php b/tests/Tests/Models/Enums/Unit.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/Unit.php rename to tests/Tests/Models/Enums/Unit.php diff --git a/tests/Doctrine/Tests/Models/Enums/UserStatus.php b/tests/Tests/Models/Enums/UserStatus.php similarity index 100% rename from tests/Doctrine/Tests/Models/Enums/UserStatus.php rename to tests/Tests/Models/Enums/UserStatus.php diff --git a/tests/Doctrine/Tests/Models/Forum/ForumAvatar.php b/tests/Tests/Models/Forum/ForumAvatar.php similarity index 100% rename from tests/Doctrine/Tests/Models/Forum/ForumAvatar.php rename to tests/Tests/Models/Forum/ForumAvatar.php diff --git a/tests/Doctrine/Tests/Models/Forum/ForumBoard.php b/tests/Tests/Models/Forum/ForumBoard.php similarity index 100% rename from tests/Doctrine/Tests/Models/Forum/ForumBoard.php rename to tests/Tests/Models/Forum/ForumBoard.php diff --git a/tests/Doctrine/Tests/Models/Forum/ForumCategory.php b/tests/Tests/Models/Forum/ForumCategory.php similarity index 100% rename from tests/Doctrine/Tests/Models/Forum/ForumCategory.php rename to tests/Tests/Models/Forum/ForumCategory.php diff --git a/tests/Doctrine/Tests/Models/Forum/ForumEntry.php b/tests/Tests/Models/Forum/ForumEntry.php similarity index 100% rename from tests/Doctrine/Tests/Models/Forum/ForumEntry.php rename to tests/Tests/Models/Forum/ForumEntry.php diff --git a/tests/Doctrine/Tests/Models/Forum/ForumUser.php b/tests/Tests/Models/Forum/ForumUser.php similarity index 100% rename from tests/Doctrine/Tests/Models/Forum/ForumUser.php rename to tests/Tests/Models/Forum/ForumUser.php diff --git a/tests/Doctrine/Tests/Models/GH10132/Complex.php b/tests/Tests/Models/GH10132/Complex.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10132/Complex.php rename to tests/Tests/Models/GH10132/Complex.php diff --git a/tests/Doctrine/Tests/Models/GH10132/ComplexChild.php b/tests/Tests/Models/GH10132/ComplexChild.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10132/ComplexChild.php rename to tests/Tests/Models/GH10132/ComplexChild.php diff --git a/tests/Doctrine/Tests/Models/GH10288/GH10288People.php b/tests/Tests/Models/GH10288/GH10288People.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10288/GH10288People.php rename to tests/Tests/Models/GH10288/GH10288People.php diff --git a/tests/Doctrine/Tests/Models/GH10334/GH10334Foo.php b/tests/Tests/Models/GH10334/GH10334Foo.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10334/GH10334Foo.php rename to tests/Tests/Models/GH10334/GH10334Foo.php diff --git a/tests/Doctrine/Tests/Models/GH10334/GH10334FooCollection.php b/tests/Tests/Models/GH10334/GH10334FooCollection.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10334/GH10334FooCollection.php rename to tests/Tests/Models/GH10334/GH10334FooCollection.php diff --git a/tests/Doctrine/Tests/Models/GH10334/GH10334Product.php b/tests/Tests/Models/GH10334/GH10334Product.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10334/GH10334Product.php rename to tests/Tests/Models/GH10334/GH10334Product.php diff --git a/tests/Doctrine/Tests/Models/GH10334/GH10334ProductType.php b/tests/Tests/Models/GH10334/GH10334ProductType.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10334/GH10334ProductType.php rename to tests/Tests/Models/GH10334/GH10334ProductType.php diff --git a/tests/Doctrine/Tests/Models/GH10334/GH10334ProductTypeId.php b/tests/Tests/Models/GH10334/GH10334ProductTypeId.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10334/GH10334ProductTypeId.php rename to tests/Tests/Models/GH10334/GH10334ProductTypeId.php diff --git a/tests/Doctrine/Tests/Models/GH10336/GH10336Entity.php b/tests/Tests/Models/GH10336/GH10336Entity.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10336/GH10336Entity.php rename to tests/Tests/Models/GH10336/GH10336Entity.php diff --git a/tests/Doctrine/Tests/Models/GH10336/GH10336Relation.php b/tests/Tests/Models/GH10336/GH10336Relation.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH10336/GH10336Relation.php rename to tests/Tests/Models/GH10336/GH10336Relation.php diff --git a/tests/Doctrine/Tests/Models/GH7141/GH7141Article.php b/tests/Tests/Models/GH7141/GH7141Article.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH7141/GH7141Article.php rename to tests/Tests/Models/GH7141/GH7141Article.php diff --git a/tests/Doctrine/Tests/Models/GH7316/GH7316Article.php b/tests/Tests/Models/GH7316/GH7316Article.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH7316/GH7316Article.php rename to tests/Tests/Models/GH7316/GH7316Article.php diff --git a/tests/Doctrine/Tests/Models/GH7717/GH7717Child.php b/tests/Tests/Models/GH7717/GH7717Child.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH7717/GH7717Child.php rename to tests/Tests/Models/GH7717/GH7717Child.php diff --git a/tests/Doctrine/Tests/Models/GH7717/GH7717Parent.php b/tests/Tests/Models/GH7717/GH7717Parent.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH7717/GH7717Parent.php rename to tests/Tests/Models/GH7717/GH7717Parent.php diff --git a/tests/Doctrine/Tests/Models/GH8565/GH8565Employee.php b/tests/Tests/Models/GH8565/GH8565Employee.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH8565/GH8565Employee.php rename to tests/Tests/Models/GH8565/GH8565Employee.php diff --git a/tests/Doctrine/Tests/Models/GH8565/GH8565Manager.php b/tests/Tests/Models/GH8565/GH8565Manager.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH8565/GH8565Manager.php rename to tests/Tests/Models/GH8565/GH8565Manager.php diff --git a/tests/Doctrine/Tests/Models/GH8565/GH8565Person.php b/tests/Tests/Models/GH8565/GH8565Person.php similarity index 100% rename from tests/Doctrine/Tests/Models/GH8565/GH8565Person.php rename to tests/Tests/Models/GH8565/GH8565Person.php diff --git a/tests/Doctrine/Tests/Models/Generic/BooleanModel.php b/tests/Tests/Models/Generic/BooleanModel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Generic/BooleanModel.php rename to tests/Tests/Models/Generic/BooleanModel.php diff --git a/tests/Doctrine/Tests/Models/Generic/DateTimeModel.php b/tests/Tests/Models/Generic/DateTimeModel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Generic/DateTimeModel.php rename to tests/Tests/Models/Generic/DateTimeModel.php diff --git a/tests/Doctrine/Tests/Models/Generic/DecimalModel.php b/tests/Tests/Models/Generic/DecimalModel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Generic/DecimalModel.php rename to tests/Tests/Models/Generic/DecimalModel.php diff --git a/tests/Doctrine/Tests/Models/Generic/NonAlphaColumnsEntity.php b/tests/Tests/Models/Generic/NonAlphaColumnsEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/Generic/NonAlphaColumnsEntity.php rename to tests/Tests/Models/Generic/NonAlphaColumnsEntity.php diff --git a/tests/Doctrine/Tests/Models/Generic/SerializationModel.php b/tests/Tests/Models/Generic/SerializationModel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Generic/SerializationModel.php rename to tests/Tests/Models/Generic/SerializationModel.php diff --git a/tests/Doctrine/Tests/Models/GeoNames/Admin1.php b/tests/Tests/Models/GeoNames/Admin1.php similarity index 100% rename from tests/Doctrine/Tests/Models/GeoNames/Admin1.php rename to tests/Tests/Models/GeoNames/Admin1.php diff --git a/tests/Doctrine/Tests/Models/GeoNames/Admin1AlternateName.php b/tests/Tests/Models/GeoNames/Admin1AlternateName.php similarity index 100% rename from tests/Doctrine/Tests/Models/GeoNames/Admin1AlternateName.php rename to tests/Tests/Models/GeoNames/Admin1AlternateName.php diff --git a/tests/Doctrine/Tests/Models/GeoNames/City.php b/tests/Tests/Models/GeoNames/City.php similarity index 100% rename from tests/Doctrine/Tests/Models/GeoNames/City.php rename to tests/Tests/Models/GeoNames/City.php diff --git a/tests/Doctrine/Tests/Models/GeoNames/Country.php b/tests/Tests/Models/GeoNames/Country.php similarity index 100% rename from tests/Doctrine/Tests/Models/GeoNames/Country.php rename to tests/Tests/Models/GeoNames/Country.php diff --git a/tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php b/tests/Tests/Models/Global/GlobalNamespaceModel.php similarity index 100% rename from tests/Doctrine/Tests/Models/Global/GlobalNamespaceModel.php rename to tests/Tests/Models/Global/GlobalNamespaceModel.php diff --git a/tests/Doctrine/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php b/tests/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php similarity index 100% rename from tests/Doctrine/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php rename to tests/Tests/Models/Hydration/EntityWithArrayDefaultArrayValueM2M.php diff --git a/tests/Doctrine/Tests/Models/Hydration/SimpleEntity.php b/tests/Tests/Models/Hydration/SimpleEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/Hydration/SimpleEntity.php rename to tests/Tests/Models/Hydration/SimpleEntity.php diff --git a/tests/Doctrine/Tests/Models/Issue5989/Issue5989Employee.php b/tests/Tests/Models/Issue5989/Issue5989Employee.php similarity index 100% rename from tests/Doctrine/Tests/Models/Issue5989/Issue5989Employee.php rename to tests/Tests/Models/Issue5989/Issue5989Employee.php diff --git a/tests/Doctrine/Tests/Models/Issue5989/Issue5989Manager.php b/tests/Tests/Models/Issue5989/Issue5989Manager.php similarity index 100% rename from tests/Doctrine/Tests/Models/Issue5989/Issue5989Manager.php rename to tests/Tests/Models/Issue5989/Issue5989Manager.php diff --git a/tests/Doctrine/Tests/Models/Issue5989/Issue5989Person.php b/tests/Tests/Models/Issue5989/Issue5989Person.php similarity index 100% rename from tests/Doctrine/Tests/Models/Issue5989/Issue5989Person.php rename to tests/Tests/Models/Issue5989/Issue5989Person.php diff --git a/tests/Doctrine/Tests/Models/Issue9300/Issue9300Child.php b/tests/Tests/Models/Issue9300/Issue9300Child.php similarity index 100% rename from tests/Doctrine/Tests/Models/Issue9300/Issue9300Child.php rename to tests/Tests/Models/Issue9300/Issue9300Child.php diff --git a/tests/Doctrine/Tests/Models/Issue9300/Issue9300Parent.php b/tests/Tests/Models/Issue9300/Issue9300Parent.php similarity index 100% rename from tests/Doctrine/Tests/Models/Issue9300/Issue9300Parent.php rename to tests/Tests/Models/Issue9300/Issue9300Parent.php diff --git a/tests/Doctrine/Tests/Models/JoinedInheritanceType/AnotherChildClass.php b/tests/Tests/Models/JoinedInheritanceType/AnotherChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/JoinedInheritanceType/AnotherChildClass.php rename to tests/Tests/Models/JoinedInheritanceType/AnotherChildClass.php diff --git a/tests/Doctrine/Tests/Models/JoinedInheritanceType/ChildClass.php b/tests/Tests/Models/JoinedInheritanceType/ChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/JoinedInheritanceType/ChildClass.php rename to tests/Tests/Models/JoinedInheritanceType/ChildClass.php diff --git a/tests/Doctrine/Tests/Models/JoinedInheritanceType/RootClass.php b/tests/Tests/Models/JoinedInheritanceType/RootClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/JoinedInheritanceType/RootClass.php rename to tests/Tests/Models/JoinedInheritanceType/RootClass.php diff --git a/tests/Doctrine/Tests/Models/Legacy/LegacyArticle.php b/tests/Tests/Models/Legacy/LegacyArticle.php similarity index 100% rename from tests/Doctrine/Tests/Models/Legacy/LegacyArticle.php rename to tests/Tests/Models/Legacy/LegacyArticle.php diff --git a/tests/Doctrine/Tests/Models/Legacy/LegacyCar.php b/tests/Tests/Models/Legacy/LegacyCar.php similarity index 100% rename from tests/Doctrine/Tests/Models/Legacy/LegacyCar.php rename to tests/Tests/Models/Legacy/LegacyCar.php diff --git a/tests/Doctrine/Tests/Models/Legacy/LegacyUser.php b/tests/Tests/Models/Legacy/LegacyUser.php similarity index 100% rename from tests/Doctrine/Tests/Models/Legacy/LegacyUser.php rename to tests/Tests/Models/Legacy/LegacyUser.php diff --git a/tests/Doctrine/Tests/Models/Legacy/LegacyUserReference.php b/tests/Tests/Models/Legacy/LegacyUserReference.php similarity index 100% rename from tests/Doctrine/Tests/Models/Legacy/LegacyUserReference.php rename to tests/Tests/Models/Legacy/LegacyUserReference.php diff --git a/tests/Doctrine/Tests/Models/ManyToManyPersister/ChildClass.php b/tests/Tests/Models/ManyToManyPersister/ChildClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/ManyToManyPersister/ChildClass.php rename to tests/Tests/Models/ManyToManyPersister/ChildClass.php diff --git a/tests/Doctrine/Tests/Models/ManyToManyPersister/OtherParentClass.php b/tests/Tests/Models/ManyToManyPersister/OtherParentClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/ManyToManyPersister/OtherParentClass.php rename to tests/Tests/Models/ManyToManyPersister/OtherParentClass.php diff --git a/tests/Doctrine/Tests/Models/ManyToManyPersister/ParentClass.php b/tests/Tests/Models/ManyToManyPersister/ParentClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/ManyToManyPersister/ParentClass.php rename to tests/Tests/Models/ManyToManyPersister/ParentClass.php diff --git a/tests/Doctrine/Tests/Models/MixedToOneIdentity/CompositeToOneKeyState.php b/tests/Tests/Models/MixedToOneIdentity/CompositeToOneKeyState.php similarity index 100% rename from tests/Doctrine/Tests/Models/MixedToOneIdentity/CompositeToOneKeyState.php rename to tests/Tests/Models/MixedToOneIdentity/CompositeToOneKeyState.php diff --git a/tests/Doctrine/Tests/Models/MixedToOneIdentity/Country.php b/tests/Tests/Models/MixedToOneIdentity/Country.php similarity index 100% rename from tests/Doctrine/Tests/Models/MixedToOneIdentity/Country.php rename to tests/Tests/Models/MixedToOneIdentity/Country.php diff --git a/tests/Doctrine/Tests/Models/Navigation/NavCountry.php b/tests/Tests/Models/Navigation/NavCountry.php similarity index 100% rename from tests/Doctrine/Tests/Models/Navigation/NavCountry.php rename to tests/Tests/Models/Navigation/NavCountry.php diff --git a/tests/Doctrine/Tests/Models/Navigation/NavPhotos.php b/tests/Tests/Models/Navigation/NavPhotos.php similarity index 100% rename from tests/Doctrine/Tests/Models/Navigation/NavPhotos.php rename to tests/Tests/Models/Navigation/NavPhotos.php diff --git a/tests/Doctrine/Tests/Models/Navigation/NavPointOfInterest.php b/tests/Tests/Models/Navigation/NavPointOfInterest.php similarity index 100% rename from tests/Doctrine/Tests/Models/Navigation/NavPointOfInterest.php rename to tests/Tests/Models/Navigation/NavPointOfInterest.php diff --git a/tests/Doctrine/Tests/Models/Navigation/NavTour.php b/tests/Tests/Models/Navigation/NavTour.php similarity index 100% rename from tests/Doctrine/Tests/Models/Navigation/NavTour.php rename to tests/Tests/Models/Navigation/NavTour.php diff --git a/tests/Doctrine/Tests/Models/Navigation/NavUser.php b/tests/Tests/Models/Navigation/NavUser.php similarity index 100% rename from tests/Doctrine/Tests/Models/Navigation/NavUser.php rename to tests/Tests/Models/Navigation/NavUser.php diff --git a/tests/Doctrine/Tests/Models/NonPublicSchemaJoins/User.php b/tests/Tests/Models/NonPublicSchemaJoins/User.php similarity index 100% rename from tests/Doctrine/Tests/Models/NonPublicSchemaJoins/User.php rename to tests/Tests/Models/NonPublicSchemaJoins/User.php diff --git a/tests/Doctrine/Tests/Models/NullDefault/NullDefaultColumn.php b/tests/Tests/Models/NullDefault/NullDefaultColumn.php similarity index 100% rename from tests/Doctrine/Tests/Models/NullDefault/NullDefaultColumn.php rename to tests/Tests/Models/NullDefault/NullDefaultColumn.php diff --git a/tests/Doctrine/Tests/Models/OneToOneInverseSideLoad/InverseSide.php b/tests/Tests/Models/OneToOneInverseSideLoad/InverseSide.php similarity index 100% rename from tests/Doctrine/Tests/Models/OneToOneInverseSideLoad/InverseSide.php rename to tests/Tests/Models/OneToOneInverseSideLoad/InverseSide.php diff --git a/tests/Doctrine/Tests/Models/OneToOneInverseSideLoad/OwningSide.php b/tests/Tests/Models/OneToOneInverseSideLoad/OwningSide.php similarity index 100% rename from tests/Doctrine/Tests/Models/OneToOneInverseSideLoad/OwningSide.php rename to tests/Tests/Models/OneToOneInverseSideLoad/OwningSide.php diff --git a/tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/Cat.php b/tests/Tests/Models/OneToOneSingleTableInheritance/Cat.php similarity index 100% rename from tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/Cat.php rename to tests/Tests/Models/OneToOneSingleTableInheritance/Cat.php diff --git a/tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/LitterBox.php b/tests/Tests/Models/OneToOneSingleTableInheritance/LitterBox.php similarity index 100% rename from tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/LitterBox.php rename to tests/Tests/Models/OneToOneSingleTableInheritance/LitterBox.php diff --git a/tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/Pet.php b/tests/Tests/Models/OneToOneSingleTableInheritance/Pet.php similarity index 100% rename from tests/Doctrine/Tests/Models/OneToOneSingleTableInheritance/Pet.php rename to tests/Tests/Models/OneToOneSingleTableInheritance/Pet.php diff --git a/tests/Doctrine/Tests/Models/OrnementalOrphanRemoval/Person.php b/tests/Tests/Models/OrnementalOrphanRemoval/Person.php similarity index 100% rename from tests/Doctrine/Tests/Models/OrnementalOrphanRemoval/Person.php rename to tests/Tests/Models/OrnementalOrphanRemoval/Person.php diff --git a/tests/Doctrine/Tests/Models/OrnementalOrphanRemoval/PhoneNumber.php b/tests/Tests/Models/OrnementalOrphanRemoval/PhoneNumber.php similarity index 100% rename from tests/Doctrine/Tests/Models/OrnementalOrphanRemoval/PhoneNumber.php rename to tests/Tests/Models/OrnementalOrphanRemoval/PhoneNumber.php diff --git a/tests/Doctrine/Tests/Models/Pagination/Company.php b/tests/Tests/Models/Pagination/Company.php similarity index 100% rename from tests/Doctrine/Tests/Models/Pagination/Company.php rename to tests/Tests/Models/Pagination/Company.php diff --git a/tests/Doctrine/Tests/Models/Pagination/Department.php b/tests/Tests/Models/Pagination/Department.php similarity index 100% rename from tests/Doctrine/Tests/Models/Pagination/Department.php rename to tests/Tests/Models/Pagination/Department.php diff --git a/tests/Doctrine/Tests/Models/Pagination/Logo.php b/tests/Tests/Models/Pagination/Logo.php similarity index 100% rename from tests/Doctrine/Tests/Models/Pagination/Logo.php rename to tests/Tests/Models/Pagination/Logo.php diff --git a/tests/Doctrine/Tests/Models/Pagination/User.php b/tests/Tests/Models/Pagination/User.php similarity index 100% rename from tests/Doctrine/Tests/Models/Pagination/User.php rename to tests/Tests/Models/Pagination/User.php diff --git a/tests/Doctrine/Tests/Models/Pagination/User1.php b/tests/Tests/Models/Pagination/User1.php similarity index 100% rename from tests/Doctrine/Tests/Models/Pagination/User1.php rename to tests/Tests/Models/Pagination/User1.php diff --git a/tests/Doctrine/Tests/Models/PersistentObject/PersistentCollectionContent.php b/tests/Tests/Models/PersistentObject/PersistentCollectionContent.php similarity index 100% rename from tests/Doctrine/Tests/Models/PersistentObject/PersistentCollectionContent.php rename to tests/Tests/Models/PersistentObject/PersistentCollectionContent.php diff --git a/tests/Doctrine/Tests/Models/PersistentObject/PersistentCollectionHolder.php b/tests/Tests/Models/PersistentObject/PersistentCollectionHolder.php similarity index 100% rename from tests/Doctrine/Tests/Models/PersistentObject/PersistentCollectionHolder.php rename to tests/Tests/Models/PersistentObject/PersistentCollectionHolder.php diff --git a/tests/Doctrine/Tests/Models/PersistentObject/PersistentEntity.php b/tests/Tests/Models/PersistentObject/PersistentEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/PersistentObject/PersistentEntity.php rename to tests/Tests/Models/PersistentObject/PersistentEntity.php diff --git a/tests/Doctrine/Tests/Models/Project/Project.php b/tests/Tests/Models/Project/Project.php similarity index 100% rename from tests/Doctrine/Tests/Models/Project/Project.php rename to tests/Tests/Models/Project/Project.php diff --git a/tests/Doctrine/Tests/Models/Project/ProjectId.php b/tests/Tests/Models/Project/ProjectId.php similarity index 100% rename from tests/Doctrine/Tests/Models/Project/ProjectId.php rename to tests/Tests/Models/Project/ProjectId.php diff --git a/tests/Doctrine/Tests/Models/Project/ProjectInvalidMapping.php b/tests/Tests/Models/Project/ProjectInvalidMapping.php similarity index 100% rename from tests/Doctrine/Tests/Models/Project/ProjectInvalidMapping.php rename to tests/Tests/Models/Project/ProjectInvalidMapping.php diff --git a/tests/Doctrine/Tests/Models/Project/ProjectName.php b/tests/Tests/Models/Project/ProjectName.php similarity index 100% rename from tests/Doctrine/Tests/Models/Project/ProjectName.php rename to tests/Tests/Models/Project/ProjectName.php diff --git a/tests/Doctrine/Tests/Models/Quote/Address.php b/tests/Tests/Models/Quote/Address.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/Address.php rename to tests/Tests/Models/Quote/Address.php diff --git a/tests/Doctrine/Tests/Models/Quote/City.php b/tests/Tests/Models/Quote/City.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/City.php rename to tests/Tests/Models/Quote/City.php diff --git a/tests/Doctrine/Tests/Models/Quote/FullAddress.php b/tests/Tests/Models/Quote/FullAddress.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/FullAddress.php rename to tests/Tests/Models/Quote/FullAddress.php diff --git a/tests/Doctrine/Tests/Models/Quote/Group.php b/tests/Tests/Models/Quote/Group.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/Group.php rename to tests/Tests/Models/Quote/Group.php diff --git a/tests/Doctrine/Tests/Models/Quote/NumericEntity.php b/tests/Tests/Models/Quote/NumericEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/NumericEntity.php rename to tests/Tests/Models/Quote/NumericEntity.php diff --git a/tests/Doctrine/Tests/Models/Quote/Phone.php b/tests/Tests/Models/Quote/Phone.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/Phone.php rename to tests/Tests/Models/Quote/Phone.php diff --git a/tests/Doctrine/Tests/Models/Quote/User.php b/tests/Tests/Models/Quote/User.php similarity index 100% rename from tests/Doctrine/Tests/Models/Quote/User.php rename to tests/Tests/Models/Quote/User.php diff --git a/tests/Doctrine/Tests/Models/ReadonlyProperties/Author.php b/tests/Tests/Models/ReadonlyProperties/Author.php similarity index 100% rename from tests/Doctrine/Tests/Models/ReadonlyProperties/Author.php rename to tests/Tests/Models/ReadonlyProperties/Author.php diff --git a/tests/Doctrine/Tests/Models/ReadonlyProperties/Book.php b/tests/Tests/Models/ReadonlyProperties/Book.php similarity index 100% rename from tests/Doctrine/Tests/Models/ReadonlyProperties/Book.php rename to tests/Tests/Models/ReadonlyProperties/Book.php diff --git a/tests/Doctrine/Tests/Models/ReadonlyProperties/SimpleBook.php b/tests/Tests/Models/ReadonlyProperties/SimpleBook.php similarity index 100% rename from tests/Doctrine/Tests/Models/ReadonlyProperties/SimpleBook.php rename to tests/Tests/Models/ReadonlyProperties/SimpleBook.php diff --git a/tests/Doctrine/Tests/Models/Reflection/AbstractEmbeddable.php b/tests/Tests/Models/Reflection/AbstractEmbeddable.php similarity index 100% rename from tests/Doctrine/Tests/Models/Reflection/AbstractEmbeddable.php rename to tests/Tests/Models/Reflection/AbstractEmbeddable.php diff --git a/tests/Doctrine/Tests/Models/Reflection/ArrayObjectExtendingClass.php b/tests/Tests/Models/Reflection/ArrayObjectExtendingClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/Reflection/ArrayObjectExtendingClass.php rename to tests/Tests/Models/Reflection/ArrayObjectExtendingClass.php diff --git a/tests/Doctrine/Tests/Models/Reflection/ClassWithMixedProperties.php b/tests/Tests/Models/Reflection/ClassWithMixedProperties.php similarity index 100% rename from tests/Doctrine/Tests/Models/Reflection/ClassWithMixedProperties.php rename to tests/Tests/Models/Reflection/ClassWithMixedProperties.php diff --git a/tests/Doctrine/Tests/Models/Reflection/ConcreteEmbeddable.php b/tests/Tests/Models/Reflection/ConcreteEmbeddable.php similarity index 100% rename from tests/Doctrine/Tests/Models/Reflection/ConcreteEmbeddable.php rename to tests/Tests/Models/Reflection/ConcreteEmbeddable.php diff --git a/tests/Doctrine/Tests/Models/Reflection/ParentClass.php b/tests/Tests/Models/Reflection/ParentClass.php similarity index 100% rename from tests/Doctrine/Tests/Models/Reflection/ParentClass.php rename to tests/Tests/Models/Reflection/ParentClass.php diff --git a/tests/Doctrine/Tests/Models/Routing/RoutingLeg.php b/tests/Tests/Models/Routing/RoutingLeg.php similarity index 100% rename from tests/Doctrine/Tests/Models/Routing/RoutingLeg.php rename to tests/Tests/Models/Routing/RoutingLeg.php diff --git a/tests/Doctrine/Tests/Models/Routing/RoutingLocation.php b/tests/Tests/Models/Routing/RoutingLocation.php similarity index 100% rename from tests/Doctrine/Tests/Models/Routing/RoutingLocation.php rename to tests/Tests/Models/Routing/RoutingLocation.php diff --git a/tests/Doctrine/Tests/Models/Routing/RoutingRoute.php b/tests/Tests/Models/Routing/RoutingRoute.php similarity index 100% rename from tests/Doctrine/Tests/Models/Routing/RoutingRoute.php rename to tests/Tests/Models/Routing/RoutingRoute.php diff --git a/tests/Doctrine/Tests/Models/Routing/RoutingRouteBooking.php b/tests/Tests/Models/Routing/RoutingRouteBooking.php similarity index 100% rename from tests/Doctrine/Tests/Models/Routing/RoutingRouteBooking.php rename to tests/Tests/Models/Routing/RoutingRouteBooking.php diff --git a/tests/Doctrine/Tests/Models/StockExchange/Bond.php b/tests/Tests/Models/StockExchange/Bond.php similarity index 100% rename from tests/Doctrine/Tests/Models/StockExchange/Bond.php rename to tests/Tests/Models/StockExchange/Bond.php diff --git a/tests/Doctrine/Tests/Models/StockExchange/Market.php b/tests/Tests/Models/StockExchange/Market.php similarity index 100% rename from tests/Doctrine/Tests/Models/StockExchange/Market.php rename to tests/Tests/Models/StockExchange/Market.php diff --git a/tests/Doctrine/Tests/Models/StockExchange/Stock.php b/tests/Tests/Models/StockExchange/Stock.php similarity index 100% rename from tests/Doctrine/Tests/Models/StockExchange/Stock.php rename to tests/Tests/Models/StockExchange/Stock.php diff --git a/tests/Doctrine/Tests/Models/Taxi/Car.php b/tests/Tests/Models/Taxi/Car.php similarity index 100% rename from tests/Doctrine/Tests/Models/Taxi/Car.php rename to tests/Tests/Models/Taxi/Car.php diff --git a/tests/Doctrine/Tests/Models/Taxi/Driver.php b/tests/Tests/Models/Taxi/Driver.php similarity index 100% rename from tests/Doctrine/Tests/Models/Taxi/Driver.php rename to tests/Tests/Models/Taxi/Driver.php diff --git a/tests/Doctrine/Tests/Models/Taxi/PaidRide.php b/tests/Tests/Models/Taxi/PaidRide.php similarity index 100% rename from tests/Doctrine/Tests/Models/Taxi/PaidRide.php rename to tests/Tests/Models/Taxi/PaidRide.php diff --git a/tests/Doctrine/Tests/Models/Taxi/Ride.php b/tests/Tests/Models/Taxi/Ride.php similarity index 100% rename from tests/Doctrine/Tests/Models/Taxi/Ride.php rename to tests/Tests/Models/Taxi/Ride.php diff --git a/tests/Doctrine/Tests/Models/Tweet/Tweet.php b/tests/Tests/Models/Tweet/Tweet.php similarity index 100% rename from tests/Doctrine/Tests/Models/Tweet/Tweet.php rename to tests/Tests/Models/Tweet/Tweet.php diff --git a/tests/Doctrine/Tests/Models/Tweet/User.php b/tests/Tests/Models/Tweet/User.php similarity index 100% rename from tests/Doctrine/Tests/Models/Tweet/User.php rename to tests/Tests/Models/Tweet/User.php diff --git a/tests/Doctrine/Tests/Models/Tweet/UserList.php b/tests/Tests/Models/Tweet/UserList.php similarity index 100% rename from tests/Doctrine/Tests/Models/Tweet/UserList.php rename to tests/Tests/Models/Tweet/UserList.php diff --git a/tests/Doctrine/Tests/Models/TypedProperties/Contact.php b/tests/Tests/Models/TypedProperties/Contact.php similarity index 100% rename from tests/Doctrine/Tests/Models/TypedProperties/Contact.php rename to tests/Tests/Models/TypedProperties/Contact.php diff --git a/tests/Doctrine/Tests/Models/TypedProperties/UserTyped.php b/tests/Tests/Models/TypedProperties/UserTyped.php similarity index 100% rename from tests/Doctrine/Tests/Models/TypedProperties/UserTyped.php rename to tests/Tests/Models/TypedProperties/UserTyped.php diff --git a/tests/Doctrine/Tests/Models/TypedProperties/UserTypedWithCustomTypedField.php b/tests/Tests/Models/TypedProperties/UserTypedWithCustomTypedField.php similarity index 100% rename from tests/Doctrine/Tests/Models/TypedProperties/UserTypedWithCustomTypedField.php rename to tests/Tests/Models/TypedProperties/UserTypedWithCustomTypedField.php diff --git a/tests/Doctrine/Tests/Models/Upsertable/Insertable.php b/tests/Tests/Models/Upsertable/Insertable.php similarity index 100% rename from tests/Doctrine/Tests/Models/Upsertable/Insertable.php rename to tests/Tests/Models/Upsertable/Insertable.php diff --git a/tests/Doctrine/Tests/Models/Upsertable/Updatable.php b/tests/Tests/Models/Upsertable/Updatable.php similarity index 100% rename from tests/Doctrine/Tests/Models/Upsertable/Updatable.php rename to tests/Tests/Models/Upsertable/Updatable.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php b/tests/Tests/Models/ValueConversionType/AuxiliaryEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/AuxiliaryEntity.php rename to tests/Tests/Models/ValueConversionType/AuxiliaryEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedManyToManyCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php b/tests/Tests/Models/ValueConversionType/InversedManyToManyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedManyToManyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyExtraLazyEntity.php b/tests/Tests/Models/ValueConversionType/InversedManyToManyExtraLazyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedManyToManyExtraLazyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedManyToManyExtraLazyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToManyCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToManyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToManyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyExtraLazyEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToManyExtraLazyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToManyExtraLazyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToManyExtraLazyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToOneCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneEntity.php b/tests/Tests/Models/ValueConversionType/InversedOneToOneEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/InversedOneToOneEntity.php rename to tests/Tests/Models/ValueConversionType/InversedOneToOneEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToManyCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToManyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToManyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyExtraLazyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToManyExtraLazyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToManyExtraLazyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToManyExtraLazyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToOneCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToOneEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToOneEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneExtraLazyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToOneExtraLazyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneExtraLazyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToOneExtraLazyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/OwningManyToOneIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningManyToOneIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningManyToOneIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php b/tests/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php rename to tests/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php b/tests/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php rename to tests/Tests/Models/ValueConversionType/OwningOneToOneCompositeIdForeignKeyEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneEntity.php b/tests/Tests/Models/ValueConversionType/OwningOneToOneEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueConversionType/OwningOneToOneEntity.php rename to tests/Tests/Models/ValueConversionType/OwningOneToOneEntity.php diff --git a/tests/Doctrine/Tests/Models/ValueObjects/Name.php b/tests/Tests/Models/ValueObjects/Name.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueObjects/Name.php rename to tests/Tests/Models/ValueObjects/Name.php diff --git a/tests/Doctrine/Tests/Models/ValueObjects/Person.php b/tests/Tests/Models/ValueObjects/Person.php similarity index 100% rename from tests/Doctrine/Tests/Models/ValueObjects/Person.php rename to tests/Tests/Models/ValueObjects/Person.php diff --git a/tests/Doctrine/Tests/Models/VersionedManyToOne/Article.php b/tests/Tests/Models/VersionedManyToOne/Article.php similarity index 100% rename from tests/Doctrine/Tests/Models/VersionedManyToOne/Article.php rename to tests/Tests/Models/VersionedManyToOne/Article.php diff --git a/tests/Doctrine/Tests/Models/VersionedManyToOne/Category.php b/tests/Tests/Models/VersionedManyToOne/Category.php similarity index 100% rename from tests/Doctrine/Tests/Models/VersionedManyToOne/Category.php rename to tests/Tests/Models/VersionedManyToOne/Category.php diff --git a/tests/Doctrine/Tests/Models/VersionedOneToOne/FirstRelatedEntity.php b/tests/Tests/Models/VersionedOneToOne/FirstRelatedEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/VersionedOneToOne/FirstRelatedEntity.php rename to tests/Tests/Models/VersionedOneToOne/FirstRelatedEntity.php diff --git a/tests/Doctrine/Tests/Models/VersionedOneToOne/SecondRelatedEntity.php b/tests/Tests/Models/VersionedOneToOne/SecondRelatedEntity.php similarity index 100% rename from tests/Doctrine/Tests/Models/VersionedOneToOne/SecondRelatedEntity.php rename to tests/Tests/Models/VersionedOneToOne/SecondRelatedEntity.php diff --git a/tests/Doctrine/Tests/ORM/AbstractQueryTest.php b/tests/Tests/ORM/AbstractQueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/AbstractQueryTest.php rename to tests/Tests/ORM/AbstractQueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php b/tests/Tests/ORM/Cache/CacheConfigTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/CacheConfigTest.php rename to tests/Tests/ORM/Cache/CacheConfigTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php b/tests/Tests/ORM/Cache/CacheKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php rename to tests/Tests/ORM/Cache/CacheKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/CacheLoggerChainTest.php b/tests/Tests/ORM/Cache/CacheLoggerChainTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/CacheLoggerChainTest.php rename to tests/Tests/ORM/Cache/CacheLoggerChainTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php b/tests/Tests/ORM/Cache/DefaultCacheFactoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultCacheFactoryTest.php rename to tests/Tests/ORM/Cache/DefaultCacheFactoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultCacheTest.php b/tests/Tests/ORM/Cache/DefaultCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultCacheTest.php rename to tests/Tests/ORM/Cache/DefaultCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultCollectionHydratorTest.php b/tests/Tests/ORM/Cache/DefaultCollectionHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultCollectionHydratorTest.php rename to tests/Tests/ORM/Cache/DefaultCollectionHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultEntityHydratorTest.php b/tests/Tests/ORM/Cache/DefaultEntityHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultEntityHydratorTest.php rename to tests/Tests/ORM/Cache/DefaultEntityHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php b/tests/Tests/ORM/Cache/DefaultQueryCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php rename to tests/Tests/ORM/Cache/DefaultQueryCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultRegionLegacyTest.php b/tests/Tests/ORM/Cache/DefaultRegionLegacyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultRegionLegacyTest.php rename to tests/Tests/ORM/Cache/DefaultRegionLegacyTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php b/tests/Tests/ORM/Cache/DefaultRegionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/DefaultRegionTest.php rename to tests/Tests/ORM/Cache/DefaultRegionTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php b/tests/Tests/ORM/Cache/FileLockRegionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/FileLockRegionTest.php rename to tests/Tests/ORM/Cache/FileLockRegionTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/MultiGetRegionTest.php b/tests/Tests/ORM/Cache/MultiGetRegionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/MultiGetRegionTest.php rename to tests/Tests/ORM/Cache/MultiGetRegionTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php b/tests/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php rename to tests/Tests/ORM/Cache/Persister/Collection/CollectionPersisterTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Collection/NonStrictReadWriteCachedCollectionPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Collection/ReadOnlyCachedCollectionPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Collection/ReadWriteCachedCollectionPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php b/tests/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php rename to tests/Tests/ORM/Cache/Persister/Entity/EntityPersisterTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Entity/NonStrictReadWriteCachedEntityPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Entity/ReadOnlyCachedEntityPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php b/tests/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php rename to tests/Tests/ORM/Cache/Persister/Entity/ReadWriteCachedEntityPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Cache/RegionTestCase.php b/tests/Tests/ORM/Cache/RegionTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/RegionTestCase.php rename to tests/Tests/ORM/Cache/RegionTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Cache/StatisticsCacheLoggerTest.php b/tests/Tests/ORM/Cache/StatisticsCacheLoggerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Cache/StatisticsCacheLoggerTest.php rename to tests/Tests/ORM/Cache/StatisticsCacheLoggerTest.php diff --git a/tests/Doctrine/Tests/ORM/ConfigurationTest.php b/tests/Tests/ORM/ConfigurationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/ConfigurationTest.php rename to tests/Tests/ORM/ConfigurationTest.php diff --git a/tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php b/tests/Tests/ORM/Decorator/EntityManagerDecoratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php rename to tests/Tests/ORM/Decorator/EntityManagerDecoratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Entity/ConstructorTest.php b/tests/Tests/ORM/Entity/ConstructorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Entity/ConstructorTest.php rename to tests/Tests/ORM/Entity/ConstructorTest.php diff --git a/tests/Doctrine/Tests/ORM/EntityManagerTest.php b/tests/Tests/ORM/EntityManagerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/EntityManagerTest.php rename to tests/Tests/ORM/EntityManagerTest.php diff --git a/tests/Doctrine/Tests/ORM/EntityNotFoundExceptionTest.php b/tests/Tests/ORM/EntityNotFoundExceptionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/EntityNotFoundExceptionTest.php rename to tests/Tests/ORM/EntityNotFoundExceptionTest.php diff --git a/tests/Doctrine/Tests/ORM/Event/OnClassMetadataNotFoundEventArgsTest.php b/tests/Tests/ORM/Event/OnClassMetadataNotFoundEventArgsTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Event/OnClassMetadataNotFoundEventArgsTest.php rename to tests/Tests/ORM/Event/OnClassMetadataNotFoundEventArgsTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/AbstractManyToManyAssociationTestCase.php b/tests/Tests/ORM/Functional/AbstractManyToManyAssociationTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/AbstractManyToManyAssociationTestCase.php rename to tests/Tests/ORM/Functional/AbstractManyToManyAssociationTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php b/tests/Tests/ORM/Functional/AdvancedAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/AdvancedAssociationTest.php rename to tests/Tests/ORM/Functional/AdvancedAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/AdvancedDqlQueryTest.php b/tests/Tests/ORM/Functional/AdvancedDqlQueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/AdvancedDqlQueryTest.php rename to tests/Tests/ORM/Functional/AdvancedDqlQueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Tests/ORM/Functional/BasicFunctionalTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php rename to tests/Tests/ORM/Functional/BasicFunctionalTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CascadeRemoveOrderTest.php b/tests/Tests/ORM/Functional/CascadeRemoveOrderTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CascadeRemoveOrderTest.php rename to tests/Tests/ORM/Functional/CascadeRemoveOrderTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php b/tests/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php rename to tests/Tests/ORM/Functional/ClassTableInheritanceSecondTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceTest.php b/tests/Tests/ORM/Functional/ClassTableInheritanceTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ClassTableInheritanceTest.php rename to tests/Tests/ORM/Functional/ClassTableInheritanceTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ClearEventTest.php b/tests/Tests/ORM/Functional/ClearEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ClearEventTest.php rename to tests/Tests/ORM/Functional/ClearEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CompositePrimaryKeyTest.php b/tests/Tests/ORM/Functional/CompositePrimaryKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CompositePrimaryKeyTest.php rename to tests/Tests/ORM/Functional/CompositePrimaryKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CompositePrimaryKeyWithAssociationsTest.php b/tests/Tests/ORM/Functional/CompositePrimaryKeyWithAssociationsTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CompositePrimaryKeyWithAssociationsTest.php rename to tests/Tests/ORM/Functional/CompositePrimaryKeyWithAssociationsTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CustomFunctionsTest.php b/tests/Tests/ORM/Functional/CustomFunctionsTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CustomFunctionsTest.php rename to tests/Tests/ORM/Functional/CustomFunctionsTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CustomIdObjectTypeTest.php b/tests/Tests/ORM/Functional/CustomIdObjectTypeTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CustomIdObjectTypeTest.php rename to tests/Tests/ORM/Functional/CustomIdObjectTypeTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/CustomRepositoryTest.php b/tests/Tests/ORM/Functional/CustomRepositoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/CustomRepositoryTest.php rename to tests/Tests/ORM/Functional/CustomRepositoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Tests/ORM/Functional/DatabaseDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php rename to tests/Tests/ORM/Functional/DatabaseDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php b/tests/Tests/ORM/Functional/DatabaseDriverTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php rename to tests/Tests/ORM/Functional/DatabaseDriverTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Functional/DefaultValuesTest.php b/tests/Tests/ORM/Functional/DefaultValuesTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/DefaultValuesTest.php rename to tests/Tests/ORM/Functional/DefaultValuesTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/DetachedEntityTest.php b/tests/Tests/ORM/Functional/DetachedEntityTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/DetachedEntityTest.php rename to tests/Tests/ORM/Functional/DetachedEntityTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Tests/ORM/Functional/EagerFetchCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php rename to tests/Tests/ORM/Functional/EagerFetchCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php b/tests/Tests/ORM/Functional/EntityListenersTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/EntityListenersTest.php rename to tests/Tests/ORM/Functional/EntityListenersTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php b/tests/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php rename to tests/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Tests/ORM/Functional/EntityRepositoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php rename to tests/Tests/ORM/Functional/EntityRepositoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/EnumTest.php b/tests/Tests/ORM/Functional/EnumTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/EnumTest.php rename to tests/Tests/ORM/Functional/EnumTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Tests/ORM/Functional/ExtraLazyCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php rename to tests/Tests/ORM/Functional/ExtraLazyCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php b/tests/Tests/ORM/Functional/FlushEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php rename to tests/Tests/ORM/Functional/FlushEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/GH7877Test.php b/tests/Tests/ORM/Functional/GH7877Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/GH7877Test.php rename to tests/Tests/ORM/Functional/GH7877Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/HydrationCacheTest.php b/tests/Tests/ORM/Functional/HydrationCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/HydrationCacheTest.php rename to tests/Tests/ORM/Functional/HydrationCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php b/tests/Tests/ORM/Functional/IdentityMapTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/IdentityMapTest.php rename to tests/Tests/ORM/Functional/IdentityMapTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/IndexByAssociationTest.php b/tests/Tests/ORM/Functional/IndexByAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/IndexByAssociationTest.php rename to tests/Tests/ORM/Functional/IndexByAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/InsertableUpdatableTest.php b/tests/Tests/ORM/Functional/InsertableUpdatableTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/InsertableUpdatableTest.php rename to tests/Tests/ORM/Functional/InsertableUpdatableTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php b/tests/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php rename to tests/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Tests/ORM/Functional/LifecycleCallbackTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php rename to tests/Tests/ORM/Functional/LifecycleCallbackTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/GearmanLockTest.php b/tests/Tests/ORM/Functional/Locking/GearmanLockTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Locking/GearmanLockTest.php rename to tests/Tests/ORM/Functional/Locking/GearmanLockTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/LockAgentWorker.php b/tests/Tests/ORM/Functional/Locking/LockAgentWorker.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Locking/LockAgentWorker.php rename to tests/Tests/ORM/Functional/Locking/LockAgentWorker.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php b/tests/Tests/ORM/Functional/Locking/LockTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php rename to tests/Tests/ORM/Functional/Locking/LockTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php b/tests/Tests/ORM/Functional/Locking/OptimisticTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php rename to tests/Tests/ORM/Functional/Locking/OptimisticTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php b/tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php rename to tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/ManyToManyBidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php b/tests/Tests/ORM/Functional/ManyToManyEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToManyEventTest.php rename to tests/Tests/ORM/Functional/ManyToManyEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManySelfReferentialAssociationTest.php b/tests/Tests/ORM/Functional/ManyToManySelfReferentialAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToManySelfReferentialAssociationTest.php rename to tests/Tests/ORM/Functional/ManyToManySelfReferentialAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToManyUnidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/ManyToManyUnidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToManyUnidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/ManyToManyUnidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ManyToOneOrphanRemovalTest.php b/tests/Tests/ORM/Functional/ManyToOneOrphanRemovalTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ManyToOneOrphanRemovalTest.php rename to tests/Tests/ORM/Functional/ManyToOneOrphanRemovalTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/MappedSuperclassTest.php b/tests/Tests/ORM/Functional/MappedSuperclassTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/MappedSuperclassTest.php rename to tests/Tests/ORM/Functional/MappedSuperclassTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeCompositeToOneKeyTest.php b/tests/Tests/ORM/Functional/MergeCompositeToOneKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/MergeCompositeToOneKeyTest.php rename to tests/Tests/ORM/Functional/MergeCompositeToOneKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php b/tests/Tests/ORM/Functional/MergeProxiesTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/MergeProxiesTest.php rename to tests/Tests/ORM/Functional/MergeProxiesTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeSharedEntitiesTest.php b/tests/Tests/ORM/Functional/MergeSharedEntitiesTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/MergeSharedEntitiesTest.php rename to tests/Tests/ORM/Functional/MergeSharedEntitiesTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/MergeVersionedManyToOneTest.php b/tests/Tests/ORM/Functional/MergeVersionedManyToOneTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/MergeVersionedManyToOneTest.php rename to tests/Tests/ORM/Functional/MergeVersionedManyToOneTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php b/tests/Tests/ORM/Functional/NativeQueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php rename to tests/Tests/ORM/Functional/NativeQueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php b/tests/Tests/ORM/Functional/NewOperatorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/NewOperatorTest.php rename to tests/Tests/ORM/Functional/NewOperatorTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/NotifyPolicyTest.php b/tests/Tests/ORM/Functional/NotifyPolicyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/NotifyPolicyTest.php rename to tests/Tests/ORM/Functional/NotifyPolicyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/OneToManyBidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php b/tests/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php rename to tests/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php b/tests/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php rename to tests/Tests/ORM/Functional/OneToManySelfReferentialAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToManyUnidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/OneToManyUnidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToManyUnidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/OneToManyUnidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/OneToOneBidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php b/tests/Tests/ORM/Functional/OneToOneEagerLoadingTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneEagerLoadingTest.php rename to tests/Tests/ORM/Functional/OneToOneEagerLoadingTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php b/tests/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php rename to tests/Tests/ORM/Functional/OneToOneInverseSideLoadAfterDqlQueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneOrphanRemovalTest.php b/tests/Tests/ORM/Functional/OneToOneOrphanRemovalTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneOrphanRemovalTest.php rename to tests/Tests/ORM/Functional/OneToOneOrphanRemovalTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php b/tests/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php rename to tests/Tests/ORM/Functional/OneToOneSelfReferentialAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneSingleTableInheritanceTest.php b/tests/Tests/ORM/Functional/OneToOneSingleTableInheritanceTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneSingleTableInheritanceTest.php rename to tests/Tests/ORM/Functional/OneToOneSingleTableInheritanceTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OneToOneUnidirectionalAssociationTest.php b/tests/Tests/ORM/Functional/OneToOneUnidirectionalAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OneToOneUnidirectionalAssociationTest.php rename to tests/Tests/ORM/Functional/OneToOneUnidirectionalAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OrderedCollectionTest.php b/tests/Tests/ORM/Functional/OrderedCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OrderedCollectionTest.php rename to tests/Tests/ORM/Functional/OrderedCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/OrderedJoinedTableInheritanceCollectionTest.php b/tests/Tests/ORM/Functional/OrderedJoinedTableInheritanceCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/OrderedJoinedTableInheritanceCollectionTest.php rename to tests/Tests/ORM/Functional/OrderedJoinedTableInheritanceCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Tests/ORM/Functional/PaginationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PaginationTest.php rename to tests/Tests/ORM/Functional/PaginationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php b/tests/Tests/ORM/Functional/ParserResultSerializationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ParserResultSerializationTest.php rename to tests/Tests/ORM/Functional/ParserResultSerializationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt b/tests/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt rename to tests/Tests/ORM/Functional/ParserResults/single_select_2_14_3.txt diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt b/tests/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt rename to tests/Tests/ORM/Functional/ParserResults/single_select_2_15_0.txt diff --git a/tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt b/tests/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt rename to tests/Tests/ORM/Functional/ParserResults/single_select_2_17_0.txt diff --git a/tests/Doctrine/Tests/ORM/Functional/PersistentCollectionCriteriaTest.php b/tests/Tests/ORM/Functional/PersistentCollectionCriteriaTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PersistentCollectionCriteriaTest.php rename to tests/Tests/ORM/Functional/PersistentCollectionCriteriaTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/PersistentCollectionTest.php b/tests/Tests/ORM/Functional/PersistentCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PersistentCollectionTest.php rename to tests/Tests/ORM/Functional/PersistentCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php b/tests/Tests/ORM/Functional/PersistentObjectTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php rename to tests/Tests/ORM/Functional/PersistentObjectTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/PostFlushEventTest.php b/tests/Tests/ORM/Functional/PostFlushEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PostFlushEventTest.php rename to tests/Tests/ORM/Functional/PostFlushEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php b/tests/Tests/ORM/Functional/PostLoadEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/PostLoadEventTest.php rename to tests/Tests/ORM/Functional/PostLoadEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php b/tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php rename to tests/Tests/ORM/Functional/ProxiesLikeEntitiesTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php b/tests/Tests/ORM/Functional/QueryBuilderParenthesisTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/QueryBuilderParenthesisTest.php rename to tests/Tests/ORM/Functional/QueryBuilderParenthesisTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php b/tests/Tests/ORM/Functional/QueryCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/QueryCacheTest.php rename to tests/Tests/ORM/Functional/QueryCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryDqlFunctionTest.php b/tests/Tests/ORM/Functional/QueryDqlFunctionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/QueryDqlFunctionTest.php rename to tests/Tests/ORM/Functional/QueryDqlFunctionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryIterableTest.php b/tests/Tests/ORM/Functional/QueryIterableTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/QueryIterableTest.php rename to tests/Tests/ORM/Functional/QueryIterableTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/QueryTest.php b/tests/Tests/ORM/Functional/QueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/QueryTest.php rename to tests/Tests/ORM/Functional/QueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ReadOnlyTest.php b/tests/Tests/ORM/Functional/ReadOnlyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ReadOnlyTest.php rename to tests/Tests/ORM/Functional/ReadOnlyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ReadonlyPropertiesTest.php b/tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ReadonlyPropertiesTest.php rename to tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php b/tests/Tests/ORM/Functional/ReferenceProxyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ReferenceProxyTest.php rename to tests/Tests/ORM/Functional/ReferenceProxyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php b/tests/Tests/ORM/Functional/ResultCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ResultCacheTest.php rename to tests/Tests/ORM/Functional/ResultCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php b/tests/Tests/ORM/Functional/SQLFilterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SQLFilterTest.php rename to tests/Tests/ORM/Functional/SQLFilterTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php b/tests/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php rename to tests/Tests/ORM/Functional/SchemaTool/CompanySchemaTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php b/tests/Tests/ORM/Functional/SchemaTool/DBAL483Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php rename to tests/Tests/ORM/Functional/SchemaTool/DBAL483Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php b/tests/Tests/ORM/Functional/SchemaTool/DDC214Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php rename to tests/Tests/ORM/Functional/SchemaTool/DDC214Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php b/tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php rename to tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php b/tests/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php rename to tests/Tests/ORM/Functional/SchemaTool/PostgreSqlSchemaToolTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaValidatorTest.php b/tests/Tests/ORM/Functional/SchemaValidatorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SchemaValidatorTest.php rename to tests/Tests/ORM/Functional/SchemaValidatorTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyWithAssociationsTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyWithAssociationsTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyWithAssociationsTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheCompositePrimaryKeyWithAssociationsTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheConcurrentTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheCriteriaTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheExtraLazyCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php b/tests/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php rename to tests/Tests/ORM/Functional/SecondLevelCacheFunctionalTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheJoinTableInheritanceTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheManyToManyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheManyToOneTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheOneToManyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheOneToOneTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheQueryCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheRepositoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheSingleTableInheritanceTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php b/tests/Tests/ORM/Functional/SecondLevelCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SecondLevelCacheTest.php rename to tests/Tests/ORM/Functional/SecondLevelCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SequenceEmulatedIdentityStrategyTest.php b/tests/Tests/ORM/Functional/SequenceEmulatedIdentityStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SequenceEmulatedIdentityStrategyTest.php rename to tests/Tests/ORM/Functional/SequenceEmulatedIdentityStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SequenceGeneratorTest.php b/tests/Tests/ORM/Functional/SequenceGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SequenceGeneratorTest.php rename to tests/Tests/ORM/Functional/SequenceGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SingleTableCompositeKeyTest.php b/tests/Tests/ORM/Functional/SingleTableCompositeKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SingleTableCompositeKeyTest.php rename to tests/Tests/ORM/Functional/SingleTableCompositeKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php b/tests/Tests/ORM/Functional/SingleTableInheritanceTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php rename to tests/Tests/ORM/Functional/SingleTableInheritanceTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php b/tests/Tests/ORM/Functional/StandardEntityPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php rename to tests/Tests/ORM/Functional/StandardEntityPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1040Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1040Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1040Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1040Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1041Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1041Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1041Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1041Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1043Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1043Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1043Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1043Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1080Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1080Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1080Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1080Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1113Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1113Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1113Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1113Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1129Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1129Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1129Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1129Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1163Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1163Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1163Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php b/tests/Tests/ORM/Functional/Ticket/DDC117Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC117Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1181Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1181Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1181Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1181Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1193Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1193Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1193Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1209Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1209Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1209Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1209Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1225Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1225Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1225Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1225Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1228Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1228Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1228Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1228Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1238Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1238Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1238Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1238Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1250Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1250Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1250Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1250Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1276Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1276Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1276Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1276Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1300Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1300Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1300Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1300Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1301Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1301Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1301Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1301Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1306Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1306Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1306Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1306Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1335Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1335Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1335Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1335Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1383Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1383Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1383Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1383Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1392Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1392Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1392Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1392Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1400Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1400Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1400Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1400Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1404Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1404Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1404Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC142Test.php b/tests/Tests/ORM/Functional/Ticket/DDC142Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC142Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC142Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1430Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1430Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1430Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1430Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1436Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1436Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1436Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1436Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC144Test.php b/tests/Tests/ORM/Functional/Ticket/DDC144Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC144Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC144Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1452Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1452Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1452Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1452Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1454Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1454Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1454Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1454Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1458Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1458Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1458Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1458Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1461Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1461Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1461Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1461Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1509Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1509Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1509Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1509Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1514Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1514Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1514Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1514Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1515Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1515Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1515Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1515Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1526Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1526Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1526Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1526Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1545Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1545Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1545Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1545Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1548Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1548Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1548Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1548Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1594Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1594Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1594Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1594Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1595Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1595Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1595Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC163Test.php b/tests/Tests/ORM/Functional/Ticket/DDC163Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC163Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC163Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1643Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1643Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1643Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1643Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1654Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1654Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1654Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1654Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1655Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1655Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1655Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1655Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1666Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1666Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1666Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1666Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1685Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1685Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1685Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1685Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php b/tests/Tests/ORM/Functional/Ticket/DDC168Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC168Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC168Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1690Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1690Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1695Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1695Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1695Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1695Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1707Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1707Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1707Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1719Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1719Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1719Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1719Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1734Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1734Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1734Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1734Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1757Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1757Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1757Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1757Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1778Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1778Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1778Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1778Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1787Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1787Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1787Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1787Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1843Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1843Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1843Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1843Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1884Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1884Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1884Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1884Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1885Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1885Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1918Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1918Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1925Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1925Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1925Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1925Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC192Test.php b/tests/Tests/ORM/Functional/Ticket/DDC192Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC192Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC192Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1995Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1995Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php b/tests/Tests/ORM/Functional/Ticket/DDC1998Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC1998Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC199Test.php b/tests/Tests/ORM/Functional/Ticket/DDC199Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC199Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC199Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2012Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2012Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2074Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2074Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2084Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2084Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2084Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2084Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2090Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2090Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2106Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2106Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php b/tests/Tests/ORM/Functional/Ticket/DDC211Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC211Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC211Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2138Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2138Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2138Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2138Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2175Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2175Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2182Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2182Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2214Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2214Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2224Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2224Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2224Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2224Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2230Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2230Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2231Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2231Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2231Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2231Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2252Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2252Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2252Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2252Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2256Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2256Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2256Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2256Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2306Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2306Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2306Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2306Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2346Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2346Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2350Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2350Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2359Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2359Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC237Test.php b/tests/Tests/ORM/Functional/Ticket/DDC237Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC237Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC237Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2387Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2387Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2409Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2409Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2415Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2415Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2494Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2494Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2519Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2519Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2575Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2575Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2575Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2575Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2579Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2579Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2579Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2579Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php b/tests/Tests/ORM/Functional/Ticket/DDC258Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC258Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC258Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2602Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2602Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2602Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2602Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2645Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2645Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2645Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2645Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2655Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2655Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2655Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2655Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2660Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2660Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2660Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2660Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2692Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2692Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2692Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2759Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2759Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2759Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2759Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2775Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2775Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2775Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2775Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2780Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2780Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2780Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2780Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2790Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2790Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2790Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2790Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC279Test.php b/tests/Tests/ORM/Functional/Ticket/DDC279Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC279Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC279Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2825Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2825Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2825Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2825Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2862Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2862Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2862Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2862Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2895Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2895Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2895Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2931Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2931Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2931Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2931Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2943Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2943Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2943Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2943Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2984Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2984Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2984Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2984Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2996Test.php b/tests/Tests/ORM/Functional/Ticket/DDC2996Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2996Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC2996Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3033Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3033Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3033Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3033Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3042Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3042Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3042Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3042Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3068Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3068Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3068Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3068Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC309Test.php b/tests/Tests/ORM/Functional/Ticket/DDC309Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC309Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC309Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3103Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3103Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3103Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3103Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3123Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3123Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3123Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3160Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3160Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3160Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3160Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3170Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3170Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3170Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3170Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3192Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3192Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3192Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3192Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3223Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3223Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3223Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3223Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3300Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3300Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3300Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3300Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3303Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3303Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3303Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3303Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC331Test.php b/tests/Tests/ORM/Functional/Ticket/DDC331Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC331Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC331Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3330Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3330Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3330Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3330Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3346Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3346Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3346Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3346Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php b/tests/Tests/ORM/Functional/Ticket/DDC345Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC345Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC345Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC353Test.php b/tests/Tests/ORM/Functional/Ticket/DDC353Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC353Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC353Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3582Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3582Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3582Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3582Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3597Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3597Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3597Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3597Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3634Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3634Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3634Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3644Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3644Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3644Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3644Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3699Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3699Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3699Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3699Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3719Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3719Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3719Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3719Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php b/tests/Tests/ORM/Functional/Ticket/DDC371Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC371Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC371Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3785Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3785Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3785Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3785Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC381Test.php b/tests/Tests/ORM/Functional/Ticket/DDC381Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC381Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC381Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php b/tests/Tests/ORM/Functional/Ticket/DDC3967Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3967Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC3967Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php b/tests/Tests/ORM/Functional/Ticket/DDC4003Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4003Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC4003Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4024Test.php b/tests/Tests/ORM/Functional/Ticket/DDC4024Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC4024Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC4024Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php b/tests/Tests/ORM/Functional/Ticket/DDC422Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC422Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC422Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php b/tests/Tests/ORM/Functional/Ticket/DDC425Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC425Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC425Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php b/tests/Tests/ORM/Functional/Ticket/DDC440Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC440Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC440Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php b/tests/Tests/ORM/Functional/Ticket/DDC444Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC444Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC444Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC448Test.php b/tests/Tests/ORM/Functional/Ticket/DDC448Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC448Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC448Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC493Test.php b/tests/Tests/ORM/Functional/Ticket/DDC493Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC493Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC493Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC501Test.php b/tests/Tests/ORM/Functional/Ticket/DDC501Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC501Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC501Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC512Test.php b/tests/Tests/ORM/Functional/Ticket/DDC512Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC512Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC512Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC513Test.php b/tests/Tests/ORM/Functional/Ticket/DDC513Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC513Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC513Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC518Test.php b/tests/Tests/ORM/Functional/Ticket/DDC518Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC518Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC518Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC522Test.php b/tests/Tests/ORM/Functional/Ticket/DDC522Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC522Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC522Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php b/tests/Tests/ORM/Functional/Ticket/DDC531Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC531Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC5684Test.php b/tests/Tests/ORM/Functional/Ticket/DDC5684Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC5684Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC5684Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC588Test.php b/tests/Tests/ORM/Functional/Ticket/DDC588Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC588Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC588Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php b/tests/Tests/ORM/Functional/Ticket/DDC599Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC599Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC599Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC618Test.php b/tests/Tests/ORM/Functional/Ticket/DDC618Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC618Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC618Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6303Test.php b/tests/Tests/ORM/Functional/Ticket/DDC6303Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6303Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC6303Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC633Test.php b/tests/Tests/ORM/Functional/Ticket/DDC633Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC633Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC633Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6460Test.php b/tests/Tests/ORM/Functional/Ticket/DDC6460Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6460Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC6460Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6558Test.php b/tests/Tests/ORM/Functional/Ticket/DDC6558Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6558Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC6558Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC656Test.php b/tests/Tests/ORM/Functional/Ticket/DDC656Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC656Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC656Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC657Test.php b/tests/Tests/ORM/Functional/Ticket/DDC657Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC657Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC657Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC698Test.php b/tests/Tests/ORM/Functional/Ticket/DDC698Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC698Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC698Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC69Test.php b/tests/Tests/ORM/Functional/Ticket/DDC69Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC69Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC69Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php b/tests/Tests/ORM/Functional/Ticket/DDC719Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC719Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC719Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC729Test.php b/tests/Tests/ORM/Functional/Ticket/DDC729Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC729Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC729Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC735Test.php b/tests/Tests/ORM/Functional/Ticket/DDC735Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC735Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC735Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC736Test.php b/tests/Tests/ORM/Functional/Ticket/DDC736Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC736Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC736Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC742Test.php b/tests/Tests/ORM/Functional/Ticket/DDC742Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC742Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC742Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC748Test.php b/tests/Tests/ORM/Functional/Ticket/DDC748Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC748Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC748Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC758Test.php b/tests/Tests/ORM/Functional/Ticket/DDC758Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC758Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC758Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC767Test.php b/tests/Tests/ORM/Functional/Ticket/DDC767Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC767Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC767Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php b/tests/Tests/ORM/Functional/Ticket/DDC7969Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC7969Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC7969Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC809Test.php b/tests/Tests/ORM/Functional/Ticket/DDC809Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC809Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC809Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php b/tests/Tests/ORM/Functional/Ticket/DDC812Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC812Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC812Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php b/tests/Tests/ORM/Functional/Ticket/DDC832Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC832Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC832Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php b/tests/Tests/ORM/Functional/Ticket/DDC837Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC837Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC849Test.php b/tests/Tests/ORM/Functional/Ticket/DDC849Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC849Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC849Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php b/tests/Tests/ORM/Functional/Ticket/DDC881Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC881Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC881Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC933Test.php b/tests/Tests/ORM/Functional/Ticket/DDC933Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC933Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC933Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC949Test.php b/tests/Tests/ORM/Functional/Ticket/DDC949Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC949Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC949Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC960Test.php b/tests/Tests/ORM/Functional/Ticket/DDC960Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC960Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC960Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC992Test.php b/tests/Tests/ORM/Functional/Ticket/DDC992Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/DDC992Test.php rename to tests/Tests/ORM/Functional/Ticket/DDC992Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/GH10049Test.php b/tests/Tests/ORM/Functional/Ticket/GH10049/GH10049Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/GH10049Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10049/GH10049Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyInheritor.php b/tests/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyInheritor.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyInheritor.php rename to tests/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyInheritor.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyOwner.php b/tests/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyOwner.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyOwner.php rename to tests/Tests/ORM/Functional/Ticket/GH10049/ReadOnlyPropertyOwner.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10132Test.php b/tests/Tests/ORM/Functional/Ticket/GH10132Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10132Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10132Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10288Test.php b/tests/Tests/ORM/Functional/Ticket/GH10288Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10288Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10288Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10334Test.php b/tests/Tests/ORM/Functional/Ticket/GH10334Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10334Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10334Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10336Test.php b/tests/Tests/ORM/Functional/Ticket/GH10336Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10336Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10336Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10348Test.php b/tests/Tests/ORM/Functional/Ticket/GH10348Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10348Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10348Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10387Test.php b/tests/Tests/ORM/Functional/Ticket/GH10387Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10387Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10387Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10450Test.php b/tests/Tests/ORM/Functional/Ticket/GH10450Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10450Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10450Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10454Test.php b/tests/Tests/ORM/Functional/Ticket/GH10454Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10454Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10454Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10462Test.php b/tests/Tests/ORM/Functional/Ticket/GH10462Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10462Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10462Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10473Test.php b/tests/Tests/ORM/Functional/Ticket/GH10473Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10473Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10473Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10531Test.php b/tests/Tests/ORM/Functional/Ticket/GH10531Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10531Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10531Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10532Test.php b/tests/Tests/ORM/Functional/Ticket/GH10532Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10532Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10532Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10566Test.php b/tests/Tests/ORM/Functional/Ticket/GH10566Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10566Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10566Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10625Test.php b/tests/Tests/ORM/Functional/Ticket/GH10625Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10625Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10625Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php b/tests/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10661/GH10661Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php b/tests/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php rename to tests/Tests/ORM/Functional/Ticket/GH10661/InvalidChildEntity.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php b/tests/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php rename to tests/Tests/ORM/Functional/Ticket/GH10661/InvalidEntity.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10747Test.php b/tests/Tests/ORM/Functional/Ticket/GH10747Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10747Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10747Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10752Test.php b/tests/Tests/ORM/Functional/Ticket/GH10752Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10752Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10752Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php b/tests/Tests/ORM/Functional/Ticket/GH10808Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10808Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10808Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10869Test.php b/tests/Tests/ORM/Functional/Ticket/GH10869Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10869Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10869Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10880Test.php b/tests/Tests/ORM/Functional/Ticket/GH10880Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH10880Test.php rename to tests/Tests/ORM/Functional/Ticket/GH10880Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php b/tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php rename to tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Entity.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php b/tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php rename to tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Enum.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php b/tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php rename to tests/Tests/ORM/Functional/Ticket/GH11017/GH11017Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php b/tests/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/EntityStatus.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php b/tests/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/GH11037Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php b/tests/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/IntEntityStatus.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php b/tests/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/InvalidEntityWithTypedEnum.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php b/tests/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/StringEntityStatus.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php b/tests/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php rename to tests/Tests/ORM/Functional/Ticket/GH11037/ValidEntityWithTypedEnum.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php b/tests/Tests/ORM/Functional/Ticket/GH11058Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11058Test.php rename to tests/Tests/ORM/Functional/Ticket/GH11058Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php b/tests/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php rename to tests/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityAdvanced.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php b/tests/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php rename to tests/Tests/ORM/Functional/Ticket/GH11072/GH11072EntityBasic.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php b/tests/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php rename to tests/Tests/ORM/Functional/Ticket/GH11072/GH11072Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH2947Test.php b/tests/Tests/ORM/Functional/Ticket/GH2947Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH2947Test.php rename to tests/Tests/ORM/Functional/Ticket/GH2947Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5562Test.php b/tests/Tests/ORM/Functional/Ticket/GH5562Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5562Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5562Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5742Test.php b/tests/Tests/ORM/Functional/Ticket/GH5742Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5742Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5742Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php b/tests/Tests/ORM/Functional/Ticket/GH5762Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5762Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5762Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5804Test.php b/tests/Tests/ORM/Functional/Ticket/GH5804Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5804Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5804Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5887Test.php b/tests/Tests/ORM/Functional/Ticket/GH5887Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5887Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5887Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5988Test.php b/tests/Tests/ORM/Functional/Ticket/GH5988Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5988Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5988Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH5998Test.php b/tests/Tests/ORM/Functional/Ticket/GH5998Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH5998Test.php rename to tests/Tests/ORM/Functional/Ticket/GH5998Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6029Test.php b/tests/Tests/ORM/Functional/Ticket/GH6029Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6029Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6029Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6141Test.php b/tests/Tests/ORM/Functional/Ticket/GH6141Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6141Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6141Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6217Test.php b/tests/Tests/ORM/Functional/Ticket/GH6217Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6217Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6217Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6362Test.php b/tests/Tests/ORM/Functional/Ticket/GH6362Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6362Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6362Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6394Test.php b/tests/Tests/ORM/Functional/Ticket/GH6394Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6394Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6394Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6402Test.php b/tests/Tests/ORM/Functional/Ticket/GH6402Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6402Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6402Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6464Test.php b/tests/Tests/ORM/Functional/Ticket/GH6464Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6464Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6464Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499OneToManyRelationshipTest.php b/tests/Tests/ORM/Functional/Ticket/GH6499OneToManyRelationshipTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499OneToManyRelationshipTest.php rename to tests/Tests/ORM/Functional/Ticket/GH6499OneToManyRelationshipTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499OneToOneRelationshipTest.php b/tests/Tests/ORM/Functional/Ticket/GH6499OneToOneRelationshipTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499OneToOneRelationshipTest.php rename to tests/Tests/ORM/Functional/Ticket/GH6499OneToOneRelationshipTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499Test.php b/tests/Tests/ORM/Functional/Ticket/GH6499Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6499Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6499Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6531Test.php b/tests/Tests/ORM/Functional/Ticket/GH6531Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6531Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6531Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6682Test.php b/tests/Tests/ORM/Functional/Ticket/GH6682Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6682Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6682Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6699Test.php b/tests/Tests/ORM/Functional/Ticket/GH6699Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6699Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6699Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6740Test.php b/tests/Tests/ORM/Functional/Ticket/GH6740Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6740Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6740Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6823Test.php b/tests/Tests/ORM/Functional/Ticket/GH6823Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6823Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6823Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6937Test.php b/tests/Tests/ORM/Functional/Ticket/GH6937Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH6937Test.php rename to tests/Tests/ORM/Functional/Ticket/GH6937Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7006Test.php b/tests/Tests/ORM/Functional/Ticket/GH7006Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7006Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7006Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php b/tests/Tests/ORM/Functional/Ticket/GH7012Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7012Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7012Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7062Test.php b/tests/Tests/ORM/Functional/Ticket/GH7062Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7062Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7062Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7067Test.php b/tests/Tests/ORM/Functional/Ticket/GH7067Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7067Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7067Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7068Test.php b/tests/Tests/ORM/Functional/Ticket/GH7068Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7068Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7068Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7079Test.php b/tests/Tests/ORM/Functional/Ticket/GH7079Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7079Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7079Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7180Test.php b/tests/Tests/ORM/Functional/Ticket/GH7180Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7180Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7180Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7259Test.php b/tests/Tests/ORM/Functional/Ticket/GH7259Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7259Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7259Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7286Test.php b/tests/Tests/ORM/Functional/Ticket/GH7286Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7286Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7286Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7366Test.php b/tests/Tests/ORM/Functional/Ticket/GH7366Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7366Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7366Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7407Test.php b/tests/Tests/ORM/Functional/Ticket/GH7407Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7407Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7407Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7496WithToIterableTest.php b/tests/Tests/ORM/Functional/Ticket/GH7496WithToIterableTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7496WithToIterableTest.php rename to tests/Tests/ORM/Functional/Ticket/GH7496WithToIterableTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7505Test.php b/tests/Tests/ORM/Functional/Ticket/GH7505Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7505Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7505Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7512Test.php b/tests/Tests/ORM/Functional/Ticket/GH7512Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7512Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7512Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7629Test.php b/tests/Tests/ORM/Functional/Ticket/GH7629Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7629Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7629Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7661Test.php b/tests/Tests/ORM/Functional/Ticket/GH7661Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7661Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7661Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7684Test.php b/tests/Tests/ORM/Functional/Ticket/GH7684Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7684Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7684Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7717Test.php b/tests/Tests/ORM/Functional/Ticket/GH7717Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7717Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7717Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7735Test.php b/tests/Tests/ORM/Functional/Ticket/GH7735Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7735Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7735Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7737Test.php b/tests/Tests/ORM/Functional/Ticket/GH7737Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7737Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7737Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7761Test.php b/tests/Tests/ORM/Functional/Ticket/GH7761Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7761Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7761Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7767Test.php b/tests/Tests/ORM/Functional/Ticket/GH7767Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7767Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7767Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7820Test.php b/tests/Tests/ORM/Functional/Ticket/GH7820Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7820Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7820Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php b/tests/Tests/ORM/Functional/Ticket/GH7829Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7829Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7829Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7836Test.php b/tests/Tests/ORM/Functional/Ticket/GH7836Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7836Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7836Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7864Test.php b/tests/Tests/ORM/Functional/Ticket/GH7864Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7864Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7864Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php b/tests/Tests/ORM/Functional/Ticket/GH7869Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7869Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7869Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7875Test.php b/tests/Tests/ORM/Functional/Ticket/GH7875Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7875Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7875Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH7941Test.php b/tests/Tests/ORM/Functional/Ticket/GH7941Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH7941Test.php rename to tests/Tests/ORM/Functional/Ticket/GH7941Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8055Test.php b/tests/Tests/ORM/Functional/Ticket/GH8055Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8055Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8055Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8061Test.php b/tests/Tests/ORM/Functional/Ticket/GH8061Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8061Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8061Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8127Test.php b/tests/Tests/ORM/Functional/Ticket/GH8127Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8127Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8127Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php b/tests/Tests/ORM/Functional/Ticket/GH8217Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8217Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8217Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8415Test.php b/tests/Tests/ORM/Functional/Ticket/GH8415Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8415Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8415Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8415ToManyAssociationTest.php b/tests/Tests/ORM/Functional/Ticket/GH8415ToManyAssociationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8415ToManyAssociationTest.php rename to tests/Tests/ORM/Functional/Ticket/GH8415ToManyAssociationTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8443Test.php b/tests/Tests/ORM/Functional/Ticket/GH8443Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8443Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8443Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8499Test.php b/tests/Tests/ORM/Functional/Ticket/GH8499Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8499Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8499Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8663Test.php b/tests/Tests/ORM/Functional/Ticket/GH8663Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8663Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8663Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH8914Test.php b/tests/Tests/ORM/Functional/Ticket/GH8914Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH8914Test.php rename to tests/Tests/ORM/Functional/Ticket/GH8914Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9027Test.php b/tests/Tests/ORM/Functional/Ticket/GH9027Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9027Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9027Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php b/tests/Tests/ORM/Functional/Ticket/GH9109Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9109Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9109Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9192Test.php b/tests/Tests/ORM/Functional/Ticket/GH9192Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9192Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9192Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9230Test.php b/tests/Tests/ORM/Functional/Ticket/GH9230Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9230Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9230Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9335Test.php b/tests/Tests/ORM/Functional/Ticket/GH9335Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9335Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9335Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/GH9467Test.php b/tests/Tests/ORM/Functional/Ticket/GH9467/GH9467Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/GH9467Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/GH9467Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceChild.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceChild.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceChild.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceChild.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonInsertableColumn.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonInsertableColumn.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonInsertableColumn.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonInsertableColumn.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonUpdatableColumn.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonUpdatableColumn.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonUpdatableColumn.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonUpdatableColumn.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonWritableColumn.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonWritableColumn.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonWritableColumn.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceNonWritableColumn.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceRoot.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceRoot.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceRoot.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceRoot.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceWritableColumn.php b/tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceWritableColumn.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceWritableColumn.php rename to tests/Tests/ORM/Functional/Ticket/GH9467/JoinedInheritanceWritableColumn.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9516Test.php b/tests/Tests/ORM/Functional/Ticket/GH9516Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9516Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9516Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9579Test.php b/tests/Tests/ORM/Functional/Ticket/GH9579Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9579Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9579Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH9807Test.php b/tests/Tests/ORM/Functional/Ticket/GH9807Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/GH9807Test.php rename to tests/Tests/ORM/Functional/Ticket/GH9807Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Issue5989Test.php b/tests/Tests/ORM/Functional/Ticket/Issue5989Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Issue5989Test.php rename to tests/Tests/ORM/Functional/Ticket/Issue5989Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Issue9300Test.php b/tests/Tests/ORM/Functional/Ticket/Issue9300Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Issue9300Test.php rename to tests/Tests/ORM/Functional/Ticket/Issue9300Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket2481Test.php b/tests/Tests/ORM/Functional/Ticket/Ticket2481Test.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket2481Test.php rename to tests/Tests/ORM/Functional/Ticket/Ticket2481Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfAbstractTest.php b/tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfAbstractTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfAbstractTest.php rename to tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfAbstractTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfMultiLevelTest.php b/tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfMultiLevelTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfMultiLevelTest.php rename to tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfMultiLevelTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfParametricTest.php b/tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfParametricTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfParametricTest.php rename to tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfParametricTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfTest.php b/tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfTest.php rename to tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfWithMultipleParametersTest.php b/tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfWithMultipleParametersTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfWithMultipleParametersTest.php rename to tests/Tests/ORM/Functional/Ticket/Ticket4646InstanceOfWithMultipleParametersTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/TypeTest.php b/tests/Tests/ORM/Functional/TypeTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/TypeTest.php rename to tests/Tests/ORM/Functional/TypeTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php b/tests/Tests/ORM/Functional/TypeValueSqlTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/TypeValueSqlTest.php rename to tests/Tests/ORM/Functional/TypeValueSqlTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/UUIDGeneratorTest.php b/tests/Tests/ORM/Functional/UUIDGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/UUIDGeneratorTest.php rename to tests/Tests/ORM/Functional/UUIDGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/UnitOfWorkLifecycleTest.php b/tests/Tests/ORM/Functional/UnitOfWorkLifecycleTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/UnitOfWorkLifecycleTest.php rename to tests/Tests/ORM/Functional/UnitOfWorkLifecycleTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdForeignKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php b/tests/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/ManyToManyCompositeIdTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyExtraLazyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/ManyToManyExtraLazyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyExtraLazyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/ManyToManyExtraLazyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/ManyToManyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdForeignKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToManyCompositeIdTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToManyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdForeignKeyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToOneCompositeIdTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php b/tests/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php rename to tests/Tests/ORM/Functional/ValueConversionType/OneToOneTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Tests/ORM/Functional/ValueObjectsTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php rename to tests/Tests/ORM/Functional/ValueObjectsTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/VersionedOneToOneTest.php b/tests/Tests/ORM/Functional/VersionedOneToOneTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/VersionedOneToOneTest.php rename to tests/Tests/ORM/Functional/VersionedOneToOneTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.Person.dcm.xml b/tests/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.Person.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.Person.dcm.xml rename to tests/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.Person.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.PhoneNumber.dcm.xml b/tests/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.PhoneNumber.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.PhoneNumber.dcm.xml rename to tests/Tests/ORM/Functional/xml/Doctrine.Tests.Models.OrnementalOrphanRemoval.PhoneNumber.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php b/tests/Tests/ORM/Hydration/AbstractHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/AbstractHydratorTest.php rename to tests/Tests/ORM/Hydration/AbstractHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/ArrayHydratorTest.php b/tests/Tests/ORM/Hydration/ArrayHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/ArrayHydratorTest.php rename to tests/Tests/ORM/Hydration/ArrayHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/CustomHydratorTest.php b/tests/Tests/ORM/Hydration/CustomHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/CustomHydratorTest.php rename to tests/Tests/ORM/Hydration/CustomHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/HydrationTestCase.php b/tests/Tests/ORM/Hydration/HydrationTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/HydrationTestCase.php rename to tests/Tests/ORM/Hydration/HydrationTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php b/tests/Tests/ORM/Hydration/ObjectHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/ObjectHydratorTest.php rename to tests/Tests/ORM/Hydration/ObjectHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php b/tests/Tests/ORM/Hydration/ResultSetMappingTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php rename to tests/Tests/ORM/Hydration/ResultSetMappingTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/ScalarColumnHydratorTest.php b/tests/Tests/ORM/Hydration/ScalarColumnHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/ScalarColumnHydratorTest.php rename to tests/Tests/ORM/Hydration/ScalarColumnHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/ScalarHydratorTest.php b/tests/Tests/ORM/Hydration/ScalarHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/ScalarHydratorTest.php rename to tests/Tests/ORM/Hydration/ScalarHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php b/tests/Tests/ORM/Hydration/SimpleObjectHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php rename to tests/Tests/ORM/Hydration/SimpleObjectHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php b/tests/Tests/ORM/Hydration/SingleScalarHydratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Hydration/SingleScalarHydratorTest.php rename to tests/Tests/ORM/Hydration/SingleScalarHydratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Id/AbstractIdGeneratorTest.php b/tests/Tests/ORM/Id/AbstractIdGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Id/AbstractIdGeneratorTest.php rename to tests/Tests/ORM/Id/AbstractIdGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Id/AssignedGeneratorTest.php b/tests/Tests/ORM/Id/AssignedGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Id/AssignedGeneratorTest.php rename to tests/Tests/ORM/Id/AssignedGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php b/tests/Tests/ORM/Id/SequenceGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Id/SequenceGeneratorTest.php rename to tests/Tests/ORM/Id/SequenceGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Internal/HydrationCompleteHandlerTest.php b/tests/Tests/ORM/Internal/HydrationCompleteHandlerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Internal/HydrationCompleteHandlerTest.php rename to tests/Tests/ORM/Internal/HydrationCompleteHandlerTest.php diff --git a/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php b/tests/Tests/ORM/Internal/TopologicalSortTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php rename to tests/Tests/ORM/Internal/TopologicalSortTest.php diff --git a/tests/Doctrine/Tests/ORM/LazyCriteriaCollectionTest.php b/tests/Tests/ORM/LazyCriteriaCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/LazyCriteriaCollectionTest.php rename to tests/Tests/ORM/LazyCriteriaCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php b/tests/Tests/ORM/Mapping/AnnotationDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/AnnotationDriverTest.php rename to tests/Tests/ORM/Mapping/AnnotationDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php b/tests/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php rename to tests/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php b/tests/Tests/ORM/Mapping/AttributeDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/AttributeDriverTest.php rename to tests/Tests/ORM/Mapping/AttributeDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/AttributeReaderTest.php b/tests/Tests/ORM/Mapping/AttributeReaderTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/AttributeReaderTest.php rename to tests/Tests/ORM/Mapping/AttributeReaderTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php b/tests/Tests/ORM/Mapping/BasicInheritanceMappingTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php rename to tests/Tests/ORM/Mapping/BasicInheritanceMappingTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php b/tests/Tests/ORM/Mapping/ClassMetadataBuilderTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ClassMetadataBuilderTest.php rename to tests/Tests/ORM/Mapping/ClassMetadataBuilderTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php b/tests/Tests/ORM/Mapping/ClassMetadataFactoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ClassMetadataFactoryTest.php rename to tests/Tests/ORM/Mapping/ClassMetadataFactoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php b/tests/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php rename to tests/Tests/ORM/Mapping/ClassMetadataLoadEventTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Tests/ORM/Mapping/ClassMetadataTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php rename to tests/Tests/ORM/Mapping/ClassMetadataTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php b/tests/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php rename to tests/Tests/ORM/Mapping/DefaultQuoteStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php b/tests/Tests/ORM/Mapping/EntityListenerResolverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/EntityListenerResolverTest.php rename to tests/Tests/ORM/Mapping/EntityListenerResolverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/FieldBuilderTest.php b/tests/Tests/ORM/Mapping/FieldBuilderTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/FieldBuilderTest.php rename to tests/Tests/ORM/Mapping/FieldBuilderTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/Fixtures/AttributeEntityWithNestedJoinColumns.php b/tests/Tests/ORM/Mapping/Fixtures/AttributeEntityWithNestedJoinColumns.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/Fixtures/AttributeEntityWithNestedJoinColumns.php rename to tests/Tests/ORM/Mapping/Fixtures/AttributeEntityWithNestedJoinColumns.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/MappingDriverTestCase.php b/tests/Tests/ORM/Mapping/MappingDriverTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/MappingDriverTestCase.php rename to tests/Tests/ORM/Mapping/MappingDriverTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/NamingStrategy/JoinColumnClassNamingStrategy.php b/tests/Tests/ORM/Mapping/NamingStrategy/JoinColumnClassNamingStrategy.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/NamingStrategy/JoinColumnClassNamingStrategy.php rename to tests/Tests/ORM/Mapping/NamingStrategy/JoinColumnClassNamingStrategy.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php b/tests/Tests/ORM/Mapping/NamingStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/NamingStrategyTest.php rename to tests/Tests/ORM/Mapping/NamingStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/PHPMappingDriverTest.php b/tests/Tests/ORM/Mapping/PHPMappingDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/PHPMappingDriverTest.php rename to tests/Tests/ORM/Mapping/PHPMappingDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/QuoteStrategyTest.php b/tests/Tests/ORM/Mapping/QuoteStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/QuoteStrategyTest.php rename to tests/Tests/ORM/Mapping/QuoteStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/Reflection/ReflectionPropertiesGetterTest.php b/tests/Tests/ORM/Mapping/Reflection/ReflectionPropertiesGetterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/Reflection/ReflectionPropertiesGetterTest.php rename to tests/Tests/ORM/Mapping/Reflection/ReflectionPropertiesGetterTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ReflectionEmbeddedPropertyTest.php b/tests/Tests/ORM/Mapping/ReflectionEmbeddedPropertyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ReflectionEmbeddedPropertyTest.php rename to tests/Tests/ORM/Mapping/ReflectionEmbeddedPropertyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/ReflectionReadonlyPropertyTest.php b/tests/Tests/ORM/Mapping/ReflectionReadonlyPropertyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/ReflectionReadonlyPropertyTest.php rename to tests/Tests/ORM/Mapping/ReflectionReadonlyPropertyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php b/tests/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php rename to tests/Tests/ORM/Mapping/StaticPHPMappingDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/Symfony/DriverTestCase.php b/tests/Tests/ORM/Mapping/Symfony/DriverTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/Symfony/DriverTestCase.php rename to tests/Tests/ORM/Mapping/Symfony/DriverTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php b/tests/Tests/ORM/Mapping/Symfony/XmlDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/Symfony/XmlDriverTest.php rename to tests/Tests/ORM/Mapping/Symfony/XmlDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/Symfony/YamlDriverTest.php b/tests/Tests/ORM/Mapping/Symfony/YamlDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/Symfony/YamlDriverTest.php rename to tests/Tests/ORM/Mapping/Symfony/YamlDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/TypedFieldMapper/CustomIntAsStringTypedFieldMapper.php b/tests/Tests/ORM/Mapping/TypedFieldMapper/CustomIntAsStringTypedFieldMapper.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/TypedFieldMapper/CustomIntAsStringTypedFieldMapper.php rename to tests/Tests/ORM/Mapping/TypedFieldMapper/CustomIntAsStringTypedFieldMapper.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/TypedFieldMapperTest.php b/tests/Tests/ORM/Mapping/TypedFieldMapperTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/TypedFieldMapperTest.php rename to tests/Tests/ORM/Mapping/TypedFieldMapperTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/UnderscoreNamingStrategyTest.php b/tests/Tests/ORM/Mapping/UnderscoreNamingStrategyTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/UnderscoreNamingStrategyTest.php rename to tests/Tests/ORM/Mapping/UnderscoreNamingStrategyTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php b/tests/Tests/ORM/Mapping/XmlMappingDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php rename to tests/Tests/ORM/Mapping/XmlMappingDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php b/tests/Tests/ORM/Mapping/YamlMappingDriverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/YamlMappingDriverTest.php rename to tests/Tests/ORM/Mapping/YamlMappingDriverTest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsAddress.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsUser.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsUser.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsUser.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.CMS.CmsUser.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Cache.City.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Cache.City.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Cache.City.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Cache.City.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFixContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyPerson.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyPerson.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyPerson.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Company.CompanyPerson.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579Admin.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579Admin.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579Admin.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579Admin.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579User.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579User.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579User.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC3579.DDC3579User.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC5934.DDC5934Contract.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC869.DDC869Payment.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Class.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Class.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Class.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Class.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Entity.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Entity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Entity.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889Entity.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889SuperClass.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889SuperClass.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889SuperClass.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC889.DDC889SuperClass.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Admin.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964Guest.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.DDC964.DDC964User.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Enums.Card.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Enums.Card.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Enums.Card.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Enums.Card.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTyped.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTyped.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTyped.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTyped.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Insertable.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Insertable.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Insertable.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Insertable.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Updatable.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Updatable.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Updatable.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.Models.Upsertable.Updatable.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Animal.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Animal.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Animal.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Animal.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Comment.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Comment.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Comment.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.Comment.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC1170Entity.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC1170Entity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC1170Entity.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC1170Entity.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC807Entity.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC807Entity.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC807Entity.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.DDC807Entity.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.PHPSLC.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.PHPSLC.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.PHPSLC.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.PHPSLC.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php b/tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php rename to tests/Tests/ORM/Mapping/php/Doctrine.Tests.ORM.Mapping.User.php diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/CatNoId.dcm.xml b/tests/Tests/ORM/Mapping/xml/CatNoId.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/CatNoId.dcm.xml rename to tests/Tests/ORM/Mapping/xml/CatNoId.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml b/tests/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml rename to tests/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml b/tests/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml rename to tests/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Cache.City.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Cache.City.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Cache.City.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Cache.City.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyContract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293Address.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293Address.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293Address.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293Address.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293User.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293User.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293User.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293User.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293UserPrefixed.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293UserPrefixed.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293UserPrefixed.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3293.DDC3293UserPrefixed.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Enums.Card.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Enums.Card.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Enums.Card.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Enums.Card.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7141.GH7141Article.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7141.GH7141Article.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7141.GH7141Article.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7141.GH7141Article.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7316.GH7316Article.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7316.GH7316Article.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7316.GH7316Article.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.GH7316.GH7316Article.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.Project.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.Project.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.Project.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.Project.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.ProjectInvalidMapping.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.ProjectInvalidMapping.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.ProjectInvalidMapping.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Project.ProjectInvalidMapping.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Name.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Name.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Name.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Name.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Person.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Person.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Person.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.ValueObjects.Person.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Comment.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Comment.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Comment.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Comment.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectAttributes.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectAttributes.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectAttributes.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectAttributes.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserMissingAttributes.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserMissingAttributes.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserMissingAttributes.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.UserMissingAttributes.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml b/tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml rename to tests/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.XMLSLC.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsUser.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsUser.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsUser.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.CMS.CmsUser.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Cache.City.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Cache.City.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Cache.City.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Cache.City.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyContract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFixContract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexContract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyFlexUltraContract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC1476.DDC1476EntityWithDefaultFieldType.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.ExplicitSchemaAndTable.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC2825.SchemaAndTableInTableName.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579Admin.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3579.DDC3579User.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityA.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityA.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityA.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityA.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityB.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityB.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityB.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC3711.DDC3711EntityB.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934BaseContract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC5934.DDC5934Contract.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869ChequePayment.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869CreditCardPayment.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC869.DDC869Payment.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Class.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889Entity.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC889.DDC889SuperClass.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Admin.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964Guest.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DDC964.DDC964User.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.AbstractContentItem.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.AbstractContentItem.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.AbstractContentItem.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.AbstractContentItem.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.Directory.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.Directory.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.Directory.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.Directory.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.File.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.File.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.File.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.DirectoryTree.File.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Enums.Card.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Enums.Card.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Enums.Card.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Enums.Card.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Generic.BooleanModel.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTyped.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.TypedProperties.UserTypedWithCustomTypedField.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Insertable.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.Models.Upsertable.Updatable.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Animal.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Animal.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Animal.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Animal.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Comment.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Comment.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Comment.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.Comment.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC1170Entity.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC2069Entity.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC2069Entity.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC2069Entity.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC2069Entity.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.GH10288EnumTypePerson.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.ReservedWordInTableColumn.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityIncompleteDiscriminatorColumnMapping.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.SingleTableEntityNoDiscriminatorColumnMapping.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.User.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectIndex.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.yml b/tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.yml rename to tests/Tests/ORM/Mapping/yaml/Doctrine.Tests.ORM.Mapping.UserIncorrectUniqueConstraint.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/ORMInvalidArgumentExceptionTest.php b/tests/Tests/ORM/ORMInvalidArgumentExceptionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/ORMInvalidArgumentExceptionTest.php rename to tests/Tests/ORM/ORMInvalidArgumentExceptionTest.php diff --git a/tests/Doctrine/Tests/ORM/ORMSetupTest.php b/tests/Tests/ORM/ORMSetupTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/ORMSetupTest.php rename to tests/Tests/ORM/ORMSetupTest.php diff --git a/tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php b/tests/Tests/ORM/Performance/SecondLevelCacheTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Performance/SecondLevelCacheTest.php rename to tests/Tests/ORM/Performance/SecondLevelCacheTest.php diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Tests/ORM/PersistentCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/PersistentCollectionTest.php rename to tests/Tests/ORM/PersistentCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeParametersTest.php b/tests/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeParametersTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeParametersTest.php rename to tests/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeParametersTest.php diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeSqlTest.php b/tests/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeSqlTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeSqlTest.php rename to tests/Tests/ORM/Persisters/BasicEntityPersisterCompositeTypeSqlTest.php diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php b/tests/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php rename to tests/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php diff --git a/tests/Doctrine/Tests/ORM/Persisters/Exception/UnrecognizedFieldTest.php b/tests/Tests/ORM/Persisters/Exception/UnrecognizedFieldTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Persisters/Exception/UnrecognizedFieldTest.php rename to tests/Tests/ORM/Persisters/Exception/UnrecognizedFieldTest.php diff --git a/tests/Doctrine/Tests/ORM/Persisters/ManyToManyPersisterTest.php b/tests/Tests/ORM/Persisters/ManyToManyPersisterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Persisters/ManyToManyPersisterTest.php rename to tests/Tests/ORM/Persisters/ManyToManyPersisterTest.php diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Tests/ORM/Proxy/ProxyFactoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php rename to tests/Tests/ORM/Proxy/ProxyFactoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/AST/InExpressionTest.php b/tests/Tests/ORM/Query/AST/InExpressionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/AST/InExpressionTest.php rename to tests/Tests/ORM/Query/AST/InExpressionTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/CustomTreeWalkersJoinTest.php b/tests/Tests/ORM/Query/CustomTreeWalkersJoinTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/CustomTreeWalkersJoinTest.php rename to tests/Tests/ORM/Query/CustomTreeWalkersJoinTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/CustomTreeWalkersTest.php b/tests/Tests/ORM/Query/CustomTreeWalkersTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/CustomTreeWalkersTest.php rename to tests/Tests/ORM/Query/CustomTreeWalkersTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/DeleteSqlGenerationTest.php b/tests/Tests/ORM/Query/DeleteSqlGenerationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/DeleteSqlGenerationTest.php rename to tests/Tests/ORM/Query/DeleteSqlGenerationTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/ExprTest.php b/tests/Tests/ORM/Query/ExprTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/ExprTest.php rename to tests/Tests/ORM/Query/ExprTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/FilterCollectionTest.php b/tests/Tests/ORM/Query/FilterCollectionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/FilterCollectionTest.php rename to tests/Tests/ORM/Query/FilterCollectionTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php b/tests/Tests/ORM/Query/LanguageRecognitionTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php rename to tests/Tests/ORM/Query/LanguageRecognitionTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/LexerTest.php b/tests/Tests/ORM/Query/LexerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/LexerTest.php rename to tests/Tests/ORM/Query/LexerTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/ParameterTypeInfererTest.php b/tests/Tests/ORM/Query/ParameterTypeInfererTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/ParameterTypeInfererTest.php rename to tests/Tests/ORM/Query/ParameterTypeInfererTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/ParserResultTest.php b/tests/Tests/ORM/Query/ParserResultTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/ParserResultTest.php rename to tests/Tests/ORM/Query/ParserResultTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/ParserTest.php b/tests/Tests/ORM/Query/ParserTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/ParserTest.php rename to tests/Tests/ORM/Query/ParserTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/QueryExpressionVisitorTest.php b/tests/Tests/ORM/Query/QueryExpressionVisitorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/QueryExpressionVisitorTest.php rename to tests/Tests/ORM/Query/QueryExpressionVisitorTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Tests/ORM/Query/QueryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/QueryTest.php rename to tests/Tests/ORM/Query/QueryTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Tests/ORM/Query/SelectSqlGenerationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php rename to tests/Tests/ORM/Query/SelectSqlGenerationTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/SqlExpressionVisitorTest.php b/tests/Tests/ORM/Query/SqlExpressionVisitorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/SqlExpressionVisitorTest.php rename to tests/Tests/ORM/Query/SqlExpressionVisitorTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/SqlWalkerTest.php b/tests/Tests/ORM/Query/SqlWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/SqlWalkerTest.php rename to tests/Tests/ORM/Query/SqlWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/TreeWalkerAdapterTest.php b/tests/Tests/ORM/Query/TreeWalkerAdapterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/TreeWalkerAdapterTest.php rename to tests/Tests/ORM/Query/TreeWalkerAdapterTest.php diff --git a/tests/Doctrine/Tests/ORM/Query/UpdateSqlGenerationTest.php b/tests/Tests/ORM/Query/UpdateSqlGenerationTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Query/UpdateSqlGenerationTest.php rename to tests/Tests/ORM/Query/UpdateSqlGenerationTest.php diff --git a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php b/tests/Tests/ORM/QueryBuilderTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/QueryBuilderTest.php rename to tests/Tests/ORM/QueryBuilderTest.php diff --git a/tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php b/tests/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php rename to tests/Tests/ORM/Repository/DefaultRepositoryFactoryTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/AttachEntityListenersListenerTest.php b/tests/Tests/ORM/Tools/AttachEntityListenersListenerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/AttachEntityListenersListenerTest.php rename to tests/Tests/ORM/Tools/AttachEntityListenersListenerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/ClearCacheCollectionRegionCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/ClearCacheEntityRegionCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/ClearCacheQueryRegionCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/EnsureProductionSettingsCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/EnsureProductionSettingsCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/EnsureProductionSettingsCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/EnsureProductionSettingsCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/GenerateRepositoriesCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/InfoCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/InfoCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/InfoCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/MappingDescribeCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/MappingDescribeCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/MappingDescribeCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/MappingDescribeCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/RunDqlCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php rename to tests/Tests/ORM/Tools/Console/Command/SchemaTool/CommandTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/CreateCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/CreateCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/CreateCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/SchemaTool/CreateCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/DropCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/DropCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/DropCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/SchemaTool/DropCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/Models/Keyboard.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/Models/Keyboard.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/Models/Keyboard.php rename to tests/Tests/ORM/Tools/Console/Command/SchemaTool/Models/Keyboard.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/UpdateCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/SchemaTool/UpdateCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/SchemaTool/UpdateCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/SchemaTool/UpdateCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/Command/ValidateSchemaCommandTest.php b/tests/Tests/ORM/Tools/Console/Command/ValidateSchemaCommandTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/Command/ValidateSchemaCommandTest.php rename to tests/Tests/ORM/Tools/Console/Command/ValidateSchemaCommandTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/ConsoleRunnerTest.php b/tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/ConsoleRunnerTest.php rename to tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Console/MetadataFilterTest.php b/tests/Tests/ORM/Tools/Console/MetadataFilterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Console/MetadataFilterTest.php rename to tests/Tests/ORM/Tools/Console/MetadataFilterTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php b/tests/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php rename to tests/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/DebugTest.php b/tests/Tests/ORM/Tools/DebugTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/DebugTest.php rename to tests/Tests/ORM/Tools/DebugTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Tests/ORM/Tools/EntityGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php rename to tests/Tests/ORM/Tools/EntityGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityRepositoryGeneratorTest.php b/tests/Tests/ORM/Tools/EntityRepositoryGeneratorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/EntityRepositoryGeneratorTest.php rename to tests/Tests/ORM/Tools/EntityRepositoryGeneratorTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/AnnotationClassMetadataExporterTest.php b/tests/Tests/ORM/Tools/Export/AnnotationClassMetadataExporterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/AnnotationClassMetadataExporterTest.php rename to tests/Tests/ORM/Tools/Export/AnnotationClassMetadataExporterTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/ClassMetadataExporterTestCase.php b/tests/Tests/ORM/Tools/Export/ClassMetadataExporterTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/ClassMetadataExporterTestCase.php rename to tests/Tests/ORM/Tools/Export/ClassMetadataExporterTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/PhpClassMetadataExporterTest.php b/tests/Tests/ORM/Tools/Export/PhpClassMetadataExporterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/PhpClassMetadataExporterTest.php rename to tests/Tests/ORM/Tools/Export/PhpClassMetadataExporterTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/XmlClassMetadataExporterTest.php b/tests/Tests/ORM/Tools/Export/XmlClassMetadataExporterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/XmlClassMetadataExporterTest.php rename to tests/Tests/ORM/Tools/Export/XmlClassMetadataExporterTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/YamlClassMetadataExporterTest.php b/tests/Tests/ORM/Tools/Export/YamlClassMetadataExporterTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/YamlClassMetadataExporterTest.php rename to tests/Tests/ORM/Tools/Export/YamlClassMetadataExporterTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php b/tests/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php rename to tests/Tests/ORM/Tools/Export/annotation/Doctrine.Tests.ORM.Tools.Export.User.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/php/Doctrine.Tests.ORM.Tools.Export.User.php b/tests/Tests/ORM/Tools/Export/php/Doctrine.Tests.ORM.Tools.Export.User.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/php/Doctrine.Tests.ORM.Tools.Export.User.php rename to tests/Tests/ORM/Tools/Export/php/Doctrine.Tests.ORM.Tools.Export.User.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/xml/Doctrine.Tests.ORM.Tools.Export.User.dcm.xml b/tests/Tests/ORM/Tools/Export/xml/Doctrine.Tests.ORM.Tools.Export.User.dcm.xml similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/xml/Doctrine.Tests.ORM.Tools.Export.User.dcm.xml rename to tests/Tests/ORM/Tools/Export/xml/Doctrine.Tests.ORM.Tools.Export.User.dcm.xml diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/yaml/Doctrine.Tests.ORM.Tools.Export.User.dcm.yml b/tests/Tests/ORM/Tools/Export/yaml/Doctrine.Tests.ORM.Tools.Export.User.dcm.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Export/yaml/Doctrine.Tests.ORM.Tools.Export.User.dcm.yml rename to tests/Tests/ORM/Tools/Export/yaml/Doctrine.Tests.ORM.Tools.Export.User.dcm.yml diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/CountOutputWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/CountWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/CountWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/CountWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/LimitSubqueryWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginationTestCase.php b/tests/Tests/ORM/Tools/Pagination/PaginationTestCase.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/PaginationTestCase.php rename to tests/Tests/ORM/Tools/Pagination/PaginationTestCase.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php b/tests/Tests/ORM/Tools/Pagination/PaginatorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/PaginatorTest.php rename to tests/Tests/ORM/Tools/Pagination/PaginatorTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/RootTypeWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/RootTypeWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/RootTypeWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/RootTypeWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php b/tests/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php rename to tests/Tests/ORM/Tools/Pagination/WhereInWalkerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/ResolveTargetEntityListenerTest.php b/tests/Tests/ORM/Tools/ResolveTargetEntityListenerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/ResolveTargetEntityListenerTest.php rename to tests/Tests/ORM/Tools/ResolveTargetEntityListenerTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php b/tests/Tests/ORM/Tools/SchemaToolTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/SchemaToolTest.php rename to tests/Tests/ORM/Tools/SchemaToolTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/SchemaValidatorTest.php b/tests/Tests/ORM/Tools/SchemaValidatorTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/SchemaValidatorTest.php rename to tests/Tests/ORM/Tools/SchemaValidatorTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/SetupTest.php b/tests/Tests/ORM/Tools/SetupTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/SetupTest.php rename to tests/Tests/ORM/Tools/SetupTest.php diff --git a/tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php b/tests/Tests/ORM/Tools/TestAsset/ChildClass.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildClass.php rename to tests/Tests/ORM/Tools/TestAsset/ChildClass.php diff --git a/tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php b/tests/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php rename to tests/Tests/ORM/Tools/TestAsset/ChildWithSameAttributesClass.php diff --git a/tests/Doctrine/Tests/ORM/Tools/TestAsset/ParentClass.php b/tests/Tests/ORM/Tools/TestAsset/ParentClass.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/TestAsset/ParentClass.php rename to tests/Tests/ORM/Tools/TestAsset/ParentClass.php diff --git a/tests/Doctrine/Tests/ORM/Tools/doctrine1schema/schema.yml b/tests/Tests/ORM/Tools/doctrine1schema/schema.yml similarity index 100% rename from tests/Doctrine/Tests/ORM/Tools/doctrine1schema/schema.yml rename to tests/Tests/ORM/Tools/doctrine1schema/schema.yml diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Tests/ORM/UnitOfWorkTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/UnitOfWorkTest.php rename to tests/Tests/ORM/UnitOfWorkTest.php diff --git a/tests/Doctrine/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php b/tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php rename to tests/Tests/ORM/Utility/HierarchyDiscriminatorResolverTest.php diff --git a/tests/Doctrine/Tests/ORM/Utility/IdentifierFlattenerEnumIdTest.php b/tests/Tests/ORM/Utility/IdentifierFlattenerEnumIdTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Utility/IdentifierFlattenerEnumIdTest.php rename to tests/Tests/ORM/Utility/IdentifierFlattenerEnumIdTest.php diff --git a/tests/Doctrine/Tests/ORM/Utility/IdentifierFlattenerTest.php b/tests/Tests/ORM/Utility/IdentifierFlattenerTest.php similarity index 100% rename from tests/Doctrine/Tests/ORM/Utility/IdentifierFlattenerTest.php rename to tests/Tests/ORM/Utility/IdentifierFlattenerTest.php diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Tests/OrmFunctionalTestCase.php similarity index 100% rename from tests/Doctrine/Tests/OrmFunctionalTestCase.php rename to tests/Tests/OrmFunctionalTestCase.php diff --git a/tests/Doctrine/Tests/OrmTestCase.php b/tests/Tests/OrmTestCase.php similarity index 100% rename from tests/Doctrine/Tests/OrmTestCase.php rename to tests/Tests/OrmTestCase.php diff --git a/tests/Doctrine/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php b/tests/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php similarity index 100% rename from tests/Doctrine/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php rename to tests/Tests/PHPUnitCompatibility/MockBuilderCompatibilityTools.php diff --git a/tests/Doctrine/Tests/TestInit.php b/tests/Tests/TestInit.php similarity index 79% rename from tests/Doctrine/Tests/TestInit.php rename to tests/Tests/TestInit.php index 2cfe1761b0d..eb2db606747 100644 --- a/tests/Doctrine/Tests/TestInit.php +++ b/tests/Tests/TestInit.php @@ -21,12 +21,12 @@ error_reporting(E_ALL | E_STRICT); date_default_timezone_set('UTC'); -if (file_exists(__DIR__ . '/../../../vendor/autoload.php')) { +if (file_exists(__DIR__ . '/../../vendor/autoload.php')) { // dependencies were installed via composer - this is the main project - require __DIR__ . '/../../../vendor/autoload.php'; -} elseif (file_exists(__DIR__ . '/../../../../../autoload.php')) { + require __DIR__ . '/../../vendor/autoload.php'; +} elseif (file_exists(__DIR__ . '/../../../../autoload.php')) { // installed as a dependency in `vendor` - require __DIR__ . '/../../../../../autoload.php'; + require __DIR__ . '/../../../../autoload.php'; } else { throw new Exception('Can\'t find autoload.php. Did you install dependencies via composer?'); } diff --git a/tests/Doctrine/Tests/TestUtil.php b/tests/Tests/TestUtil.php similarity index 100% rename from tests/Doctrine/Tests/TestUtil.php rename to tests/Tests/TestUtil.php From e585a92763612455f591b44cf0482d9852cc5fc0 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Tue, 2 Jan 2024 21:31:28 +0100 Subject: [PATCH 064/128] Mention that ``postRemove`` may still see removed entities in in-memory collections (#11146) ... plus minor tweaks. --- docs/en/reference/events.rst | 47 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index 40dea522329..19332ee9f37 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -173,6 +173,19 @@ Events Overview | :ref:`onClear` | ``$em->clear()`` | No | `OnClearEventArgs`_ | +-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +.. warning:: + + Making changes to entities and calling ``EntityManager::flush()`` from within + event handlers dispatched by ``EntityManager::flush()`` itself is strongly + discouraged, and might be deprecated and eventually prevented in the future. + + The reason is that it causes re-entrance into ``UnitOfWork::commit()`` while a commit + is currently being processed. The ``UnitOfWork`` was never designed to support this, + and its behavior in this situation is not covered by any tests. + + This may lead to entity or collection updates being missed, applied only in parts and + changes being lost at the end of the commit phase. + Naming convention ~~~~~~~~~~~~~~~~~ @@ -699,30 +712,33 @@ Restrictions for this event: postUpdate, postRemove, postPersist ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These three post* events are called inside ``EntityManager::flush()``. +These three ``post*`` events are called inside ``EntityManager::flush()``. Changes in here are not relevant to the persistence in the database, but you can use these events to alter non-persistable items, like non-mapped fields, logging or even associated classes that are not directly mapped by Doctrine. - The ``postUpdate`` event occurs after the database - update operations to entity data. It is not called for a DQL - ``UPDATE`` statement. + update operations to entity data, but before the database transaction + has been committed. It is not called for a DQL ``UPDATE`` statement. - The ``postPersist`` event occurs for an entity after the entity has been made persistent. It will be invoked after all database insert - operations for new entities have been performed. Generated primary - key values will be available for all entities at the time this - event is triggered. + operations for new entities have been performed, but before the database + transaction has been committed. Generated primary key values will be + available for all entities at the time this event is triggered. - The ``postRemove`` event occurs for an entity after the entity has been deleted. It will be invoked after all database - delete operations for entity rows have been executed. This event is - not called for a DQL ``DELETE`` statement. + delete operations for entity rows have been executed, but before the + database transaction has been committed. This event is not called for + a DQL ``DELETE`` statement. .. note:: At the time ``postPersist`` is called, there may still be collection and/or "extra" updates pending. The database may not yet be completely in - sync with the entity states in memory, not even for the new entities. + sync with the entity states in memory, not even for the new entities. Similarly, + also at the time ``postUpdate`` and ``postRemove`` are called, in-memory collections + may still be in a "dirty" state or still contain removed entities. .. warning:: @@ -731,19 +747,6 @@ not directly mapped by Doctrine. cascade remove relations. In this case, you should load yourself the proxy in the associated ``pre*`` event. -.. warning:: - - Making changes to entities and calling ``EntityManager::flush()`` from within - ``post*`` event handlers is strongly discouraged, and might be deprecated and - eventually prevented in the future. - - The reason is that it causes re-entrance into ``UnitOfWork::commit()`` while a commit - is currently being processed. The ``UnitOfWork`` was never designed to support this, - and its behavior in this situation is not covered by any tests. - - This may lead to entity or collection updates being missed, applied only in parts and - changes being lost at the end of the commit phase. - .. _reference-events-post-load: postLoad From c6b3509aa909f5116ef27c48aaadc13e14cbe37c Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 12 Jan 2024 22:44:07 +0100 Subject: [PATCH 065/128] Include `ON DELETE CASCADE` associations in the delete order computation (#10913) In order to resolve #10348, some changes were included in #10547 to improve the computed _delete_ order for entities. One assumption was that foreign key references with `ON DELETE SET NULL` or `... CASCADE` need not need to be taken into consideration when planning the deletion order, since the RDBMS would unset or cascade-delete such associations by itself when necessary. Only associations that do _not_ use RDBMS-level cascade handling would be sequenced, to make sure the referring entity is deleted before the referred-to one. This assumption is wrong for `ON DELETE CASCADE`. The following examples give reasons why we need to also consider such associations, and in addition, we need to be able to deal with cycles formed by them. In the following diagrams, `odc` means `ON DELETE CASCADE`, and `ref` is a regular foreign key with no extra `ON DELETE` semantics. ```mermaid graph LR; C-->|ref| B; B-->|odc| A; ``` In this example, C must be removed before B and A. If we ignore the B->A dependency in the delete order computation, the result may not to be correct. ACB is not a working solution. ```mermaid graph LR; A-->|odc| B; B-->|odc| A; C-->|ref| B; ``` This is the situation in #10912. We have to deal with a cycle in the graph. C must be removed before A as well as B. If we ignore the B->A dependency (e.g. because we set it to "optional" to get away with the cycle), we might end up with an incorrect order ACB. ```mermaid graph LR; A-->|odc| B; B-->|odc| A; A-->|ref| C; C-->|ref| B; ``` This example has no possible remove order. But, if we treat `odc` edges as optional, A -> C -> B would wrongly be deemed suitable. ```mermaid graph LR; A-->|ref| B; B-->|odc| C; C-->|odc| B; D-->|ref| C; ``` Here, we must first remove A and D in any order; then, B and C in any order. If we treat one of the `odc` edges as optional, we might find the invalid solutions ABDC or DCAB. #### Solution implemented in this PR First, build a graph with a node for every to-be-removed entity, and edges for `ON DELETE CASCADE` associations between those entities. Then, use [Tarjan's algorithm](https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm) to find strongly connected components (SCCs) in this graph. The significance of SCCs is that whenever we remove one of the entities in a SCC from the database (no matter which one), the DBMS will immediately remove _all_ the other entities of that group as well. For every SCC, pick one (arbitrary) entity from the group to represent all entities of that group. Then, build a second graph. Again we have nodes for all entities that are to be removed. This time, we insert edges for all regular (foreign key) associations and those with `ON DELETE CASCADE`. `ON DELETE SET NULL` can be left out. The edges are not added between the entities themselves, but between the entities representing the respective SCCs. Also, for all non-trivial SCCs (those containing more than a single entity), add dependency edges to indicate that all entities of the SCC shall be processed _after_ the entity representing the group. This is to make sure we do not remove a SCC inadvertedly by removing one of its entities too early. Run a topological sort on the second graph to get the actual delete order. Cycles in this second graph are a problem, there is no delete order. Fixes #10912. --- .../Internal/StronglyConnectedComponents.php | 170 ++++++++++++++++++ lib/Doctrine/ORM/UnitOfWork.php | 82 +++++++-- .../ORM/Functional/Ticket/GH10912Test.php | 165 +++++++++++++++++ .../ORM/Functional/Ticket/GH10913Test.php | 167 +++++++++++++++++ .../StronglyConnectedComponentsTest.php | 113 ++++++++++++ 5 files changed, 687 insertions(+), 10 deletions(-) create mode 100644 lib/Doctrine/ORM/Internal/StronglyConnectedComponents.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10912Test.php create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10913Test.php create mode 100644 tests/Doctrine/Tests/ORM/Internal/StronglyConnectedComponentsTest.php diff --git a/lib/Doctrine/ORM/Internal/StronglyConnectedComponents.php b/lib/Doctrine/ORM/Internal/StronglyConnectedComponents.php new file mode 100644 index 00000000000..0e184c30fc6 --- /dev/null +++ b/lib/Doctrine/ORM/Internal/StronglyConnectedComponents.php @@ -0,0 +1,170 @@ + + */ + private $nodes = []; + + /** + * DFS state for the different nodes, indexed by node object id and using one of + * this class' constants as value. + * + * @var array + */ + private $states = []; + + /** + * Edges between the nodes. The first-level key is the object id of the outgoing + * node; the second array maps the destination node by object id as key. + * + * @var array> + */ + private $edges = []; + + /** + * DFS numbers, by object ID + * + * @var array + */ + private $dfs = []; + + /** + * lowlink numbers, by object ID + * + * @var array + */ + private $lowlink = []; + + /** @var int */ + private $maxdfs = 0; + + /** + * Nodes representing the SCC another node is in, indexed by lookup-node object ID + * + * @var array + */ + private $representingNodes = []; + + /** + * Stack with OIDs of nodes visited in the current state of the DFS + * + * @var list + */ + private $stack = []; + + /** @param object $node */ + public function addNode($node): void + { + $id = spl_object_id($node); + $this->nodes[$id] = $node; + $this->states[$id] = self::NOT_VISITED; + $this->edges[$id] = []; + } + + /** @param object $node */ + public function hasNode($node): bool + { + return isset($this->nodes[spl_object_id($node)]); + } + + /** + * Adds a new edge between two nodes to the graph + * + * @param object $from + * @param object $to + */ + public function addEdge($from, $to): void + { + $fromId = spl_object_id($from); + $toId = spl_object_id($to); + + $this->edges[$fromId][$toId] = true; + } + + public function findStronglyConnectedComponents(): void + { + foreach (array_keys($this->nodes) as $oid) { + if ($this->states[$oid] === self::NOT_VISITED) { + $this->tarjan($oid); + } + } + } + + private function tarjan(int $oid): void + { + $this->dfs[$oid] = $this->lowlink[$oid] = $this->maxdfs++; + $this->states[$oid] = self::IN_PROGRESS; + array_push($this->stack, $oid); + + foreach ($this->edges[$oid] as $adjacentId => $ignored) { + if ($this->states[$adjacentId] === self::NOT_VISITED) { + $this->tarjan($adjacentId); + $this->lowlink[$oid] = min($this->lowlink[$oid], $this->lowlink[$adjacentId]); + } elseif ($this->states[$adjacentId] === self::IN_PROGRESS) { + $this->lowlink[$oid] = min($this->lowlink[$oid], $this->dfs[$adjacentId]); + } + } + + $lowlink = $this->lowlink[$oid]; + if ($lowlink === $this->dfs[$oid]) { + $representingNode = null; + do { + $unwindOid = array_pop($this->stack); + + if (! $representingNode) { + $representingNode = $this->nodes[$unwindOid]; + } + + $this->representingNodes[$unwindOid] = $representingNode; + $this->states[$unwindOid] = self::VISITED; + } while ($unwindOid !== $oid); + } + } + + /** + * @param object $node + * + * @return object + */ + public function getNodeRepresentingStronglyConnectedComponent($node) + { + $oid = spl_object_id($node); + + if (! isset($this->representingNodes[$oid])) { + throw new InvalidArgumentException('unknown node'); + } + + return $this->representingNodes[$oid]; + } +} diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 3b875f2afe1..00698e56c60 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -28,6 +28,7 @@ use Doctrine\ORM\Exception\UnexpectedAssociationValue; use Doctrine\ORM\Id\AssignedGenerator; use Doctrine\ORM\Internal\HydrationCompleteHandler; +use Doctrine\ORM\Internal\StronglyConnectedComponents; use Doctrine\ORM\Internal\TopologicalSort; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; @@ -1391,14 +1392,19 @@ private function computeInsertExecutionOrder(): array /** @return list */ private function computeDeleteExecutionOrder(): array { - $sort = new TopologicalSort(); + $stronglyConnectedComponents = new StronglyConnectedComponents(); + $sort = new TopologicalSort(); - // First make sure we have all the nodes foreach ($this->entityDeletions as $entity) { + $stronglyConnectedComponents->addNode($entity); $sort->addNode($entity); } - // Now add edges + // First, consider only "on delete cascade" associations between entities + // and find strongly connected groups. Once we delete any one of the entities + // in such a group, _all_ of the other entities will be removed as well. So, + // we need to treat those groups like a single entity when performing delete + // order topological sorting. foreach ($this->entityDeletions as $entity) { $class = $this->em->getClassMetadata(get_class($entity)); @@ -1410,16 +1416,65 @@ private function computeDeleteExecutionOrder(): array continue; } - // For associations that implement a database-level cascade/set null operation, + assert(isset($assoc['joinColumns'])); + $joinColumns = reset($assoc['joinColumns']); + if (! isset($joinColumns['onDelete'])) { + continue; + } + + $onDeleteOption = strtolower($joinColumns['onDelete']); + if ($onDeleteOption !== 'cascade') { + continue; + } + + $targetEntity = $class->getFieldValue($entity, $assoc['fieldName']); + + // If the association does not refer to another entity or that entity + // is not to be deleted, there is no ordering problem and we can + // skip this particular association. + if ($targetEntity === null || ! $stronglyConnectedComponents->hasNode($targetEntity)) { + continue; + } + + $stronglyConnectedComponents->addEdge($entity, $targetEntity); + } + } + + $stronglyConnectedComponents->findStronglyConnectedComponents(); + + // Now do the actual topological sorting to find the delete order. + foreach ($this->entityDeletions as $entity) { + $class = $this->em->getClassMetadata(get_class($entity)); + + // Get the entities representing the SCC + $entityComponent = $stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($entity); + + // When $entity is part of a non-trivial strongly connected component group + // (a group containing not only those entities alone), make sure we process it _after_ the + // entity representing the group. + // The dependency direction implies that "$entity depends on $entityComponent + // being deleted first". The topological sort will output the depended-upon nodes first. + if ($entityComponent !== $entity) { + $sort->addEdge($entity, $entityComponent, false); + } + + foreach ($class->associationMappings as $assoc) { + // We only need to consider the owning sides of to-one associations, + // since many-to-many associations can always be (and have already been) + // deleted in a preceding step. + if (! ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE)) { + continue; + } + + // For associations that implement a database-level set null operation, // we do not have to follow a particular order: If the referred-to entity is - // deleted first, the DBMS will either delete the current $entity right away - // (CASCADE) or temporarily set the foreign key to NULL (SET NULL). - // Either way, we can skip it in the computation. + // deleted first, the DBMS will temporarily set the foreign key to NULL (SET NULL). + // So, we can skip it in the computation. assert(isset($assoc['joinColumns'])); $joinColumns = reset($assoc['joinColumns']); if (isset($joinColumns['onDelete'])) { $onDeleteOption = strtolower($joinColumns['onDelete']); - if ($onDeleteOption === 'cascade' || $onDeleteOption === 'set null') { + if ($onDeleteOption === 'set null') { continue; } } @@ -1433,10 +1488,17 @@ private function computeDeleteExecutionOrder(): array continue; } - // Add dependency. The dependency direction implies that "$targetEntity depends on $entity + // Get the entities representing the SCC + $targetEntityComponent = $stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($targetEntity); + + // When we have a dependency between two different groups of strongly connected nodes, + // add it to the computation. + // The dependency direction implies that "$targetEntityComponent depends on $entityComponent // being deleted first". The topological sort will output the depended-upon nodes first, // so we can work through the result in the returned order. - $sort->addEdge($targetEntity, $entity, false); + if ($targetEntityComponent !== $entityComponent) { + $sort->addEdge($targetEntityComponent, $entityComponent, false); + } } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10912Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10912Test.php new file mode 100644 index 00000000000..b81f23f51ee --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10912Test.php @@ -0,0 +1,165 @@ +setUpEntitySchema([ + GH10912User::class, + GH10912Profile::class, + GH10912Room::class, + ]); + } + + public function testIssue(): void + { + $user = new GH10912User(); + $profile = new GH10912Profile(); + $room = new GH10912Room(); + + $user->rooms->add($room); + $user->profile = $profile; + $profile->user = $user; + $room->user = $user; + + $this->_em->persist($room); + $this->_em->persist($user); + $this->_em->persist($profile); + $this->_em->flush(); + + /* + * This issue is about finding a special deletion order: + * $user and $profile cross-reference each other with ON DELETE CASCADE. + * So, whichever one gets deleted first, the DBMS will immediately dispose + * of the other one as well. + * + * $user -> $room is the unproblematic (irrelevant) inverse side of + * a OneToMany association. + * + * $room -> $user is a not-nullable, no DBMS-level-cascade, owning side + * of ManyToOne. We *must* remove the $room _before_ the $user can be + * deleted. And remember, $user deletion happens either when we DELETE the + * user (direct deletion), or when we delete the $profile (ON DELETE CASCADE + * propagates to the user). + * + * In the original bug report, the ordering of fields in the entities was + * relevant, in combination with a cascade=persist configuration. + * + * But, for the sake of clarity, let's put these features away and create + * the problematic sequence in UnitOfWork::$entityDeletions directly: + */ + $this->_em->remove($profile); + $this->_em->remove($user); + $this->_em->remove($room); + + $queryLog = $this->getQueryLog(); + $queryLog->reset()->enable(); + + $this->_em->flush(); + + $queries = array_values(array_filter($queryLog->queries, static function (array $entry): bool { + return strpos($entry['sql'], 'DELETE') === 0; + })); + + self::assertCount(3, $queries); + + // we do not care about the order of $user vs. $profile, so do not check them. + self::assertSame('DELETE FROM GH10912Room WHERE id = ?', $queries[0]['sql'], '$room deletion is the first query'); + + // The EntityManager is aware that all three entities have been deleted (sanity check) + $im = $this->_em->getUnitOfWork()->getIdentityMap(); + self::assertEmpty($im[GH10912Profile::class]); + self::assertEmpty($im[GH10912User::class]); + self::assertEmpty($im[GH10912Room::class]); + } +} + +/** @ORM\Entity */ +class GH10912User +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\OneToMany(targetEntity=GH10912Room::class, mappedBy="user") + * + * @var Collection + */ + public $rooms; + + /** + * @ORM\OneToOne(targetEntity=GH10912Profile::class) + * @ORM\JoinColumn(onDelete="cascade") + * + * @var GH10912Profile + */ + public $profile; + + public function __construct() + { + $this->rooms = new ArrayCollection(); + } +} + +/** @ORM\Entity */ +class GH10912Profile +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\OneToOne(targetEntity=GH10912User::class) + * @ORM\JoinColumn(onDelete="cascade") + * + * @var GH10912User + */ + public $user; +} + +/** @ORM\Entity */ +class GH10912Room +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\ManyToOne(targetEntity=GH10912User::class, inversedBy="rooms") + * @ORM\JoinColumn(nullable=false) + * + * @var GH10912User + */ + public $user; +} diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10913Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10913Test.php new file mode 100644 index 00000000000..c75f7d9da7a --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10913Test.php @@ -0,0 +1,167 @@ +setUpEntitySchema([ + GH10913Entity::class, + ]); + } + + public function testExample1(): void + { + [$a, $b, $c] = $this->createEntities(3); + + $c->ref = $b; + $b->odc = $a; + + $this->_em->persist($a); + $this->_em->persist($b); + $this->_em->persist($c); + $this->_em->flush(); + + $this->_em->remove($a); + $this->_em->remove($b); + $this->_em->remove($c); + + $this->flushAndAssertNumberOfDeleteQueries(3); + } + + public function testExample2(): void + { + [$a, $b, $c] = $this->createEntities(3); + + $a->odc = $b; + $b->odc = $a; + $c->ref = $b; + + $this->_em->persist($a); + $this->_em->persist($b); + $this->_em->persist($c); + $this->_em->flush(); + + $this->_em->remove($a); + $this->_em->remove($b); + $this->_em->remove($c); + + $this->flushAndAssertNumberOfDeleteQueries(3); + } + + public function testExample3(): void + { + [$a, $b, $c] = $this->createEntities(3); + + $a->odc = $b; + $a->ref = $c; + $c->ref = $b; + $b->odc = $a; + + $this->_em->persist($a); + $this->_em->persist($b); + $this->_em->persist($c); + $this->_em->flush(); + + $this->_em->remove($a); + $this->_em->remove($b); + $this->_em->remove($c); + + self::expectException(CycleDetectedException::class); + + $this->_em->flush(); + } + + public function testExample4(): void + { + [$a, $b, $c, $d] = $this->createEntities(4); + + $a->ref = $b; + $b->odc = $c; + $c->odc = $b; + $d->ref = $c; + + $this->_em->persist($a); + $this->_em->persist($b); + $this->_em->persist($c); + $this->_em->persist($d); + $this->_em->flush(); + + $this->_em->remove($b); + $this->_em->remove($c); + $this->_em->remove($d); + $this->_em->remove($a); + + $this->flushAndAssertNumberOfDeleteQueries(4); + } + + private function flushAndAssertNumberOfDeleteQueries(int $expectedCount): void + { + $queryLog = $this->getQueryLog(); + $queryLog->reset()->enable(); + + $this->_em->flush(); + + $queries = array_values(array_filter($queryLog->queries, static function (array $entry): bool { + return strpos($entry['sql'], 'DELETE') === 0; + })); + + self::assertCount($expectedCount, $queries); + } + + /** + * @return list + */ + private function createEntities(int $count = 1): array + { + $result = []; + + for ($i = 0; $i < $count; $i++) { + $result[] = new GH10913Entity(); + } + + return $result; + } +} + +/** @ORM\Entity */ +class GH10913Entity +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + public $id; + + /** + * @ORM\ManyToOne(targetEntity=GH10913Entity::class) + * @ORM\JoinColumn(nullable=true, onDelete="CASCADE") + * + * @var GH10913Entity + */ + public $odc; + + /** + * @ORM\ManyToOne(targetEntity=GH10913Entity::class) + * @ORM\JoinColumn(nullable=true) + * + * @var GH10913Entity + */ + public $ref; +} diff --git a/tests/Doctrine/Tests/ORM/Internal/StronglyConnectedComponentsTest.php b/tests/Doctrine/Tests/ORM/Internal/StronglyConnectedComponentsTest.php new file mode 100644 index 00000000000..a2adee9dc22 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Internal/StronglyConnectedComponentsTest.php @@ -0,0 +1,113 @@ + */ + private $nodes = []; + + /** @var StronglyConnectedComponents */ + private $stronglyConnectedComponents; + + protected function setUp(): void + { + $this->stronglyConnectedComponents = new StronglyConnectedComponents(); + } + + public function testFindStronglyConnectedComponents(): void + { + // A -> B <-> C -> D <-> E + $this->addNodes('A', 'B', 'C', 'D', 'E'); + + $this->addEdge('A', 'B'); + $this->addEdge('B', 'C'); + $this->addEdge('C', 'B'); + $this->addEdge('C', 'D'); + $this->addEdge('D', 'E'); + $this->addEdge('E', 'D'); + + $this->stronglyConnectedComponents->findStronglyConnectedComponents(); + + $this->assertNodesAreInSameComponent('B', 'C'); + $this->assertNodesAreInSameComponent('D', 'E'); + $this->assertNodesAreNotInSameComponent('A', 'B'); + $this->assertNodesAreNotInSameComponent('A', 'D'); + } + + public function testFindStronglyConnectedComponents2(): void + { + // A -> B -> C -> D -> B + $this->addNodes('A', 'B', 'C', 'D'); + + $this->addEdge('A', 'B'); + $this->addEdge('B', 'C'); + $this->addEdge('C', 'D'); + $this->addEdge('D', 'B'); + + $this->stronglyConnectedComponents->findStronglyConnectedComponents(); + + $this->assertNodesAreInSameComponent('B', 'C'); + $this->assertNodesAreInSameComponent('C', 'D'); + $this->assertNodesAreNotInSameComponent('A', 'B'); + } + + public function testFindStronglyConnectedComponents3(): void + { + // v---------. + // A -> B -> C -> D -> E + // ^--------Β΄ + + $this->addNodes('A', 'B', 'C', 'D', 'E'); + + $this->addEdge('A', 'B'); + $this->addEdge('B', 'C'); + $this->addEdge('C', 'D'); + $this->addEdge('D', 'E'); + $this->addEdge('E', 'C'); + $this->addEdge('D', 'B'); + + $this->stronglyConnectedComponents->findStronglyConnectedComponents(); + + $this->assertNodesAreInSameComponent('B', 'C'); + $this->assertNodesAreInSameComponent('C', 'D'); + $this->assertNodesAreInSameComponent('D', 'E'); + $this->assertNodesAreInSameComponent('E', 'B'); + $this->assertNodesAreNotInSameComponent('A', 'B'); + } + + private function addNodes(string ...$names): void + { + foreach ($names as $name) { + $node = new Node($name); + $this->nodes[$name] = $node; + $this->stronglyConnectedComponents->addNode($node); + } + } + + private function addEdge(string $from, string $to, bool $optional = false): void + { + $this->stronglyConnectedComponents->addEdge($this->nodes[$from], $this->nodes[$to], $optional); + } + + private function assertNodesAreInSameComponent(string $first, string $second): void + { + self::assertSame( + $this->stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($this->nodes[$first]), + $this->stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($this->nodes[$second]) + ); + } + + private function assertNodesAreNotInSameComponent(string $first, string $second): void + { + self::assertNotSame( + $this->stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($this->nodes[$first]), + $this->stronglyConnectedComponents->getNodeRepresentingStronglyConnectedComponent($this->nodes[$second]) + ); + } +} From 3dd3d38857617ef1935ff9c5ec93e7959f429984 Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Fri, 12 Jan 2024 22:59:14 +0100 Subject: [PATCH 066/128] Fix `@SequenceGeneratorDefinition` inheritance, take 1 (#11050) #10927 reported that #10455 broke the way how the default `@SequenceGeneratorDefinition` is created and inherited by subclasses for ID columns using `@GeneratedValue(strategy="SEQUENCE")`. First, I had to understand how `@SequenceGeneratorDefinition` has been handled before #10455 when entity inheritance comes into play: * Entity and mapped superclasses inherit the ID generator type (as given by `@GeneratedValue`) from their parent classes * `@SequenceGeneratorDefinition`, however, is not generally inherited * ... instead, a default sequence generator definition is created for every class when no explicit configuration is given. In this case, sequence names are based on the current class' table name. * Once a root entity has been identified, all subclasses inherit its sequence generator definition unchanged. #### Why did #10455 break this? When I implemented #10455, I was mislead by two tests `BasicInheritanceMappingTest::testGeneratedValueFromMappedSuperclass` and `BasicInheritanceMappingTest::testMultipleMappedSuperclasses`. These tests check the sequence generator definition that is inherited by an entity class from a mapped superclass, either directly or through an additional (intermediate) mapped superclass. The tests expect the sequence generator definition on the entity _to be the same_ as on the base mapped superclass. The reason why the tests worked before was the quirky behaviour of the annotation and attribute drivers that #10455 was aiming at: The drivers did not report the `@SequenceGeneratorDefinition` on the base mapped superclass where it was actually defined. Instead, they reported this `@SequenceGeneratorDefinition` for the entity class only. This means the inheritance rules stated above did not take effect, since the ID field with the sequence generator was virtually pushed down to the entity class. In #10455, I did not realize that these failing tests had to do with the quirky and changed mapping driver behaviour. Instead, I tried to "fix" the inheritance rules by passing along the sequence generator definition unchanged once the ID column had been defined. #### Consequences of the change suggested here This PR reverts the changes made to `@SequenceGeneratorDefinition` inheritance behaviour that were done in #10455. This means that with the new "report fields where declared" driver mode (which is active in our functional tests) we can not expect the sequence generator definition to be inherited from mapped superclasses. The two test cases from `BasicInheritanceMappingTest` are removed. I will leave a notice in #10455 to indicate that the new driver mode also affects sequence generator definitions. The `GH10927Test` test case validates the sequence names generated in a few cases. In fact, I wrote this test against the `2.15.x` branch to make sure we get results that are consistent with the previous behaviour. This also means `@SequenceGeneratorDefinition` on mapped superclasses is pointless: The mapped superclass does not make use of the definition itself (it has no table), and the setting is never inherited to child classes. Fixes #10927. There is another implementation with slightly different inheritance semantics in #11052, in case the fix is not good enough and we'd need to review the topic later on. --- .../ORM/Mapping/ClassMetadataFactory.php | 10 +- .../ORM/Functional/Ticket/GH10927Test.php | 122 ++++++++++++++++++ .../Mapping/BasicInheritanceMappingTest.php | 33 +---- 3 files changed, 130 insertions(+), 35 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH10927Test.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index 67ff0ef726e..4134ca097c9 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -123,7 +123,7 @@ protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonS if ($parent) { $class->setInheritanceType($parent->inheritanceType); $class->setDiscriminatorColumn($parent->discriminatorColumn); - $this->inheritIdGeneratorMapping($class, $parent); + $class->setIdGeneratorType($parent->generatorType); $this->addInheritedFields($class, $parent); $this->addInheritedRelations($class, $parent); $this->addInheritedEmbeddedClasses($class, $parent); @@ -151,8 +151,12 @@ protected function doLoadMetadata($class, $parent, $rootEntityFound, array $nonS throw MappingException::reflectionFailure($class->getName(), $e); } - // Complete id generator mapping when the generator was declared/added in this class - if ($class->identifier && (! $parent || ! $parent->identifier)) { + // If this class has a parent the id generator strategy is inherited. + // However this is only true if the hierarchy of parents contains the root entity, + // if it consists of mapped superclasses these don't necessarily include the id field. + if ($parent && $rootEntityFound) { + $this->inheritIdGeneratorMapping($class, $parent); + } else { $this->completeIdGeneratorMapping($class); } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10927Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10927Test.php new file mode 100644 index 00000000000..5675674e512 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH10927Test.php @@ -0,0 +1,122 @@ +_em->getConnection()->getDatabasePlatform(); + if (! $platform instanceof PostgreSQLPlatform) { + self::markTestSkipped('The ' . self::class . ' requires the use of postgresql.'); + } + + $this->setUpEntitySchema([ + GH10927RootMappedSuperclass::class, + GH10927InheritedMappedSuperclass::class, + GH10927EntityA::class, + GH10927EntityB::class, + GH10927EntityC::class, + ]); + } + + public function testSequenceGeneratorDefinitionForRootMappedSuperclass(): void + { + $metadata = $this->_em->getClassMetadata(GH10927RootMappedSuperclass::class); + + self::assertNull($metadata->sequenceGeneratorDefinition); + } + + public function testSequenceGeneratorDefinitionForEntityA(): void + { + $metadata = $this->_em->getClassMetadata(GH10927EntityA::class); + + self::assertSame('GH10927EntityA_id_seq', $metadata->sequenceGeneratorDefinition['sequenceName']); + } + + public function testSequenceGeneratorDefinitionForInheritedMappedSuperclass(): void + { + $metadata = $this->_em->getClassMetadata(GH10927InheritedMappedSuperclass::class); + + self::assertSame('GH10927InheritedMappedSuperclass_id_seq', $metadata->sequenceGeneratorDefinition['sequenceName']); + } + + public function testSequenceGeneratorDefinitionForEntityB(): void + { + $metadata = $this->_em->getClassMetadata(GH10927EntityB::class); + + self::assertSame('GH10927EntityB_id_seq', $metadata->sequenceGeneratorDefinition['sequenceName']); + } + + public function testSequenceGeneratorDefinitionForEntityC(): void + { + $metadata = $this->_em->getClassMetadata(GH10927EntityC::class); + + self::assertSame('GH10927EntityB_id_seq', $metadata->sequenceGeneratorDefinition['sequenceName']); + } +} + +/** + * @ORM\MappedSuperclass() + */ +class GH10927RootMappedSuperclass +{ +} + +/** + * @ORM\Entity() + */ +class GH10927EntityA extends GH10927RootMappedSuperclass +{ + /** + * @ORM\Id + * @ORM\GeneratedValue(strategy="SEQUENCE") + * @ORM\Column(type="integer") + * + * @var int|null + */ + private $id = null; +} + +/** + * @ORM\MappedSuperclass() + */ +class GH10927InheritedMappedSuperclass extends GH10927RootMappedSuperclass +{ + /** + * @ORM\Id + * @ORM\GeneratedValue(strategy="SEQUENCE") + * @ORM\Column(type="integer") + * + * @var int|null + */ + private $id = null; +} + +/** + * @ORM\Entity() + * @ORM\InheritanceType("JOINED") + * @ORM\DiscriminatorColumn(name="discr", type="string") + * @ORM\DiscriminatorMap({"B" = "GH10927EntityB", "C" = "GH10927EntityC"}) + */ +class GH10927EntityB extends GH10927InheritedMappedSuperclass +{ +} + +/** + * @ORM\Entity() + */ +class GH10927EntityC extends GH10927EntityB +{ +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php index f7b2c97b620..a5e65643b34 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/BasicInheritanceMappingTest.php @@ -163,22 +163,7 @@ public function testMappedSuperclassWithId(): void /** * @group DDC-1156 * @group DDC-1218 - */ - public function testGeneratedValueFromMappedSuperclass(): void - { - $class = $this->cmf->getMetadataFor(SuperclassEntity::class); - assert($class instanceof ClassMetadata); - - self::assertInstanceOf(IdSequenceGenerator::class, $class->idGenerator); - self::assertEquals( - ['allocationSize' => 1, 'initialValue' => 10, 'sequenceName' => 'foo'], - $class->sequenceGeneratorDefinition - ); - } - - /** - * @group DDC-1156 - * @group DDC-1218 + * @group GH-10927 */ public function testSequenceDefinitionInHierarchyWithSandwichMappedSuperclass(): void { @@ -192,22 +177,6 @@ public function testSequenceDefinitionInHierarchyWithSandwichMappedSuperclass(): ); } - /** - * @group DDC-1156 - * @group DDC-1218 - */ - public function testMultipleMappedSuperclasses(): void - { - $class = $this->cmf->getMetadataFor(MediumSuperclassEntity::class); - assert($class instanceof ClassMetadata); - - self::assertInstanceOf(IdSequenceGenerator::class, $class->idGenerator); - self::assertEquals( - ['allocationSize' => 1, 'initialValue' => 10, 'sequenceName' => 'foo'], - $class->sequenceGeneratorDefinition - ); - } - /** * Ensure indexes are inherited from the mapped superclass. * From a8632aca8fca88444328737137d0daf6520ef70b Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Sat, 13 Jan 2024 00:06:34 +0100 Subject: [PATCH 067/128] Keep the `declared` mapping information when using attribute overrides (#11135) When using `AttributeOverride` to override mapping information inherited from a parent class (a mapped superclass), make sure to keep information about where the field was originally declared. This is important for `private` fields: Without the correct `declared` information, it will lead to errors when cached mapping information is loaded, reflection wakes up and looks for the private field in the wrong class. --- .../ORM/Mapping/ClassMetadataInfo.php | 4 + .../ORM/Functional/Ticket/GH11135Test.php | 73 +++++++++++++++++++ .../Tests/ORM/Mapping/ClassMetadataTest.php | 26 +++++++ 3 files changed, 103 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/GH11135Test.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 9d8f27cd1a8..9553d84e7a2 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2558,6 +2558,10 @@ public function setAttributeOverride($fieldName, array $overrideMapping) $overrideMapping['id'] = $mapping['id']; } + if (isset($mapping['declared'])) { + $overrideMapping['declared'] = $mapping['declared']; + } + if (! isset($overrideMapping['type'])) { $overrideMapping['type'] = $mapping['type']; } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11135Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11135Test.php new file mode 100644 index 00000000000..7a3e6a246bb --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH11135Test.php @@ -0,0 +1,73 @@ +setUpEntitySchema([ + GH11135MappedSuperclass::class, + GH11135EntityWithOverride::class, + GH11135EntityWithoutOverride::class, + ]); + } + + public function testOverrideInheritsDeclaringClass(): void + { + $cm1 = $this->_em->getClassMetadata(GH11135EntityWithOverride::class); + $cm2 = $this->_em->getClassMetadata(GH11135EntityWithoutOverride::class); + + self::assertSame($cm1->getFieldMapping('id')['declared'], $cm2->getFieldMapping('id')['declared']); + self::assertSame($cm1->getAssociationMapping('ref')['declared'], $cm2->getAssociationMapping('ref')['declared']); + } +} + +/** + * @ORM\MappedSuperclass + */ +class GH11135MappedSuperclass +{ + /** + * @ORM\Id + * @ORM\Column(type="integer") + * @ORM\GeneratedValue + * + * @var int + */ + private $id; + + /** + * @ORM\ManyToOne(targetEntity="GH11135EntityWithoutOverride") + * + * @var GH11135EntityWithoutOverride + */ + private $ref; +} + +/** + * @ORM\Entity() + * @ORM\AttributeOverrides({ + * @ORM\AttributeOverride(name="id", column=@ORM\Column(name="id_overridden")) + * }) + * @ORM\AssociationOverrides({ + * @ORM\AssociationOverride(name="ref", joinColumns=@ORM\JoinColumn(name="ref_overridden", referencedColumnName="id")) + * }) + */ +class GH11135EntityWithOverride extends GH11135MappedSuperclass +{ +} + +/** + * @ORM\Entity() + */ +class GH11135EntityWithoutOverride extends GH11135MappedSuperclass +{ +} diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php index 79da971300d..d1e82c1922b 100644 --- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php @@ -29,6 +29,8 @@ use Doctrine\Tests\Models\DDC6412\DDC6412File; use Doctrine\Tests\Models\DDC964\DDC964Admin; use Doctrine\Tests\Models\DDC964\DDC964Guest; +use Doctrine\Tests\Models\DirectoryTree\AbstractContentItem; +use Doctrine\Tests\Models\DirectoryTree\Directory; use Doctrine\Tests\Models\Routing\RoutingLeg; use Doctrine\Tests\Models\TypedProperties; use Doctrine\Tests\ORM\Mapping\TypedFieldMapper\CustomIntAsStringTypedFieldMapper; @@ -1186,6 +1188,30 @@ public function testInvalidOverrideAttributeFieldTypeException(): void $cm->setAttributeOverride('name', ['type' => 'date']); } + public function testAttributeOverrideKeepsDeclaringClass(): void + { + $cm = new ClassMetadata(Directory::class); + $cm->mapField(['fieldName' => 'id', 'type' => 'integer', 'declared' => AbstractContentItem::class]); + $cm->setAttributeOverride('id', ['columnName' => 'new_id']); + + $mapping = $cm->getFieldMapping('id'); + + self::assertArrayHasKey('declared', $mapping); + self::assertSame(AbstractContentItem::class, $mapping['declared']); + } + + public function testAssociationOverrideKeepsDeclaringClass(): void + { + $cm = new ClassMetadata(Directory::class); + $cm->mapManyToOne(['fieldName' => 'parentDirectory', 'targetEntity' => Directory::class, 'cascade' => ['remove'], 'declared' => Directory::class]); + $cm->setAssociationOverride('parentDirectory', ['cascade' => '']); + + $mapping = $cm->getAssociationMapping('parentDirectory'); + + self::assertArrayHasKey('declared', $mapping); + self::assertSame(Directory::class, $mapping['declared']); + } + /** @group DDC-1955 */ public function testInvalidEntityListenerClassException(): void { From 8f15337b03c2c1dd7123301d688907787a457c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 16 Jan 2024 22:01:16 +0100 Subject: [PATCH 068/128] Remove redundant tags The "any" tags inside the definition for mapped superclasses and embeddables duplicate what is already done for entities. The other removed "any" tags are also redundant, as they duplicate what's already done inside the grandparent "choice" tag. Starting with version libxml 2.12, such redundant tags cause errors about the content model not being "determinist". Fixes #11117 --- doctrine-mapping.xsd | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd index a9b1a367e67..a058787746c 100644 --- a/doctrine-mapping.xsd +++ b/doctrine-mapping.xsd @@ -148,7 +148,6 @@ - @@ -226,22 +225,13 @@ - - - - - - + - - - - - + @@ -565,7 +555,6 @@ - @@ -583,7 +572,6 @@ - From 4875f4c878ca8f1f551609ac7120e3a4e91caed0 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Thu, 18 Jan 2024 09:54:46 +0100 Subject: [PATCH 069/128] Use foreach on iterable to prevent table locks during tests --- .../Tests/ORM/Functional/EagerFetchCollectionTest.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php index cd76ee8b078..ff0eab56d63 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EagerFetchCollectionTest.php @@ -18,6 +18,10 @@ protected function setUp(): void parent::setUp(); $this->createSchemaForModels(EagerFetchOwner::class, EagerFetchChild::class); + + // Ensure tables are empty + $this->_em->getRepository(EagerFetchChild::class)->createQueryBuilder('o')->delete()->getQuery()->execute(); + $this->_em->getRepository(EagerFetchOwner::class)->createQueryBuilder('o')->delete()->getQuery()->execute(); } public function testEagerFetchMode(): void @@ -91,9 +95,11 @@ public function testEagerFetchWithIterable(): void $this->_em->clear(); $iterable = $this->_em->getRepository(EagerFetchOwner::class)->createQueryBuilder('o')->getQuery()->toIterable(); - $owner = $iterable->current(); - $this->assertCount(2, $owner->children); + // There is only a single record, but use a foreach to ensure the iterator is marked as finished and the table lock is released + foreach ($iterable as $owner) { + $this->assertCount(2, $owner->children); + } } protected function createOwnerWithChildren(int $children): EagerFetchOwner From d98186e2c48ffb6b2ca15706f500fa36528b9ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 18 Jan 2024 21:19:28 +0100 Subject: [PATCH 070/128] Make Doctrine\Tests\ORM\Internal\Node autoloadable It is used in several tests. --- tests/Doctrine/Tests/ORM/Internal/Node.php | 16 ++++++++++++++++ .../Tests/ORM/Internal/TopologicalSortTest.php | 11 ----------- 2 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Internal/Node.php diff --git a/tests/Doctrine/Tests/ORM/Internal/Node.php b/tests/Doctrine/Tests/ORM/Internal/Node.php new file mode 100644 index 00000000000..d53954a2ea2 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Internal/Node.php @@ -0,0 +1,16 @@ +name = $name; + } +} diff --git a/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php b/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php index d0dd9178c15..e1a93b684ef 100644 --- a/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php +++ b/tests/Doctrine/Tests/ORM/Internal/TopologicalSortTest.php @@ -287,14 +287,3 @@ private function computeResult(): array }, array_values($this->topologicalSort->sort())); } } - -class Node -{ - /** @var string */ - public $name; - - public function __construct(string $name) - { - $this->name = $name; - } -} From 0b3cd726091f12017d9b2129a65aac7d6a35d05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 20 Jan 2024 13:45:04 +0100 Subject: [PATCH 071/128] Remove references to JIRA --- SECURITY.md | 5 ++--- docs/en/reference/security.rst | 5 ++--- .../ORM/Tools/Pagination/LimitSubqueryOutputWalker.php | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index d7013cb4069..b0e72932b29 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,6 +13,5 @@ understand the assumptions we make. - [DBAL Security Page](https://www.doctrine-project.org/projects/doctrine-dbal/en/stable/reference/security.html) - [ORM Security Page](https://www.doctrine-project.org/projects/doctrine-orm/en/stable/reference/security.html) -If you find a Security bug in Doctrine, please report it on Jira and change the -Security Level to "Security Issues". It will be visible to Doctrine Core -developers and you only. +If you find a Security bug in Doctrine, please follow our +[Security reporting guidelines](https://www.doctrine-project.org/policies/security.html#reporting). diff --git a/docs/en/reference/security.rst b/docs/en/reference/security.rst index 51e6a3903a6..53d2a87ab60 100644 --- a/docs/en/reference/security.rst +++ b/docs/en/reference/security.rst @@ -12,9 +12,8 @@ page only handles Security issues in the ORM. - `DBAL Security Page ` -If you find a Security bug in Doctrine, please report it on Jira and change the -Security Level to "Security Issues". It will be visible to Doctrine Core -developers and you only. +If you find a Security bug in Doctrine, please follow our +`Security reporting guidelines `_. User input and Doctrine ORM --------------------------- diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php index 52a35b83435..f92c1145d4f 100644 --- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php +++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php @@ -257,7 +257,7 @@ public function walkSelectStatementWithoutRowNumber(SelectStatement $AST, $addMi $innerSql ); - // http://www.doctrine-project.org/jira/browse/DDC-1958 + // https://github.com/doctrine/orm/issues/2630 $sql = $this->preserveSqlOrdering($sqlIdentifier, $innerSql, $sql, $orderByClause); // Apply the limit and offset. From ac24c11808c1869f7bdb813c165d4566c1a2df17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 20 Jan 2024 21:53:48 +0100 Subject: [PATCH 072/128] Modernize code in documentation (#11179) Somehow, there still were code samples relying on annotations. --- docs/en/cookbook/aggregate-fields.rst | 127 +++++++----------- .../resolve-target-entity-listener.rst | 21 +-- 2 files changed, 56 insertions(+), 92 deletions(-) diff --git a/docs/en/cookbook/aggregate-fields.rst b/docs/en/cookbook/aggregate-fields.rst index c9635fa52d6..001d70d34b4 100644 --- a/docs/en/cookbook/aggregate-fields.rst +++ b/docs/en/cookbook/aggregate-fields.rst @@ -36,71 +36,50 @@ Our entities look like: namespace Bank\Entities; use Doctrine\ORM\Mapping as ORM; - - /** - * @ORM\Entity - */ + use Doctrine\Common\Collections\ArrayCollection; + use Doctrine\Common\Collections\Collection; + + #[ORM\Entity] class Account { - /** - * @ORM\Id - * @ORM\GeneratedValue - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: 'integer')] private ?int $id; - - /** - * @ORM\Column(type="string", unique=true) - */ - private string $no; - - /** - * @ORM\OneToMany(targetEntity="Entry", mappedBy="account", cascade={"persist"}) - */ - private array $entries; - - /** - * @ORM\Column(type="integer") - */ - private int $maxCredit = 0; - - public function __construct(string $no, int $maxCredit = 0) - { - $this->no = $no; - $this->maxCredit = $maxCredit; - $this->entries = new \Doctrine\Common\Collections\ArrayCollection(); + + #[ORM\OneToMany(targetEntity: Entry::class, mappedBy: 'account', cascade: ['persist'])] + private Collection $entries; + + + public function __construct( + #[ORM\Column(type: 'string', unique: true)] + private string $no, + + #[ORM\Column(type: 'integer')] + private int $maxCredit = 0, + ) { + $this->entries = new ArrayCollection(); } } - - /** - * @ORM\Entity - */ + + #[ORM\Entity] class Entry { - /** - * @ORM\Id - * @ORM\GeneratedValue - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue] + #[ORM\Column(type: 'integer')] private ?int $id; - - /** - * @ORM\ManyToOne(targetEntity="Account", inversedBy="entries") - */ - private Account $account; - - /** - * @ORM\Column(type="integer") - */ - private int $amount; - - public function __construct(Account $account, int $amount) - { - $this->account = $account; - $this->amount = $amount; + + public function __construct( + #[ORM\ManyToOne(targetEntity: Account::class, inversedBy: 'entries')] + private Account $account, + + #[ORM\Column(type: 'integer')] + private int $amount, + ) { // more stuff here, from/to whom, stated reason, execution date and such } - + public function getAmount(): Amount { return $this->amount; @@ -193,9 +172,8 @@ relation with this method: public function addEntry(int $amount): void { $this->assertAcceptEntryAllowed($amount); - - $e = new Entry($this, $amount); - $this->entries[] = $e; + + $this->entries[] = new Entry($this, $amount); } } @@ -213,18 +191,18 @@ Now look at the following test-code for our entities: { $account = new Account("123456", maxCredit: 200); $this->assertEquals(0, $account->getBalance()); - + $account->addEntry(500); $this->assertEquals(500, $account->getBalance()); - + $account->addEntry(-700); $this->assertEquals(-200, $account->getBalance()); } - + public function testExceedMaxLimit() { $account = new Account("123456", maxCredit: 200); - + $this->expectException(Exception::class); $account->addEntry(-1000); } @@ -285,22 +263,19 @@ entries collection) we want to add an aggregate field called balance; } - + public function addEntry(int $amount): void { $this->assertAcceptEntryAllowed($amount); - - $e = new Entry($this, $amount); - $this->entries[] = $e; + + $this->entries[] = new Entry($this, $amount); $this->balance += $amount; } } @@ -331,13 +306,13 @@ potentially lead to inconsistent state. See this example: // The Account $accId has a balance of 0 and a max credit limit of 200: // request 1 account $account1 = $em->find(Account::class, $accId); - + // request 2 account $account2 = $em->find(Account::class, $accId); - + $account1->addEntry(-200); $account2->addEntry(-200); - + // now request 1 and 2 both flush the changes. The aggregate field ``Account::$balance`` is now -200, however the @@ -357,10 +332,8 @@ Optimistic locking is as easy as adding a version column: class Account { - /** - * @ORM\Column(type="integer") - * @ORM\Version - */ + #[ORM\Column(type: 'integer')] + #[ORM\Version] private int $version; } diff --git a/docs/en/cookbook/resolve-target-entity-listener.rst b/docs/en/cookbook/resolve-target-entity-listener.rst index 04a50e56043..294c5779af4 100644 --- a/docs/en/cookbook/resolve-target-entity-listener.rst +++ b/docs/en/cookbook/resolve-target-entity-listener.rst @@ -47,10 +47,8 @@ A Customer entity use Acme\CustomerModule\Entity\Customer as BaseCustomer; use Acme\InvoiceModule\Model\InvoiceSubjectInterface; - /** - * @ORM\Entity - * @ORM\Table(name="customer") - */ + #[ORM\Entity] + #[ORM\Table(name: 'customer')] class Customer extends BaseCustomer implements InvoiceSubjectInterface { // In our example, any methods defined in the InvoiceSubjectInterface @@ -69,19 +67,12 @@ An Invoice entity use Doctrine\ORM\Mapping AS ORM; use Acme\InvoiceModule\Model\InvoiceSubjectInterface; - /** - * Represents an Invoice. - * - * @ORM\Entity - * @ORM\Table(name="invoice") - */ + #[ORM\Entity] + #[ORM\Table(name: 'invoice')] class Invoice { - /** - * @ORM\ManyToOne(targetEntity="Acme\InvoiceModule\Model\InvoiceSubjectInterface") - * @var InvoiceSubjectInterface - */ - protected $subject; + #[ORM\ManyToOne(targetEntity: InvoiceSubjectInterface::class)] + protected InvoiceSubjectInterface $subject; } An InvoiceSubjectInterface From df730d69b8de8685e5bfc97a8ea56665baa4ff8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 21 Jan 2024 19:23:14 +0100 Subject: [PATCH 073/128] Allow doctrine/lexer 3 --- composer.json | 2 +- src/Query/Lexer.php | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 1404346847a..ee4f1f0bc08 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2", + "doctrine/lexer": "^2 || ^3", "doctrine/persistence": "^2.4 || ^3", "psr/cache": "^1 || ^2 || ^3", "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", diff --git a/src/Query/Lexer.php b/src/Query/Lexer.php index bf471b09a04..da68a6c6c1a 100644 --- a/src/Query/Lexer.php +++ b/src/Query/Lexer.php @@ -145,6 +145,8 @@ protected function getNonCatchablePatterns() /** * {@inheritDoc} + * + * @param string $value */ protected function getType(&$value) { From 4bddab9e099c5b3c9788d17a1563300bb7d6b106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 21 Jan 2024 23:40:35 +0100 Subject: [PATCH 074/128] Look for lib remnants in hidden files --- .github/workflows/coding-standards.yml | 4 ++-- .github/workflows/continuous-integration.yml | 4 ++-- .github/workflows/phpbench.yml | 4 ++-- .github/workflows/static-analysis.yml | 4 ++-- .gitignore | 3 --- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 1ce1a90c1b0..ac2788b39a4 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -8,7 +8,7 @@ on: - .github/workflows/coding-standards.yml - bin/** - composer.* - - lib/** + - src/** - phpcs.xml.dist - tests/** push: @@ -18,7 +18,7 @@ on: - .github/workflows/coding-standards.yml - bin/** - composer.* - - lib/** + - src/** - phpcs.xml.dist - tests/** diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 4dc184b39b0..695c299d379 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -8,7 +8,7 @@ on: - .github/workflows/continuous-integration.yml - ci/** - composer.* - - lib/** + - src/** - phpunit.xml.dist - tests/** push: @@ -18,7 +18,7 @@ on: - .github/workflows/continuous-integration.yml - ci/** - composer.* - - lib/** + - src/** - phpunit.xml.dist - tests/** diff --git a/.github/workflows/phpbench.yml b/.github/workflows/phpbench.yml index a2a82d78883..1e7ad8c10d1 100644 --- a/.github/workflows/phpbench.yml +++ b/.github/workflows/phpbench.yml @@ -8,7 +8,7 @@ on: paths: - .github/workflows/phpbench.yml - composer.* - - lib/** + - src/** - phpbench.json - tests/** push: @@ -17,7 +17,7 @@ on: paths: - .github/workflows/phpbench.yml - composer.* - - lib/** + - src/** - phpbench.json - tests/** diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 8cb1dfe095f..c21e5cbea56 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -7,7 +7,7 @@ on: paths: - .github/workflows/static-analysis.yml - composer.* - - lib/** + - src/** - phpstan* - psalm* - tests/Doctrine/StaticAnalysis/** @@ -17,7 +17,7 @@ on: paths: - .github/workflows/static-analysis.yml - composer.* - - lib/** + - src/** - phpstan* - psalm* - tests/Doctrine/StaticAnalysis/** diff --git a/.gitignore b/.gitignore index 4b84f4214b1..0b0720faa94 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,6 @@ logs/ reports/ dist/ download/ -lib/api/ -lib/Doctrine/Common -lib/Doctrine/DBAL /.settings/ .buildpath .project From 7151db3cb8a71486e0e02d3f71d20e649e31fa04 Mon Sep 17 00:00:00 2001 From: thePanz Date: Fri, 19 Jan 2024 23:22:57 +0100 Subject: [PATCH 075/128] Throw exception when trying to use non-backed enum types --- .../ORM/Mapping/DefaultTypedFieldMapper.php | 10 +++++- lib/Doctrine/ORM/Mapping/MappingException.php | 10 ++++++ .../Tests/Models/Enums/FaultySwitch.php | 22 ++++++++++++ .../Tests/Models/Enums/SwitchStatus.php | 11 ++++++ .../ORM/Mapping/TypedEnumFieldMapperTest.php | 34 +++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 tests/Doctrine/Tests/Models/Enums/FaultySwitch.php create mode 100644 tests/Doctrine/Tests/Models/Enums/SwitchStatus.php create mode 100644 tests/Doctrine/Tests/ORM/Mapping/TypedEnumFieldMapperTest.php diff --git a/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php b/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php index bc538271467..7e57a4798cd 100644 --- a/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php +++ b/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php @@ -57,7 +57,15 @@ public function validateAndComplete(array $mapping, ReflectionProperty $field): $mapping['enumType'] = $type->getName(); $reflection = new ReflectionEnum($type->getName()); - $type = $reflection->getBackingType(); + if (! $reflection->isBacked()) { + throw MappingException::backedEnumTypeRequired( + $field->class, + $mapping['fieldName'], + $mapping['enumType'] + ); + } + + $type = $reflection->getBackingType(); assert($type instanceof ReflectionNamedType); } diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index c0a5d1392fe..864da952763 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -954,6 +954,16 @@ public static function enumsRequirePhp81(string $className, string $fieldName): return new self(sprintf('Enum types require PHP 8.1 in %s::$%s', $className, $fieldName)); } + public static function backedEnumTypeRequired(string $className, string $fieldName, string $enumType): self + { + return new self(sprintf( + 'Attempting to map a non-backed enum type %s in entity %s::$%s. Please use backed enums only', + $enumType, + $className, + $fieldName + )); + } + public static function nonEnumTypeMapped(string $className, string $fieldName, string $enumType): self { return new self(sprintf( diff --git a/tests/Doctrine/Tests/Models/Enums/FaultySwitch.php b/tests/Doctrine/Tests/Models/Enums/FaultySwitch.php new file mode 100644 index 00000000000..7f01b239966 --- /dev/null +++ b/tests/Doctrine/Tests/Models/Enums/FaultySwitch.php @@ -0,0 +1,22 @@ += 8.1 + */ +class TypedEnumFieldMapperTest extends OrmTestCase +{ + private static function defaultTypedFieldMapper(): DefaultTypedFieldMapper + { + return new DefaultTypedFieldMapper(); + } + + public function testNotBackedEnumThrows(): void + { + $reflectionClass = new ReflectionClass(FaultySwitch::class); + + $this->expectException(MappingException::class); + $this->expectExceptionMessage( + 'Attempting to map a non-backed enum type Doctrine\Tests\Models\Enums\SwitchStatus in entity Doctrine\Tests\Models\Enums\FaultySwitch::$status. Please use backed enums only' + ); + + self::defaultTypedFieldMapper()->validateAndComplete(['fieldName' => 'status'], $reflectionClass->getProperty('status')); + } +} From 020d31efba2d2a5c4cb483889f4f099fb160b602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 23 Jan 2024 19:51:48 +0100 Subject: [PATCH 076/128] Remove remaining submodules (#11183) We are no longer relying on either piece of software. --- .gitmodules | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 8727b0dadbc..00000000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "docs/en/_theme"] - path = docs/en/_theme - url = git://github.com/doctrine/doctrine-sphinx-theme.git -[submodule "lib/vendor/doctrine-build-common"] - path = lib/vendor/doctrine-build-common - url = git://github.com/doctrine/doctrine-build-common.git From 624c56be72f1e626ec1995bd4da0201ccb62f53d Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 26 Jan 2024 00:52:35 +0100 Subject: [PATCH 077/128] Update branches in README --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b72a261a80f..22aab0538c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -| [3.0.x][3.0] | [2.16.x][2.16] | [2.15.x][2.15] | +| [3.0.x][3.0] | [2.18.x][2.18] | [2.17.x][2.17] | |:----------------:|:----------------:|:----------:| -| [![Build status][3.0 image]][3.0] | [![Build status][2.16 image]][2.16] | [![Build status][2.15 image]][2.15] | -| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.16 coverage image]][2.16 coverage] | [![Coverage Status][2.15 coverage image]][2.15 coverage] | +| [![Build status][3.0 image]][3.0] | [![Build status][2.18 image]][2.18] | [![Build status][2.17 image]][2.17] | +| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.18 coverage image]][2.18 coverage] | [![Coverage Status][2.17 coverage image]][2.17 coverage] | [

πŸ‡ΊπŸ‡¦ UKRAINE NEEDS YOUR HELP NOW!

](https://www.doctrine-project.org/stop-war.html) @@ -22,11 +22,11 @@ without requiring unnecessary code duplication. [3.0]: https://github.com/doctrine/orm/tree/3.0.x [3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg [3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x - [2.16 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.16.x - [2.16]: https://github.com/doctrine/orm/tree/2.16.x - [2.16 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.16.x/graph/badge.svg - [2.16 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.16.x - [2.15 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.15.x - [2.15]: https://github.com/doctrine/orm/tree/2.15.x - [2.15 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.15.x/graph/badge.svg - [2.15 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.15.x + [2.18 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.18.x + [2.18]: https://github.com/doctrine/orm/tree/2.18.x + [2.18 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.18.x/graph/badge.svg + [2.18 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.18.x + [2.17 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.17.x + [2.17]: https://github.com/doctrine/orm/tree/2.17.x + [2.17 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.17.x/graph/badge.svg + [2.17 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.17.x From d386b43be3fe4c2533fa7f2c9d8208fdcc61fb5a Mon Sep 17 00:00:00 2001 From: "Jonathan H. Wage" Date: Fri, 26 Jan 2024 09:59:03 -0600 Subject: [PATCH 078/128] Remove XML validation disabling deprecation. --- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 82ad11a2981..ed4c5d5e799 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -5,7 +5,6 @@ namespace Doctrine\ORM\Mapping\Driver; use Doctrine\Common\Collections\Criteria; -use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; @@ -56,15 +55,6 @@ public function __construct($locator, $fileExtension = self::DEFAULT_FILE_EXTENS ); } - if (! $isXsdValidationEnabled) { - Deprecation::trigger( - 'doctrine/orm', - 'https://github.com/doctrine/orm/pull/6728', - 'Using XML mapping driver with XSD validation disabled is deprecated' - . ' and will not be supported in Doctrine ORM 3.0.' - ); - } - if ($isXsdValidationEnabled && ! extension_loaded('dom')) { throw new LogicException( 'XSD validation cannot be enabled because the DOM extension is missing.' From b9881373784e9f9f4b449be24e89286bbcbb2eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 28 Jan 2024 16:30:02 +0100 Subject: [PATCH 079/128] Ignore deprecations handled in next major These deprecations have been handled on 4.0.x in https://github.com/doctrine/orm/pull/11061, it is safe to ignore them. --- psalm.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/psalm.xml b/psalm.xml index a8a096c3ae4..46769875687 100644 --- a/psalm.xml +++ b/psalm.xml @@ -88,6 +88,8 @@ + + From e110941f9db627441755827e3387f4de0c9808c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 29 Jan 2024 17:25:08 +0100 Subject: [PATCH 080/128] Use a more specific type for getSqlStatements() It is strictly beneficial for the Psalm baseline. --- psalm-baseline.xml | 9 --------- src/Query/Exec/AbstractSqlExecutor.php | 2 +- src/Query/Exec/MultiTableUpdateExecutor.php | 8 ++++---- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 2521ceb9193..34b44307ff3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1445,12 +1445,6 @@ $sqlParams - - parse()->getSqlExecutor()->getSqlStatements()]]> - - - |string]]> - getDQL()]]> @@ -1896,9 +1890,6 @@ MultiTableUpdateExecutor MultiTableUpdateExecutor - - sqlStatements]]> - diff --git a/src/Query/Exec/AbstractSqlExecutor.php b/src/Query/Exec/AbstractSqlExecutor.php index 0348446a97c..ec8ad481d7b 100644 --- a/src/Query/Exec/AbstractSqlExecutor.php +++ b/src/Query/Exec/AbstractSqlExecutor.php @@ -45,7 +45,7 @@ public function __construct() /** * Gets the SQL statements that are executed by the executor. * - * @return mixed[]|string All the SQL update statements. + * @return list|string All the SQL update statements. */ public function getSqlStatements() { diff --git a/src/Query/Exec/MultiTableUpdateExecutor.php b/src/Query/Exec/MultiTableUpdateExecutor.php index f1e491bd258..eb3ac148020 100644 --- a/src/Query/Exec/MultiTableUpdateExecutor.php +++ b/src/Query/Exec/MultiTableUpdateExecutor.php @@ -87,13 +87,13 @@ public function __construct(AST\Node $AST, $sqlWalker) // 3. Create and store UPDATE statements $classNames = array_merge($primaryClass->parentClasses, [$primaryClass->name], $primaryClass->subClasses); - $i = -1; foreach (array_reverse($classNames) as $className) { $affected = false; $class = $em->getClassMetadata($className); $updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class, $platform) . ' SET '; + $sqlParameters = []; foreach ($updateItems as $updateItem) { $field = $updateItem->pathExpression->field; @@ -105,7 +105,6 @@ public function __construct(AST\Node $AST, $sqlWalker) if (! $affected) { $affected = true; - ++$i; } else { $updateSql .= ', '; } @@ -113,7 +112,7 @@ public function __construct(AST\Node $AST, $sqlWalker) $updateSql .= $sqlWalker->walkUpdateItem($updateItem); if ($newValue instanceof AST\InputParameter) { - $this->sqlParameters[$i][] = $newValue->name; + $sqlParameters[] = $newValue->name; ++$this->numParametersInUpdateClause; } @@ -121,7 +120,8 @@ public function __construct(AST\Node $AST, $sqlWalker) } if ($affected) { - $this->sqlStatements[$i] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; + $this->sqlParameters[] = $sqlParameters; + $this->sqlStatements[] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; } } From 152ebd756ccbb6e9ce5c85d500f552e2197f0bcf Mon Sep 17 00:00:00 2001 From: Matthias Pigulla Date: Tue, 30 Jan 2024 08:57:52 +0100 Subject: [PATCH 081/128] Cover limit/offset values in `LimitSubqueryOutputWalkerTest` This will help to make sure we don't lose those parts of the SQL when working on #11188. --- .../LimitSubqueryOutputWalkerTest.php | 300 +++++++----------- 1 file changed, 118 insertions(+), 182 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php index e3863300412..cb69a3a5674 100644 --- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM\Tools\Pagination; +use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; @@ -18,273 +19,212 @@ class_exists('Doctrine\DBAL\Platforms\PostgreSqlPlatform'); final class LimitSubqueryOutputWalkerTest extends PaginationTestCase { + /** + * @var AbstractPlatform|null + */ + private $originalDatabasePlatform; + + protected function setUp(): void + { + parent::setUp(); + + $this->originalDatabasePlatform = $this->entityManager->getConnection()->getDatabasePlatform(); + } + + protected function tearDown(): void + { + if ($this->originalDatabasePlatform) { + $this->entityManager->getConnection()->setDatabasePlatform($this->originalDatabasePlatform); + } + + parent::tearDown(); + } + + private function replaceDatabasePlatform(AbstractPlatform $platform): void + { + $this->entityManager->getConnection()->setDatabasePlatform($platform); + } + public function testLimitSubquery(): void { - $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a' - ); - $query->expireQueryCache(true); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, m0_.author_id AS author_id_5, m0_.category_id AS category_id_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result', - $limitQuery->getSQL() + 'SELECT DISTINCT id_0 FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, m0_.author_id AS author_id_5, m0_.category_id AS category_id_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result LIMIT 20 OFFSET 10', + $query->getSQL() ); } public function testLimitSubqueryWithSortPg(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title' - ); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title'); self::assertSame( - 'SELECT DISTINCT id_0, MIN(sclr_5) AS dctrn_minrownum FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS sclr_5, m0_.author_id AS author_id_6, m0_.category_id AS category_id_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT DISTINCT id_0, MIN(sclr_5) AS dctrn_minrownum FROM (SELECT m0_.id AS id_0, m0_.title AS title_1, c1_.id AS id_2, a2_.id AS id_3, a2_.name AS name_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS sclr_5, m0_.author_id AS author_id_6, m0_.category_id AS category_id_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithScalarSortPg(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( - 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity' - ); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity'); self::assertSame( - 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithMixedSortPg(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( - 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' - ); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC'); self::assertSame( - 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithHiddenScalarSortPg(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( - 'SELECT u, g, COUNT(g.id) AS hidden g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' - ); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, g, COUNT(g.id) AS hidden g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC'); self::assertSame( - 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT DISTINCT id_1, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS sclr_0, u1_.id AS id_1, g0_.id AS id_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS sclr_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY id_1 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryPg(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); $this->testLimitSubquery(); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithSortOracle(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title' - ); - $query->expireQueryCache(true); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title'); self::assertSame( - 'SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS SCLR_5, m0_.author_id AS AUTHOR_ID_6, m0_.category_id AS CATEGORY_ID_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, ROW_NUMBER() OVER(ORDER BY m0_.title ASC) AS SCLR_5, m0_.author_id AS AUTHOR_ID_6, m0_.category_id AS CATEGORY_ID_7 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithScalarSortOracle(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query = $this->entityManager->createQuery( - 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity' - ); - $query->expireQueryCache(true); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity'); self::assertSame( - 'SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryWithMixedSortOracle(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query = $this->entityManager->createQuery( - 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC' - ); - $query->expireQueryCache(true); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC'); self::assertSame( - 'SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC', - $limitQuery->getSQL() + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_1, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT COUNT(g0_.id) AS SCLR_0, u1_.id AS ID_1, g0_.id AS ID_2, ROW_NUMBER() OVER(ORDER BY COUNT(g0_.id) ASC, u1_.id DESC) AS SCLR_3 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id) dctrn_result GROUP BY ID_1 ORDER BY dctrn_minrownum ASC) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testLimitSubqueryOracle(): void { - $odp = $this->entityManager->getConnection()->getDatabasePlatform(); - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query = $this->entityManager->createQuery( - 'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a' - ); - $query->expireQueryCache(true); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a'); self::assertSame( - 'SELECT DISTINCT ID_0 FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, m0_.author_id AS AUTHOR_ID_5, m0_.category_id AS CATEGORY_ID_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result', - $limitQuery->getSQL() + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_0 FROM (SELECT m0_.id AS ID_0, m0_.title AS TITLE_1, c1_.id AS ID_2, a2_.id AS ID_3, a2_.name AS NAME_4, m0_.author_id AS AUTHOR_ID_5, m0_.category_id AS CATEGORY_ID_6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', + $query->getSQL() ); - - $this->entityManager->getConnection()->setDatabasePlatform($odp); } public function testCountQueryMixedResultsWithName(): void { - $query = $this->entityManager->createQuery( - 'SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a' - ); - $limitQuery = clone $query; - $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT a, sum(a.name) as foo FROM Doctrine\Tests\ORM\Tools\Pagination\Author a'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, sum(a0_.name) AS sclr_2 FROM Author a0_) dctrn_result', - $limitQuery->getSQL() + 'SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, sum(a0_.name) AS sclr_2 FROM Author a0_) dctrn_result LIMIT 20 OFFSET 10', + $query->getSQL() ); } /** @group DDC-3336 */ public function testCountQueryWithArithmeticOrderByCondition(): void { - $query = $this->entityManager->createQuery( - 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY (1 - 1000) * 1 DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY (1 - 1000) * 1 DESC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, (1 - 1000) * 1 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result_inner ORDER BY (1 - 1000) * 1 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, (1 - 1000) * 1 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1 FROM Author a0_) dctrn_result_inner ORDER BY (1 - 1000) * 1 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testCountQueryWithComplexScalarOrderByItemWithoutJoin(): void { - $query = $this->entityManager->createQuery( - 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageHeight * a.imageWidth DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageHeight * a.imageWidth DESC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_2 * imageWidth_3 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.imageHeight AS imageHeight_2, a0_.imageWidth AS imageWidth_3, a0_.imageAltDesc AS imageAltDesc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY imageHeight_2 * imageWidth_3 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_2 * imageWidth_3 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.imageHeight AS imageHeight_2, a0_.imageWidth AS imageWidth_3, a0_.imageAltDesc AS imageAltDesc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY imageHeight_2 * imageWidth_3 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testCountQueryWithComplexScalarOrderByItemJoinedWithoutPartial(): void { - $query = $this->entityManager->createQuery( - 'SELECT u FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.imageHeight * a.imageWidth DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.imageHeight * a.imageWidth DESC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_3 * imageWidth_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image AS image_2, a1_.imageHeight AS imageHeight_3, a1_.imageWidth AS imageWidth_4, a1_.imageAltDesc AS imageAltDesc_5, a1_.user_id AS user_id_6 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_3 * imageWidth_4 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_3 * imageWidth_4 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.image AS image_2, a1_.imageHeight AS imageHeight_3, a1_.imageWidth AS imageWidth_4, a1_.imageAltDesc AS imageAltDesc_5, a1_.user_id AS user_id_6 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_3 * imageWidth_4 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testCountQueryWithComplexScalarOrderByItemJoinedWithPartial(): void { - $query = $this->entityManager->createQuery( - 'SELECT u, partial a.{id, imageAltDesc} FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.imageHeight * a.imageWidth DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT u, partial a.{id, imageAltDesc} FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.avatar a ORDER BY a.imageHeight * a.imageWidth DESC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_5 * imageWidth_6 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.imageAltDesc AS imageAltDesc_2, a1_.id AS id_3, a1_.image AS image_4, a1_.imageHeight AS imageHeight_5, a1_.imageWidth AS imageWidth_6, a1_.imageAltDesc AS imageAltDesc_7, a1_.user_id AS user_id_8 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_5 * imageWidth_6 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageHeight_5 * imageWidth_6 FROM (SELECT u0_.id AS id_0, a1_.id AS id_1, a1_.imageAltDesc AS imageAltDesc_2, a1_.id AS id_3, a1_.image AS image_4, a1_.imageHeight AS imageHeight_5, a1_.imageWidth AS imageWidth_6, a1_.imageAltDesc AS imageAltDesc_7, a1_.user_id AS user_id_8 FROM User u0_ INNER JOIN Avatar a1_ ON u0_.id = a1_.user_id) dctrn_result_inner ORDER BY imageHeight_5 * imageWidth_6 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testCountQueryWithComplexScalarOrderByItemOracle(): void { - $query = $this->entityManager->createQuery( - 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageHeight * a.imageWidth DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageHeight * a.imageWidth DESC'); self::assertSame( - 'SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.image AS IMAGE_1, a0_.imageHeight AS IMAGEHEIGHT_2, a0_.imageWidth AS IMAGEWIDTH_3, a0_.imageAltDesc AS IMAGEALTDESC_4, ROW_NUMBER() OVER(ORDER BY a0_.imageHeight * a0_.imageWidth DESC) AS SCLR_5, a0_.user_id AS USER_ID_6 FROM Avatar a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_0, MIN(SCLR_5) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.image AS IMAGE_1, a0_.imageHeight AS IMAGEHEIGHT_2, a0_.imageWidth AS IMAGEWIDTH_3, a0_.imageAltDesc AS IMAGEALTDESC_4, ROW_NUMBER() OVER(ORDER BY a0_.imageHeight * a0_.imageWidth DESC) AS SCLR_5, a0_.user_id AS USER_ID_6 FROM Avatar a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', $query->getSQL() ); } @@ -292,75 +232,65 @@ public function testCountQueryWithComplexScalarOrderByItemOracle(): void /** @group DDC-3434 */ public function testLimitSubqueryWithHiddenSelectionInOrderBy(): void { - $query = $this->entityManager->createQuery( + $query = $this->createQuery( 'SELECT a, a.name AS HIDDEN ord FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY ord DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); - self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result_inner ORDER BY name_2 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, a0_.name AS name_2 FROM Author a0_) dctrn_result_inner ORDER BY name_2 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testLimitSubqueryWithColumnWithSortDirectionInName(): void { - $query = $this->entityManager->createQuery( - 'SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageAltDesc DESC' - ); - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); - - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $this->replaceDatabasePlatform(new MySQLPlatform()); + $query = $this->createQuery('SELECT a FROM Doctrine\Tests\ORM\Tools\Pagination\Avatar a ORDER BY a.imageAltDesc DESC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageAltDesc_4 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.imageHeight AS imageHeight_2, a0_.imageWidth AS imageWidth_3, a0_.imageAltDesc AS imageAltDesc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY imageAltDesc_4 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, imageAltDesc_4 FROM (SELECT a0_.id AS id_0, a0_.image AS image_1, a0_.imageHeight AS imageHeight_2, a0_.imageWidth AS imageWidth_3, a0_.imageAltDesc AS imageAltDesc_4, a0_.user_id AS user_id_5 FROM Avatar a0_) dctrn_result_inner ORDER BY imageAltDesc_4 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testLimitSubqueryWithOrderByInnerJoined(): void { - $query = $this->entityManager->createQuery( - 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b JOIN b.author a ORDER BY a.name ASC' - ); - - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query = $this->createQuery('SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b JOIN b.author a ORDER BY a.name ASC'); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT b0_.id AS id_0, a1_.id AS id_1, a1_.name AS name_2, b0_.author_id AS author_id_3, b0_.category_id AS category_id_4 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_2 ASC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, name_2 FROM (SELECT b0_.id AS id_0, a1_.id AS id_1, a1_.name AS name_2, b0_.author_id AS author_id_3, b0_.category_id AS category_id_4 FROM BlogPost b0_ INNER JOIN Author a1_ ON b0_.author_id = a1_.id) dctrn_result_inner ORDER BY name_2 ASC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testLimitSubqueryWithOrderByAndSubSelectInWhereClauseMySql(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); - $query = $this->entityManager->createQuery( + $this->replaceDatabasePlatform(new MySQLPlatform()); + + $query = $this->createQuery( 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b WHERE ((SELECT COUNT(simple.id) FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost simple) = 1) ORDER BY b.id DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.author_id AS author_id_1, b0_.category_id AS category_id_2 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_3 FROM BlogPost b1_) = 1)) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } public function testLimitSubqueryWithOrderByAndSubSelectInWhereClausePgSql(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); + + $query = $this->createQuery( 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost b WHERE ((SELECT COUNT(simple.id) FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost simple) = 1) ORDER BY b.id DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0, MIN(sclr_1) AS dctrn_minrownum FROM (SELECT b0_.id AS id_0, ROW_NUMBER() OVER(ORDER BY b0_.id DESC) AS sclr_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_4 FROM BlogPost b1_) = 1)) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', + 'SELECT DISTINCT id_0, MIN(sclr_1) AS dctrn_minrownum FROM (SELECT b0_.id AS id_0, ROW_NUMBER() OVER(ORDER BY b0_.id DESC) AS sclr_1, b0_.author_id AS author_id_2, b0_.category_id AS category_id_3 FROM BlogPost b0_ WHERE ((SELECT COUNT(b1_.id) AS sclr_4 FROM BlogPost b1_) = 1)) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', $query->getSQL() ); } @@ -370,16 +300,15 @@ public function testLimitSubqueryWithOrderByAndSubSelectInWhereClausePgSql(): vo */ public function testLimitSubqueryOrderByFieldFromMappedSuperclass(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); // now use the third one in query - $query = $this->entityManager->createQuery( + $query = $this->createQuery( 'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\Banner b ORDER BY b.id DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result_inner ORDER BY id_0 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } @@ -389,9 +318,9 @@ public function testLimitSubqueryOrderByFieldFromMappedSuperclass(): void */ public function testLimitSubqueryOrderBySubSelectOrderByExpression(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new MySQLPlatform()); + $this->replaceDatabasePlatform(new MySQLPlatform()); - $query = $this->entityManager->createQuery( + $query = $this->createQuery( 'SELECT a, ( SELECT MIN(bp.title) @@ -401,10 +330,9 @@ public function testLimitSubqueryOrderBySubSelectOrderByExpression(): void FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY first_blog_post DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, sclr_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result_inner ORDER BY sclr_2 DESC) dctrn_result', + 'SELECT DISTINCT id_0 FROM (SELECT DISTINCT id_0, sclr_2 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result_inner ORDER BY sclr_2 DESC) dctrn_result LIMIT 20 OFFSET 10', $query->getSQL() ); } @@ -414,9 +342,9 @@ public function testLimitSubqueryOrderBySubSelectOrderByExpression(): void */ public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new PostgreSQLPlatform()); + $this->replaceDatabasePlatform(new PostgreSQLPlatform()); - $query = $this->entityManager->createQuery( + $query = $this->createQuery( 'SELECT a, ( SELECT MIN(bp.title) @@ -426,10 +354,9 @@ public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg(): void FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY first_blog_post DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT id_0, MIN(sclr_4) AS dctrn_minrownum FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS sclr_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS sclr_4 FROM Author a0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC', + 'SELECT DISTINCT id_0, MIN(sclr_4) AS dctrn_minrownum FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS sclr_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS sclr_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS sclr_4 FROM Author a0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC LIMIT 20 OFFSET 10', $query->getSQL() ); } @@ -439,9 +366,9 @@ public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg(): void */ public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle(): void { - $this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform()); + $this->replaceDatabasePlatform(new OraclePlatform()); - $query = $this->entityManager->createQuery( + $query = $this->createQuery( 'SELECT a, ( SELECT MIN(bp.title) @@ -451,11 +378,20 @@ public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle(): void FROM Doctrine\Tests\ORM\Tools\Pagination\Author a ORDER BY first_blog_post DESC' ); - $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); self::assertSame( - 'SELECT DISTINCT ID_0, MIN(SCLR_4) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.name AS NAME_1, (SELECT MIN(m1_.title) AS SCLR_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS SCLR_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS SCLR_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS SCLR_4 FROM Author a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC', + 'SELECT * FROM (SELECT a.*, ROWNUM AS doctrine_rownum FROM (SELECT DISTINCT ID_0, MIN(SCLR_4) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.name AS NAME_1, (SELECT MIN(m1_.title) AS SCLR_3 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS SCLR_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS SCLR_5 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS SCLR_4 FROM Author a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC) a WHERE ROWNUM <= 30) WHERE doctrine_rownum >= 11', $query->getSQL() ); } + + private function createQuery(string $dql): Query + { + $query = $this->entityManager->createQuery($dql); + $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, LimitSubqueryOutputWalker::class); + $query->setFirstResult(10); + $query->setMaxResults(20); + + return $query; + } } From 79c7c5087e911258a7f410585a093fa464b90977 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 15 Nov 2023 23:48:59 +0100 Subject: [PATCH 082/128] Fix calls to removed lock methods (#11061) --- .../Entity/BasicEntityPersister.php | 11 +++-- .../Entity/JoinedSubclassPersister.php | 6 ++- lib/Doctrine/ORM/Query/SqlWalker.php | 7 ++- lib/Doctrine/ORM/Utility/LockSqlHelper.php | 47 +++++++++++++++++++ phpstan-dbal2.neon | 2 + phpstan-persistence2.neon | 3 ++ phpstan.neon | 3 ++ psalm.xml | 2 + .../Tests/ORM/Functional/Locking/LockTest.php | 23 +++++---- 9 files changed, 84 insertions(+), 20 deletions(-) create mode 100644 lib/Doctrine/ORM/Utility/LockSqlHelper.php diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index 0d11dc9238d..e83589c4180 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -31,6 +31,7 @@ use Doctrine\ORM\Repository\Exception\InvalidFindByCall; use Doctrine\ORM\UnitOfWork; use Doctrine\ORM\Utility\IdentifierFlattener; +use Doctrine\ORM\Utility\LockSqlHelper; use Doctrine\ORM\Utility\PersisterHelper; use LengthException; @@ -92,6 +93,8 @@ */ class BasicEntityPersister implements EntityPersister { + use LockSqlHelper; + /** @var array */ private static $comparisonMap = [ Comparison::EQ => '= %s', @@ -1116,11 +1119,11 @@ public function getSelectSQL($criteria, $assoc = null, $lockMode = null, $limit switch ($lockMode) { case LockMode::PESSIMISTIC_READ: - $lockSql = ' ' . $this->platform->getReadLockSQL(); + $lockSql = ' ' . $this->getReadLockSQL($this->platform); break; case LockMode::PESSIMISTIC_WRITE: - $lockSql = ' ' . $this->platform->getWriteLockSQL(); + $lockSql = ' ' . $this->getWriteLockSQL($this->platform); break; } @@ -1578,11 +1581,11 @@ public function lock(array $criteria, $lockMode) switch ($lockMode) { case LockMode::PESSIMISTIC_READ: - $lockSql = $this->platform->getReadLockSQL(); + $lockSql = $this->getReadLockSQL($this->platform); break; case LockMode::PESSIMISTIC_WRITE: - $lockSql = $this->platform->getWriteLockSQL(); + $lockSql = $this->getWriteLockSQL($this->platform); break; } diff --git a/lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php index f286ac1d8e4..1d6a47855f9 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/JoinedSubclassPersister.php @@ -10,6 +10,7 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Internal\SQLResultCasing; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Utility\LockSqlHelper; use Doctrine\ORM\Utility\PersisterHelper; use LengthException; @@ -26,6 +27,7 @@ */ class JoinedSubclassPersister extends AbstractEntityInheritancePersister { + use LockSqlHelper; use SQLResultCasing; /** @@ -316,12 +318,12 @@ public function getSelectSQL($criteria, $assoc = null, $lockMode = null, $limit switch ($lockMode) { case LockMode::PESSIMISTIC_READ: - $lockSql = ' ' . $this->platform->getReadLockSQL(); + $lockSql = ' ' . $this->getReadLockSQL($this->platform); break; case LockMode::PESSIMISTIC_WRITE: - $lockSql = ' ' . $this->platform->getWriteLockSQL(); + $lockSql = ' ' . $this->getWriteLockSQL($this->platform); break; } diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php index 34e5b22580d..f3d0ab794c0 100644 --- a/lib/Doctrine/ORM/Query/SqlWalker.php +++ b/lib/Doctrine/ORM/Query/SqlWalker.php @@ -16,6 +16,7 @@ use Doctrine\ORM\OptimisticLockException; use Doctrine\ORM\Query; use Doctrine\ORM\Utility\HierarchyDiscriminatorResolver; +use Doctrine\ORM\Utility\LockSqlHelper; use Doctrine\ORM\Utility\PersisterHelper; use InvalidArgumentException; use LogicException; @@ -48,6 +49,8 @@ */ class SqlWalker implements TreeWalker { + use LockSqlHelper; + public const HINT_DISTINCT = 'doctrine.distinct'; /** @@ -577,11 +580,11 @@ public function walkSelectStatement(AST\SelectStatement $AST) } if ($lockMode === LockMode::PESSIMISTIC_READ) { - return $sql . ' ' . $this->platform->getReadLockSQL(); + return $sql . ' ' . $this->getReadLockSQL($this->platform); } if ($lockMode === LockMode::PESSIMISTIC_WRITE) { - return $sql . ' ' . $this->platform->getWriteLockSQL(); + return $sql . ' ' . $this->getWriteLockSQL($this->platform); } if ($lockMode !== LockMode::OPTIMISTIC) { diff --git a/lib/Doctrine/ORM/Utility/LockSqlHelper.php b/lib/Doctrine/ORM/Utility/LockSqlHelper.php new file mode 100644 index 00000000000..30d86a5ce5c --- /dev/null +++ b/lib/Doctrine/ORM/Utility/LockSqlHelper.php @@ -0,0 +1,47 @@ +getWriteLockSQL($platform); + } + + private function getWriteLockSQL(AbstractPlatform $platform): string + { + if ($platform instanceof DB2Platform) { + return 'WITH RR USE AND KEEP UPDATE LOCKS'; + } + + if ($platform instanceof SqlitePlatform) { + return ''; + } + + if ($platform instanceof SQLServerPlatform) { + return ''; + } + + return 'FOR UPDATE'; + } +} diff --git a/phpstan-dbal2.neon b/phpstan-dbal2.neon index c2a8bcb4476..21d1518fd2c 100644 --- a/phpstan-dbal2.neon +++ b/phpstan-dbal2.neon @@ -10,6 +10,8 @@ parameters: - '/Call to an undefined method Doctrine\\DBAL\\Connection::createSchemaManager\(\)\./' # Class name will change in DBAL 3. - '/^Class Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform not found\.$/' + - '/^Class Doctrine\\DBAL\\Platforms\\AbstractMySQLPlatform not found\.$/' + - '/^Class Doctrine\\DBAL\\Platforms\\MySQLPlatform not found\.$/' - message: '/Doctrine\\DBAL\\Platforms\\MyS(ql|QL)Platform/' path: lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php diff --git a/phpstan-persistence2.neon b/phpstan-persistence2.neon index 41d9db7a30c..5d077ce6fe2 100644 --- a/phpstan-persistence2.neon +++ b/phpstan-persistence2.neon @@ -27,6 +27,9 @@ parameters: - message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + - + message: '/^Instanceof between Doctrine\\DBAL\\Platforms\\AbstractPlatform and Doctrine\\DBAL\\Platforms\\MySQLPlatform will always evaluate to false\.$/' + path: lib/Doctrine/ORM/Utility/LockSqlHelper.php # False positive - diff --git a/phpstan.neon b/phpstan.neon index c80418eede6..2d8e67554ac 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -27,6 +27,9 @@ parameters: - message: '/^Call to static method ensure\(\) on an unknown class Doctrine\\DBAL\\ForwardCompatibility\\Result\.$/' path: lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php + - + message: '/^Instanceof between Doctrine\\DBAL\\Platforms\\AbstractPlatform and Doctrine\\DBAL\\Platforms\\MySQLPlatform will always evaluate to false\.$/' + path: lib/Doctrine/ORM/Utility/LockSqlHelper.php # False positive - diff --git a/psalm.xml b/psalm.xml index a8a096c3ae4..05e6f636797 100644 --- a/psalm.xml +++ b/psalm.xml @@ -158,6 +158,7 @@ + @@ -256,6 +257,7 @@ + diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php b/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php index c3992212748..2b5b398ce8d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/Locking/LockTest.php @@ -5,6 +5,7 @@ namespace Doctrine\Tests\ORM\Functional\Locking; use Doctrine\DBAL\LockMode; +use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\ORM\OptimisticLockException; use Doctrine\ORM\Query; use Doctrine\ORM\TransactionRequiredException; @@ -168,9 +169,7 @@ public function testRefreshWithLockPessimisticWriteNoTransactionThrowsException( */ public function testLockPessimisticWrite(): void { - $writeLockSql = $this->_em->getConnection()->getDatabasePlatform()->getWriteLockSQL(); - - if (! $writeLockSql) { + if ($this->_em->getConnection()->getDatabasePlatform() instanceof SQLitePlatform) { self::markTestSkipped('Database Driver has no Write Lock support.'); } @@ -195,7 +194,7 @@ public function testLockPessimisticWrite(): void $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; } - self::assertStringContainsString($writeLockSql, $lastLoggedQuery); + self::assertStringContainsString('FOR UPDATE', $lastLoggedQuery); } /** @@ -203,9 +202,7 @@ public function testLockPessimisticWrite(): void */ public function testRefreshWithLockPessimisticWrite(): void { - $writeLockSql = $this->_em->getConnection()->getDatabasePlatform()->getWriteLockSQL(); - - if (! $writeLockSql) { + if ($this->_em->getConnection()->getDatabasePlatform() instanceof SQLitePlatform) { self::markTestSkipped('Database Driver has no Write Lock support.'); } @@ -230,15 +227,13 @@ public function testRefreshWithLockPessimisticWrite(): void $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; } - self::assertStringContainsString($writeLockSql, $lastLoggedQuery); + self::assertStringContainsString('FOR UPDATE', $lastLoggedQuery); } /** @group DDC-178 */ public function testLockPessimisticRead(): void { - $readLockSql = $this->_em->getConnection()->getDatabasePlatform()->getReadLockSQL(); - - if (! $readLockSql) { + if ($this->_em->getConnection()->getDatabasePlatform() instanceof SQLitePlatform) { self::markTestSkipped('Database Driver has no Write Lock support.'); } @@ -264,7 +259,11 @@ public function testLockPessimisticRead(): void $lastLoggedQuery = $this->getLastLoggedQuery(1)['sql']; } - self::assertStringContainsString($readLockSql, $lastLoggedQuery); + self::assertThat($lastLoggedQuery, self::logicalOr( + self::stringContains('FOR UPDATE'), + self::stringContains('FOR SHARE'), + self::stringContains('LOCK IN SHARE MODE') + )); } /** @group DDC-1693 */ From a9fcaf1d18f939a81b8e42a5876cef7a8a101905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 3 Feb 2024 18:33:26 +0100 Subject: [PATCH 083/128] Update branch metadata --- .doctrine-project.json | 10 ++++++++-- README.md | 14 +++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.doctrine-project.json b/.doctrine-project.json index 1795e4513ac..577fd732682 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -11,17 +11,23 @@ "slug": "latest", "upcoming": true }, + { + "name": "2.19", + "branchName": "2.19.x", + "slug": "2.19", + "upcoming": true + }, { "name": "2.18", "branchName": "2.18.x", "slug": "2.18", - "upcoming": true + "current": true }, { "name": "2.17", "branchName": "2.17.x", "slug": "2.17", - "current": true + "maintained": false }, { "name": "2.16", diff --git a/README.md b/README.md index 22aab0538c4..a128c1f1e9c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -| [3.0.x][3.0] | [2.18.x][2.18] | [2.17.x][2.17] | +| [3.0.x][3.0] | [2.19.x][2.19] | [2.18.x][2.18] | |:----------------:|:----------------:|:----------:| -| [![Build status][3.0 image]][3.0] | [![Build status][2.18 image]][2.18] | [![Build status][2.17 image]][2.17] | -| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.18 coverage image]][2.18 coverage] | [![Coverage Status][2.17 coverage image]][2.17 coverage] | +| [![Build status][3.0 image]][3.0] | [![Build status][2.19 image]][2.19] | [![Build status][2.18 image]][2.18] | +| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.19 coverage image]][2.19 coverage] | [![Coverage Status][2.18 coverage image]][2.18 coverage] | [

πŸ‡ΊπŸ‡¦ UKRAINE NEEDS YOUR HELP NOW!

](https://www.doctrine-project.org/stop-war.html) @@ -22,11 +22,11 @@ without requiring unnecessary code duplication. [3.0]: https://github.com/doctrine/orm/tree/3.0.x [3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg [3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x + [2.19 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.19.x + [2.19]: https://github.com/doctrine/orm/tree/2.19.x + [2.19 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.19.x/graph/badge.svg + [2.19 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.19.x [2.18 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.18.x [2.18]: https://github.com/doctrine/orm/tree/2.18.x [2.18 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.18.x/graph/badge.svg [2.18 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.18.x - [2.17 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.17.x - [2.17]: https://github.com/doctrine/orm/tree/2.17.x - [2.17 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.17.x/graph/badge.svg - [2.17 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.17.x From 9ce9ae2818379574f784f22dc1c183015ab6a018 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sat, 3 Feb 2024 19:18:18 +0100 Subject: [PATCH 084/128] Update branches in README --- README.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a128c1f1e9c..c8e009fd5a5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -| [3.0.x][3.0] | [2.19.x][2.19] | [2.18.x][2.18] | -|:----------------:|:----------------:|:----------:| -| [![Build status][3.0 image]][3.0] | [![Build status][2.19 image]][2.19] | [![Build status][2.18 image]][2.18] | -| [![Coverage Status][3.0 coverage image]][3.0 coverage]| [![Coverage Status][2.19 coverage image]][2.19 coverage] | [![Coverage Status][2.18 coverage image]][2.18 coverage] | +| [4.0.x][4.0] | [3.1.x][3.1] | [3.0.x][3.0] | [2.19.x][2.19] | [2.18.x][2.18] | +|:------------------------------------------------------:|:------------------------------------------------------:|:-------------------------------------------------------:|:--------------------------------------------------------:|:---------------------------------------------------------:| +| [![Build status][4.0 image]][4.0] | [![Build status][3.1 image]][3.1] | [![Build status][3.0 image]][3.0] | [![Build status][2.19 image]][2.19] | [![Build status][2.18 image]][2.18] | +| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.1 coverage image]][3.1 coverage] | [![Coverage Status][3.0 coverage image]][3.0 coverage] | [![Coverage Status][2.19 coverage image]][2.19 coverage] | [![Coverage Status][2.18 coverage image]][2.18 coverage] | [

πŸ‡ΊπŸ‡¦ UKRAINE NEEDS YOUR HELP NOW!

](https://www.doctrine-project.org/stop-war.html) @@ -18,6 +18,14 @@ without requiring unnecessary code duplication. * [Documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/stable/index.html) + [4.0 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0.x + [4.0]: https://github.com/doctrine/orm/tree/4.0.x + [4.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/4.0.x/graph/badge.svg + [4.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/4.0.x + [3.1 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.1.x + [3.1]: https://github.com/doctrine/orm/tree/3.1.x + [3.1 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.1.x/graph/badge.svg + [3.1 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.1.x [3.0 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.0.x [3.0]: https://github.com/doctrine/orm/tree/3.0.x [3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg From 6f98147d093bc594199c98eb49af71fc558ca1f9 Mon Sep 17 00:00:00 2001 From: Michael Skvortsov Date: Sun, 4 Feb 2024 01:11:40 +0200 Subject: [PATCH 085/128] Ignore subclasses without discriminatorValue when generating discriminator column condition SQL (#11200) After commit https://github.com/doctrine/orm/commit/4e8e3ef30b3d214640883aec5a17896afc006116 when `\Doctrine\ORM\Query\SqlWalker` generates dicsriminator column condition SQL (method `\Doctrine\ORM\Query\SqlWalker::generateDiscriminatorColumnConditionSQL`) it adds an empty string to the list of possible values if the inheritance hierarchy contains a non-root abstract class. When the discriminator column is implemented with a custom type in PostgreSQL (equivalent of Enum) the query fails because the type cannot have a value of an empty string. It boils down to the fact that `\Doctrine\ORM\Mapping\ClassMetadataInfo::$subClasses` contains an abstract class and in its Metadata the value of `\Doctrine\ORM\Mapping\ClassMetadataInfo::$discriminatorValue` is `null`. #### Previous behavior In version 2.14.1 `\Doctrine\ORM\Mapping\ClassMetadataInfo::$subClasses` does not contain an abstract class. Fixes #11199, fixes #11177, fixes #10846. --------- Co-authored-by: Michael Skvortsov Co-authored-by: Matthias Pigulla --- src/Query/SqlWalker.php | 24 +++-- .../ORM/Functional/Ticket/GH11199Test.php | 96 +++++++++++++++++++ 2 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11199Test.php diff --git a/src/Query/SqlWalker.php b/src/Query/SqlWalker.php index f3d0ab794c0..70971459340 100644 --- a/src/Query/SqlWalker.php +++ b/src/Query/SqlWalker.php @@ -471,6 +471,10 @@ private function generateDiscriminatorColumnConditionSQL(array $dqlAliases): str continue; } + $sqlTableAlias = $this->useSqlTableAliases + ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' + : ''; + $conn = $this->em->getConnection(); $values = []; @@ -479,14 +483,22 @@ private function generateDiscriminatorColumnConditionSQL(array $dqlAliases): str } foreach ($class->subClasses as $subclassName) { - $values[] = $conn->quote($this->em->getClassMetadata($subclassName)->discriminatorValue); - } + $subclassMetadata = $this->em->getClassMetadata($subclassName); - $sqlTableAlias = $this->useSqlTableAliases - ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' - : ''; + // Abstract entity classes show up in the list of subClasses, but may be omitted + // from the discriminator map. In that case, they have a null discriminator value. + if ($subclassMetadata->discriminatorValue === null) { + continue; + } - $sqlParts[] = $sqlTableAlias . $class->getDiscriminatorColumn()['name'] . ' IN (' . implode(', ', $values) . ')'; + $values[] = $conn->quote($subclassMetadata->discriminatorValue); + } + + if ($values !== []) { + $sqlParts[] = $sqlTableAlias . $class->getDiscriminatorColumn()['name'] . ' IN (' . implode(', ', $values) . ')'; + } else { + $sqlParts[] = '1=0'; // impossible condition + } } $sql = implode(' AND ', $sqlParts); diff --git a/tests/Tests/ORM/Functional/Ticket/GH11199Test.php b/tests/Tests/ORM/Functional/Ticket/GH11199Test.php new file mode 100644 index 00000000000..cac299e12b8 --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11199Test.php @@ -0,0 +1,96 @@ +setUpEntitySchema([ + GH11199Root::class, + GH11199Parent::class, + GH11199Foo::class, + GH11199Baz::class, + GH11199AbstractLeaf::class, + ]); + } + + public function dqlStatements(): Generator + { + yield ['SELECT e FROM ' . GH11199Root::class . ' e', "/WHERE g0_.asset_type IN \('root', 'foo', 'baz'\)$/"]; + yield ['SELECT e FROM ' . GH11199Parent::class . ' e', "/WHERE g0_.asset_type IN \('foo'\)$/"]; + yield ['SELECT e FROM ' . GH11199Foo::class . ' e', "/WHERE g0_.asset_type IN \('foo'\)$/"]; + yield ['SELECT e FROM ' . GH11199Baz::class . ' e', "/WHERE g0_.asset_type IN \('baz'\)$/"]; + yield ['SELECT e FROM ' . GH11199AbstractLeaf::class . ' e', '/WHERE 1=0/']; + } + + /** + * @dataProvider dqlStatements + */ + public function testGH11199(string $dql, string $expectedDiscriminatorValues): void + { + $query = $this->_em->createQuery($dql); + $sql = $query->getSQL(); + + self::assertMatchesRegularExpression($expectedDiscriminatorValues, $sql); + } +} + +/** + * @ORM\Entity() + * @ORM\Table(name="gh11199") + * @ORM\InheritanceType("SINGLE_TABLE") + * @ORM\DiscriminatorColumn(name="asset_type", type="string") + * @ORM\DiscriminatorMap({ + * "root" = "\Doctrine\Tests\ORM\Functional\Ticket\GH11199Root", + * "foo" = "\Doctrine\Tests\ORM\Functional\Ticket\GH11199Foo", + * "baz" = "\Doctrine\Tests\ORM\Functional\Ticket\GH11199Baz", + * }) + */ +class GH11199Root +{ + /** + * @ORM\Id + * @ORM\GeneratedValue(strategy="IDENTITY") + * @ORM\Column(type="integer") + * + * @var int|null + */ + private $id = null; +} + +/** + * @ORM\Entity() + */ +abstract class GH11199Parent extends GH11199Root +{ +} + +/** + * @ORM\Entity() + */ +class GH11199Foo extends GH11199Parent +{ +} + +/** + * @ORM\Entity() + */ +class GH11199Baz extends GH11199Root +{ +} + +/** + * @ORM\Entity() + */ +abstract class GH11199AbstractLeaf extends GH11199Root +{ +} From 40fbbf4429b0d66517244051237a2bd0616a7a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 4 Feb 2024 17:41:45 +0100 Subject: [PATCH 086/128] Point link to correct upgrade guide (#11220) --- docs/en/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/index.rst b/docs/en/index.rst index a7979cb1a70..0236d9968c8 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -96,7 +96,7 @@ Tutorials Changelogs ---------- -* `Upgrade `_ +* `Upgrade `_ Cookbook -------- From 5049b615c510bb9c5bcc62df92c6fc622cb7fb57 Mon Sep 17 00:00:00 2001 From: Karoly Gossler Date: Wed, 7 Feb 2024 13:31:08 +0100 Subject: [PATCH 087/128] Add TokenType class (#11228) * Add TokenType class Co-authored-by: Alexander M. Turek * Deprecated Lexer constants in favour of TokenType * Replace all Lexer::T_ occurrences with TokenType::T_ * Add upgrade note * Fixed import Lexer => TokenType * Fixed deprecation phpdoc * Replaced int value with matching constant of TokenType * Update src/Query/Lexer.php --------- Co-authored-by: Alexander M. Turek --- UPGRADE.md | 6 + .../cookbook/dql-user-defined-functions.rst | 20 +- .../reference/dql-doctrine-query-language.rst | 8 +- psalm-baseline.xml | 2 +- src/Query/AST/Functions/AbsFunction.php | 8 +- src/Query/AST/Functions/BitAndFunction.php | 10 +- src/Query/AST/Functions/BitOrFunction.php | 10 +- src/Query/AST/Functions/ConcatFunction.php | 14 +- .../AST/Functions/CurrentDateFunction.php | 8 +- .../AST/Functions/CurrentTimeFunction.php | 8 +- .../Functions/CurrentTimestampFunction.php | 8 +- src/Query/AST/Functions/DateAddFunction.php | 12 +- src/Query/AST/Functions/DateDiffFunction.php | 10 +- src/Query/AST/Functions/IdentityFunction.php | 14 +- src/Query/AST/Functions/LengthFunction.php | 8 +- src/Query/AST/Functions/LocateFunction.php | 14 +- src/Query/AST/Functions/LowerFunction.php | 8 +- src/Query/AST/Functions/ModFunction.php | 10 +- src/Query/AST/Functions/SizeFunction.php | 8 +- src/Query/AST/Functions/SqrtFunction.php | 8 +- src/Query/AST/Functions/SubstringFunction.php | 14 +- src/Query/AST/Functions/TrimFunction.php | 20 +- src/Query/AST/Functions/UpperFunction.php | 8 +- src/Query/Lexer.php | 316 ++++++-- src/Query/Parser.php | 690 +++++++++--------- src/Query/TokenType.php | 99 +++ .../ORM/Functional/CustomFunctionsTest.php | 8 +- .../ORM/Functional/Ticket/GH7286Test.php | 10 +- tests/Tests/ORM/Query/LexerTest.php | 69 +- tests/Tests/ORM/Query/ParserTest.php | 28 +- .../ORM/Query/SelectSqlGenerationTest.php | 8 +- .../Tests/ORM/Query/TreeWalkerAdapterTest.php | 6 +- 32 files changed, 865 insertions(+), 605 deletions(-) create mode 100644 src/Query/TokenType.php diff --git a/UPGRADE.md b/UPGRADE.md index df40b151d24..a0a360d72d7 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,3 +1,9 @@ +# Upgrade to 2.19 + +## Deprecate `Doctrine\ORM\Query\Lexer::T_*` constants + +Use `Doctrine\ORM\Query\TokenType::T_*` instead. + # Upgrade to 2.17 ## Deprecate annotations classes for named queries diff --git a/docs/en/cookbook/dql-user-defined-functions.rst b/docs/en/cookbook/dql-user-defined-functions.rst index 9345a2535e9..b189ed59fcd 100644 --- a/docs/en/cookbook/dql-user-defined-functions.rst +++ b/docs/en/cookbook/dql-user-defined-functions.rst @@ -99,12 +99,12 @@ discuss it step by step: public function parse(\Doctrine\ORM\Query\Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); // (2) - $parser->match(Lexer::T_OPEN_PARENTHESIS); // (3) + $parser->match(TokenType::T_IDENTIFIER); // (2) + $parser->match(TokenType::T_OPEN_PARENTHESIS); // (3) $this->firstDateExpression = $parser->ArithmeticPrimary(); // (4) - $parser->match(Lexer::T_COMMA); // (5) + $parser->match(TokenType::T_COMMA); // (5) $this->secondDateExpression = $parser->ArithmeticPrimary(); // (6) - $parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3) + $parser->match(TokenType::T_CLOSE_PARENTHESIS); // (3) } public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) @@ -183,23 +183,23 @@ I'll skip the blah and show the code for this function: public function parse(\Doctrine\ORM\Query\Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstDateExpression = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); - $parser->match(Lexer::T_IDENTIFIER); + $parser->match(TokenType::T_COMMA); + $parser->match(TokenType::T_IDENTIFIER); $this->intervalExpression = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_IDENTIFIER); + $parser->match(TokenType::T_IDENTIFIER); /** @var Lexer $lexer */ $lexer = $parser->getLexer(); $this->unit = $lexer->token['value']; - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst index a9a7d6d3a1c..571190072e3 100644 --- a/docs/en/reference/dql-doctrine-query-language.rst +++ b/docs/en/reference/dql-doctrine-query-language.rst @@ -812,7 +812,7 @@ classes have to implement the base class : namespace MyProject\Query\AST; use Doctrine\ORM\Query\AST\Functions\FunctionNode; - use Doctrine\ORM\Query\Lexer; + use Doctrine\ORM\Query\TokenType; class MysqlFloor extends FunctionNode { @@ -827,12 +827,12 @@ classes have to implement the base class : public function parse(\Doctrine\ORM\Query\Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 34b44307ff3..d2e890f17b5 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -2046,7 +2046,7 @@ $AST instanceof AST\SelectStatement - $token === Lexer::T_IDENTIFIER + $token === TokenType::T_IDENTIFIER
diff --git a/src/Query/AST/Functions/AbsFunction.php b/src/Query/AST/Functions/AbsFunction.php index c7c35a9dfda..5c0fd7fac15 100644 --- a/src/Query/AST/Functions/AbsFunction.php +++ b/src/Query/AST/Functions/AbsFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "ABS" "(" SimpleArithmeticExpression ")" @@ -30,11 +30,11 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/BitAndFunction.php b/src/Query/AST/Functions/BitAndFunction.php index 93edf48ae59..c278de5e36e 100644 --- a/src/Query/AST/Functions/BitAndFunction.php +++ b/src/Query/AST/Functions/BitAndFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "BIT_AND" "(" ArithmeticPrimary "," ArithmeticPrimary ")" @@ -36,13 +36,13 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstArithmetic = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->secondArithmetic = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/BitOrFunction.php b/src/Query/AST/Functions/BitOrFunction.php index 94fea1d8ea3..a380009cceb 100644 --- a/src/Query/AST/Functions/BitOrFunction.php +++ b/src/Query/AST/Functions/BitOrFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "BIT_OR" "(" ArithmeticPrimary "," ArithmeticPrimary ")" @@ -36,13 +36,13 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstArithmetic = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->secondArithmetic = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/ConcatFunction.php b/src/Query/AST/Functions/ConcatFunction.php index 8a67fbbb896..f25f0e69668 100644 --- a/src/Query/AST/Functions/ConcatFunction.php +++ b/src/Query/AST/Functions/ConcatFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "CONCAT" "(" StringPrimary "," StringPrimary {"," StringPrimary }* ")" @@ -42,22 +42,22 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstStringPrimary = $parser->StringPrimary(); $this->concatExpressions[] = $this->firstStringPrimary; - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->secondStringPrimary = $parser->StringPrimary(); $this->concatExpressions[] = $this->secondStringPrimary; - while ($parser->getLexer()->isNextToken(Lexer::T_COMMA)) { - $parser->match(Lexer::T_COMMA); + while ($parser->getLexer()->isNextToken(TokenType::T_COMMA)) { + $parser->match(TokenType::T_COMMA); $this->concatExpressions[] = $parser->StringPrimary(); } - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/CurrentDateFunction.php b/src/Query/AST/Functions/CurrentDateFunction.php index ee7e733901c..c19c640c598 100644 --- a/src/Query/AST/Functions/CurrentDateFunction.php +++ b/src/Query/AST/Functions/CurrentDateFunction.php @@ -4,9 +4,9 @@ namespace Doctrine\ORM\Query\AST\Functions; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "CURRENT_DATE" @@ -24,8 +24,8 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/CurrentTimeFunction.php b/src/Query/AST/Functions/CurrentTimeFunction.php index e906cbe58eb..3595a0385d9 100644 --- a/src/Query/AST/Functions/CurrentTimeFunction.php +++ b/src/Query/AST/Functions/CurrentTimeFunction.php @@ -4,9 +4,9 @@ namespace Doctrine\ORM\Query\AST\Functions; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "CURRENT_TIME" @@ -24,8 +24,8 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/CurrentTimestampFunction.php b/src/Query/AST/Functions/CurrentTimestampFunction.php index 0bf1a801e25..349e32746df 100644 --- a/src/Query/AST/Functions/CurrentTimestampFunction.php +++ b/src/Query/AST/Functions/CurrentTimestampFunction.php @@ -4,9 +4,9 @@ namespace Doctrine\ORM\Query\AST\Functions; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "CURRENT_TIMESTAMP" @@ -24,8 +24,8 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/DateAddFunction.php b/src/Query/AST/Functions/DateAddFunction.php index efa7849e647..e980e8e8155 100644 --- a/src/Query/AST/Functions/DateAddFunction.php +++ b/src/Query/AST/Functions/DateAddFunction.php @@ -5,10 +5,10 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function strtolower; @@ -84,15 +84,15 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstDateExpression = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->intervalExpression = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->unit = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/DateDiffFunction.php b/src/Query/AST/Functions/DateDiffFunction.php index 181535265f4..209df00abd5 100644 --- a/src/Query/AST/Functions/DateDiffFunction.php +++ b/src/Query/AST/Functions/DateDiffFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "DATE_DIFF" "(" ArithmeticPrimary "," ArithmeticPrimary ")" @@ -34,13 +34,13 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->date1 = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->date2 = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/IdentityFunction.php b/src/Query/AST/Functions/IdentityFunction.php index 10b8dc80582..e292c975afd 100644 --- a/src/Query/AST/Functions/IdentityFunction.php +++ b/src/Query/AST/Functions/IdentityFunction.php @@ -5,10 +5,10 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\PathExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function assert; use function reset; @@ -77,20 +77,20 @@ public function getSql(SqlWalker $sqlWalker) */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->pathExpression = $parser->SingleValuedAssociationPathExpression(); - if ($parser->getLexer()->isNextToken(Lexer::T_COMMA)) { - $parser->match(Lexer::T_COMMA); - $parser->match(Lexer::T_STRING); + if ($parser->getLexer()->isNextToken(TokenType::T_COMMA)) { + $parser->match(TokenType::T_COMMA); + $parser->match(TokenType::T_STRING); $token = $parser->getLexer()->token; assert($token !== null); $this->fieldMapping = $token->value; } - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/LengthFunction.php b/src/Query/AST/Functions/LengthFunction.php index 29b603c2484..42420af54f0 100644 --- a/src/Query/AST/Functions/LengthFunction.php +++ b/src/Query/AST/Functions/LengthFunction.php @@ -8,9 +8,9 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Query\AST\Node; use Doctrine\ORM\Query\AST\TypedExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "LENGTH" "(" StringPrimary ")" @@ -33,12 +33,12 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->stringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } public function getReturnType(): Type diff --git a/src/Query/AST/Functions/LocateFunction.php b/src/Query/AST/Functions/LocateFunction.php index 20badbc91eb..2942f06107d 100644 --- a/src/Query/AST/Functions/LocateFunction.php +++ b/src/Query/AST/Functions/LocateFunction.php @@ -6,9 +6,9 @@ use Doctrine\ORM\Query\AST\Node; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" @@ -48,22 +48,22 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstStringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->secondStringPrimary = $parser->StringPrimary(); $lexer = $parser->getLexer(); - if ($lexer->isNextToken(Lexer::T_COMMA)) { - $parser->match(Lexer::T_COMMA); + if ($lexer->isNextToken(TokenType::T_COMMA)) { + $parser->match(TokenType::T_COMMA); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); } - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/LowerFunction.php b/src/Query/AST/Functions/LowerFunction.php index 0b7fcf83b88..e6c73cde4d9 100644 --- a/src/Query/AST/Functions/LowerFunction.php +++ b/src/Query/AST/Functions/LowerFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function sprintf; @@ -33,11 +33,11 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->stringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/ModFunction.php b/src/Query/AST/Functions/ModFunction.php index c0077d04080..ea6ee2e0d4e 100644 --- a/src/Query/AST/Functions/ModFunction.php +++ b/src/Query/AST/Functions/ModFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" @@ -34,15 +34,15 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/SizeFunction.php b/src/Query/AST/Functions/SizeFunction.php index 70b7f6dadf3..4576f26d21f 100644 --- a/src/Query/AST/Functions/SizeFunction.php +++ b/src/Query/AST/Functions/SizeFunction.php @@ -6,9 +6,9 @@ use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Query\AST\PathExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function assert; @@ -105,11 +105,11 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->collectionPathExpression = $parser->CollectionValuedPathExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/SqrtFunction.php b/src/Query/AST/Functions/SqrtFunction.php index 4e3a87015f9..a5cf3038768 100644 --- a/src/Query/AST/Functions/SqrtFunction.php +++ b/src/Query/AST/Functions/SqrtFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function sprintf; @@ -33,11 +33,11 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/SubstringFunction.php b/src/Query/AST/Functions/SubstringFunction.php index 292248ea079..50031c7b361 100644 --- a/src/Query/AST/Functions/SubstringFunction.php +++ b/src/Query/AST/Functions/SubstringFunction.php @@ -6,9 +6,9 @@ use Doctrine\ORM\Query\AST\Node; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; /** * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" @@ -44,22 +44,22 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->stringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); $lexer = $parser->getLexer(); - if ($lexer->isNextToken(Lexer::T_COMMA)) { - $parser->match(Lexer::T_COMMA); + if ($lexer->isNextToken(TokenType::T_COMMA)) { + $parser->match(TokenType::T_COMMA); $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); } - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/AST/Functions/TrimFunction.php b/src/Query/AST/Functions/TrimFunction.php index 8c2b307faea..c2adeb121b9 100644 --- a/src/Query/AST/Functions/TrimFunction.php +++ b/src/Query/AST/Functions/TrimFunction.php @@ -6,9 +6,9 @@ use Doctrine\DBAL\Platforms\TrimMode; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function assert; use function strcasecmp; @@ -62,25 +62,25 @@ public function parse(Parser $parser) { $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->parseTrimMode($parser); - if ($lexer->isNextToken(Lexer::T_STRING)) { - $parser->match(Lexer::T_STRING); + if ($lexer->isNextToken(TokenType::T_STRING)) { + $parser->match(TokenType::T_STRING); assert($lexer->token !== null); $this->trimChar = $lexer->token->value; } if ($this->leading || $this->trailing || $this->both || $this->trimChar) { - $parser->match(Lexer::T_FROM); + $parser->match(TokenType::T_FROM); } $this->stringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } /** @psalm-return TrimMode::* */ @@ -108,7 +108,7 @@ private function parseTrimMode(Parser $parser): void $value = $lexer->lookahead->value; if (strcasecmp('leading', $value) === 0) { - $parser->match(Lexer::T_LEADING); + $parser->match(TokenType::T_LEADING); $this->leading = true; @@ -116,7 +116,7 @@ private function parseTrimMode(Parser $parser): void } if (strcasecmp('trailing', $value) === 0) { - $parser->match(Lexer::T_TRAILING); + $parser->match(TokenType::T_TRAILING); $this->trailing = true; @@ -124,7 +124,7 @@ private function parseTrimMode(Parser $parser): void } if (strcasecmp('both', $value) === 0) { - $parser->match(Lexer::T_BOTH); + $parser->match(TokenType::T_BOTH); $this->both = true; diff --git a/src/Query/AST/Functions/UpperFunction.php b/src/Query/AST/Functions/UpperFunction.php index d896c5af7f7..15273973f98 100644 --- a/src/Query/AST/Functions/UpperFunction.php +++ b/src/Query/AST/Functions/UpperFunction.php @@ -5,9 +5,9 @@ namespace Doctrine\ORM\Query\AST\Functions; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use function sprintf; @@ -33,11 +33,11 @@ public function getSql(SqlWalker $sqlWalker) /** @inheritDoc */ public function parse(Parser $parser) { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->stringPrimary = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } diff --git a/src/Query/Lexer.php b/src/Query/Lexer.php index da68a6c6c1a..d4f0aefc255 100644 --- a/src/Query/Lexer.php +++ b/src/Query/Lexer.php @@ -21,95 +21,249 @@ /** * Scans a DQL query for tokens. * - * @extends AbstractLexer + * @extends AbstractLexer */ class Lexer extends AbstractLexer { // All tokens that are not valid identifiers must be < 100 - public const T_NONE = 1; - public const T_INTEGER = 2; - public const T_STRING = 3; - public const T_INPUT_PARAMETER = 4; - public const T_FLOAT = 5; - public const T_CLOSE_PARENTHESIS = 6; - public const T_OPEN_PARENTHESIS = 7; - public const T_COMMA = 8; - public const T_DIVIDE = 9; - public const T_DOT = 10; - public const T_EQUALS = 11; - public const T_GREATER_THAN = 12; - public const T_LOWER_THAN = 13; - public const T_MINUS = 14; - public const T_MULTIPLY = 15; - public const T_NEGATE = 16; - public const T_PLUS = 17; - public const T_OPEN_CURLY_BRACE = 18; - public const T_CLOSE_CURLY_BRACE = 19; + /** @deprecated use {@see TokenType::T_NONE} */ + public const T_NONE = TokenType::T_NONE; + + /** @deprecated use {@see TokenType::T_INTEGER} */ + public const T_INTEGER = TokenType::T_INTEGER; + + /** @deprecated use {@see TokenType::T_STRING} */ + public const T_STRING = TokenType::T_STRING; + + /** @deprecated use {@see TokenType::T_INPUT_PARAMETER} */ + public const T_INPUT_PARAMETER = TokenType::T_INPUT_PARAMETER; + + /** @deprecated use {@see TokenType::T_FLOAT} */ + public const T_FLOAT = TokenType::T_FLOAT; + + /** @deprecated use {@see TokenType::T_CLOSE_PARENTHESIS} */ + public const T_CLOSE_PARENTHESIS = TokenType::T_CLOSE_PARENTHESIS; + + /** @deprecated use {@see TokenType::T_OPEN_PARENTHESIS} */ + public const T_OPEN_PARENTHESIS = TokenType::T_OPEN_PARENTHESIS; + + /** @deprecated use {@see TokenType::T_COMMA} */ + public const T_COMMA = TokenType::T_COMMA; + + /** @deprecated use {@see TokenType::T_DIVIDE} */ + public const T_DIVIDE = TokenType::T_DIVIDE; + + /** @deprecated use {@see TokenType::T_DOT} */ + public const T_DOT = TokenType::T_DOT; + + /** @deprecated use {@see TokenType::T_EQUALS} */ + public const T_EQUALS = TokenType::T_EQUALS; + + /** @deprecated use {@see TokenType::T_GREATER_THAN} */ + public const T_GREATER_THAN = TokenType::T_GREATER_THAN; + + /** @deprecated use {@see TokenType::T_LOWER_THAN} */ + public const T_LOWER_THAN = TokenType::T_LOWER_THAN; + + /** @deprecated use {@see TokenType::T_MINUS} */ + public const T_MINUS = TokenType::T_MINUS; + + /** @deprecated use {@see TokenType::T_MULTIPLY} */ + public const T_MULTIPLY = TokenType::T_MULTIPLY; + + /** @deprecated use {@see TokenType::T_NEGATE} */ + public const T_NEGATE = TokenType::T_NEGATE; + + /** @deprecated use {@see TokenType::T_PLUS} */ + public const T_PLUS = TokenType::T_PLUS; + + /** @deprecated use {@see TokenType::T_OPEN_CURLY_BRACE} */ + public const T_OPEN_CURLY_BRACE = TokenType::T_OPEN_CURLY_BRACE; + + /** @deprecated use {@see TokenType::T_CLOSE_CURLY_BRACE} */ + public const T_CLOSE_CURLY_BRACE = TokenType::T_CLOSE_CURLY_BRACE; // All tokens that are identifiers or keywords that could be considered as identifiers should be >= 100 /** @deprecated No Replacement planned. */ - public const T_ALIASED_NAME = 100; - public const T_FULLY_QUALIFIED_NAME = 101; - public const T_IDENTIFIER = 102; + public const T_ALIASED_NAME = TokenType::T_ALIASED_NAME; + + /** @deprecated use {@see TokenType::T_FULLY_QUALIFIED_NAME} */ + public const T_FULLY_QUALIFIED_NAME = TokenType::T_FULLY_QUALIFIED_NAME; + + /** @deprecated use {@see TokenType::T_IDENTIFIER} */ + public const T_IDENTIFIER = TokenType::T_IDENTIFIER; // All keyword tokens should be >= 200 - public const T_ALL = 200; - public const T_AND = 201; - public const T_ANY = 202; - public const T_AS = 203; - public const T_ASC = 204; - public const T_AVG = 205; - public const T_BETWEEN = 206; - public const T_BOTH = 207; - public const T_BY = 208; - public const T_CASE = 209; - public const T_COALESCE = 210; - public const T_COUNT = 211; - public const T_DELETE = 212; - public const T_DESC = 213; - public const T_DISTINCT = 214; - public const T_ELSE = 215; - public const T_EMPTY = 216; - public const T_END = 217; - public const T_ESCAPE = 218; - public const T_EXISTS = 219; - public const T_FALSE = 220; - public const T_FROM = 221; - public const T_GROUP = 222; - public const T_HAVING = 223; - public const T_HIDDEN = 224; - public const T_IN = 225; - public const T_INDEX = 226; - public const T_INNER = 227; - public const T_INSTANCE = 228; - public const T_IS = 229; - public const T_JOIN = 230; - public const T_LEADING = 231; - public const T_LEFT = 232; - public const T_LIKE = 233; - public const T_MAX = 234; - public const T_MEMBER = 235; - public const T_MIN = 236; - public const T_NEW = 237; - public const T_NOT = 238; - public const T_NULL = 239; - public const T_NULLIF = 240; - public const T_OF = 241; - public const T_OR = 242; - public const T_ORDER = 243; - public const T_OUTER = 244; - public const T_PARTIAL = 245; - public const T_SELECT = 246; - public const T_SET = 247; - public const T_SOME = 248; - public const T_SUM = 249; - public const T_THEN = 250; - public const T_TRAILING = 251; - public const T_TRUE = 252; - public const T_UPDATE = 253; - public const T_WHEN = 254; - public const T_WHERE = 255; - public const T_WITH = 256; + /** @deprecated use {@see TokenType::T_ALL} */ + public const T_ALL = TokenType::T_ALL; + + /** @deprecated use {@see TokenType::T_AND} */ + public const T_AND = TokenType::T_AND; + + /** @deprecated use {@see TokenType::T_ANY} */ + public const T_ANY = TokenType::T_ANY; + + /** @deprecated use {@see TokenType::T_AS} */ + public const T_AS = TokenType::T_AS; + + /** @deprecated use {@see TokenType::T_ASC} */ + public const T_ASC = TokenType::T_ASC; + + /** @deprecated use {@see TokenType::T_AVG} */ + public const T_AVG = TokenType::T_AVG; + + /** @deprecated use {@see TokenType::T_BETWEEN} */ + public const T_BETWEEN = TokenType::T_BETWEEN; + + /** @deprecated use {@see TokenType::T_BOTH} */ + public const T_BOTH = TokenType::T_BOTH; + + /** @deprecated use {@see TokenType::T_BY} */ + public const T_BY = TokenType::T_BY; + + /** @deprecated use {@see TokenType::T_CASE} */ + public const T_CASE = TokenType::T_CASE; + + /** @deprecated use {@see TokenType::T_COALESCE} */ + public const T_COALESCE = TokenType::T_COALESCE; + + /** @deprecated use {@see TokenType::T_COUNT} */ + public const T_COUNT = TokenType::T_COUNT; + + /** @deprecated use {@see TokenType::T_DELETE} */ + public const T_DELETE = TokenType::T_DELETE; + + /** @deprecated use {@see TokenType::T_DESC} */ + public const T_DESC = TokenType::T_DESC; + + /** @deprecated use {@see TokenType::T_DISTINCT} */ + public const T_DISTINCT = TokenType::T_DISTINCT; + + /** @deprecated use {@see TokenType::T_ELSE} */ + public const T_ELSE = TokenType::T_ELSE; + + /** @deprecated use {@see TokenType::T_EMPTY} */ + public const T_EMPTY = TokenType::T_EMPTY; + + /** @deprecated use {@see TokenType::T_END} */ + public const T_END = TokenType::T_END; + + /** @deprecated use {@see TokenType::T_ESCAPE} */ + public const T_ESCAPE = TokenType::T_ESCAPE; + + /** @deprecated use {@see TokenType::T_EXISTS} */ + public const T_EXISTS = TokenType::T_EXISTS; + + /** @deprecated use {@see TokenType::T_FALSE} */ + public const T_FALSE = TokenType::T_FALSE; + + /** @deprecated use {@see TokenType::T_FROM} */ + public const T_FROM = TokenType::T_FROM; + + /** @deprecated use {@see TokenType::T_GROUP} */ + public const T_GROUP = TokenType::T_GROUP; + + /** @deprecated use {@see TokenType::T_HAVING} */ + public const T_HAVING = TokenType::T_HAVING; + + /** @deprecated use {@see TokenType::T_HIDDEN} */ + public const T_HIDDEN = TokenType::T_HIDDEN; + + /** @deprecated use {@see TokenType::T_IN} */ + public const T_IN = TokenType::T_IN; + + /** @deprecated use {@see TokenType::T_INDEX} */ + public const T_INDEX = TokenType::T_INDEX; + + /** @deprecated use {@see TokenType::T_INNER} */ + public const T_INNER = TokenType::T_INNER; + + /** @deprecated use {@see TokenType::T_INSTANCE} */ + public const T_INSTANCE = TokenType::T_INSTANCE; + + /** @deprecated use {@see TokenType::T_IS} */ + public const T_IS = TokenType::T_IS; + + /** @deprecated use {@see TokenType::T_JOIN} */ + public const T_JOIN = TokenType::T_JOIN; + + /** @deprecated use {@see TokenType::T_LEADING} */ + public const T_LEADING = TokenType::T_LEADING; + + /** @deprecated use {@see TokenType::T_LEFT} */ + public const T_LEFT = TokenType::T_LEFT; + + /** @deprecated use {@see TokenType::T_LIKE} */ + public const T_LIKE = TokenType::T_LIKE; + + /** @deprecated use {@see TokenType::T_MAX} */ + public const T_MAX = TokenType::T_MAX; + + /** @deprecated use {@see TokenType::T_MEMBER} */ + public const T_MEMBER = TokenType::T_MEMBER; + + /** @deprecated use {@see TokenType::T_MIN} */ + public const T_MIN = TokenType::T_MIN; + + /** @deprecated use {@see TokenType::T_NEW} */ + public const T_NEW = TokenType::T_NEW; + + /** @deprecated use {@see TokenType::T_NOT} */ + public const T_NOT = TokenType::T_NOT; + + /** @deprecated use {@see TokenType::T_NULL} */ + public const T_NULL = TokenType::T_NULL; + + /** @deprecated use {@see TokenType::T_NULLIF} */ + public const T_NULLIF = TokenType::T_NULLIF; + + /** @deprecated use {@see TokenType::T_OF} */ + public const T_OF = TokenType::T_OF; + + /** @deprecated use {@see TokenType::T_OR} */ + public const T_OR = TokenType::T_OR; + + /** @deprecated use {@see TokenType::T_ORDER} */ + public const T_ORDER = TokenType::T_ORDER; + + /** @deprecated use {@see TokenType::T_OUTER} */ + public const T_OUTER = TokenType::T_OUTER; + + /** @deprecated use {@see TokenType::T_PARTIAL} */ + public const T_PARTIAL = TokenType::T_PARTIAL; + + /** @deprecated use {@see TokenType::T_SELECT} */ + public const T_SELECT = TokenType::T_SELECT; + + /** @deprecated use {@see TokenType::T_SET} */ + public const T_SET = TokenType::T_SET; + + /** @deprecated use {@see TokenType::T_SOME} */ + public const T_SOME = TokenType::T_SOME; + + /** @deprecated use {@see TokenType::T_SUM} */ + public const T_SUM = TokenType::T_SUM; + + /** @deprecated use {@see TokenType::T_THEN} */ + public const T_THEN = TokenType::T_THEN; + + /** @deprecated use {@see TokenType::T_TRAILING} */ + public const T_TRAILING = TokenType::T_TRAILING; + + /** @deprecated use {@see TokenType::T_TRUE} */ + public const T_TRUE = TokenType::T_TRUE; + + /** @deprecated use {@see TokenType::T_UPDATE} */ + public const T_UPDATE = TokenType::T_UPDATE; + + /** @deprecated use {@see TokenType::T_WHEN} */ + public const T_WHEN = TokenType::T_WHEN; + + /** @deprecated use {@see TokenType::T_WHERE} */ + public const T_WHERE = TokenType::T_WHERE; + + /** @deprecated use {@see TokenType::T_WITH} */ + public const T_WITH = TokenType::T_WITH; /** * Creates a new query scanner object. @@ -169,7 +323,7 @@ protected function getType(&$value) // Recognize identifiers, aliased or qualified names case ctype_alpha($value[0]) || $value[0] === '_' || $value[0] === '\\': - $name = 'Doctrine\ORM\Query\Lexer::T_' . strtoupper($value); + $name = 'Doctrine\ORM\Query\TokenType::T_' . strtoupper($value); if (defined($name)) { $type = constant($name); diff --git a/src/Query/Parser.php b/src/Query/Parser.php index 7e69b4865d0..949a8f4ebdd 100644 --- a/src/Query/Parser.php +++ b/src/Query/Parser.php @@ -36,7 +36,7 @@ * Parses a DQL query, reports any errors in it, and generates an AST. * * @psalm-import-type AssociationMapping from ClassMetadata - * @psalm-type DqlToken = Token + * @psalm-type DqlToken = Token * @psalm-type QueryComponent = array{ * metadata?: ClassMetadata, * parent?: string|null, @@ -290,7 +290,7 @@ public function getAST() * If they match, updates the lookahead token; otherwise raises a syntax * error. * - * @param Lexer::T_* $token The token type. + * @param TokenType::T_* $token The token type. * * @return void * @@ -308,17 +308,17 @@ public function match($token) } // If parameter is not identifier (1-99) must be exact match - if ($token < Lexer::T_IDENTIFIER) { + if ($token < TokenType::T_IDENTIFIER) { $this->syntaxError($this->lexer->getLiteral($token)); } // If parameter is keyword (200+) must be exact match - if ($token > Lexer::T_IDENTIFIER) { + if ($token > TokenType::T_IDENTIFIER) { $this->syntaxError($this->lexer->getLiteral($token)); } // If parameter is T_IDENTIFIER, then matches T_IDENTIFIER (100) and keywords (200+) - if ($token === Lexer::T_IDENTIFIER && $lookaheadType < Lexer::T_IDENTIFIER) { + if ($token === TokenType::T_IDENTIFIER && $lookaheadType < TokenType::T_IDENTIFIER) { $this->syntaxError($this->lexer->getLiteral($token)); } @@ -510,11 +510,11 @@ private function peekBeyondClosingParenthesis(bool $resetPeek = true) while ($numUnmatched > 0 && $token !== null) { switch ($token->type) { - case Lexer::T_OPEN_PARENTHESIS: + case TokenType::T_OPEN_PARENTHESIS: ++$numUnmatched; break; - case Lexer::T_CLOSE_PARENTHESIS: + case TokenType::T_CLOSE_PARENTHESIS: --$numUnmatched; break; @@ -539,7 +539,7 @@ private function peekBeyondClosingParenthesis(bool $resetPeek = true) */ private function isMathOperator($token): bool { - return $token !== null && in_array($token->type, [Lexer::T_PLUS, Lexer::T_MINUS, Lexer::T_DIVIDE, Lexer::T_MULTIPLY], true); + return $token !== null && in_array($token->type, [TokenType::T_PLUS, TokenType::T_MINUS, TokenType::T_DIVIDE, TokenType::T_MULTIPLY], true); } /** @@ -555,13 +555,13 @@ private function isFunction(): bool $this->lexer->resetPeek(); - return $lookaheadType >= Lexer::T_IDENTIFIER && $peek !== null && $peek->type === Lexer::T_OPEN_PARENTHESIS; + return $lookaheadType >= TokenType::T_IDENTIFIER && $peek !== null && $peek->type === TokenType::T_OPEN_PARENTHESIS; } /** * Checks whether the given token type indicates an aggregate function. * - * @psalm-param Lexer::T_* $tokenType + * @psalm-param TokenType::T_* $tokenType * * @return bool TRUE if the token type is an aggregate function, FALSE otherwise. */ @@ -569,7 +569,7 @@ private function isAggregateFunction(int $tokenType): bool { return in_array( $tokenType, - [Lexer::T_AVG, Lexer::T_MIN, Lexer::T_MAX, Lexer::T_SUM, Lexer::T_COUNT], + [TokenType::T_AVG, TokenType::T_MIN, TokenType::T_MAX, TokenType::T_SUM, TokenType::T_COUNT], true ); } @@ -583,7 +583,7 @@ private function isNextAllAnySome(): bool return in_array( $this->lexer->lookahead->type, - [Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME], + [TokenType::T_ALL, TokenType::T_ANY, TokenType::T_SOME], true ); } @@ -846,15 +846,15 @@ public function QueryLanguage() $this->lexer->moveNext(); switch ($this->lexer->lookahead->type ?? null) { - case Lexer::T_SELECT: + case TokenType::T_SELECT: $statement = $this->SelectStatement(); break; - case Lexer::T_UPDATE: + case TokenType::T_UPDATE: $statement = $this->UpdateStatement(); break; - case Lexer::T_DELETE: + case TokenType::T_DELETE: $statement = $this->DeleteStatement(); break; @@ -880,10 +880,10 @@ public function SelectStatement() { $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause()); - $selectStatement->whereClause = $this->lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; - $selectStatement->groupByClause = $this->lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null; - $selectStatement->havingClause = $this->lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null; - $selectStatement->orderByClause = $this->lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null; + $selectStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; + $selectStatement->groupByClause = $this->lexer->isNextToken(TokenType::T_GROUP) ? $this->GroupByClause() : null; + $selectStatement->havingClause = $this->lexer->isNextToken(TokenType::T_HAVING) ? $this->HavingClause() : null; + $selectStatement->orderByClause = $this->lexer->isNextToken(TokenType::T_ORDER) ? $this->OrderByClause() : null; return $selectStatement; } @@ -897,7 +897,7 @@ public function UpdateStatement() { $updateStatement = new AST\UpdateStatement($this->UpdateClause()); - $updateStatement->whereClause = $this->lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + $updateStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; return $updateStatement; } @@ -911,7 +911,7 @@ public function DeleteStatement() { $deleteStatement = new AST\DeleteStatement($this->DeleteClause()); - $deleteStatement->whereClause = $this->lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; + $deleteStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; return $deleteStatement; } @@ -923,7 +923,7 @@ public function DeleteStatement() */ public function IdentificationVariable() { - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $identVariable = $this->lexer->token->value; @@ -944,7 +944,7 @@ public function IdentificationVariable() */ public function AliasIdentificationVariable() { - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $aliasIdentVariable = $this->lexer->token->value; @@ -967,21 +967,21 @@ public function AliasIdentificationVariable() */ public function AbstractSchemaName() { - if ($this->lexer->isNextToken(Lexer::T_FULLY_QUALIFIED_NAME)) { - $this->match(Lexer::T_FULLY_QUALIFIED_NAME); + if ($this->lexer->isNextToken(TokenType::T_FULLY_QUALIFIED_NAME)) { + $this->match(TokenType::T_FULLY_QUALIFIED_NAME); assert($this->lexer->token !== null); return $this->lexer->token->value; } - if ($this->lexer->isNextToken(Lexer::T_IDENTIFIER)) { - $this->match(Lexer::T_IDENTIFIER); + if ($this->lexer->isNextToken(TokenType::T_IDENTIFIER)) { + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); return $this->lexer->token->value; } - $this->match(Lexer::T_ALIASED_NAME); + $this->match(TokenType::T_ALIASED_NAME); assert($this->lexer->token !== null); @@ -1022,7 +1022,7 @@ private function validateAbstractSchemaName(string $schemaName): void */ public function AliasResultVariable() { - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $resultVariable = $this->lexer->token->value; @@ -1045,7 +1045,7 @@ public function AliasResultVariable() */ public function ResultVariable() { - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $resultVariable = $this->lexer->token->value; @@ -1075,8 +1075,8 @@ public function JoinAssociationPathExpression() ); } - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $field = $this->lexer->token->value; @@ -1108,15 +1108,15 @@ public function PathExpression($expectedTypes) $field = null; assert($this->lexer->token !== null); - if ($this->lexer->isNextToken(Lexer::T_DOT)) { - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_IDENTIFIER); + if ($this->lexer->isNextToken(TokenType::T_DOT)) { + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_IDENTIFIER); $field = $this->lexer->token->value; - while ($this->lexer->isNextToken(Lexer::T_DOT)) { - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_IDENTIFIER); + while ($this->lexer->isNextToken(TokenType::T_DOT)) { + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_IDENTIFIER); $field .= '.' . $this->lexer->token->value; } } @@ -1198,11 +1198,11 @@ public function CollectionValuedPathExpression() public function SelectClause() { $isDistinct = false; - $this->match(Lexer::T_SELECT); + $this->match(TokenType::T_SELECT); // Check for DISTINCT - if ($this->lexer->isNextToken(Lexer::T_DISTINCT)) { - $this->match(Lexer::T_DISTINCT); + if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { + $this->match(TokenType::T_DISTINCT); $isDistinct = true; } @@ -1211,8 +1211,8 @@ public function SelectClause() $selectExpressions = []; $selectExpressions[] = $this->SelectExpression(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $selectExpressions[] = $this->SelectExpression(); } @@ -1228,10 +1228,10 @@ public function SelectClause() public function SimpleSelectClause() { $isDistinct = false; - $this->match(Lexer::T_SELECT); + $this->match(TokenType::T_SELECT); - if ($this->lexer->isNextToken(Lexer::T_DISTINCT)) { - $this->match(Lexer::T_DISTINCT); + if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { + $this->match(TokenType::T_DISTINCT); $isDistinct = true; } @@ -1246,7 +1246,7 @@ public function SimpleSelectClause() */ public function UpdateClause() { - $this->match(Lexer::T_UPDATE); + $this->match(TokenType::T_UPDATE); assert($this->lexer->lookahead !== null); $token = $this->lexer->lookahead; @@ -1254,8 +1254,8 @@ public function UpdateClause() $this->validateAbstractSchemaName($abstractSchemaName); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } $aliasIdentificationVariable = $this->AliasIdentificationVariable(); @@ -1274,13 +1274,13 @@ public function UpdateClause() $this->queryComponents[$aliasIdentificationVariable] = $queryComponent; - $this->match(Lexer::T_SET); + $this->match(TokenType::T_SET); $updateItems = []; $updateItems[] = $this->UpdateItem(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $updateItems[] = $this->UpdateItem(); } @@ -1298,10 +1298,10 @@ public function UpdateClause() */ public function DeleteClause() { - $this->match(Lexer::T_DELETE); + $this->match(TokenType::T_DELETE); - if ($this->lexer->isNextToken(Lexer::T_FROM)) { - $this->match(Lexer::T_FROM); + if ($this->lexer->isNextToken(TokenType::T_FROM)) { + $this->match(TokenType::T_FROM); } assert($this->lexer->lookahead !== null); @@ -1312,11 +1312,11 @@ public function DeleteClause() $deleteClause = new AST\DeleteClause($abstractSchemaName); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } - $aliasIdentificationVariable = $this->lexer->isNextToken(Lexer::T_IDENTIFIER) + $aliasIdentificationVariable = $this->lexer->isNextToken(TokenType::T_IDENTIFIER) ? $this->AliasIdentificationVariable() : 'alias_should_have_been_set'; @@ -1345,13 +1345,13 @@ public function DeleteClause() */ public function FromClause() { - $this->match(Lexer::T_FROM); + $this->match(TokenType::T_FROM); $identificationVariableDeclarations = []; $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); } @@ -1366,13 +1366,13 @@ public function FromClause() */ public function SubselectFromClause() { - $this->match(Lexer::T_FROM); + $this->match(TokenType::T_FROM); $identificationVariables = []; $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); } @@ -1387,7 +1387,7 @@ public function SubselectFromClause() */ public function WhereClause() { - $this->match(Lexer::T_WHERE); + $this->match(TokenType::T_WHERE); return new AST\WhereClause($this->ConditionalExpression()); } @@ -1399,7 +1399,7 @@ public function WhereClause() */ public function HavingClause() { - $this->match(Lexer::T_HAVING); + $this->match(TokenType::T_HAVING); return new AST\HavingClause($this->ConditionalExpression()); } @@ -1411,13 +1411,13 @@ public function HavingClause() */ public function GroupByClause() { - $this->match(Lexer::T_GROUP); - $this->match(Lexer::T_BY); + $this->match(TokenType::T_GROUP); + $this->match(TokenType::T_BY); $groupByItems = [$this->GroupByItem()]; - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $groupByItems[] = $this->GroupByItem(); } @@ -1432,14 +1432,14 @@ public function GroupByClause() */ public function OrderByClause() { - $this->match(Lexer::T_ORDER); - $this->match(Lexer::T_BY); + $this->match(TokenType::T_ORDER); + $this->match(TokenType::T_BY); $orderByItems = []; $orderByItems[] = $this->OrderByItem(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $orderByItems[] = $this->OrderByItem(); } @@ -1459,10 +1459,10 @@ public function Subselect() $subselect = new AST\Subselect($this->SimpleSelectClause(), $this->SubselectFromClause()); - $subselect->whereClause = $this->lexer->isNextToken(Lexer::T_WHERE) ? $this->WhereClause() : null; - $subselect->groupByClause = $this->lexer->isNextToken(Lexer::T_GROUP) ? $this->GroupByClause() : null; - $subselect->havingClause = $this->lexer->isNextToken(Lexer::T_HAVING) ? $this->HavingClause() : null; - $subselect->orderByClause = $this->lexer->isNextToken(Lexer::T_ORDER) ? $this->OrderByClause() : null; + $subselect->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; + $subselect->groupByClause = $this->lexer->isNextToken(TokenType::T_GROUP) ? $this->GroupByClause() : null; + $subselect->havingClause = $this->lexer->isNextToken(TokenType::T_HAVING) ? $this->HavingClause() : null; + $subselect->orderByClause = $this->lexer->isNextToken(TokenType::T_ORDER) ? $this->OrderByClause() : null; // Decrease query nesting level $this->nestingLevel--; @@ -1479,7 +1479,7 @@ public function UpdateItem() { $pathExpr = $this->SingleValuedPathExpression(); - $this->match(Lexer::T_EQUALS); + $this->match(TokenType::T_EQUALS); return new AST\UpdateItem($pathExpr, $this->NewValue()); } @@ -1494,7 +1494,7 @@ public function GroupByItem() // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression $glimpse = $this->lexer->glimpse(); - if ($glimpse !== null && $glimpse->type === Lexer::T_DOT) { + if ($glimpse !== null && $glimpse->type === TokenType::T_DOT) { return $this->SingleValuedPathExpression(); } @@ -1536,7 +1536,7 @@ public function OrderByItem() $expr = $this->SimpleArithmeticExpression(); break; - case $glimpse !== null && $glimpse->type === Lexer::T_DOT: + case $glimpse !== null && $glimpse->type === TokenType::T_DOT: $expr = $this->SingleValuedPathExpression(); break; @@ -1544,7 +1544,7 @@ public function OrderByItem() $expr = $this->ScalarExpression(); break; - case $this->lexer->lookahead->type === Lexer::T_CASE: + case $this->lexer->lookahead->type === TokenType::T_CASE: $expr = $this->CaseExpression(); break; @@ -1561,13 +1561,13 @@ public function OrderByItem() $item = new AST\OrderByItem($expr); switch (true) { - case $this->lexer->isNextToken(Lexer::T_DESC): - $this->match(Lexer::T_DESC); + case $this->lexer->isNextToken(TokenType::T_DESC): + $this->match(TokenType::T_DESC); $type = 'DESC'; break; - case $this->lexer->isNextToken(Lexer::T_ASC): - $this->match(Lexer::T_ASC); + case $this->lexer->isNextToken(TokenType::T_ASC): + $this->match(TokenType::T_ASC); break; default: @@ -1594,14 +1594,14 @@ public function OrderByItem() */ public function NewValue() { - if ($this->lexer->isNextToken(Lexer::T_NULL)) { - $this->match(Lexer::T_NULL); + if ($this->lexer->isNextToken(TokenType::T_NULL)) { + $this->match(TokenType::T_NULL); return null; } - if ($this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { - $this->match(Lexer::T_INPUT_PARAMETER); + if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { + $this->match(TokenType::T_INPUT_PARAMETER); assert($this->lexer->token !== null); return new AST\InputParameter($this->lexer->token->value); @@ -1619,16 +1619,16 @@ public function IdentificationVariableDeclaration() { $joins = []; $rangeVariableDeclaration = $this->RangeVariableDeclaration(); - $indexBy = $this->lexer->isNextToken(Lexer::T_INDEX) + $indexBy = $this->lexer->isNextToken(TokenType::T_INDEX) ? $this->IndexBy() : null; $rangeVariableDeclaration->isRoot = true; while ( - $this->lexer->isNextToken(Lexer::T_LEFT) || - $this->lexer->isNextToken(Lexer::T_INNER) || - $this->lexer->isNextToken(Lexer::T_JOIN) + $this->lexer->isNextToken(TokenType::T_LEFT) || + $this->lexer->isNextToken(TokenType::T_INNER) || + $this->lexer->isNextToken(TokenType::T_JOIN) ) { $joins[] = $this->Join(); } @@ -1663,11 +1663,11 @@ public function SubselectIdentificationVariableDeclaration() $glimpse = $this->lexer->glimpse(); - if ($glimpse->type == Lexer::T_DOT) { + if ($glimpse->type == TokenType::T_DOT) { $associationPathExpression = $this->AssociationPathExpression(); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } $aliasIdentificationVariable = $this->AliasIdentificationVariable(); @@ -1711,34 +1711,34 @@ public function Join() $joinType = AST\Join::JOIN_TYPE_INNER; switch (true) { - case $this->lexer->isNextToken(Lexer::T_LEFT): - $this->match(Lexer::T_LEFT); + case $this->lexer->isNextToken(TokenType::T_LEFT): + $this->match(TokenType::T_LEFT); $joinType = AST\Join::JOIN_TYPE_LEFT; // Possible LEFT OUTER join - if ($this->lexer->isNextToken(Lexer::T_OUTER)) { - $this->match(Lexer::T_OUTER); + if ($this->lexer->isNextToken(TokenType::T_OUTER)) { + $this->match(TokenType::T_OUTER); $joinType = AST\Join::JOIN_TYPE_LEFTOUTER; } break; - case $this->lexer->isNextToken(Lexer::T_INNER): - $this->match(Lexer::T_INNER); + case $this->lexer->isNextToken(TokenType::T_INNER): + $this->match(TokenType::T_INNER); break; default: // Do nothing } - $this->match(Lexer::T_JOIN); + $this->match(TokenType::T_JOIN); $next = $this->lexer->glimpse(); assert($next !== null); - $joinDeclaration = $next->type === Lexer::T_DOT ? $this->JoinAssociationDeclaration() : $this->RangeVariableDeclaration(); - $adhocConditions = $this->lexer->isNextToken(Lexer::T_WITH); + $joinDeclaration = $next->type === TokenType::T_DOT ? $this->JoinAssociationDeclaration() : $this->RangeVariableDeclaration(); + $adhocConditions = $this->lexer->isNextToken(TokenType::T_WITH); $join = new AST\Join($joinType, $joinDeclaration); // Describe non-root join declaration @@ -1748,7 +1748,7 @@ public function Join() // Check for ad-hoc Join conditions if ($adhocConditions) { - $this->match(Lexer::T_WITH); + $this->match(TokenType::T_WITH); $join->conditionalExpression = $this->ConditionalExpression(); } @@ -1765,7 +1765,7 @@ public function Join() */ public function RangeVariableDeclaration() { - if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) && $this->lexer->glimpse()->type === Lexer::T_SELECT) { + if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) && $this->lexer->glimpse()->type === TokenType::T_SELECT) { $this->semanticalError('Subquery is not supported here', $this->lexer->token); } @@ -1773,8 +1773,8 @@ public function RangeVariableDeclaration() $this->validateAbstractSchemaName($abstractSchemaName); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } assert($this->lexer->lookahead !== null); @@ -1806,14 +1806,14 @@ public function JoinAssociationDeclaration() { $joinAssociationPathExpression = $this->JoinAssociationPathExpression(); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } assert($this->lexer->lookahead !== null); $aliasIdentificationVariable = $this->AliasIdentificationVariable(); - $indexBy = $this->lexer->isNextToken(Lexer::T_INDEX) ? $this->IndexBy() : null; + $indexBy = $this->lexer->isNextToken(TokenType::T_INDEX) ? $this->IndexBy() : null; $identificationVariable = $joinAssociationPathExpression->identificationVariable; $field = $joinAssociationPathExpression->associationField; @@ -1850,44 +1850,44 @@ public function PartialObjectExpression() 'PARTIAL syntax in DQL is deprecated.' ); - $this->match(Lexer::T_PARTIAL); + $this->match(TokenType::T_PARTIAL); $partialFieldSet = []; $identificationVariable = $this->IdentificationVariable(); - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_OPEN_CURLY_BRACE); - $this->match(Lexer::T_IDENTIFIER); + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_OPEN_CURLY_BRACE); + $this->match(TokenType::T_IDENTIFIER); assert($this->lexer->token !== null); $field = $this->lexer->token->value; // First field in partial expression might be embeddable property - while ($this->lexer->isNextToken(Lexer::T_DOT)) { - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_IDENTIFIER); + while ($this->lexer->isNextToken(TokenType::T_DOT)) { + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_IDENTIFIER); $field .= '.' . $this->lexer->token->value; } $partialFieldSet[] = $field; - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); - $this->match(Lexer::T_IDENTIFIER); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); + $this->match(TokenType::T_IDENTIFIER); $field = $this->lexer->token->value; - while ($this->lexer->isNextToken(Lexer::T_DOT)) { - $this->match(Lexer::T_DOT); - $this->match(Lexer::T_IDENTIFIER); + while ($this->lexer->isNextToken(TokenType::T_DOT)) { + $this->match(TokenType::T_DOT); + $this->match(TokenType::T_IDENTIFIER); $field .= '.' . $this->lexer->token->value; } $partialFieldSet[] = $field; } - $this->match(Lexer::T_CLOSE_CURLY_BRACE); + $this->match(TokenType::T_CLOSE_CURLY_BRACE); $partialObjectExpression = new AST\PartialObjectExpression($identificationVariable, $partialFieldSet); @@ -1908,22 +1908,22 @@ public function PartialObjectExpression() */ public function NewObjectExpression() { - $this->match(Lexer::T_NEW); + $this->match(TokenType::T_NEW); $className = $this->AbstractSchemaName(); // note that this is not yet validated $token = $this->lexer->token; - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $args[] = $this->NewObjectArg(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $args[] = $this->NewObjectArg(); } - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); $expression = new AST\NewObjectExpression($className, $args); @@ -1949,10 +1949,10 @@ public function NewObjectArg() $peek = $this->lexer->glimpse(); assert($peek !== null); - if ($token->type === Lexer::T_OPEN_PARENTHESIS && $peek->type === Lexer::T_SELECT) { - $this->match(Lexer::T_OPEN_PARENTHESIS); + if ($token->type === TokenType::T_OPEN_PARENTHESIS && $peek->type === TokenType::T_SELECT) { + $this->match(TokenType::T_OPEN_PARENTHESIS); $expression = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $expression; } @@ -1967,8 +1967,8 @@ public function NewObjectArg() */ public function IndexBy() { - $this->match(Lexer::T_INDEX); - $this->match(Lexer::T_BY); + $this->match(TokenType::T_INDEX); + $this->match(TokenType::T_BY); $pathExpr = $this->SingleValuedPathExpression(); // Add the INDEX BY info to the query component @@ -1992,23 +1992,23 @@ public function ScalarExpression() $peek = $this->lexer->glimpse(); switch (true) { - case $lookahead === Lexer::T_INTEGER: - case $lookahead === Lexer::T_FLOAT: + case $lookahead === TokenType::T_INTEGER: + case $lookahead === TokenType::T_FLOAT: // SimpleArithmeticExpression : (- u.value ) or ( + u.value ) or ( - 1 ) or ( + 1 ) - case $lookahead === Lexer::T_MINUS: - case $lookahead === Lexer::T_PLUS: + case $lookahead === TokenType::T_MINUS: + case $lookahead === TokenType::T_PLUS: return $this->SimpleArithmeticExpression(); - case $lookahead === Lexer::T_STRING: + case $lookahead === TokenType::T_STRING: return $this->StringPrimary(); - case $lookahead === Lexer::T_TRUE: - case $lookahead === Lexer::T_FALSE: + case $lookahead === TokenType::T_TRUE: + case $lookahead === TokenType::T_FALSE: $this->match($lookahead); return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token->value); - case $lookahead === Lexer::T_INPUT_PARAMETER: + case $lookahead === TokenType::T_INPUT_PARAMETER: switch (true) { case $this->isMathOperator($peek): // :param + u.value @@ -2017,14 +2017,14 @@ public function ScalarExpression() default: return $this->InputParameter(); } - case $lookahead === Lexer::T_CASE: - case $lookahead === Lexer::T_COALESCE: - case $lookahead === Lexer::T_NULLIF: + case $lookahead === TokenType::T_CASE: + case $lookahead === TokenType::T_COALESCE: + case $lookahead === TokenType::T_NULLIF: // Since NULLIF and COALESCE can be identified as a function, // we need to check these before checking for FunctionDeclaration return $this->CaseExpression(); - case $lookahead === Lexer::T_OPEN_PARENTHESIS: + case $lookahead === TokenType::T_OPEN_PARENTHESIS: return $this->SimpleArithmeticExpression(); // this check must be done before checking for a filed path expression @@ -2043,7 +2043,7 @@ public function ScalarExpression() break; // it is no function, so it must be a field path - case $lookahead === Lexer::T_IDENTIFIER: + case $lookahead === TokenType::T_IDENTIFIER: $this->lexer->peek(); // lookahead => '.' $this->lexer->peek(); // lookahead => token after '.' $peek = $this->lexer->peek(); // lookahead => token after the token after the '.' @@ -2078,18 +2078,18 @@ public function CaseExpression() $lookahead = $this->lexer->lookahead->type; switch ($lookahead) { - case Lexer::T_NULLIF: + case TokenType::T_NULLIF: return $this->NullIfExpression(); - case Lexer::T_COALESCE: + case TokenType::T_COALESCE: return $this->CoalesceExpression(); - case Lexer::T_CASE: + case TokenType::T_CASE: $this->lexer->resetPeek(); $peek = $this->lexer->peek(); assert($peek !== null); - if ($peek->type === Lexer::T_WHEN) { + if ($peek->type === TokenType::T_WHEN) { return $this->GeneralCaseExpression(); } @@ -2110,20 +2110,20 @@ public function CaseExpression() */ public function CoalesceExpression() { - $this->match(Lexer::T_COALESCE); - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_COALESCE); + $this->match(TokenType::T_OPEN_PARENTHESIS); // Process ScalarExpressions (1..N) $scalarExpressions = []; $scalarExpressions[] = $this->ScalarExpression(); - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $scalarExpressions[] = $this->ScalarExpression(); } - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\CoalesceExpression($scalarExpressions); } @@ -2135,14 +2135,14 @@ public function CoalesceExpression() */ public function NullIfExpression() { - $this->match(Lexer::T_NULLIF); - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_NULLIF); + $this->match(TokenType::T_OPEN_PARENTHESIS); $firstExpression = $this->ScalarExpression(); - $this->match(Lexer::T_COMMA); + $this->match(TokenType::T_COMMA); $secondExpression = $this->ScalarExpression(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\NullIfExpression($firstExpression, $secondExpression); } @@ -2154,18 +2154,18 @@ public function NullIfExpression() */ public function GeneralCaseExpression() { - $this->match(Lexer::T_CASE); + $this->match(TokenType::T_CASE); // Process WhenClause (1..N) $whenClauses = []; do { $whenClauses[] = $this->WhenClause(); - } while ($this->lexer->isNextToken(Lexer::T_WHEN)); + } while ($this->lexer->isNextToken(TokenType::T_WHEN)); - $this->match(Lexer::T_ELSE); + $this->match(TokenType::T_ELSE); $scalarExpression = $this->ScalarExpression(); - $this->match(Lexer::T_END); + $this->match(TokenType::T_END); return new AST\GeneralCaseExpression($whenClauses, $scalarExpression); } @@ -2178,7 +2178,7 @@ public function GeneralCaseExpression() */ public function SimpleCaseExpression() { - $this->match(Lexer::T_CASE); + $this->match(TokenType::T_CASE); $caseOperand = $this->StateFieldPathExpression(); // Process SimpleWhenClause (1..N) @@ -2186,11 +2186,11 @@ public function SimpleCaseExpression() do { $simpleWhenClauses[] = $this->SimpleWhenClause(); - } while ($this->lexer->isNextToken(Lexer::T_WHEN)); + } while ($this->lexer->isNextToken(TokenType::T_WHEN)); - $this->match(Lexer::T_ELSE); + $this->match(TokenType::T_ELSE); $scalarExpression = $this->ScalarExpression(); - $this->match(Lexer::T_END); + $this->match(TokenType::T_END); return new AST\SimpleCaseExpression($caseOperand, $simpleWhenClauses, $scalarExpression); } @@ -2202,9 +2202,9 @@ public function SimpleCaseExpression() */ public function WhenClause() { - $this->match(Lexer::T_WHEN); + $this->match(TokenType::T_WHEN); $conditionalExpression = $this->ConditionalExpression(); - $this->match(Lexer::T_THEN); + $this->match(TokenType::T_THEN); return new AST\WhenClause($conditionalExpression, $this->ScalarExpression()); } @@ -2216,9 +2216,9 @@ public function WhenClause() */ public function SimpleWhenClause() { - $this->match(Lexer::T_WHEN); + $this->match(TokenType::T_WHEN); $conditionalExpression = $this->ScalarExpression(); - $this->match(Lexer::T_THEN); + $this->match(TokenType::T_THEN); return new AST\SimpleWhenClause($conditionalExpression, $this->ScalarExpression()); } @@ -2242,19 +2242,19 @@ public function SelectExpression() switch (true) { // ScalarExpression (u.name) - case $lookaheadType === Lexer::T_IDENTIFIER && $peek->type === Lexer::T_DOT: + case $lookaheadType === TokenType::T_IDENTIFIER && $peek->type === TokenType::T_DOT: $expression = $this->ScalarExpression(); break; // IdentificationVariable (u) - case $lookaheadType === Lexer::T_IDENTIFIER && $peek->type !== Lexer::T_OPEN_PARENTHESIS: + case $lookaheadType === TokenType::T_IDENTIFIER && $peek->type !== TokenType::T_OPEN_PARENTHESIS: $expression = $identVariable = $this->IdentificationVariable(); break; // CaseExpression (CASE ... or NULLIF(...) or COALESCE(...)) - case $lookaheadType === Lexer::T_CASE: - case $lookaheadType === Lexer::T_COALESCE: - case $lookaheadType === Lexer::T_NULLIF: + case $lookaheadType === TokenType::T_CASE: + case $lookaheadType === TokenType::T_COALESCE: + case $lookaheadType === TokenType::T_NULLIF: $expression = $this->CaseExpression(); break; @@ -2277,31 +2277,31 @@ public function SelectExpression() break; // PartialObjectExpression (PARTIAL u.{id, name}) - case $lookaheadType === Lexer::T_PARTIAL: + case $lookaheadType === TokenType::T_PARTIAL: $expression = $this->PartialObjectExpression(); $identVariable = $expression->identificationVariable; break; // Subselect - case $lookaheadType === Lexer::T_OPEN_PARENTHESIS && $peek->type === Lexer::T_SELECT: - $this->match(Lexer::T_OPEN_PARENTHESIS); + case $lookaheadType === TokenType::T_OPEN_PARENTHESIS && $peek->type === TokenType::T_SELECT: + $this->match(TokenType::T_OPEN_PARENTHESIS); $expression = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); break; // Shortcut: ScalarExpression => SimpleArithmeticExpression - case $lookaheadType === Lexer::T_OPEN_PARENTHESIS: - case $lookaheadType === Lexer::T_INTEGER: - case $lookaheadType === Lexer::T_STRING: - case $lookaheadType === Lexer::T_FLOAT: + case $lookaheadType === TokenType::T_OPEN_PARENTHESIS: + case $lookaheadType === TokenType::T_INTEGER: + case $lookaheadType === TokenType::T_STRING: + case $lookaheadType === TokenType::T_FLOAT: // SimpleArithmeticExpression : (- u.value ) or ( + u.value ) - case $lookaheadType === Lexer::T_MINUS: - case $lookaheadType === Lexer::T_PLUS: + case $lookaheadType === TokenType::T_MINUS: + case $lookaheadType === TokenType::T_PLUS: $expression = $this->SimpleArithmeticExpression(); break; // NewObjectExpression (New ClassName(id, name)) - case $lookaheadType === Lexer::T_NEW: + case $lookaheadType === TokenType::T_NEW: $expression = $this->NewObjectExpression(); break; @@ -2315,23 +2315,23 @@ public function SelectExpression() // [["AS"] ["HIDDEN"] AliasResultVariable] $mustHaveAliasResultVariable = false; - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); $mustHaveAliasResultVariable = true; } $hiddenAliasResultVariable = false; - if ($this->lexer->isNextToken(Lexer::T_HIDDEN)) { - $this->match(Lexer::T_HIDDEN); + if ($this->lexer->isNextToken(TokenType::T_HIDDEN)) { + $this->match(TokenType::T_HIDDEN); $hiddenAliasResultVariable = true; } $aliasResultVariable = null; - if ($mustHaveAliasResultVariable || $this->lexer->isNextToken(Lexer::T_IDENTIFIER)) { + if ($mustHaveAliasResultVariable || $this->lexer->isNextToken(TokenType::T_IDENTIFIER)) { assert($expression instanceof AST\Node || is_string($expression)); $token = $this->lexer->lookahead; $aliasResultVariable = $this->AliasResultVariable(); @@ -2370,14 +2370,14 @@ public function SimpleSelectExpression() assert($peek !== null); switch ($this->lexer->lookahead->type) { - case Lexer::T_IDENTIFIER: + case TokenType::T_IDENTIFIER: switch (true) { - case $peek->type === Lexer::T_DOT: + case $peek->type === TokenType::T_DOT: $expression = $this->StateFieldPathExpression(); return new AST\SimpleSelectExpression($expression); - case $peek->type !== Lexer::T_OPEN_PARENTHESIS: + case $peek->type !== TokenType::T_OPEN_PARENTHESIS: $expression = $this->IdentificationVariable(); return new AST\SimpleSelectExpression($expression); @@ -2402,8 +2402,8 @@ public function SimpleSelectExpression() break; - case Lexer::T_OPEN_PARENTHESIS: - if ($peek->type !== Lexer::T_SELECT) { + case TokenType::T_OPEN_PARENTHESIS: + if ($peek->type !== TokenType::T_SELECT) { // Shortcut: ScalarExpression => SimpleArithmeticExpression $expression = $this->SimpleArithmeticExpression(); @@ -2411,9 +2411,9 @@ public function SimpleSelectExpression() } // Subselect - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $expression = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\SimpleSelectExpression($expression); @@ -2426,11 +2426,11 @@ public function SimpleSelectExpression() $expression = $this->ScalarExpression(); $expr = new AST\SimpleSelectExpression($expression); - if ($this->lexer->isNextToken(Lexer::T_AS)) { - $this->match(Lexer::T_AS); + if ($this->lexer->isNextToken(TokenType::T_AS)) { + $this->match(TokenType::T_AS); } - if ($this->lexer->isNextToken(Lexer::T_IDENTIFIER)) { + if ($this->lexer->isNextToken(TokenType::T_IDENTIFIER)) { $token = $this->lexer->lookahead; $resultVariable = $this->AliasResultVariable(); $expr->fieldIdentificationVariable = $resultVariable; @@ -2456,8 +2456,8 @@ public function ConditionalExpression() $conditionalTerms = []; $conditionalTerms[] = $this->ConditionalTerm(); - while ($this->lexer->isNextToken(Lexer::T_OR)) { - $this->match(Lexer::T_OR); + while ($this->lexer->isNextToken(TokenType::T_OR)) { + $this->match(TokenType::T_OR); $conditionalTerms[] = $this->ConditionalTerm(); } @@ -2481,8 +2481,8 @@ public function ConditionalTerm() $conditionalFactors = []; $conditionalFactors[] = $this->ConditionalFactor(); - while ($this->lexer->isNextToken(Lexer::T_AND)) { - $this->match(Lexer::T_AND); + while ($this->lexer->isNextToken(TokenType::T_AND)) { + $this->match(TokenType::T_AND); $conditionalFactors[] = $this->ConditionalFactor(); } @@ -2505,8 +2505,8 @@ public function ConditionalFactor() { $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } @@ -2531,7 +2531,7 @@ public function ConditionalPrimary() { $condPrimary = new AST\ConditionalPrimary(); - if (! $this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + if (! $this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); return $condPrimary; @@ -2543,7 +2543,7 @@ public function ConditionalPrimary() if ( $peek !== null && ( in_array($peek->value, ['=', '<', '<=', '<>', '>', '>=', '!='], true) || - in_array($peek->type, [Lexer::T_NOT, Lexer::T_BETWEEN, Lexer::T_LIKE, Lexer::T_IN, Lexer::T_IS, Lexer::T_EXISTS], true) || + in_array($peek->type, [TokenType::T_NOT, TokenType::T_BETWEEN, TokenType::T_LIKE, TokenType::T_IN, TokenType::T_IS, TokenType::T_EXISTS], true) || $this->isMathOperator($peek) ) ) { @@ -2552,9 +2552,9 @@ public function ConditionalPrimary() return $condPrimary; } - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $condPrimary->conditionalExpression = $this->ConditionalExpression(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $condPrimary; } @@ -2579,7 +2579,7 @@ public function ConditionalPrimary() public function SimpleConditionalExpression() { assert($this->lexer->lookahead !== null); - if ($this->lexer->isNextToken(Lexer::T_EXISTS)) { + if ($this->lexer->isNextToken(TokenType::T_EXISTS)) { return $this->ExistsExpression(); } @@ -2587,13 +2587,13 @@ public function SimpleConditionalExpression() $peek = $this->lexer->glimpse(); $lookahead = $token; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { + if ($this->lexer->isNextToken(TokenType::T_NOT)) { $token = $this->lexer->glimpse(); } assert($token !== null); assert($peek !== null); - if ($token->type === Lexer::T_IDENTIFIER || $token->type === Lexer::T_INPUT_PARAMETER || $this->isFunction()) { + if ($token->type === TokenType::T_IDENTIFIER || $token->type === TokenType::T_INPUT_PARAMETER || $this->isFunction()) { // Peek beyond the matching closing parenthesis. $beyond = $this->lexer->peek(); @@ -2603,12 +2603,12 @@ public function SimpleConditionalExpression() $token = $this->peekBeyondClosingParenthesis(false); assert($token !== null); - if ($token->type === Lexer::T_NOT) { + if ($token->type === TokenType::T_NOT) { $token = $this->lexer->peek(); assert($token !== null); } - if ($token->type === Lexer::T_IS) { + if ($token->type === TokenType::T_IS) { $lookahead = $this->lexer->peek(); } @@ -2627,7 +2627,7 @@ public function SimpleConditionalExpression() // Also peek beyond a NOT if there is one. assert($token !== null); - if ($token->type === Lexer::T_NOT) { + if ($token->type === TokenType::T_NOT) { $token = $this->lexer->peek(); assert($token !== null); } @@ -2638,39 +2638,39 @@ public function SimpleConditionalExpression() assert($lookahead !== null); // Also peek beyond a NOT if there is one. - if ($lookahead->type === Lexer::T_NOT) { + if ($lookahead->type === TokenType::T_NOT) { $lookahead = $this->lexer->peek(); } $this->lexer->resetPeek(); } - if ($token->type === Lexer::T_BETWEEN) { + if ($token->type === TokenType::T_BETWEEN) { return $this->BetweenExpression(); } - if ($token->type === Lexer::T_LIKE) { + if ($token->type === TokenType::T_LIKE) { return $this->LikeExpression(); } - if ($token->type === Lexer::T_IN) { + if ($token->type === TokenType::T_IN) { return $this->InExpression(); } - if ($token->type === Lexer::T_INSTANCE) { + if ($token->type === TokenType::T_INSTANCE) { return $this->InstanceOfExpression(); } - if ($token->type === Lexer::T_MEMBER) { + if ($token->type === TokenType::T_MEMBER) { return $this->CollectionMemberExpression(); } assert($lookahead !== null); - if ($token->type === Lexer::T_IS && $lookahead->type === Lexer::T_NULL) { + if ($token->type === TokenType::T_IS && $lookahead->type === TokenType::T_NULL) { return $this->NullComparisonExpression(); } - if ($token->type === Lexer::T_IS && $lookahead->type === Lexer::T_EMPTY) { + if ($token->type === TokenType::T_IS && $lookahead->type === TokenType::T_EMPTY) { return $this->EmptyCollectionComparisonExpression(); } @@ -2685,15 +2685,15 @@ public function SimpleConditionalExpression() public function EmptyCollectionComparisonExpression() { $pathExpression = $this->CollectionValuedPathExpression(); - $this->match(Lexer::T_IS); + $this->match(TokenType::T_IS); $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_EMPTY); + $this->match(TokenType::T_EMPTY); return new AST\EmptyCollectionComparisonExpression( $pathExpression, @@ -2714,16 +2714,16 @@ public function CollectionMemberExpression() $not = false; $entityExpr = $this->EntityExpression(); - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_MEMBER); + $this->match(TokenType::T_MEMBER); - if ($this->lexer->isNextToken(Lexer::T_OF)) { - $this->match(Lexer::T_OF); + if ($this->lexer->isNextToken(TokenType::T_OF)) { + $this->match(TokenType::T_OF); } return new AST\CollectionMemberExpression( @@ -2743,23 +2743,23 @@ public function Literal() assert($this->lexer->lookahead !== null); assert($this->lexer->token !== null); switch ($this->lexer->lookahead->type) { - case Lexer::T_STRING: - $this->match(Lexer::T_STRING); + case TokenType::T_STRING: + $this->match(TokenType::T_STRING); return new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); - case Lexer::T_INTEGER: - case Lexer::T_FLOAT: + case TokenType::T_INTEGER: + case TokenType::T_FLOAT: $this->match( - $this->lexer->isNextToken(Lexer::T_INTEGER) ? Lexer::T_INTEGER : Lexer::T_FLOAT + $this->lexer->isNextToken(TokenType::T_INTEGER) ? TokenType::T_INTEGER : TokenType::T_FLOAT ); return new AST\Literal(AST\Literal::NUMERIC, $this->lexer->token->value); - case Lexer::T_TRUE: - case Lexer::T_FALSE: + case TokenType::T_TRUE: + case TokenType::T_FALSE: $this->match( - $this->lexer->isNextToken(Lexer::T_TRUE) ? Lexer::T_TRUE : Lexer::T_FALSE + $this->lexer->isNextToken(TokenType::T_TRUE) ? TokenType::T_TRUE : TokenType::T_FALSE ); return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token->value); @@ -2777,7 +2777,7 @@ public function Literal() public function InParameter() { assert($this->lexer->lookahead !== null); - if ($this->lexer->lookahead->type === Lexer::T_INPUT_PARAMETER) { + if ($this->lexer->lookahead->type === TokenType::T_INPUT_PARAMETER) { return $this->InputParameter(); } @@ -2791,7 +2791,7 @@ public function InParameter() */ public function InputParameter() { - $this->match(Lexer::T_INPUT_PARAMETER); + $this->match(TokenType::T_INPUT_PARAMETER); assert($this->lexer->token !== null); return new AST\InputParameter($this->lexer->token->value); @@ -2806,14 +2806,14 @@ public function ArithmeticExpression() { $expr = new AST\ArithmeticExpression(); - if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { + if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { $peek = $this->lexer->glimpse(); assert($peek !== null); - if ($peek->type === Lexer::T_SELECT) { - $this->match(Lexer::T_OPEN_PARENTHESIS); + if ($peek->type === TokenType::T_SELECT) { + $this->match(TokenType::T_OPEN_PARENTHESIS); $expr->subselect = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $expr; } @@ -2834,8 +2834,8 @@ public function SimpleArithmeticExpression() $terms = []; $terms[] = $this->ArithmeticTerm(); - while (($isPlus = $this->lexer->isNextToken(Lexer::T_PLUS)) || $this->lexer->isNextToken(Lexer::T_MINUS)) { - $this->match($isPlus ? Lexer::T_PLUS : Lexer::T_MINUS); + while (($isPlus = $this->lexer->isNextToken(TokenType::T_PLUS)) || $this->lexer->isNextToken(TokenType::T_MINUS)) { + $this->match($isPlus ? TokenType::T_PLUS : TokenType::T_MINUS); assert($this->lexer->token !== null); $terms[] = $this->lexer->token->value; @@ -2861,8 +2861,8 @@ public function ArithmeticTerm() $factors = []; $factors[] = $this->ArithmeticFactor(); - while (($isMult = $this->lexer->isNextToken(Lexer::T_MULTIPLY)) || $this->lexer->isNextToken(Lexer::T_DIVIDE)) { - $this->match($isMult ? Lexer::T_MULTIPLY : Lexer::T_DIVIDE); + while (($isMult = $this->lexer->isNextToken(TokenType::T_MULTIPLY)) || $this->lexer->isNextToken(TokenType::T_DIVIDE)) { + $this->match($isMult ? TokenType::T_MULTIPLY : TokenType::T_DIVIDE); assert($this->lexer->token !== null); $factors[] = $this->lexer->token->value; @@ -2887,9 +2887,9 @@ public function ArithmeticFactor() { $sign = null; - $isPlus = $this->lexer->isNextToken(Lexer::T_PLUS); - if ($isPlus || $this->lexer->isNextToken(Lexer::T_MINUS)) { - $this->match($isPlus ? Lexer::T_PLUS : Lexer::T_MINUS); + $isPlus = $this->lexer->isNextToken(TokenType::T_PLUS); + if ($isPlus || $this->lexer->isNextToken(TokenType::T_MINUS)) { + $this->match($isPlus ? TokenType::T_PLUS : TokenType::T_MINUS); $sign = $isPlus; } @@ -2914,24 +2914,24 @@ public function ArithmeticFactor() */ public function ArithmeticPrimary() { - if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { - $this->match(Lexer::T_OPEN_PARENTHESIS); + if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { + $this->match(TokenType::T_OPEN_PARENTHESIS); $expr = $this->SimpleArithmeticExpression(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\ParenthesisExpression($expr); } assert($this->lexer->lookahead !== null); switch ($this->lexer->lookahead->type) { - case Lexer::T_COALESCE: - case Lexer::T_NULLIF: - case Lexer::T_CASE: + case TokenType::T_COALESCE: + case TokenType::T_NULLIF: + case TokenType::T_CASE: return $this->CaseExpression(); - case Lexer::T_IDENTIFIER: + case TokenType::T_IDENTIFIER: $peek = $this->lexer->glimpse(); if ($peek !== null && $peek->value === '(') { @@ -2948,7 +2948,7 @@ public function ArithmeticPrimary() return $this->StateFieldPathExpression(); - case Lexer::T_INPUT_PARAMETER: + case TokenType::T_INPUT_PARAMETER: return $this->InputParameter(); default: @@ -2973,10 +2973,10 @@ public function StringExpression() assert($peek !== null); // Subselect - if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) && $peek->type === Lexer::T_SELECT) { - $this->match(Lexer::T_OPEN_PARENTHESIS); + if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) && $peek->type === TokenType::T_SELECT) { + $this->match(TokenType::T_OPEN_PARENTHESIS); $expr = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $expr; } @@ -2984,7 +2984,7 @@ public function StringExpression() assert($this->lexer->lookahead !== null); // ResultVariable (string) if ( - $this->lexer->isNextToken(Lexer::T_IDENTIFIER) && + $this->lexer->isNextToken(TokenType::T_IDENTIFIER) && isset($this->queryComponents[$this->lexer->lookahead->value]['resultVariable']) ) { return $this->ResultVariable(); @@ -3004,7 +3004,7 @@ public function StringPrimary() $lookaheadType = $this->lexer->lookahead->type; switch ($lookaheadType) { - case Lexer::T_IDENTIFIER: + case TokenType::T_IDENTIFIER: $peek = $this->lexer->glimpse(); assert($peek !== null); @@ -3020,18 +3020,18 @@ public function StringPrimary() $this->syntaxError("'.' or '('"); break; - case Lexer::T_STRING: - $this->match(Lexer::T_STRING); + case TokenType::T_STRING: + $this->match(TokenType::T_STRING); assert($this->lexer->token !== null); return new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); - case Lexer::T_INPUT_PARAMETER: + case TokenType::T_INPUT_PARAMETER: return $this->InputParameter(); - case Lexer::T_CASE: - case Lexer::T_COALESCE: - case Lexer::T_NULLIF: + case TokenType::T_CASE: + case TokenType::T_COALESCE: + case TokenType::T_NULLIF: return $this->CaseExpression(); default: @@ -3056,7 +3056,7 @@ public function EntityExpression() $glimpse = $this->lexer->glimpse(); assert($glimpse !== null); - if ($this->lexer->isNextToken(Lexer::T_IDENTIFIER) && $glimpse->value === '.') { + if ($this->lexer->isNextToken(TokenType::T_IDENTIFIER) && $glimpse->value === '.') { return $this->SingleValuedAssociationPathExpression(); } @@ -3070,7 +3070,7 @@ public function EntityExpression() */ public function SimpleEntityExpression() { - if ($this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { + if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { return $this->InputParameter(); } @@ -3089,23 +3089,23 @@ public function AggregateExpression() $lookaheadType = $this->lexer->lookahead->type; $isDistinct = false; - if (! in_array($lookaheadType, [Lexer::T_COUNT, Lexer::T_AVG, Lexer::T_MAX, Lexer::T_MIN, Lexer::T_SUM], true)) { + if (! in_array($lookaheadType, [TokenType::T_COUNT, TokenType::T_AVG, TokenType::T_MAX, TokenType::T_MIN, TokenType::T_SUM], true)) { $this->syntaxError('One of: MAX, MIN, AVG, SUM, COUNT'); } $this->match($lookaheadType); assert($this->lexer->token !== null); $functionName = $this->lexer->token->value; - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); - if ($this->lexer->isNextToken(Lexer::T_DISTINCT)) { - $this->match(Lexer::T_DISTINCT); + if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { + $this->match(TokenType::T_DISTINCT); $isDistinct = true; } $pathExp = $this->SimpleArithmeticExpression(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\AggregateExpression($functionName, $pathExp, $isDistinct); } @@ -3121,17 +3121,17 @@ public function QuantifiedExpression() $lookaheadType = $this->lexer->lookahead->type; $value = $this->lexer->lookahead->value; - if (! in_array($lookaheadType, [Lexer::T_ALL, Lexer::T_ANY, Lexer::T_SOME], true)) { + if (! in_array($lookaheadType, [TokenType::T_ALL, TokenType::T_ANY, TokenType::T_SOME], true)) { $this->syntaxError('ALL, ANY or SOME'); } $this->match($lookaheadType); - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $qExpr = new AST\QuantifiedExpression($this->Subselect()); $qExpr->type = $value; - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $qExpr; } @@ -3146,14 +3146,14 @@ public function BetweenExpression() $not = false; $arithExpr1 = $this->ArithmeticExpression(); - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_BETWEEN); + $this->match(TokenType::T_BETWEEN); $arithExpr2 = $this->ArithmeticExpression(); - $this->match(Lexer::T_AND); + $this->match(TokenType::T_AND); $arithExpr3 = $this->ArithmeticExpression(); return new AST\BetweenExpression($arithExpr1, $arithExpr2, $arithExpr3, $not); @@ -3187,15 +3187,15 @@ public function InExpression() $expression = $this->ArithmeticExpression(); $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_IN); - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_IN); + $this->match(TokenType::T_OPEN_PARENTHESIS); - if ($this->lexer->isNextToken(Lexer::T_SELECT)) { + if ($this->lexer->isNextToken(TokenType::T_SELECT)) { $inExpression = new AST\InSubselectExpression( $expression, $this->Subselect(), @@ -3204,8 +3204,8 @@ public function InExpression() } else { $literals = [$this->InParameter()]; - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $literals[] = $this->InParameter(); } @@ -3216,7 +3216,7 @@ public function InExpression() ); } - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $inExpression; } @@ -3231,15 +3231,15 @@ public function InstanceOfExpression() $identificationVariable = $this->IdentificationVariable(); $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_INSTANCE); - $this->match(Lexer::T_OF); + $this->match(TokenType::T_INSTANCE); + $this->match(TokenType::T_OF); - $exprValues = $this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) + $exprValues = $this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) ? $this->InstanceOfParameterList() : [$this->InstanceOfParameter()]; @@ -3253,17 +3253,17 @@ public function InstanceOfExpression() /** @return non-empty-list */ public function InstanceOfParameterList(): array { - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $exprValues = [$this->InstanceOfParameter()]; - while ($this->lexer->isNextToken(Lexer::T_COMMA)) { - $this->match(Lexer::T_COMMA); + while ($this->lexer->isNextToken(TokenType::T_COMMA)) { + $this->match(TokenType::T_COMMA); $exprValues[] = $this->InstanceOfParameter(); } - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return $exprValues; } @@ -3275,8 +3275,8 @@ public function InstanceOfParameterList(): array */ public function InstanceOfParameter() { - if ($this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { - $this->match(Lexer::T_INPUT_PARAMETER); + if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { + $this->match(TokenType::T_INPUT_PARAMETER); assert($this->lexer->token !== null); return new AST\InputParameter($this->lexer->token->value); @@ -3299,15 +3299,15 @@ public function LikeExpression() $stringExpr = $this->StringExpression(); $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_LIKE); + $this->match(TokenType::T_LIKE); - if ($this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) { - $this->match(Lexer::T_INPUT_PARAMETER); + if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { + $this->match(TokenType::T_INPUT_PARAMETER); assert($this->lexer->token !== null); $stringPattern = new AST\InputParameter($this->lexer->token->value); } else { @@ -3316,9 +3316,9 @@ public function LikeExpression() $escapeChar = null; - if ($this->lexer->lookahead !== null && $this->lexer->lookahead->type === Lexer::T_ESCAPE) { - $this->match(Lexer::T_ESCAPE); - $this->match(Lexer::T_STRING); + if ($this->lexer->lookahead !== null && $this->lexer->lookahead->type === TokenType::T_ESCAPE) { + $this->match(TokenType::T_ESCAPE); + $this->match(TokenType::T_STRING); assert($this->lexer->token !== null); $escapeChar = new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); @@ -3335,18 +3335,18 @@ public function LikeExpression() public function NullComparisonExpression() { switch (true) { - case $this->lexer->isNextToken(Lexer::T_INPUT_PARAMETER): - $this->match(Lexer::T_INPUT_PARAMETER); + case $this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER): + $this->match(TokenType::T_INPUT_PARAMETER); assert($this->lexer->token !== null); $expr = new AST\InputParameter($this->lexer->token->value); break; - case $this->lexer->isNextToken(Lexer::T_NULLIF): + case $this->lexer->isNextToken(TokenType::T_NULLIF): $expr = $this->NullIfExpression(); break; - case $this->lexer->isNextToken(Lexer::T_COALESCE): + case $this->lexer->isNextToken(TokenType::T_COALESCE): $expr = $this->CoalesceExpression(); break; @@ -3359,7 +3359,7 @@ public function NullComparisonExpression() $glimpse = $this->lexer->glimpse(); assert($glimpse !== null); - if ($glimpse->type === Lexer::T_DOT) { + if ($glimpse->type === TokenType::T_DOT) { $expr = $this->SingleValuedPathExpression(); // Leave switch statement @@ -3389,16 +3389,16 @@ public function NullComparisonExpression() break; } - $this->match(Lexer::T_IS); + $this->match(TokenType::T_IS); $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_NULL); + $this->match(TokenType::T_NULL); return new AST\NullComparisonExpression($expr, $not); } @@ -3412,17 +3412,17 @@ public function ExistsExpression() { $not = false; - if ($this->lexer->isNextToken(Lexer::T_NOT)) { - $this->match(Lexer::T_NOT); + if ($this->lexer->isNextToken(TokenType::T_NOT)) { + $this->match(TokenType::T_NOT); $not = true; } - $this->match(Lexer::T_EXISTS); - $this->match(Lexer::T_OPEN_PARENTHESIS); + $this->match(TokenType::T_EXISTS); + $this->match(TokenType::T_OPEN_PARENTHESIS); $subselect = $this->Subselect(); - $this->match(Lexer::T_CLOSE_PARENTHESIS); + $this->match(TokenType::T_CLOSE_PARENTHESIS); return new AST\ExistsExpression($subselect, $not); } @@ -3437,38 +3437,38 @@ public function ComparisonOperator() assert($this->lexer->lookahead !== null); switch ($this->lexer->lookahead->value) { case '=': - $this->match(Lexer::T_EQUALS); + $this->match(TokenType::T_EQUALS); return '='; case '<': - $this->match(Lexer::T_LOWER_THAN); + $this->match(TokenType::T_LOWER_THAN); $operator = '<'; - if ($this->lexer->isNextToken(Lexer::T_EQUALS)) { - $this->match(Lexer::T_EQUALS); + if ($this->lexer->isNextToken(TokenType::T_EQUALS)) { + $this->match(TokenType::T_EQUALS); $operator .= '='; - } elseif ($this->lexer->isNextToken(Lexer::T_GREATER_THAN)) { - $this->match(Lexer::T_GREATER_THAN); + } elseif ($this->lexer->isNextToken(TokenType::T_GREATER_THAN)) { + $this->match(TokenType::T_GREATER_THAN); $operator .= '>'; } return $operator; case '>': - $this->match(Lexer::T_GREATER_THAN); + $this->match(TokenType::T_GREATER_THAN); $operator = '>'; - if ($this->lexer->isNextToken(Lexer::T_EQUALS)) { - $this->match(Lexer::T_EQUALS); + if ($this->lexer->isNextToken(TokenType::T_EQUALS)) { + $this->match(TokenType::T_EQUALS); $operator .= '='; } return $operator; case '!': - $this->match(Lexer::T_NEGATE); - $this->match(Lexer::T_EQUALS); + $this->match(TokenType::T_NEGATE); + $this->match(TokenType::T_EQUALS); return '<>'; diff --git a/src/Query/TokenType.php b/src/Query/TokenType.php new file mode 100644 index 00000000000..417c7506d25 --- /dev/null +++ b/src/Query/TokenType.php @@ -0,0 +1,99 @@ += 100 + /** @deprecated No Replacement planned. */ + public const T_ALIASED_NAME = 100; + public const T_FULLY_QUALIFIED_NAME = 101; + public const T_IDENTIFIER = 102; + + // All keyword tokens should be >= 200 + public const T_ALL = 200; + public const T_AND = 201; + public const T_ANY = 202; + public const T_AS = 203; + public const T_ASC = 204; + public const T_AVG = 205; + public const T_BETWEEN = 206; + public const T_BOTH = 207; + public const T_BY = 208; + public const T_CASE = 209; + public const T_COALESCE = 210; + public const T_COUNT = 211; + public const T_DELETE = 212; + public const T_DESC = 213; + public const T_DISTINCT = 214; + public const T_ELSE = 215; + public const T_EMPTY = 216; + public const T_END = 217; + public const T_ESCAPE = 218; + public const T_EXISTS = 219; + public const T_FALSE = 220; + public const T_FROM = 221; + public const T_GROUP = 222; + public const T_HAVING = 223; + public const T_HIDDEN = 224; + public const T_IN = 225; + public const T_INDEX = 226; + public const T_INNER = 227; + public const T_INSTANCE = 228; + public const T_IS = 229; + public const T_JOIN = 230; + public const T_LEADING = 231; + public const T_LEFT = 232; + public const T_LIKE = 233; + public const T_MAX = 234; + public const T_MEMBER = 235; + public const T_MIN = 236; + public const T_NEW = 237; + public const T_NOT = 238; + public const T_NULL = 239; + public const T_NULLIF = 240; + public const T_OF = 241; + public const T_OR = 242; + public const T_ORDER = 243; + public const T_OUTER = 244; + public const T_PARTIAL = 245; + public const T_SELECT = 246; + public const T_SET = 247; + public const T_SOME = 248; + public const T_SUM = 249; + public const T_THEN = 250; + public const T_TRAILING = 251; + public const T_TRUE = 252; + public const T_UPDATE = 253; + public const T_WHEN = 254; + public const T_WHERE = 255; + public const T_WITH = 256; + + /** @internal */ + private function __construct() + { + } +} diff --git a/tests/Tests/ORM/Functional/CustomFunctionsTest.php b/tests/Tests/ORM/Functional/CustomFunctionsTest.php index f4027d7dc83..284aee8c68a 100644 --- a/tests/Tests/ORM/Functional/CustomFunctionsTest.php +++ b/tests/Tests/ORM/Functional/CustomFunctionsTest.php @@ -7,9 +7,9 @@ use Doctrine\ORM\Query; use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\AST\PathExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use Doctrine\Tests\Models\CMS\CmsUser; use Doctrine\Tests\OrmFunctionalTestCase; @@ -75,10 +75,10 @@ class NoOp extends FunctionNode public function parse(Parser $parser): void { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->field = $parser->ArithmeticPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } public function getSql(SqlWalker $sqlWalker): string diff --git a/tests/Tests/ORM/Functional/Ticket/GH7286Test.php b/tests/Tests/ORM/Functional/Ticket/GH7286Test.php index 0fd6d8aa37f..e46c963277b 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH7286Test.php +++ b/tests/Tests/ORM/Functional/Ticket/GH7286Test.php @@ -10,9 +10,9 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\AST\Node; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use Doctrine\Tests\OrmFunctionalTestCase; final class GH7286Test extends OrmFunctionalTestCase @@ -114,14 +114,14 @@ class GH7286CustomConcat extends FunctionNode public function parse(Parser $parser): void { - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->first = $parser->StringPrimary(); - $parser->match(Lexer::T_COMMA); + $parser->match(TokenType::T_COMMA); $this->second = $parser->StringPrimary(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } public function getSql(SqlWalker $walker): string diff --git a/tests/Tests/ORM/Query/LexerTest.php b/tests/Tests/ORM/Query/LexerTest.php index 99b13063636..9aa818d1dd2 100644 --- a/tests/Tests/ORM/Query/LexerTest.php +++ b/tests/Tests/ORM/Query/LexerTest.php @@ -6,6 +6,7 @@ use Doctrine\Common\Lexer\Token; use Doctrine\ORM\Query\Lexer; +use Doctrine\ORM\Query\TokenType; use Doctrine\Tests\OrmTestCase; class LexerTest extends OrmTestCase @@ -35,7 +36,7 @@ public function testScannerRecognizesTerminalString(): void $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_ALL, $token->type); + self::assertEquals(TokenType::T_ALL, $token->type); } public function testScannerRecognizesDecimalInteger(): void @@ -43,7 +44,7 @@ public function testScannerRecognizesDecimalInteger(): void $lexer = new Lexer('1234'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_INTEGER, $token->type); + self::assertEquals(TokenType::T_INTEGER, $token->type); self::assertEquals(1234, $token->value); } @@ -52,7 +53,7 @@ public function testScannerRecognizesFloat(): void $lexer = new Lexer('1.234'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertEquals(1.234, $token->value); } @@ -61,7 +62,7 @@ public function testScannerRecognizesFloatWithExponent(): void $lexer = new Lexer('1.2e3'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertEquals(1.2e3, $token->value); } @@ -70,7 +71,7 @@ public function testScannerRecognizesFloatWithExponent2(): void $lexer = new Lexer('0.2e3'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertEquals(.2e3, $token->value); } @@ -79,7 +80,7 @@ public function testScannerRecognizesFloatWithNegativeExponent(): void $lexer = new Lexer('7E-10'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertEquals(7E-10, $token->value); } @@ -88,7 +89,7 @@ public function testScannerRecognizesFloatBig(): void $lexer = new Lexer('123456789.01'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertEquals(1.2345678901e8, $token->value); } @@ -97,12 +98,12 @@ public function testScannerRecognizesFloatContainingWhitespace(): void $lexer = new Lexer('- 1.234e2'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_MINUS, $token->type); + self::assertEquals(TokenType::T_MINUS, $token->type); self::assertEquals('-', $token->value); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_FLOAT, $token->type); + self::assertEquals(TokenType::T_FLOAT, $token->type); self::assertNotEquals(-1.234e2, $token->value); self::assertEquals(1.234e2, $token->value); } @@ -112,7 +113,7 @@ public function testScannerRecognizesStringContainingWhitespace(): void $lexer = new Lexer("'This is a string.'"); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_STRING, $token->type); + self::assertEquals(TokenType::T_STRING, $token->type); self::assertEquals('This is a string.', $token->value); } @@ -121,7 +122,7 @@ public function testScannerRecognizesStringContainingSingleQuotes(): void $lexer = new Lexer("'abc''defg'''"); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_STRING, $token->type); + self::assertEquals(TokenType::T_STRING, $token->type); self::assertEquals("abc'defg'", $token->value); } @@ -130,7 +131,7 @@ public function testScannerRecognizesInputParameter(): void $lexer = new Lexer('?1'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_INPUT_PARAMETER, $token->type); + self::assertEquals(TokenType::T_INPUT_PARAMETER, $token->type); self::assertEquals('?1', $token->value); } @@ -139,7 +140,7 @@ public function testScannerRecognizesNamedInputParameter(): void $lexer = new Lexer(':name'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_INPUT_PARAMETER, $token->type); + self::assertEquals(TokenType::T_INPUT_PARAMETER, $token->type); self::assertEquals(':name', $token->value); } @@ -148,7 +149,7 @@ public function testScannerRecognizesNamedInputParameterStartingWithUnderscore() $lexer = new Lexer(':_name'); $lexer->moveNext(); $token = $lexer->lookahead; - self::assertEquals(Lexer::T_INPUT_PARAMETER, $token->type); + self::assertEquals(TokenType::T_INPUT_PARAMETER, $token->type); self::assertEquals(':_name', $token->value); } @@ -158,17 +159,17 @@ public function testScannerTokenizesASimpleQueryCorrectly(): void $lexer = new Lexer($dql); $tokens = [ - new Token('SELECT', Lexer::T_SELECT, 0), - new Token('u', Lexer::T_IDENTIFIER, 7), - new Token('FROM', Lexer::T_FROM, 9), - new Token('My\Namespace\User', Lexer::T_FULLY_QUALIFIED_NAME, 14), - new Token('u', Lexer::T_IDENTIFIER, 32), - new Token('WHERE', Lexer::T_WHERE, 34), - new Token('u', Lexer::T_IDENTIFIER, 40), - new Token('.', Lexer::T_DOT, 41), - new Token('name', Lexer::T_IDENTIFIER, 42), - new Token('=', Lexer::T_EQUALS, 47), - new Token("Jack O'Neil", Lexer::T_STRING, 49), + new Token('SELECT', TokenType::T_SELECT, 0), + new Token('u', TokenType::T_IDENTIFIER, 7), + new Token('FROM', TokenType::T_FROM, 9), + new Token('My\Namespace\User', TokenType::T_FULLY_QUALIFIED_NAME, 14), + new Token('u', TokenType::T_IDENTIFIER, 32), + new Token('WHERE', TokenType::T_WHERE, 34), + new Token('u', TokenType::T_IDENTIFIER, 40), + new Token('.', TokenType::T_DOT, 41), + new Token('name', TokenType::T_IDENTIFIER, 42), + new Token('=', TokenType::T_EQUALS, 47), + new Token("Jack O'Neil", TokenType::T_STRING, 49), ]; foreach ($tokens as $expected) { @@ -186,15 +187,15 @@ public function testScannerTokenizesASimpleQueryCorrectly(): void public static function provideTokens(): array { return [ - [Lexer::T_IDENTIFIER, 'u'], // one char - [Lexer::T_IDENTIFIER, 'someIdentifier'], - [Lexer::T_IDENTIFIER, 's0m31d3nt1f13r'], // including digits - [Lexer::T_IDENTIFIER, 'some_identifier'], // including underscore - [Lexer::T_IDENTIFIER, '_some_identifier'], // starts with underscore - [Lexer::T_IDENTIFIER, 'comma'], // name of a token class with value < 100 (whitebox test) - [Lexer::T_FULLY_QUALIFIED_NAME, 'Some\Class'], // DQL class reference - [Lexer::T_ALIASED_NAME, 'Some:Name'], - [Lexer::T_ALIASED_NAME, 'Some:Subclassed\Name'], + [TokenType::T_IDENTIFIER, 'u'], // one char + [TokenType::T_IDENTIFIER, 'someIdentifier'], + [TokenType::T_IDENTIFIER, 's0m31d3nt1f13r'], // including digits + [TokenType::T_IDENTIFIER, 'some_identifier'], // including underscore + [TokenType::T_IDENTIFIER, '_some_identifier'], // starts with underscore + [TokenType::T_IDENTIFIER, 'comma'], // name of a token class with value < 100 (whitebox test) + [TokenType::T_FULLY_QUALIFIED_NAME, 'Some\Class'], // DQL class reference + [TokenType::T_ALIASED_NAME, 'Some:Name'], + [TokenType::T_ALIASED_NAME, 'Some:Subclassed\Name'], ]; } } diff --git a/tests/Tests/ORM/Query/ParserTest.php b/tests/Tests/ORM/Query/ParserTest.php index 9ad751d76b3..2bc42a58b8f 100644 --- a/tests/Tests/ORM/Query/ParserTest.php +++ b/tests/Tests/ORM/Query/ParserTest.php @@ -6,9 +6,9 @@ use Doctrine\Common\Persistence\PersistentObject; use Doctrine\ORM\Query; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\QueryException; +use Doctrine\ORM\Query\TokenType; use Doctrine\Tests\Models\CMS\CmsUser; use Doctrine\Tests\OrmTestCase; use stdClass; @@ -124,11 +124,11 @@ public static function validMatches(): array * but in LexerTest. */ return [ - [Lexer::T_WHERE, 'where'], // keyword - [Lexer::T_DOT, '.'], // token that cannot be an identifier - [Lexer::T_IDENTIFIER, 'someIdentifier'], - [Lexer::T_IDENTIFIER, 'from'], // also a terminal string (the "FROM" keyword) as in DDC-505 - [Lexer::T_IDENTIFIER, 'comma'], + [TokenType::T_WHERE, 'where'], // keyword + [TokenType::T_DOT, '.'], // token that cannot be an identifier + [TokenType::T_IDENTIFIER, 'someIdentifier'], + [TokenType::T_IDENTIFIER, 'from'], // also a terminal string (the "FROM" keyword) as in DDC-505 + [TokenType::T_IDENTIFIER, 'comma'], // not even a terminal string, but the name of a constant in the Lexer (whitebox test) ]; } @@ -137,15 +137,15 @@ public static function validMatches(): array public static function invalidMatches(): array { return [ - [Lexer::T_DOT, 'ALL'], // ALL is a terminal string (reserved keyword) and also possibly an identifier - [Lexer::T_DOT, ','], // "," is a token on its own, but cannot be used as identifier - [Lexer::T_WHERE, 'WITH'], // as in DDC-3697 - [Lexer::T_WHERE, '.'], + [TokenType::T_DOT, 'ALL'], // ALL is a terminal string (reserved keyword) and also possibly an identifier + [TokenType::T_DOT, ','], // "," is a token on its own, but cannot be used as identifier + [TokenType::T_WHERE, 'WITH'], // as in DDC-3697 + [TokenType::T_WHERE, '.'], // The following are qualified or aliased names and must not be accepted where only an Identifier is expected - [Lexer::T_IDENTIFIER, '\\Some\\Class'], - [Lexer::T_IDENTIFIER, 'Some\\Class'], - [Lexer::T_IDENTIFIER, 'Some:Name'], + [TokenType::T_IDENTIFIER, '\\Some\\Class'], + [TokenType::T_IDENTIFIER, 'Some\\Class'], + [TokenType::T_IDENTIFIER, 'Some:Name'], ]; } @@ -164,7 +164,7 @@ public function testNullLookahead(): void $parser = new Parser($query); $this->expectException(QueryException::class); - $parser->match(Lexer::T_SELECT); + $parser->match(TokenType::T_SELECT); } private function createParser(string $dql): Parser diff --git a/tests/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Tests/ORM/Query/SelectSqlGenerationTest.php index 540d870828f..5effffe36d0 100644 --- a/tests/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -18,10 +18,10 @@ use Doctrine\ORM\Query as ORMQuery; use Doctrine\ORM\Query\AST\Functions\FunctionNode; use Doctrine\ORM\Query\AST\SimpleArithmeticExpression; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\Parser; use Doctrine\ORM\Query\QueryException; use Doctrine\ORM\Query\SqlWalker; +use Doctrine\ORM\Query\TokenType; use Doctrine\Tests\DbalTypes\NegativeToPositiveType; use Doctrine\Tests\Models\CMS\CmsGroup; use Doctrine\Tests\Models\CMS\CmsPhonenumber; @@ -2186,12 +2186,12 @@ public function parse(Parser $parser): void { $lexer = $parser->getLexer(); - $parser->match(Lexer::T_IDENTIFIER); - $parser->match(Lexer::T_OPEN_PARENTHESIS); + $parser->match(TokenType::T_IDENTIFIER); + $parser->match(TokenType::T_OPEN_PARENTHESIS); $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - $parser->match(Lexer::T_CLOSE_PARENTHESIS); + $parser->match(TokenType::T_CLOSE_PARENTHESIS); } } /** @Entity */ diff --git a/tests/Tests/ORM/Query/TreeWalkerAdapterTest.php b/tests/Tests/ORM/Query/TreeWalkerAdapterTest.php index d0915bde9b6..4613de998af 100644 --- a/tests/Tests/ORM/Query/TreeWalkerAdapterTest.php +++ b/tests/Tests/ORM/Query/TreeWalkerAdapterTest.php @@ -7,8 +7,8 @@ use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\AbstractQuery; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Query\Lexer; use Doctrine\ORM\Query\ParserResult; +use Doctrine\ORM\Query\TokenType; use Doctrine\ORM\Query\TreeWalkerAdapter; use PHPUnit\Framework\TestCase; use stdClass; @@ -33,7 +33,7 @@ public function testDeprecatedSetQueryComponent(): void 'relation' => null, 'map' => null, 'nestingLevel' => 0, - 'token' => ['value' => '', 'type' => Lexer::T_NONE, 'position' => 0], + 'token' => ['value' => '', 'type' => TokenType::T_NONE, 'position' => 0], ]); } @@ -52,7 +52,7 @@ public function doSetQueryComponent(): void 'relation' => null, 'map' => null, 'nestingLevel' => 0, - 'token' => ['value' => '', 'type' => Lexer::T_NONE, 'position' => 0], + 'token' => ['value' => '', 'type' => TokenType::T_NONE, 'position' => 0], ]); } }; From 7baef1e120e7b03e7ae7ceea4a879c29196001de Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 7 Feb 2024 15:39:20 +0100 Subject: [PATCH 088/128] Remove references to deprecated constants from Lexer (#11234) --- src/Query/Lexer.php | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Query/Lexer.php b/src/Query/Lexer.php index d4f0aefc255..69c329fe590 100644 --- a/src/Query/Lexer.php +++ b/src/Query/Lexer.php @@ -304,22 +304,22 @@ protected function getNonCatchablePatterns() */ protected function getType(&$value) { - $type = self::T_NONE; + $type = TokenType::T_NONE; switch (true) { // Recognize numeric values case is_numeric($value): if (str_contains($value, '.') || stripos($value, 'e') !== false) { - return self::T_FLOAT; + return TokenType::T_FLOAT; } - return self::T_INTEGER; + return TokenType::T_INTEGER; // Recognize quoted strings case $value[0] === "'": $value = str_replace("''", "'", substr($value, 1, strlen($value) - 2)); - return self::T_STRING; + return TokenType::T_STRING; // Recognize identifiers, aliased or qualified names case ctype_alpha($value[0]) || $value[0] === '_' || $value[0] === '\\': @@ -341,61 +341,61 @@ protected function getType(&$value) $value ); - return self::T_ALIASED_NAME; + return TokenType::T_ALIASED_NAME; } if (str_contains($value, '\\')) { - return self::T_FULLY_QUALIFIED_NAME; + return TokenType::T_FULLY_QUALIFIED_NAME; } - return self::T_IDENTIFIER; + return TokenType::T_IDENTIFIER; // Recognize input parameters case $value[0] === '?' || $value[0] === ':': - return self::T_INPUT_PARAMETER; + return TokenType::T_INPUT_PARAMETER; // Recognize symbols case $value === '.': - return self::T_DOT; + return TokenType::T_DOT; case $value === ',': - return self::T_COMMA; + return TokenType::T_COMMA; case $value === '(': - return self::T_OPEN_PARENTHESIS; + return TokenType::T_OPEN_PARENTHESIS; case $value === ')': - return self::T_CLOSE_PARENTHESIS; + return TokenType::T_CLOSE_PARENTHESIS; case $value === '=': - return self::T_EQUALS; + return TokenType::T_EQUALS; case $value === '>': - return self::T_GREATER_THAN; + return TokenType::T_GREATER_THAN; case $value === '<': - return self::T_LOWER_THAN; + return TokenType::T_LOWER_THAN; case $value === '+': - return self::T_PLUS; + return TokenType::T_PLUS; case $value === '-': - return self::T_MINUS; + return TokenType::T_MINUS; case $value === '*': - return self::T_MULTIPLY; + return TokenType::T_MULTIPLY; case $value === '/': - return self::T_DIVIDE; + return TokenType::T_DIVIDE; case $value === '!': - return self::T_NEGATE; + return TokenType::T_NEGATE; case $value === '{': - return self::T_OPEN_CURLY_BRACE; + return TokenType::T_OPEN_CURLY_BRACE; case $value === '}': - return self::T_CLOSE_CURLY_BRACE; + return TokenType::T_CLOSE_CURLY_BRACE; // Default default: From 1d218bae30d67662498eb0e30cce2c5e329a2c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 12 Feb 2024 23:46:09 +0100 Subject: [PATCH 089/128] Make docs valid according to guides 0.3.3 (#11252) --- .github/workflows/documentation.yml | 6 +- docs/en/reference/basic-mapping.rst | 2 +- docs/en/reference/events.rst | 80 +++++++++++------------ docs/en/reference/faq.rst | 2 +- docs/en/reference/inheritance-mapping.rst | 2 +- docs/en/sidebar.rst | 2 + 6 files changed, 46 insertions(+), 48 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 58c53f5ae38..f0bbf5b9e2a 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -40,9 +40,5 @@ jobs: with: dependency-versions: "highest" - - name: "Add dummy title to the sidebar" - run: | - printf '%s\n%s\n\n%s\n' "Dummy title" "===========" "$(cat docs/en/sidebar.rst)" > docs/en/sidebar.rst - - name: "Run guides-cli" - run: "vendor/bin/guides -vvv --no-progress docs/en 2>&1 | grep -v 'Unknown directive' | ( ! grep WARNING )" + run: "vendor/bin/guides -vvv --no-progress docs/en 2>&1 | grep -v 'No template found for rendering directive' | ( ! grep WARNING )" diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index 66b552a1d87..a61e5d8d0e4 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -462,7 +462,7 @@ Here is the list of possible generation strategies: a new entity is passed to ``EntityManager#persist``. NONE is the same as leaving off the ``#[GeneratedValue]`` entirely. - ``CUSTOM``: With this option, you can use the ``#[CustomIdGenerator]`` attribute. - It will allow you to pass a :ref:`class of your own to generate the identifiers.` + It will allow you to pass a :ref:`class of your own to generate the identifiers. ` Sequence Generator ^^^^^^^^^^^^^^^^^^ diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst index 408014cf417..dbde6d19df2 100644 --- a/docs/en/reference/events.rst +++ b/docs/en/reference/events.rst @@ -131,47 +131,47 @@ There are two ways to set up an event handler: * For *all events* you can create a Lifecycle Event Listener or Subscriber class and register it by calling ``$eventManager->addEventListener()`` or ``eventManager->addEventSubscriber()``, see -:ref:`Listening and subscribing to Lifecycle Events` +:ref:`Listening and subscribing to Lifecycle Events ` * For *some events* (see table below), you can create a *Lifecycle Callback* method in the -entity, see :ref:`Lifecycle Callbacks`. +entity, see :ref:`Lifecycle Callbacks `. .. _reference-events-lifecycle-events: Events Overview --------------- -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| Event | Dispatched by | Lifecycle | Passed | -| | | Callback | Argument | -+=================================================================+=======================+===========+=====================================+ -| :ref:`preRemove` | ``$em->remove()`` | Yes | `PreRemoveEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`postRemove` | ``$em->flush()`` | Yes | `PostRemoveEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`prePersist` | ``$em->persist()`` | Yes | `PrePersistEventArgs`_ | -| | on *initial* persist | | | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`postPersist` | ``$em->flush()`` | Yes | `PostPersistEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`preUpdate` | ``$em->flush()`` | Yes | `PreUpdateEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`postUpdate` | ``$em->flush()`` | Yes | `PostUpdateEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`postLoad` | Loading from database | Yes | `PostLoadEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`loadClassMetadata` | Loading of mapping | No | `LoadClassMetadataEventArgs`_ | -| | metadata | | | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| ``onClassMetadataNotFound`` | ``MappingException`` | No | `OnClassMetadataNotFoundEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`preFlush` | ``$em->flush()`` | Yes | `PreFlushEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`onFlush` | ``$em->flush()`` | No | `OnFlushEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`postFlush` | ``$em->flush()`` | No | `PostFlushEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ -| :ref:`onClear` | ``$em->clear()`` | No | `OnClearEventArgs`_ | -+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| Event | Dispatched by | Lifecycle | Passed | +| | | Callback | Argument | ++==================================================================+=======================+===========+=====================================+ +| :ref:`preRemove ` | ``$em->remove()`` | Yes | `PreRemoveEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`postRemove ` | ``$em->flush()`` | Yes | `PostRemoveEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`prePersist ` | ``$em->persist()`` | Yes | `PrePersistEventArgs`_ | +| | on *initial* persist | | | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`postPersist ` | ``$em->flush()`` | Yes | `PostPersistEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`preUpdate ` | ``$em->flush()`` | Yes | `PreUpdateEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`postUpdate ` | ``$em->flush()`` | Yes | `PostUpdateEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`postLoad ` | Loading from database | Yes | `PostLoadEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`loadClassMetadata ` | Loading of mapping | No | `LoadClassMetadataEventArgs`_ | +| | metadata | | | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| ``onClassMetadataNotFound`` | ``MappingException`` | No | `OnClassMetadataNotFoundEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`preFlush ` | ``$em->flush()`` | Yes | `PreFlushEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`onFlush ` | ``$em->flush()`` | No | `OnFlushEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`postFlush ` | ``$em->flush()`` | No | `PostFlushEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ +| :ref:`onClear ` | ``$em->clear()`` | No | `OnClearEventArgs`_ | ++------------------------------------------------------------------+-----------------------+-----------+-------------------------------------+ .. warning:: @@ -358,7 +358,7 @@ behaviors across different entity classes. Note that they require much more detailed knowledge about the inner workings of the ``EntityManager`` and ``UnitOfWork`` classes. Please -read the :ref:`Implementing Event Listeners` section +read the :ref:`Implementing Event Listeners ` section carefully if you are trying to write your own listener. For event subscribers, there are no surprises. They declare the @@ -471,11 +471,11 @@ prePersist There are two ways for the ``prePersist`` event to be triggered: - One is when you call ``EntityManager::persist()``. The - event is also called for all :ref:`cascaded associations`. + event is also called for all :ref:`cascaded associations `. - The other is inside the ``flush()`` method when changes to associations are computed and - this association is marked as :ref:`cascade: persist`. Any new entity found + this association is marked as :ref:`cascade: persist `. Any new entity found during this operation is also persisted and ``prePersist`` called - on it. This is called :ref:`persistence by reachability`. + on it. This is called :ref:`persistence by reachability `. In both cases you get passed a ``PrePersistEventArgs`` instance which has access to the entity and the entity manager. @@ -499,7 +499,7 @@ preRemove The ``preRemove`` event is called on every entity immediately when it is passed to the ``EntityManager::remove()`` method. It is cascaded for all -associations that are marked as :ref:`cascade: remove` +associations that are marked as :ref:`cascade: remove ` It is not called for a DQL ``DELETE`` statement. @@ -547,7 +547,7 @@ entities and their associations have been computed. This means, the - Collections scheduled for removal To make use of the ``onFlush`` event you have to be familiar with the -internal :ref:`UnitOfWork` API, which grants you access to the previously +internal :ref:`UnitOfWork ` API, which grants you access to the previously mentioned sets. See this example: .. code-block:: php diff --git a/docs/en/reference/faq.rst b/docs/en/reference/faq.rst index a81812a9c2b..85b6e35d851 100644 --- a/docs/en/reference/faq.rst +++ b/docs/en/reference/faq.rst @@ -101,7 +101,7 @@ The many-to-many association is only supporting foreign keys in the table defini To work with many-to-many tables containing extra columns you have to use the foreign keys as primary keys feature of Doctrine ORM. -See :doc:`the tutorial on composite primary keys for more information<../tutorials/composite-primary-keys>`. +See :doc:`the tutorial on composite primary keys for more information <../tutorials/composite-primary-keys>`. How can i paginate fetch-joined collections? diff --git a/docs/en/reference/inheritance-mapping.rst b/docs/en/reference/inheritance-mapping.rst index 0e23c8f7d87..448c9dd401b 100644 --- a/docs/en/reference/inheritance-mapping.rst +++ b/docs/en/reference/inheritance-mapping.rst @@ -380,7 +380,7 @@ It is not supported to use overrides in entity inheritance scenarios. .. note:: When using traits, make sure not to miss the warnings given in the - :doc:`Limitations and Known Issues` chapter. + :doc:`Limitations and Known Issues ` chapter. Association Override diff --git a/docs/en/sidebar.rst b/docs/en/sidebar.rst index 0430bcc7504..c87651c2fbe 100644 --- a/docs/en/sidebar.rst +++ b/docs/en/sidebar.rst @@ -1,3 +1,5 @@ +:orphan: + .. toc:: .. tocheader:: Tutorials From e5e3166747f75892e799ace32061faf7354094ca Mon Sep 17 00:00:00 2001 From: Dmitry Bannik Date: Tue, 13 Feb 2024 14:15:19 +0300 Subject: [PATCH 090/128] #11090 - Fix obtaining an identifier in cases where the hydration has not yet fully completed on eagerLoadCollections --- src/UnitOfWork.php | 12 +++- .../WithFetchEager/AbstractRemoveControl.php | 49 ++++++++++++++ .../WithFetchEager/MobileRemoteControl.php | 14 ++++ .../WithFetchEager/User.php | 35 ++++++++++ .../AbstractRemoveControl.php | 49 ++++++++++++++ .../WithoutFetchEager/MobileRemoteControl.php | 14 ++++ .../WithoutFetchEager/User.php | 35 ++++++++++ .../ORM/Functional/AbstractFetchEagerTest.php | 64 +++++++++++++++++++ 8 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php create mode 100644 tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php create mode 100644 tests/Tests/Models/AbstractFetchEager/WithFetchEager/User.php create mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php create mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php create mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/User.php create mode 100644 tests/Tests/ORM/Functional/AbstractFetchEagerTest.php diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index 00698e56c60..07903c3e6c0 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3252,7 +3252,17 @@ private function eagerLoadCollections(array $collections, array $mapping): void foreach ($found as $targetValue) { $sourceEntity = $targetProperty->getValue($targetValue); - $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); + // In cases where the hydration $targetValue has not yet fully completed + if ($sourceEntity === null && isset($targetClass->associationMappings[$mappedBy]['joinColumns'])) { + $data = $this->getOriginalEntityData($targetValue); + $id = []; + foreach ($targetClass->associationMappings[$mappedBy]['joinColumns'] as $joinColumn) { + $id[] = $data[$joinColumn['name']]; + } + } else { + $id = $this->identifierFlattener->flattenIdentifier($class, $class->getIdentifierValues($sourceEntity)); + } + $idHash = implode(' ', $id); if (isset($mapping['indexBy'])) { diff --git a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php b/tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php new file mode 100644 index 00000000000..7c69c15d75a --- /dev/null +++ b/tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php @@ -0,0 +1,49 @@ + + */ + public $users; + + public function __construct(string $name) + { + $this->name = $name; + $this->users = new ArrayCollection(); + } +} diff --git a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php new file mode 100644 index 00000000000..cdbca6f3f0f --- /dev/null +++ b/tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php @@ -0,0 +1,14 @@ +remoteControl = $control; + } +} diff --git a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php new file mode 100644 index 00000000000..82bb2f705f6 --- /dev/null +++ b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php @@ -0,0 +1,49 @@ + + */ + public $users; + + public function __construct(string $name) + { + $this->name = $name; + $this->users = new ArrayCollection(); + } +} diff --git a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php new file mode 100644 index 00000000000..6628234450f --- /dev/null +++ b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php @@ -0,0 +1,14 @@ +remoteControl = $control; + } +} diff --git a/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php new file mode 100644 index 00000000000..14e50f70b4b --- /dev/null +++ b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php @@ -0,0 +1,64 @@ +createSchemaForModels( + AbstractRemoveControl::class, + User::class + ); + + $control = new MobileRemoteControl('smart'); + $user = new User($control); + + $entityManage = $this->getEntityManager(); + + $entityManage->persist($control); + $entityManage->persist($user); + $entityManage->flush(); + $entityManage->clear(); + + $user = $entityManage->find(User::class, $user->id); + + self::assertNotNull($user); + self::assertEquals('smart', $user->remoteControl->name); + self::assertTrue($user->remoteControl->users->contains($user)); + } + + public function testWithoutAbstractFetchEager(): void + { + $this->createSchemaForModels( + AbstractRemoveControlWithoutFetchEager::class, + UserWithoutFetchEager::class + ); + + $control = new MobileRemoteControlWithoutFetchEager('smart'); + $user = new UserWithoutFetchEager($control); + + $entityManage = $this->getEntityManager(); + + $entityManage->persist($control); + $entityManage->persist($user); + $entityManage->flush(); + $entityManage->clear(); + + $user = $entityManage->find(UserWithoutFetchEager::class, $user->id); + + self::assertNotNull($user); + self::assertEquals('smart', $user->remoteControl->name); + self::assertTrue($user->remoteControl->users->contains($user)); + } +} From 7b3db4a0375128bc10a617f90384c360a43fda8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 17 Feb 2024 14:59:24 +0100 Subject: [PATCH 091/128] Use correction sectionauthor syntax --- .../en/cookbook/implementing-arrayaccess-for-domain-objects.rst | 2 +- .../cookbook/implementing-the-notify-changetracking-policy.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/cookbook/implementing-arrayaccess-for-domain-objects.rst b/docs/en/cookbook/implementing-arrayaccess-for-domain-objects.rst index 363d1ad8ba1..40ca4fbdfc5 100644 --- a/docs/en/cookbook/implementing-arrayaccess-for-domain-objects.rst +++ b/docs/en/cookbook/implementing-arrayaccess-for-domain-objects.rst @@ -1,7 +1,7 @@ Implementing ArrayAccess for Domain Objects =========================================== -.. sectionauthor:: Roman Borschel (roman@code-factory.org) +.. sectionauthor:: Roman Borschel This recipe will show you how to implement ArrayAccess for your domain objects in order to allow more uniform access, for example diff --git a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst index 2415db1dc97..13ada8fb572 100644 --- a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst +++ b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst @@ -1,7 +1,7 @@ Implementing the Notify ChangeTracking Policy ============================================= -.. sectionauthor:: Roman Borschel (roman@code-factory.org) +.. sectionauthor:: Roman Borschel The NOTIFY change-tracking policy is the most effective change-tracking policy provided by Doctrine but it requires some From fe0647053a7e87e25b571d1375ce947431eea0f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 17 Feb 2024 15:06:46 +0100 Subject: [PATCH 092/128] Mark document as orphan It is here for backward compatibilty reasons. --- docs/en/reference/installation.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/reference/installation.rst b/docs/en/reference/installation.rst index dab1364f777..2c0d5823009 100644 --- a/docs/en/reference/installation.rst +++ b/docs/en/reference/installation.rst @@ -1,3 +1,5 @@ +:orphan: + Installation ============ From dba9d72b2d370035ced6d634fc89814e90ddfa66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sat, 17 Feb 2024 15:10:28 +0100 Subject: [PATCH 093/128] Add type field mapper documentation to the sidebar --- docs/en/sidebar.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/sidebar.rst b/docs/en/sidebar.rst index c87651c2fbe..f67304e8457 100644 --- a/docs/en/sidebar.rst +++ b/docs/en/sidebar.rst @@ -33,6 +33,7 @@ reference/inheritance-mapping reference/working-with-objects reference/working-with-associations + reference/typedfieldmapper reference/events reference/unitofwork reference/unitofwork-associations From 7c2907805184107e464dab2bfd0743df77ea9ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 18 Feb 2024 11:32:14 +0100 Subject: [PATCH 094/128] Treat '0' as a legitimate trim char Because of a loose comparison, it was not. --- src/Query/AST/Functions/TrimFunction.php | 2 +- tests/Tests/ORM/Query/LanguageRecognitionTest.php | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Query/AST/Functions/TrimFunction.php b/src/Query/AST/Functions/TrimFunction.php index 8c2b307faea..f9c6e406fea 100644 --- a/src/Query/AST/Functions/TrimFunction.php +++ b/src/Query/AST/Functions/TrimFunction.php @@ -74,7 +74,7 @@ public function parse(Parser $parser) $this->trimChar = $lexer->token->value; } - if ($this->leading || $this->trailing || $this->both || $this->trimChar) { + if ($this->leading || $this->trailing || $this->both || ($this->trimChar !== false)) { $parser->match(Lexer::T_FROM); } diff --git a/tests/Tests/ORM/Query/LanguageRecognitionTest.php b/tests/Tests/ORM/Query/LanguageRecognitionTest.php index 4d1972593f3..a2e0e600969 100644 --- a/tests/Tests/ORM/Query/LanguageRecognitionTest.php +++ b/tests/Tests/ORM/Query/LanguageRecognitionTest.php @@ -172,6 +172,11 @@ public function testFunctionalExpressionsSupportedInWherePart(): void $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'"); } + public function testTrimFalsyString(): void + { + $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM('0' FROM u.name) = 'someone'"); + } + public function testArithmeticExpressionsSupportedInWherePart(): void { $this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000'); From cf408ad9ae817948e66fc5c6487a28bc2e5b98ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 18 Feb 2024 12:26:18 +0100 Subject: [PATCH 095/128] Remove unused baseline entries --- psalm-baseline.xml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 34b44307ff3..3123bf33d28 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1543,15 +1543,6 @@ - - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - ArithmeticPrimary()]]> ArithmeticPrimary()]]> @@ -1572,15 +1563,6 @@ - - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - intervalExpression->dispatch($sqlWalker)]]> - unit->value]]> From e4769d319146cde533429a381a6fa3636203e3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 18 Feb 2024 15:51:05 +0100 Subject: [PATCH 096/128] docs: recommend safer way to disable logging (#11269) * Remove trailing newlines * Recommend safer way to disable logging Resetting the middlewares on the configuration object will only work if the connection object hasn't been built from that configuration object yet. Instead, people should find the logger bound to the logging middleware and disable it. --- docs/en/reference/batch-processing.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/en/reference/batch-processing.rst b/docs/en/reference/batch-processing.rst index 12cac934164..ee381bbe5c4 100644 --- a/docs/en/reference/batch-processing.rst +++ b/docs/en/reference/batch-processing.rst @@ -18,14 +18,20 @@ especially what the strategies presented here provide help with. .. note:: - Having an SQL logger enabled when processing batches can have a serious impact on performance and resource usage. - To avoid that you should remove the corresponding middleware. - To remove all middlewares, you can use this line: + Having an SQL logger enabled when processing batches can have a + serious impact on performance and resource usage. + To avoid that, you should use a PSR logger implementation that can be + disabled at runtime. + For example, with Monolog, you can use ``Logger::pushHandler()`` + to push a ``NullHandler`` to the logger instance, and then pop it + when you need to enable logging again. + + With DBAL 2, you can disable the SQL logger like below: + .. code-block:: php getConnection()->getConfiguration()->setMiddlewares([]); // DBAL 3 - $em->getConnection()->getConfiguration()->setSQLLogger(null); // DBAL 2 + $em->getConnection()->getConfiguration()->setSQLLogger(null); Bulk Inserts ------------ @@ -188,6 +194,3 @@ problems using the following approach: Iterating results is not possible with queries that fetch-join a collection-valued association. The nature of such SQL result sets is not suitable for incremental hydration. - - - From 0efac091417a499e88fe2907b0699d4f5fbf6ffd Mon Sep 17 00:00:00 2001 From: Karoly Gossler Date: Wed, 21 Feb 2024 18:51:21 +0100 Subject: [PATCH 097/128] Fix Static Analysis folder reference (#11281) --- .github/workflows/static-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index c21e5cbea56..88b7196e357 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -10,7 +10,7 @@ on: - src/** - phpstan* - psalm* - - tests/Doctrine/StaticAnalysis/** + - tests/StaticAnalysis/** push: branches: - "*.x" @@ -20,7 +20,7 @@ on: - src/** - phpstan* - psalm* - - tests/Doctrine/StaticAnalysis/** + - tests/StaticAnalysis/** jobs: static-analysis-phpstan: From 8d4718f875b3ea142203ae4258ad4e91f1bacecb Mon Sep 17 00:00:00 2001 From: Mark Schmale Date: Thu, 22 Feb 2024 10:58:50 +0100 Subject: [PATCH 098/128] provides a test case for github issue 11154 After 2.17 (some?) EAGER fetched OneToMany associations stopped working, if they have multiple join columns. Loads for these associations will trigger a `MessingPositionalParameter` exception "Positional parameter at index 1 does not have a bound value". This test case should reproduce this issue, so it can be fixed. --- .../RootEntity.php | 56 +++++++++++++++++ .../SecondLevel.php | 62 +++++++++++++++++++ ...agerFetchOneToManyWithCompositeKeyTest.php | 31 ++++++++++ tests/Tests/OrmFunctionalTestCase.php | 9 +++ 4 files changed, 158 insertions(+) create mode 100644 tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php create mode 100644 tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php create mode 100644 tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php new file mode 100644 index 00000000000..af16c686970 --- /dev/null +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/RootEntity.php @@ -0,0 +1,56 @@ + + */ + private $secondLevel; + + public function __construct(int $id, string $other) + { + $this->otherKey = $other; + $this->secondLevel = new ArrayCollection(); + $this->id = $id; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getOtherKey(): string + { + return $this->otherKey; + } +} diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php new file mode 100644 index 00000000000..e67f3abc4fb --- /dev/null +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php @@ -0,0 +1,62 @@ +id = $id; + $this->upperId = $upper->getId(); + $this->otherKey = $upper->getOtherKey(); + $this->root = $upper; + } + + public function getId(): ?int + { + return $this->id; + } +} diff --git a/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php new file mode 100644 index 00000000000..8ad78cb253d --- /dev/null +++ b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php @@ -0,0 +1,31 @@ +useModelSet('eager_fetched_composite_one_to_many'); + + parent::setUp(); + } + + /** @ticket 11154 */ + public function testItDoesNotThrowAnExceptionWhenTriggeringALoad(): void + { + $a1 = new RootEntity(1, 'A'); + + $this->_em->persist($a1); + $this->_em->flush(); + + $this->_em->clear(); + + self::assertCount(1, $this->_em->getRepository(RootEntity::class)->findAll()); + } +} diff --git a/tests/Tests/OrmFunctionalTestCase.php b/tests/Tests/OrmFunctionalTestCase.php index 4a64136f184..ea2a0110405 100644 --- a/tests/Tests/OrmFunctionalTestCase.php +++ b/tests/Tests/OrmFunctionalTestCase.php @@ -342,6 +342,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase Models\Issue9300\Issue9300Child::class, Models\Issue9300\Issue9300Parent::class, ], + 'eager_fetched_composite_one_to_many' => [ + Models\EagerFetchedCompositeOneToMany\RootEntity::class, + Models\EagerFetchedCompositeOneToMany\SecondLevel::class, + ], ]; /** @param class-string ...$models */ @@ -671,6 +675,11 @@ protected function tearDown(): void $conn->executeStatement('DELETE FROM issue5989_managers'); } + if (isset($this->_usedModelSets['eager_fetched_composite_one_to_many'])) { + $conn->executeStatement('DELETE FROM eager_composite_join_second_level'); + $conn->executeStatement('DELETE FROM eager_composite_join_root'); + } + $this->_em->clear(); } From e6eef1a97d41f1ee244b6e69d7359d00cb3e4c4a Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 22 Feb 2024 13:22:44 +0100 Subject: [PATCH 099/128] Backport QueryParameterTest (#11288) --- .../ORM/Functional/QueryParameterTest.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 tests/Tests/ORM/Functional/QueryParameterTest.php diff --git a/tests/Tests/ORM/Functional/QueryParameterTest.php b/tests/Tests/ORM/Functional/QueryParameterTest.php new file mode 100644 index 00000000000..db5dffd9df1 --- /dev/null +++ b/tests/Tests/ORM/Functional/QueryParameterTest.php @@ -0,0 +1,127 @@ +useModelSet('cms'); + + parent::setUp(); + + $user = new CmsUser(); + $user->name = 'John Doe'; + $user->username = 'john'; + $user2 = new CmsUser(); + $user2->name = 'Jane Doe'; + $user2->username = 'jane'; + $user3 = new CmsUser(); + $user3->name = 'Just Bill'; + $user3->username = 'bill'; + + $this->_em->persist($user); + $this->_em->persist($user2); + $this->_em->persist($user3); + $this->_em->flush(); + + $this->userId = $user->id; + + $this->_em->clear(); + } + + public function testParameterTypeInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->setParameter('id', $this->userId, ParameterType::INTEGER) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testParameterTypeInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->getQuery() + ->setParameter('id', $this->userId, ParameterType::INTEGER) + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testDbalTypeStringInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->setParameter('id', $this->userId, Types::INTEGER) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testDbalTypeStringInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.id = :id') + ->getQuery() + ->setParameter('id', $this->userId, Types::INTEGER) + ->getArrayResult(); + + self::assertSame([['name' => 'John Doe']], $result); + } + + public function testArrayParameterTypeInBuilder(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.username IN (:usernames)') + ->orderBy('u.username') + ->setParameter('usernames', ['john', 'jane'], class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY) + ->getQuery() + ->getArrayResult(); + + self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result); + } + + public function testArrayParameterTypeInQuery(): void + { + $result = $this->_em->createQueryBuilder() + ->from(CmsUser::class, 'u') + ->select('u.name') + ->where('u.username IN (:usernames)') + ->orderBy('u.username') + ->getQuery() + ->setParameter('usernames', ['john', 'jane'], class_exists(ArrayParameterType::class) ? ArrayParameterType::STRING : Connection::PARAM_STR_ARRAY) + ->getArrayResult(); + + self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result); + } +} From cc314d0fb7bfcfcf026ee197293e037a24e2b646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 22 Feb 2024 23:08:53 +0100 Subject: [PATCH 100/128] Remove wrong annotation about return type Although this method is guaranteed to return either null or something that can be used as a fully qualified class name, it never actually checks that the class actually exists. Adding such a check breaks several tests, including some that expect a exceptions at some later points in the execution. --- phpstan-baseline.neon | 5 ----- psalm-baseline.xml | 5 ----- src/Mapping/ClassMetadataInfo.php | 1 - 3 files changed, 11 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e824e0ad896..e288862b309 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -170,11 +170,6 @@ parameters: count: 2 path: src/Mapping/ClassMetadataFactory.php - - - message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\ClassMetadataInfo\\:\\:fullyQualifiedClassName\\(\\) should return class\\-string\\|null but returns string\\|null\\.$#" - count: 1 - path: src/Mapping/ClassMetadataInfo.php - - message: "#^Method Doctrine\\\\ORM\\\\Mapping\\\\NamingStrategy\\:\\:joinColumnName\\(\\) invoked with 2 parameters, 1 required\\.$#" count: 2 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 3123bf33d28..b41991b5210 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -607,7 +607,6 @@ $definition sqlResultSetMappings]]> - subClasses]]> $mapping @@ -618,16 +617,12 @@ getReflectionClass - $className - $className $columnNames $mapping $quotedColumnNames - namespace . '\\' . $className]]> FieldMapping - class-string|null ]]> ]]> diff --git a/src/Mapping/ClassMetadataInfo.php b/src/Mapping/ClassMetadataInfo.php index 9553d84e7a2..3e373a0956d 100644 --- a/src/Mapping/ClassMetadataInfo.php +++ b/src/Mapping/ClassMetadataInfo.php @@ -3707,7 +3707,6 @@ public function getAssociationsByTargetClass($targetClass) * @param string|null $className * * @return string|null null if the input value is null - * @psalm-return class-string|null */ public function fullyQualifiedClassName($className) { From 0f8d1935128e0880fe7a1ceea4750e632793b2e1 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Fri, 23 Feb 2024 14:56:59 +0100 Subject: [PATCH 101/128] Fix sql walker phpdoc --- phpstan-baseline.neon | 15 --------------- psalm-baseline.xml | 18 ------------------ src/Query/SqlWalker.php | 2 +- 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e824e0ad896..00b82e63608 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -330,21 +330,6 @@ parameters: count: 1 path: src/Query/AST/Functions/DateSubFunction.php - - - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" - count: 1 - path: src/Query/AST/Functions/LengthFunction.php - - - - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" - count: 1 - path: src/Query/AST/Functions/LowerFunction.php - - - - message: "#^Parameter \\#1 \\$simpleArithmeticExpr of method Doctrine\\\\ORM\\\\Query\\\\SqlWalker\\:\\:walkSimpleArithmeticExpression\\(\\) expects Doctrine\\\\ORM\\\\Query\\\\AST\\\\SimpleArithmeticExpression, Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node given\\.$#" - count: 1 - path: src/Query/AST/Functions/UpperFunction.php - - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\AST\\\\IndexBy\\:\\:dispatch\\(\\) should return string but returns void\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 3123bf33d28..ead713bf97f 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1577,11 +1577,6 @@ - - - stringPrimary]]> - - simpleArithmeticExpression]]> @@ -1590,11 +1585,6 @@ SimpleArithmeticExpression()]]> - - - stringPrimary]]> - - SimpleArithmeticExpression()]]> @@ -1622,11 +1612,6 @@ SimpleArithmeticExpression()]]> - - - stringPrimary]]> - - $sqlWalker @@ -2131,9 +2116,6 @@ $expression - - pathExpression]]> - whereClause]]> whereClause]]> diff --git a/src/Query/SqlWalker.php b/src/Query/SqlWalker.php index 70971459340..4948be46536 100644 --- a/src/Query/SqlWalker.php +++ b/src/Query/SqlWalker.php @@ -2588,7 +2588,7 @@ public function walkArithmeticExpression($arithmeticExpr) /** * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. * - * @param AST\SimpleArithmeticExpression $simpleArithmeticExpr + * @param AST\Node|string $simpleArithmeticExpr * * @return string * From 08d3f7275598d34c44e6fcbc7e62299fefb2261d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 25 Feb 2024 22:03:34 +0100 Subject: [PATCH 102/128] Deprecate invalid method call `getAssociationMappedByTargetField()` returns `null` when called with the owning side of an association. This is undocumented and wrong because the phpdoc advertises a string as a return type. Instead, callers should ensure they are calling that method with an inverse side. Closes #11250 --- UPGRADE.md | 11 +++++++++++ src/Mapping/ClassMetadataInfo.php | 11 +++++++++++ tests/Tests/ORM/Mapping/ClassMetadataTest.php | 13 +++++++++++++ 3 files changed, 35 insertions(+) diff --git a/UPGRADE.md b/UPGRADE.md index a0a360d72d7..5689b307bda 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,16 @@ # Upgrade to 2.19 +## Deprecate calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association + +Calling +`Doctrine\ORM\Mapping\ClassMetadata::getAssociationMappedByTargetField()` with +the owning side of an association returns `null`, which is undocumented, and +wrong according to the phpdoc of the parent method. + +If you do not know whether you are on the owning or inverse side of an association, +you can use `Doctrine\ORM\Mapping\ClassMetadata::isAssociationInverseSide()` +to find out. + ## Deprecate `Doctrine\ORM\Query\Lexer::T_*` constants Use `Doctrine\ORM\Query\TokenType::T_*` instead. diff --git a/src/Mapping/ClassMetadataInfo.php b/src/Mapping/ClassMetadataInfo.php index 3e373a0956d..3780a5d44af 100644 --- a/src/Mapping/ClassMetadataInfo.php +++ b/src/Mapping/ClassMetadataInfo.php @@ -3681,6 +3681,17 @@ public function isAssociationInverseSide($fieldName) */ public function getAssociationMappedByTargetField($fieldName) { + if (! $this->isAssociationInverseSide($fieldName)) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/orm/pull/11309', + 'Calling %s with owning side field %s is deprecated and will no longer be supported in Doctrine ORM 3.0. Call %s::isAssociationInverseSide() to check first.', + __METHOD__, + $fieldName, + self::class + ); + } + return $this->associationMappings[$fieldName]['mappedBy']; } diff --git a/tests/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Tests/ORM/Mapping/ClassMetadataTest.php index d1e82c1922b..48079777276 100644 --- a/tests/Tests/ORM/Mapping/ClassMetadataTest.php +++ b/tests/Tests/ORM/Mapping/ClassMetadataTest.php @@ -6,6 +6,7 @@ use ArrayObject; use Doctrine\DBAL\Types\Types; +use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\Events; use Doctrine\ORM\Mapping\ChainTypedFieldMapper; use Doctrine\ORM\Mapping\ClassMetadata; @@ -54,6 +55,8 @@ class ClassMetadataTest extends OrmTestCase { + use VerifyDeprecations; + public function testClassMetadataInstanceSerialization(): void { $cm = new ClassMetadata(CMS\CmsUser::class); @@ -1379,6 +1382,16 @@ public function testRejectsEmbeddableWithoutValidClassName(): void 'columnPrefix' => false, ]); } + + public function testInvalidCallToGetAssociationMappedByTargetFieldIsDeprecated(): void + { + $metadata = new ClassMetadata(self::class); + $metadata->mapOneToOne(['fieldName' => 'foo', 'targetEntity' => 'bar']); + + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/11309'); + + $metadata->getAssociationMappedByTargetField('foo'); + } } /** @MappedSuperclass */ From feb27f00c12eb5385c628c4c1f23a87ed79db06b Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 27 Feb 2024 17:37:52 +0100 Subject: [PATCH 103/128] Address deprecations from Collection 2.2 (#11315) --- phpcs.xml.dist | 5 ++ phpstan-persistence2.neon | 25 +++++++++ .../Entity/AbstractEntityPersister.php | 5 +- src/Internal/CriteriaOrderings.php | 54 +++++++++++++++++++ src/Mapping/Driver/XmlDriver.php | 8 ++- src/PersistentCollection.php | 7 ++- .../Collection/ManyToManyPersister.php | 5 +- .../Entity/BasicEntityPersister.php | 4 +- src/QueryBuilder.php | 27 +++++----- .../ManyToManyBasicAssociationTest.php | 6 ++- .../ORM/Functional/Ticket/GH7767Test.php | 11 ++-- .../ORM/Functional/Ticket/GH7836Test.php | 23 ++++++-- tests/Tests/ORM/QueryBuilderTest.php | 6 ++- 13 files changed, 156 insertions(+), 30 deletions(-) create mode 100644 src/Internal/CriteriaOrderings.php diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 3fa9a3f13f1..6de9ebe57a2 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -279,4 +279,9 @@ src/QueryBuilder.php + + + + src/Mapping/Driver/XmlDriver.php + diff --git a/phpstan-persistence2.neon b/phpstan-persistence2.neon index de49a183766..dfa68ac9ec8 100644 --- a/phpstan-persistence2.neon +++ b/phpstan-persistence2.neon @@ -31,6 +31,31 @@ parameters: message: '/^Instanceof between Doctrine\\DBAL\\Platforms\\AbstractPlatform and Doctrine\\DBAL\\Platforms\\MySQLPlatform will always evaluate to false\.$/' path: src/Utility/LockSqlHelper.php + # Forward compatibility with Collections 3 + - + message: '#^Parameter \$order of anonymous function has invalid type Doctrine\\Common\\Collections\\Order\.$#' + path: src/Internal/CriteriaOrderings.php + + - + message: '#^Anonymous function has invalid return type Doctrine\\Common\\Collections\\Order\.$#' + path: src/Internal/CriteriaOrderings.php + + - + message: '#^Access to property \$value on an unknown class Doctrine\\Common\\Collections\\Order\.$#' + path: src/Internal/CriteriaOrderings.php + + - + message: '#^Call to static method from\(\) on an unknown class Doctrine\\Common\\Collections\\Order\.$#' + path: src/Internal/CriteriaOrderings.php + + - + message: '#^Call to an undefined method Doctrine\\Common\\Collections\\Criteria\:\:orderings\(\)\.$#' + path: src/Internal/CriteriaOrderings.php + + - + message: '#^Method .+\:\:mapToOrderEnumIfAvailable\(\) has invalid return type Doctrine\\Common\\Collections\\Order\.$#' + path: src/Internal/CriteriaOrderings.php + # False positive - message: '/^Call to an undefined method Doctrine\\Common\\Cache\\Cache::deleteAll\(\)\.$/' diff --git a/src/Cache/Persister/Entity/AbstractEntityPersister.php b/src/Cache/Persister/Entity/AbstractEntityPersister.php index 5831af99816..a00ed5be935 100644 --- a/src/Cache/Persister/Entity/AbstractEntityPersister.php +++ b/src/Cache/Persister/Entity/AbstractEntityPersister.php @@ -16,6 +16,7 @@ use Doctrine\ORM\Cache\TimestampCacheKey; use Doctrine\ORM\Cache\TimestampRegion; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Internal\CriteriaOrderings; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadataFactory; use Doctrine\ORM\PersistentCollection; @@ -30,6 +31,8 @@ abstract class AbstractEntityPersister implements CachedEntityPersister { + use CriteriaOrderings; + /** @var UnitOfWork */ protected $uow; @@ -475,7 +478,7 @@ public function count($criteria = []) */ public function loadCriteria(Criteria $criteria) { - $orderBy = $criteria->getOrderings(); + $orderBy = self::getCriteriaOrderings($criteria); $limit = $criteria->getMaxResults(); $offset = $criteria->getFirstResult(); $query = $this->persister->getSelectSQL($criteria); diff --git a/src/Internal/CriteriaOrderings.php b/src/Internal/CriteriaOrderings.php new file mode 100644 index 00000000000..249b0c6f664 --- /dev/null +++ b/src/Internal/CriteriaOrderings.php @@ -0,0 +1,54 @@ + + * + * @psalm-suppress DeprecatedMethod We need to call the deprecated API if the new one does not exist yet. + */ + private static function getCriteriaOrderings(Criteria $criteria): array + { + if (! method_exists(Criteria::class, 'orderings')) { + return $criteria->getOrderings(); + } + + return array_map( + static function (Order $order): string { + return $order->value; + }, + $criteria->orderings() + ); + } + + /** + * @param array $orderings + * + * @return array|array + */ + private static function mapToOrderEnumIfAvailable(array $orderings): array + { + if (! class_exists(Order::class)) { + return $orderings; + } + + return array_map( + static function (string $order): Order { + return Order::from(strtoupper($order)); + }, + $orderings + ); + } +} diff --git a/src/Mapping/Driver/XmlDriver.php b/src/Mapping/Driver/XmlDriver.php index 01b3ba03954..60223020dc9 100644 --- a/src/Mapping/Driver/XmlDriver.php +++ b/src/Mapping/Driver/XmlDriver.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Mapping\Driver; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; use Doctrine\ORM\Mapping\Builder\EntityListenerBuilder; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; @@ -16,6 +17,7 @@ use SimpleXMLElement; use function assert; +use function class_exists; use function constant; use function count; use function defined; @@ -481,9 +483,10 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad if (isset($oneToManyElement->{'order-by'})) { $orderBy = []; foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} ?? [] as $orderByField) { + /** @psalm-suppress DeprecatedConstant */ $orderBy[(string) $orderByField['name']] = isset($orderByField['direction']) ? (string) $orderByField['direction'] - : Criteria::ASC; + : (class_exists(Order::class) ? (Order::Ascending)->value : Criteria::ASC); } $mapping['orderBy'] = $orderBy; @@ -609,9 +612,10 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad if (isset($manyToManyElement->{'order-by'})) { $orderBy = []; foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} ?? [] as $orderByField) { + /** @psalm-suppress DeprecatedConstant */ $orderBy[(string) $orderByField['name']] = isset($orderByField['direction']) ? (string) $orderByField['direction'] - : Criteria::ASC; + : (class_exists(Order::class) ? (Order::Ascending)->value : Criteria::ASC); } $mapping['orderBy'] = $orderBy; diff --git a/src/PersistentCollection.php b/src/PersistentCollection.php index c39252d7a27..4470a64a5cd 100644 --- a/src/PersistentCollection.php +++ b/src/PersistentCollection.php @@ -9,6 +9,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\Selectable; +use Doctrine\ORM\Internal\CriteriaOrderings; use Doctrine\ORM\Mapping\ClassMetadata; use ReturnTypeWillChange; use RuntimeException; @@ -41,6 +42,8 @@ */ final class PersistentCollection extends AbstractLazyCollection implements Selectable { + use CriteriaOrderings; + /** * A snapshot of the collection at the moment it was fetched from the database. * This is used to create a diff of the collection at commit time. @@ -671,7 +674,9 @@ public function matching(Criteria $criteria): Collection $criteria = clone $criteria; $criteria->where($expression); - $criteria->orderBy($criteria->getOrderings() ?: $association['orderBy'] ?? []); + $criteria->orderBy(self::mapToOrderEnumIfAvailable( + self::getCriteriaOrderings($criteria) ?: $association['orderBy'] ?? [] + )); $persister = $this->getUnitOfWork()->getEntityPersister($association['targetEntity']); diff --git a/src/Persisters/Collection/ManyToManyPersister.php b/src/Persisters/Collection/ManyToManyPersister.php index 93502bbe625..f31110b1407 100644 --- a/src/Persisters/Collection/ManyToManyPersister.php +++ b/src/Persisters/Collection/ManyToManyPersister.php @@ -8,6 +8,7 @@ use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\Expr\Comparison; use Doctrine\DBAL\Exception as DBALException; +use Doctrine\ORM\Internal\CriteriaOrderings; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\Persisters\SqlValueVisitor; @@ -30,6 +31,8 @@ */ class ManyToManyPersister extends AbstractCollectionPersister { + use CriteriaOrderings; + /** * {@inheritDoc} */ @@ -745,7 +748,7 @@ private function expandCriteriaParameters(Criteria $criteria): array private function getOrderingSql(Criteria $criteria, ClassMetadata $targetClass): string { - $orderings = $criteria->getOrderings(); + $orderings = self::getCriteriaOrderings($criteria); if ($orderings) { $orderBy = []; foreach ($orderings as $name => $direction) { diff --git a/src/Persisters/Entity/BasicEntityPersister.php b/src/Persisters/Entity/BasicEntityPersister.php index e83589c4180..00fe7b03703 100644 --- a/src/Persisters/Entity/BasicEntityPersister.php +++ b/src/Persisters/Entity/BasicEntityPersister.php @@ -15,6 +15,7 @@ use Doctrine\DBAL\Types\Types; use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\Internal\CriteriaOrderings; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\MappingException; use Doctrine\ORM\Mapping\QuoteStrategy; @@ -93,6 +94,7 @@ */ class BasicEntityPersister implements EntityPersister { + use CriteriaOrderings; use LockSqlHelper; /** @var array */ @@ -884,7 +886,7 @@ public function count($criteria = []) */ public function loadCriteria(Criteria $criteria) { - $orderBy = $criteria->getOrderings(); + $orderBy = self::getCriteriaOrderings($criteria); $limit = $criteria->getMaxResults(); $offset = $criteria->getFirstResult(); $query = $this->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy); diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 30ca64c41c2..deb67b6b291 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -7,6 +7,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; use Doctrine\Deprecations\Deprecation; +use Doctrine\ORM\Internal\CriteriaOrderings; use Doctrine\ORM\Query\Expr; use Doctrine\ORM\Query\Parameter; use Doctrine\ORM\Query\QueryExpressionVisitor; @@ -39,6 +40,8 @@ */ class QueryBuilder { + use CriteriaOrderings; + /** @deprecated */ public const SELECT = 0; @@ -1375,22 +1378,20 @@ public function addCriteria(Criteria $criteria) } } - if ($criteria->getOrderings()) { - foreach ($criteria->getOrderings() as $sort => $order) { - $hasValidAlias = false; - foreach ($allAliases as $alias) { - if (str_starts_with($sort . '.', $alias . '.')) { - $hasValidAlias = true; - break; - } - } - - if (! $hasValidAlias) { - $sort = $allAliases[0] . '.' . $sort; + foreach (self::getCriteriaOrderings($criteria) as $sort => $order) { + $hasValidAlias = false; + foreach ($allAliases as $alias) { + if (str_starts_with($sort . '.', $alias . '.')) { + $hasValidAlias = true; + break; } + } - $this->addOrderBy($sort, $order); + if (! $hasValidAlias) { + $sort = $allAliases[0] . '.' . $sort; } + + $this->addOrderBy($sort, $order); } // Overwrite limits only if they was set in criteria diff --git a/tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php b/tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php index 994d2bb8aa5..afe0c8e62e7 100644 --- a/tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php +++ b/tests/Tests/ORM/Functional/ManyToManyBasicAssociationTest.php @@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\UnitOfWork; use Doctrine\Tests\Models\CMS\CmsGroup; @@ -14,6 +15,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use function assert; +use function class_exists; use function get_class; /** @@ -436,7 +438,7 @@ public function testManyToManyOrderByIsNotIgnored(): void $user = $this->_em->find(get_class($user), $user->id); $criteria = Criteria::create() - ->orderBy(['name' => Criteria::ASC]); + ->orderBy(['name' => class_exists(Order::class) ? Order::Ascending : Criteria::ASC]); self::assertEquals( ['A', 'B', 'C', 'Developers_0'], @@ -478,7 +480,7 @@ public function testManyToManyOrderByHonorsFieldNameColumnNameAliases(): void $user = $this->_em->find(get_class($user), $user->id); $criteria = Criteria::create() - ->orderBy(['name' => Criteria::ASC]); + ->orderBy(['name' => class_exists(Order::class) ? Order::Ascending : Criteria::ASC]); self::assertEquals( ['A', 'B', 'C'], diff --git a/tests/Tests/ORM/Functional/Ticket/GH7767Test.php b/tests/Tests/ORM/Functional/Ticket/GH7767Test.php index 455c63d2dee..dc993eec353 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH7767Test.php +++ b/tests/Tests/ORM/Functional/Ticket/GH7767Test.php @@ -6,6 +6,8 @@ use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; +use Doctrine\Common\Collections\Selectable; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; @@ -16,6 +18,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use function assert; +use function class_exists; /** @group GH7767 */ class GH7767Test extends OrmFunctionalTestCase @@ -53,7 +56,9 @@ public function testMatchingOverrulesCollectionOrdering(): void $parent = $this->_em->find(GH7767ParentEntity::class, 1); assert($parent instanceof GH7767ParentEntity); - $children = $parent->getChildren()->matching(Criteria::create()->orderBy(['position' => 'DESC'])); + $children = $parent->getChildren()->matching( + Criteria::create()->orderBy(['position' => class_exists(Order::class) ? Order::Descending : 'DESC']) + ); self::assertEquals(300, $children[0]->position); self::assertEquals(200, $children[1]->position); @@ -73,7 +78,7 @@ class GH7767ParentEntity private $id; /** - * @psalm-var Collection + * @psalm-var Collection&Selectable * @OneToMany(targetEntity=GH7767ChildEntity::class, mappedBy="parent", fetch="EXTRA_LAZY", cascade={"persist"}) * @OrderBy({"position" = "ASC"}) */ @@ -84,7 +89,7 @@ public function addChild(int $position): void $this->children[] = new GH7767ChildEntity($this, $position); } - /** @psalm-return Collection */ + /** @psalm-return Collection&Selectable */ public function getChildren(): Collection { return $this->children; diff --git a/tests/Tests/ORM/Functional/Ticket/GH7836Test.php b/tests/Tests/ORM/Functional/Ticket/GH7836Test.php index 2ad1eb4ec8d..646bbf66170 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH7836Test.php +++ b/tests/Tests/ORM/Functional/Ticket/GH7836Test.php @@ -6,6 +6,8 @@ use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; +use Doctrine\Common\Collections\Selectable; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; @@ -16,6 +18,7 @@ use Doctrine\Tests\OrmFunctionalTestCase; use function assert; +use function class_exists; /** @group GH7836 */ class GH7836Test extends OrmFunctionalTestCase @@ -56,7 +59,13 @@ public function testMatchingOverrulesCollectionOrdering(): void $parent = $this->_em->find(GH7836ParentEntity::class, 1); assert($parent instanceof GH7836ParentEntity); - $children = $parent->getChildren()->matching(Criteria::create()->orderBy(['position' => 'DESC', 'name' => 'ASC'])); + $children = $parent->getChildren()->matching( + Criteria::create()->orderBy( + class_exists(Order::class) + ? ['position' => Order::Descending, 'name' => Order::Ascending] + : ['position' => 'DESC', 'name' => 'ASC'] + ) + ); self::assertSame(200, $children[0]->position); self::assertSame('baz', $children[0]->name); @@ -71,7 +80,13 @@ public function testMatchingKeepsOrderOfCriteriaOrderingKeys(): void $parent = $this->_em->find(GH7836ParentEntity::class, 1); assert($parent instanceof GH7836ParentEntity); - $children = $parent->getChildren()->matching(Criteria::create()->orderBy(['name' => 'ASC', 'position' => 'ASC'])); + $children = $parent->getChildren()->matching( + Criteria::create()->orderBy( + class_exists(Order::class) + ? ['name' => Order::Ascending, 'position' => Order::Ascending] + : ['name' => 'ASC', 'position' => 'ASC'] + ) + ); self::assertSame(100, $children[0]->position); self::assertSame('bar', $children[0]->name); @@ -94,7 +109,7 @@ class GH7836ParentEntity private $id; /** - * @var Collection + * @var Collection&Selectable * @OneToMany(targetEntity=GH7836ChildEntity::class, mappedBy="parent", fetch="EXTRA_LAZY", cascade={"persist"}) * @OrderBy({"position" = "ASC", "name" = "ASC"}) */ @@ -105,7 +120,7 @@ public function addChild(int $position, string $name): void $this->children[] = new GH7836ChildEntity($this, $position, $name); } - /** @psalm-return Collection */ + /** @psalm-return Collection&Selectable */ public function getChildren(): Collection { return $this->children; diff --git a/tests/Tests/ORM/QueryBuilderTest.php b/tests/Tests/ORM/QueryBuilderTest.php index 28774189a29..f8ca83c9e9a 100644 --- a/tests/Tests/ORM/QueryBuilderTest.php +++ b/tests/Tests/ORM/QueryBuilderTest.php @@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use Doctrine\ORM\Cache; use Doctrine\ORM\Query; @@ -22,6 +23,7 @@ use InvalidArgumentException; use function array_filter; +use function class_exists; use function get_class; /** @@ -576,7 +578,7 @@ public function testAddCriteriaOrder(): void ->from(CmsUser::class, 'u'); $criteria = new Criteria(); - $criteria->orderBy(['field' => Criteria::DESC]); + $criteria->orderBy(['field' => class_exists(Order::class) ? Order::Descending : Criteria::DESC]); $qb->addCriteria($criteria); @@ -593,7 +595,7 @@ public function testAddCriteriaOrderOnJoinAlias(): void ->join('u.article', 'a'); $criteria = new Criteria(); - $criteria->orderBy(['a.field' => Criteria::DESC]); + $criteria->orderBy(['a.field' => class_exists(Order::class) ? Order::Descending : Criteria::DESC]); $qb->addCriteria($criteria); From 4fc86294145cd0447660b057f274f73ab95346c3 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 29 Feb 2024 16:47:35 +0100 Subject: [PATCH 104/128] PHPStan 1.10.59 (#11320) --- composer.json | 2 +- phpstan-baseline.neon | 16 +++------------- src/Mapping/DefaultTypedFieldMapper.php | 10 ++++++---- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index ee4f1f0bc08..108d37fdc5c 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.35", + "phpstan/phpstan": "~1.4.10 || 1.10.59", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 52bb9d5a437..c33099dee7a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -231,7 +231,7 @@ parameters: path: src/Mapping/Driver/XmlDriver.php - - message: "#^Offset 'version' on \\*NEVER\\* in isset\\(\\) always exists and is always null\\.$#" + message: "#^Offset 'version' on \\*NEVER\\* in isset\\(\\) always exists and is not nullable\\.$#" count: 1 path: src/Mapping/Driver/XmlDriver.php @@ -326,7 +326,7 @@ parameters: path: src/Query/AST/Functions/DateSubFunction.php - - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\AST\\\\IndexBy\\:\\:dispatch\\(\\) should return string but returns void\\.$#" + message: "#^Method Doctrine\\\\ORM\\\\Query\\\\AST\\\\IndexBy\\:\\:dispatch\\(\\) should return string but returns null\\.$#" count: 1 path: src/Query/AST/IndexBy.php @@ -375,11 +375,6 @@ parameters: count: 1 path: src/Query/Expr/Select.php - - - message: "#^Comparison operation \"\\<\" between null and 102 is always true\\.$#" - count: 1 - path: src/Query/Parser.php - - message: "#^Method Doctrine\\\\ORM\\\\Query\\\\Parser\\:\\:ArithmeticFactor\\(\\) should return Doctrine\\\\ORM\\\\Query\\\\AST\\\\ArithmeticFactor but returns Doctrine\\\\ORM\\\\Query\\\\AST\\\\Node\\|string\\.$#" count: 1 @@ -395,14 +390,9 @@ parameters: count: 1 path: src/Query/Parser.php - - - message: "#^Result of && is always true\\.$#" - count: 1 - path: src/Query/Parser.php - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 4 + count: 3 path: src/Query/Parser.php - diff --git a/src/Mapping/DefaultTypedFieldMapper.php b/src/Mapping/DefaultTypedFieldMapper.php index 7e57a4798cd..db7737f58e4 100644 --- a/src/Mapping/DefaultTypedFieldMapper.php +++ b/src/Mapping/DefaultTypedFieldMapper.php @@ -4,6 +4,7 @@ namespace Doctrine\ORM\Mapping; +use BackedEnum; use DateInterval; use DateTime; use DateTimeImmutable; @@ -16,6 +17,7 @@ use function array_merge; use function assert; use function enum_exists; +use function is_a; use const PHP_VERSION_ID; @@ -54,18 +56,18 @@ public function validateAndComplete(array $mapping, ReflectionProperty $field): && ($type instanceof ReflectionNamedType) ) { if (PHP_VERSION_ID >= 80100 && ! $type->isBuiltin() && enum_exists($type->getName())) { - $mapping['enumType'] = $type->getName(); - $reflection = new ReflectionEnum($type->getName()); if (! $reflection->isBacked()) { throw MappingException::backedEnumTypeRequired( $field->class, $mapping['fieldName'], - $mapping['enumType'] + $type->getName() ); } - $type = $reflection->getBackingType(); + assert(is_a($type->getName(), BackedEnum::class, true)); + $mapping['enumType'] = $type->getName(); + $type = $reflection->getBackingType(); assert($type instanceof ReflectionNamedType); } From 52a6a21387380b09419a66a7ec1c66f6cab69b20 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 1 Mar 2024 10:47:18 +0100 Subject: [PATCH 105/128] Psalm 5.22.2 (#11326) --- composer.json | 2 +- psalm-baseline.xml | 1611 ++++++++++++++++++++++++-------------------- psalm.xml | 6 + 3 files changed, 880 insertions(+), 739 deletions(-) diff --git a/composer.json b/composer.json index 108d37fdc5c..c43da335c67 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "4.30.0 || 5.16.0" + "vimeo/psalm": "4.30.0 || 5.22.2" }, "conflict": { "doctrine/annotations": "<1.13 || >= 3.0" diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 223173b32f4..2ee190b60d7 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,57 +1,57 @@ - + - IterableResult + - iterate + - in_array($fetchMode, [Mapping\ClassMetadata::FETCH_EAGER, Mapping\ClassMetadata::FETCH_LAZY], true) + isEmpty() ? $filteredParameters->first() : null]]> - Parameter|null + - \Doctrine\Common\Cache\Cache + - $alias - $data - $data + + + _em->getConfiguration()->getResultCacheImpl()]]> _queryCacheProfile->getResultCacheDriver()]]> - $stmt - $stmt + + - getCacheLogger - getQueryCache + + - (bool) $cacheable - (int) $cacheMode - (int) $lifetime - (string) $cacheRegion + + + + - getTimestampRegion + - (string) $association - (string) $entityClass + + @@ -64,18 +64,18 @@ ->getCacheFactory()]]> - getCacheFactory + - string + fileLockRegionDirectory]]> - (string) $fileLockRegionDirectory + @@ -91,7 +91,7 @@ - getCacheRegion + @@ -102,30 +102,30 @@ identifiers[$index]]]> - $id + class]]> class]]> - getCacheLogger + - assert($cm instanceof ClassMetadata) + - getCacheRegion - resolveAssociationEntries - resolveAssociationEntries - storeEntityCache - storeEntityCache + + + + + - $cache - $entityKey + + identifiers]]> @@ -135,8 +135,8 @@ getOwner()]]> - buildCollectionHydrator - getCacheFactory + + @@ -156,16 +156,16 @@ getOwner()]]> - lock - lock + + - $cacheEntry + - loadAll + class]]> @@ -178,31 +178,31 @@ getCache()]]> - getCacheFactory - getTimestampRegion + + - assert($metadata instanceof ClassMetadata) + - getCacheRegion - getCacheRegion - getCacheRegion - getCacheRegion - loadCollectionCache - loadCollectionCache - storeCollectionCache - storeCollectionCache - storeEntityCache + + + + + + + + + - $isChanged + - lock - lock + + @@ -210,27 +210,27 @@ cache]]> - CacheProvider + - (int) $defaultLifetime - (int) $defaultLifetime - (int) $defaultLockLifetime - (int) $defaultLockLifetime - (int) $lifetime - (int) $lifetime + + + + + + - (float) $time + - (string) $space + @@ -240,71 +240,71 @@ - $className + - getMetadataCacheImpl - getQueryCacheImpl + + - (bool) $flag + - copy - getHydrator - transactional - transactional + + + + wrapped->getClassMetadata($className)]]> - getClassMetadata + - $entity - $lockMode - $lockVersion + + + - wrapInTransaction + - $className + - find - flush + + - $className - $connection - $entityName + + + - getMetadataCacheImpl - merge + + - is_object($entity) - is_object($entity) - is_object($entity) - is_object($entity) - is_object($entity) + + + + + - ClassMetadataFactory + - $entity - $entity - $entity - $entity + + + + name ? $entity : null]]> name ? $entity : null]]> load($sortedId, null, null, [], $lockMode)]]> @@ -312,124 +312,131 @@ metadataFactory->getMetadataFor($className)]]> - ?T - getClassMetadata + + - wrapInTransaction + - $entity - $entity - $entity - $entity - $entity - $entityName - $entityName + + + + + + + getProxyDir()]]> getProxyNamespace()]]> - createCache - getCacheFactory + + - new $metadataFactoryClassName() + - (string) $hydrationMode + - $repository instanceof EntityRepository - is_object($connection) + + - new $class($this) + - addNamedNativeQueryMapping + load($criteria, null, null, [], null, 1, $orderBy)]]> - new LazyCriteriaCollection($persister, $criteria) + - ?T + &Selectable]]> - find + - (string) $className + - BaseORMException + - $entity + - serialize - unserialize + + - $currentLevel + nextValue]]> nextValue]]> - getTableHiLoCurrentValSql - getTableHiLoUpdateNextValSql + + - IterableResult - new IterableResult($this) + + + + associationMappings[$fieldName]['joinColumns'][0]]]> + associationMappings[$fieldName]['joinColumns'][0]['name']]]> + + + + associationMappings[$fieldName]['joinColumns']]]> associationMappings[$fieldName]['joinColumns']]]> - return $rowData; - return $rowData; + + - $index + - $result[$resultKey] - $result[$resultKey] + + - $result + - $baseElement + resultPointers[$parent]]]> @@ -441,10 +448,10 @@ - mixed[]|false + - Iterator + hydrator->hydrateRow()]]> @@ -456,32 +463,40 @@ - $element + - $index + - $parentObject - $parentObject - $parentObject - $parentObject - $parentObject - $parentObject - $parentObject + + + + + + + + + associationMappings[$class->identifier[0]]['joinColumns'][0]]]> + associationMappings[$class->identifier[0]]['joinColumns'][0]['name']]]> + associationMappings[$fieldName]['joinColumns'][0]]]> + associationMappings[$fieldName]['joinColumns'][0]['name']]]> + + + reflFields]]> - getValue - getValue - getValue - setValue - setValue + + + + + associationMappings[$class->identifier[0]]['joinColumns']]]> @@ -491,71 +506,77 @@ - $class + + + + + + + - $repositoryClassName + - addNamedQuery + - $class + - $generatedValue - $sequenceDef - $version + + + - (bool) $flag - (bool) $flag - (string) $customIdGenerator + + + - ClassMetadata - ClassMetadata - ClassMetadata - ClassMetadata + + + + - $class - $class - $platformFamily + + + - new UuidGenerator() + - ClassMetadata::GENERATOR_TYPE_UUID + - addNamedNativeQuery - addNamedQuery + + table[$indexType][$indexName]]]> - $driver - $evm + + table[$indexType]]]> @@ -565,21 +586,21 @@ em]]> - getConfiguration - getConfiguration - getConfiguration - getConfiguration - getConfiguration - getConnection + + + + + + - $mapping + - canEmulateSchemas - canRequireSQLConversion + + columnNames]]> @@ -588,79 +609,88 @@ columnNames]]> - table]]> table]]> - - $mapping - $mapping - $overrideMapping + + + - ReflectionProperty - ReflectionProperty - getAssociationMappedByTargetField + + + + + - $definition + sqlResultSetMappings]]> - $mapping + reflClass]]> - AssociationMapping - getReflectionClass + + - $columnNames - $mapping - $quotedColumnNames + + + - FieldMapping + ]]> ]]> + associationMappings[$fieldName]['joinColumns'][0]['name']]]> + associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName']]]> associationMappings[$fieldName]['mappedBy']]]> reflClass]]> reflFields[$name]]]> reflFields[$this->identifier[0]]]]> - $entity - $fieldName - $fieldName + + + - $class - $className + + + + + associationMappings[$fieldName]['joinColumns'][0]]]> + associationMappings[$fieldName]['joinColumns'][0]]]> + associationMappings[$fieldName]['joinColumns'][0]['name']]]> + associationMappings[$fieldName]['joinColumns'][0]['referencedColumnName']]]> + reflClass->name]]> reflClass->name]]> - getProperty - getProperty - getProperty - getValue - getValue - getValue - instantiate - setValue - setValue + + + + + + + + + @@ -675,35 +705,34 @@ associationMappings[$idProperty]['joinColumns']]]> - $idGenerator - $namespace - $table - $tableGeneratorDefinition + + + + - $mapping !== false - $mapping !== false - + + - array_values + - joinColumnName - joinColumnName + + - $name + - is_object($object) + - new $className() + instances]]> @@ -716,15 +745,21 @@ - canEmulateSchemas - canEmulateSchemas + + - $quotedColumnNames + - getIdentifierColumnNames + + + + + + + associationMappings[$fieldName]['joinColumns']]]> @@ -732,19 +767,19 @@ - $mapping + - array + - array_merge(self::DEFAULT_TYPED_FIELD_MAPPINGS, $typedFieldMappings) + - addNamedNativeQuery - addNamedQuery + + - $mapping + - $metadata + - array{ + + * }]]> - $listenerClassName + @@ -791,16 +826,16 @@ name)]]> - mapEmbedded - mapManyToMany - mapManyToOne - mapOneToMany - mapOneToOne + + + + + - $columnDef + - $mapping + - $metadata + - array{ + + * }]]> - $listenerClassName + getReflectionClass()]]> - assert($cacheAttribute instanceof Mapping\Cache) - assert($method instanceof ReflectionMethod) - assert($method instanceof ReflectionMethod) - assert($property instanceof ReflectionProperty) + + + + name)]]> @@ -848,46 +883,46 @@ - $metadata instanceof ClassMetadata + namespace . $this->classNamesForTables[$tableName]]]> namespace . $this->inflector->classify(strtolower($tableName))]]> - $metadata + - class-string + - $metadata + tables[$tableName]]]> tables[$tableName]]]> - getColumns - getColumns - getIndexes + + + - PHPDriver + - $fileExtension - $prefixes + + - $fileExtension - $prefixes + + @@ -896,11 +931,11 @@ - addNamedNativeQuery - addNamedQuery + + - $columnDef + table]]> @@ -910,15 +945,15 @@ {'discriminator-map'}]]> - $mapping - $result + + $usage, 'region' => $region, ]]]> - array{ + - array{usage: int|null, region?: string} - loadMappingFile + * }]]> + + - $fileExtension - $locator + + - $metadata + {'discriminator-column'}]]> @@ -965,8 +1000,8 @@ ]]]> - addNamedNativeQuery - addNamedQuery + + - $fileExtension - $locator + + - $metadata + - array{usage: int|null, region: string|null} + - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element + + + + + + + + + + + + + + + + + + - $element - $element - $element - $element - $element - $element - $element - $element - $element - $element + + + + + + + + + + - $columnPrefix + - $discriminatorColumn - $entityClass + + - $column - $name + + - $value + - $inverseJoinColumns - $joinColumns + + - $className - $className - $indexName - $indexName + + + + - $name - $query - $resultClass - $resultSetMapping + + + + - $value + - $name - $query + + @@ -1077,33 +1112,33 @@ embeddedClass]]> - $object - $object - $value + + + - ReflectionEmbeddedProperty - ReflectionEmbeddedProperty + + - (string) $embeddedClass + - ReflectionEnumProperty - ReflectionEnumProperty + + - ReflectionReadonlyProperty - ReflectionReadonlyProperty + + - $name + @@ -1113,14 +1148,14 @@ - $sql + ]]> - object|null - object|null + + unwrap()->matching($criteria)]]> - $offset + - $value - $value + + backRefFieldName]]> + getMapping()['indexBy']]]> - setValue - setValue + + @@ -1172,8 +1208,25 @@ getOwner()]]> getOwner()]]> getOwner()]]> - $owner + + + + + + + + + + + + + + + + + + associationMappings]]> associationMappings]]> @@ -1181,17 +1234,33 @@ associationMappings]]> associationMappings]]> + + + + + + + + + + + + + + + + - getFieldForColumn - getFieldForColumn + + - $mapping[$sourceRelationMode] - $mapping[$targetRelationMode] + + @@ -1211,7 +1280,7 @@ - int|null + associationMappings]]> + + associationMappings[$mapping['mappedBy']]['joinColumns']]]> + associationMappings[$mapping['mappedBy']]['joinColumns']]]> @@ -1237,53 +1309,55 @@ - $assoc - $association + + - $value === null + - $assoc + getMetadataFactory()]]> - $hints - $hints + + true]]]> true]]]> true]]]> - loadOneToOneEntity + - $newValue - [$params, $types] - [$sqlParams, $sqlTypes] + + + - loadAll + - expandCriteriaParameters - expandParameters + + ]]> - $targetEntity - $targetEntity + + - $association - $type + + + + @@ -1293,16 +1367,22 @@ class->associationMappings]]> - $joinColumns + + + + + + + - getValue - getValue - getValue - getValue - getValue - getValue - setValue + + + + + + + @@ -1332,18 +1412,18 @@ - $selectJoinSql + - $class + - (bool) $handlesLimits + - loadAll + @@ -1358,27 +1438,27 @@ - $columnList + - $className - substr($className, $pos + Proxy::MARKER_LENGTH + 2) + + - string + - $classMetadata - $classMetadata - $classMetadata + + + - createCloner - createInitializer + + getReflectionProperties()]]> @@ -1386,7 +1466,7 @@ getMetadataFactory()]]> - Closure + proxyFactories]]> @@ -1399,125 +1479,127 @@ proxyFactories[$className] = $proxyFactory]]> - $i + - $i + name]]> name]]> - getValue - setAccessible - setValue - setValue + + + 4]]> - __wakeup + + + + - require $fileName + - IterableResult + - parent::iterate($parameters, $hydrationMode) + - $sqlParams + getDQL()]]> - evictEntityRegion + - $parserResult + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + @@ -1543,9 +1625,9 @@ ArithmeticPrimary()]]> - null - null - null + + + unit->value]]> @@ -1564,10 +1646,16 @@ - $sqlWalker + + + + + + + @@ -1587,10 +1675,22 @@ + + + + + + + + associationMappings]]> associationMappings]]> + + + + @@ -1609,27 +1709,27 @@ - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + @@ -1637,161 +1737,161 @@ simpleStateFieldPathExpression]]> - dispatch + walkIndexBy($this)]]> - $sqlWalker + - null - null + + - $sqlWalker + - $sqlWalker + - $sqlWalker + - walkJoinPathExpression + - walkJoinVariableDeclaration + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - null + - $sqlWalker + - $sqlWalker + - $sqlWalker + - walkWhenClauseExpression + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - $sqlWalker + - walkWhenClauseExpression + - $sqlWalker + @@ -1804,12 +1904,12 @@ sqlStatements === null]]> - null + - $_sqlStatements - $queryCacheProfile - $sqlStatements + + + _sqlStatements !== null]]> @@ -1824,33 +1924,33 @@ - $numDeleted + - int + sqlStatements]]> - MultiTableDeleteExecutor - MultiTableDeleteExecutor + + - $numUpdated + - int + sqlStatements]]> - MultiTableUpdateExecutor - MultiTableUpdateExecutor - MultiTableUpdateExecutor + + + @@ -1858,8 +1958,8 @@ sqlStatements]]> - SingleSelectExecutor - SingleSelectExecutor + + @@ -1867,31 +1967,31 @@ executeStatement($this->sqlStatements, $params, $types)]]> - int + sqlStatements]]> - SingleTableDeleteUpdateExecutor - SingleTableDeleteUpdateExecutor - SingleTableDeleteUpdateExecutor + + + - $y + - $allowedClasses - $parts + + - $part + @@ -1904,7 +2004,7 @@ - $parts + @@ -1914,27 +2014,27 @@ - $parts + - $allowedClasses - $parts + + - $allowedClasses - $parts + + - $value + - static function ($value) use ($connection, $param) { + parameters]]> @@ -1942,50 +2042,50 @@ - Connection::PARAM_INT_ARRAY - Connection::PARAM_STR_ARRAY + + - $stringPattern + - AST\SelectStatement|AST\UpdateStatement|AST\DeleteStatement + queryComponents]]> - $factors[0] - $primary - $terms[0] + + + - AST\ArithmeticFactor - AST\ArithmeticTerm - AST\SimpleArithmeticExpression|AST\ArithmeticTerm + + + - new $functionClass($functionName) - new $functionClass($functionName) - new $functionClass($functionName) + + + - $function - $function - $function + + + - $statement + - $AST - $expr - $pathExp + + + lexer->getLiteral($token)]]> lexer->getLiteral($token)]]> lexer->getLiteral($token)]]> @@ -1994,7 +2094,7 @@ SimpleArithmeticExpression()]]> - $dql + query->getDQL()]]> value]]> @@ -2004,16 +2104,16 @@ value]]> - $args + - $AST instanceof AST\SelectStatement - $token === Lexer::T_IDENTIFIER + + - $sqlExecutor + @@ -2024,18 +2124,18 @@ ]]> - Comparison::EQ + - $class + - addNamedNativeQueryEntityResultMapping - addNamedNativeQueryEntityResultMapping - addNamedNativeQueryResultClassMapping - addNamedNativeQueryResultSetMapping + + + + @@ -2046,70 +2146,70 @@ - is_string($expression) + - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string - string + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - $expr + queryComponents[$expression]]]> - string + - $query + - $expression + whereClause]]> @@ -2117,10 +2217,28 @@ whereClause]]> simpleArithmeticExpression]]> subselect]]> - $condExpr + + + + + rangeVariableDeclaration]]> + + whereClause]]> + + + + + + + + + + + + associationMappings]]> associationMappings]]> @@ -2128,8 +2246,16 @@ scalarResultAliasMap]]> scalarResultAliasMap]]> + + + + + + + + - dispatch + @@ -2144,37 +2270,37 @@ - $whereClause !== null + - getExecutor + - null + - getExecutor + - $dqlAlias + - null + - $condPrimary + - $value + - TreeWalker|null + |false]]> @@ -2191,35 +2317,35 @@ $join]]]> - getRootAlias - getRootAlias + + isEmpty() ? $filteredParameters->first() : null]]> - Parameter|null + - new ArrayCollection($parameters) + - $spacePos - $spacePos + + - $spacePos - $spacePos + + - $dqlPart + - $alias - $alias + + - self::SELECT + @@ -2228,58 +2354,58 @@ repositoryList[$repositoryHash] = $this->createRepository($entityManager, $entityName)]]> - ObjectRepository + - $repository instanceof EntityRepository + - new $repositoryClassName($entityManager, $metadata) + - evictAll + - evictAll + - getQueryCacheImpl + - $fromPaths - $metadata + + - ClassMetadataExporter - ClassMetadataExporter - ClassMetadataExporter|null - EntityGenerator - EntityGenerator - EntityGenerator|null - new ClassMetadataExporter() - new ConvertDoctrine1Schema($fromPaths) - new EntityGenerator() - private $entityGenerator = null; - private $metadataExporter = null; + + + + + + + + + + + - $metadata + - AbstractExporter - new ClassMetadataExporter() - new DisconnectedClassMetadataFactory() - new EntityGenerator() + + + + name]]> @@ -2287,16 +2413,16 @@ - connect + - $metadatas + - new DisconnectedClassMetadataFactory() - new EntityGenerator() + + name]]> @@ -2312,7 +2438,7 @@ - new EntityRepositoryGenerator() + customRepositoryClassName]]> @@ -2320,7 +2446,7 @@ - getAllClassNames + @@ -2328,12 +2454,12 @@ entityListeners]]> - getAllClassNames + - int + executeSchemaCommand($input, $output, new SchemaTool($em), $metadatas, $ui)]]> @@ -2341,15 +2467,15 @@ - $metadatas - $metadatas + + - $metadatas - $metadatas - $metadatas + + + getName()]]> @@ -2358,7 +2484,7 @@ - $metadatas + getName()]]> @@ -2367,20 +2493,23 @@ - new ArrayIterator($metadatas) + - MetadataFilter + + + + - $state === UnitOfWork::STATE_DETACHED + @@ -2391,20 +2520,20 @@ - $tokens[$i - 1] + - $last + name, '\\')]]> - $variableType + - $classToExtend + - (bool) $embeddablesImmutable + lifecycleCallbacks)]]> @@ -2412,43 +2541,43 @@ - $fullClassName - $fullClassName - $fullClassName + + + - $repositoryName + - Driver\AbstractExporter - Driver\AnnotationExporter::class - Driver\PhpExporter::class - Driver\XmlExporter::class - Driver\YamlExporter::class - Driver\YamlExporter::class - ExportException::invalidExporterDriverType($type) + + + + + + + - new $class($dest) + - new $class($dest) + - Driver\AbstractExporter + - ExportException::attemptOverwriteExistingFile($path) + - string + _outputDir]]> @@ -2456,12 +2585,12 @@ - AbstractExporter - EntityGenerator - EntityGenerator|null + + + - $_extension + @@ -2469,10 +2598,10 @@ changeTrackingPolicy]]> - AbstractExporter + - $_extension + @@ -2488,10 +2617,10 @@ asXML()]]> - AbstractExporter + - $_extension + @@ -2506,22 +2635,22 @@ changeTrackingPolicy]]> - AbstractExporter + null]]]> - $array + - $array + &array{entityListeners: array>}]]> - $_extension + @@ -2535,7 +2664,7 @@ - $query + associationMappings[$property]['joinColumns']]]> @@ -2543,7 +2672,7 @@ - $query + @@ -2564,29 +2693,29 @@ - $parameters + - (bool) $fetchJoinCollection + - $orderByClause + - $classes + - canEmulateSchemas + - $asset + - $referencedFieldName + @@ -2598,14 +2727,14 @@ - is_numeric($indexName) + - assert(is_array($assoc)) - is_array($assoc) + + - $indexName + @@ -2622,7 +2751,7 @@ - $paths + @@ -2635,12 +2764,12 @@ - ! is_object($object) - is_object($object) + + - $collectionToDelete - $collectionToUpdate + + getMetadataFactory()]]> @@ -2648,80 +2777,80 @@ entityChangeSets]]> - $managedCopy - $prevManagedCopy - $previousManagedCopy + + + - $entityState - $entityState - $object + + + - $value + identityMap[$rootClassName]]]> - $assoc - $assoc + + getTypeOfField($class->getSingleIdentifierFieldName())]]> getOwner()]]> getOwner()]]> - $owner + reflFields]]> reflFields]]> - buildCachedCollectionPersister - buildCachedEntityPersister - getCacheFactory - getCacheFactory - getValue - getValue - getValue - getValue - getValue - getValue - getValue - getValue - getValue - getValue - getValue - getValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue - setValue + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - unwrap - unwrap - unwrap + + + - is_array($entity) + - $visited + @@ -2739,6 +2868,12 @@ + + + + + + diff --git a/psalm.xml b/psalm.xml index 46d39f56301..19b4e9368ca 100644 --- a/psalm.xml +++ b/psalm.xml @@ -243,6 +243,12 @@ + + + + + + From e62571c8f40c56797137d491067fc573b28739fe Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 2 Mar 2024 23:11:11 +0100 Subject: [PATCH 106/128] Refator array_map into simple loop for performance. (#11332) --- src/UnitOfWork.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index 00698e56c60..0ccbb8ead5f 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -1781,18 +1781,15 @@ public function addToIdentityMap($entity) */ final public static function getIdHashByIdentifier(array $identifier): string { + foreach ($identifier as $k => $value) { + if ($value instanceof BackedEnum) { + $identifier[$k] = $value->value; + } + } + return implode( ' ', - array_map( - static function ($value) { - if ($value instanceof BackedEnum) { - return $value->value; - } - - return $value; - }, - $identifier - ) + $identifier ); } From ab5e9e393b94bfcf851d4f4188298f7e1c47479e Mon Sep 17 00:00:00 2001 From: Rok Motaln Date: Sun, 3 Mar 2024 16:02:48 +0100 Subject: [PATCH 107/128] Fix SchemaTool::getSchemaFromMetadata() uniqueConstraint without a predefined name (#11314) * Fix loading SchemaTool::getSchemaFromMetadata() uniqueConstraint without a name Fixes a type miss-match exception when reading a UniqueConstraint defined on an Entity which doesn't have a predefined name. * Fix deprecation on DBAL 3 --------- Co-authored-by: Alexander M. Turek --- src/Tools/SchemaTool.php | 2 +- tests/Tests/ORM/Tools/SchemaToolTest.php | 47 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Tools/SchemaTool.php b/src/Tools/SchemaTool.php index 2e02279cc0c..532d40d82a9 100644 --- a/src/Tools/SchemaTool.php +++ b/src/Tools/SchemaTool.php @@ -365,7 +365,7 @@ static function (ClassMetadata $class) use ($idMapping): bool { if (isset($class->table['uniqueConstraints'])) { foreach ($class->table['uniqueConstraints'] as $indexName => $indexData) { - $uniqIndex = new Index($indexName, $this->getIndexColumns($class, $indexData), true, false, [], $indexData['options'] ?? []); + $uniqIndex = new Index('tmp__' . $indexName, $this->getIndexColumns($class, $indexData), true, false, [], $indexData['options'] ?? []); foreach ($table->getIndexes() as $tableIndexName => $tableIndex) { $method = method_exists($tableIndex, 'isFulfilledBy') ? 'isFulfilledBy' : 'isFullfilledBy'; diff --git a/tests/Tests/ORM/Tools/SchemaToolTest.php b/tests/Tests/ORM/Tools/SchemaToolTest.php index 83f70e85965..bc0e811f68f 100644 --- a/tests/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Tests/ORM/Tools/SchemaToolTest.php @@ -374,6 +374,27 @@ public function testConfigurationSchemaIgnoredEntity(): void self::assertTrue($schema->hasTable('first_entity'), 'Table first_entity should exist.'); self::assertFalse($schema->hasTable('second_entity'), 'Table second_entity should not exist.'); } + + #[Group('11314')] + public function testLoadUniqueConstraintWithoutName(): void + { + $em = $this->getTestEntityManager(); + $entity = $em->getClassMetadata(GH11314Entity::class); + + $schemaTool = new SchemaTool($em); + $schema = $schemaTool->getSchemaFromMetadata([$entity]); + + self::assertTrue($schema->hasTable('GH11314Entity')); + + $tableEntity = $schema->getTable('GH11314Entity'); + + self::assertTrue($tableEntity->hasIndex('uniq_2d81a3ed5bf54558875f7fd5')); + + $tableIndex = $tableEntity->getIndex('uniq_2d81a3ed5bf54558875f7fd5'); + + self::assertTrue($tableIndex->isUnique()); + self::assertSame(['field', 'anotherField'], $tableIndex->getColumns()); + } } /** @@ -559,6 +580,32 @@ class IndexByFieldEntity public $fieldName; } +/** + * @Entity + * @Table(uniqueConstraints={@UniqueConstraint(columns={"field", "anotherField"})}) + */ +class GH11314Entity +{ + /** + * @Column(type="integer") + * @Id + * @var int + */ + private $id; + + /** + * @Column(name="field", type="string") + * @var string + */ + private $field; + + /** + * @Column(name="anotherField", type="string") + * @var string + */ + private $anotherField; +} + class IncorrectIndexByFieldEntity { /** @var int */ From 21221f73cc85d7c09a43dc42f28882a65cb0219e Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 3 Mar 2024 16:46:12 +0100 Subject: [PATCH 108/128] Bump CI workflows (#11336) --- .github/workflows/continuous-integration.yml | 14 +++++++------- .github/workflows/documentation.yml | 2 +- .github/workflows/release-on-milestone-closed.yml | 2 +- .github/workflows/static-analysis.yml | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 695c299d379..ab98943cc3d 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -97,9 +97,9 @@ jobs: ORM_PROXY_IMPLEMENTATION: "${{ matrix.proxy }}" - name: "Upload coverage file" - uses: "actions/upload-artifact@v3" + uses: "actions/upload-artifact@v4" with: - name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage" + name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.proxy }}-coverage" path: "coverage*.xml" @@ -170,9 +170,9 @@ jobs: run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml" - name: "Upload coverage file" - uses: "actions/upload-artifact@v3" + uses: "actions/upload-artifact@v4" with: - name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage" + name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.extension }}-coverage" path: "coverage.xml" @@ -240,7 +240,7 @@ jobs: run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml" - name: "Upload coverage file" - uses: "actions/upload-artifact@v3" + uses: "actions/upload-artifact@v4" with: name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage" path: "coverage.xml" @@ -317,7 +317,7 @@ jobs: ENABLE_SECOND_LEVEL_CACHE: 1 - name: "Upload coverage files" - uses: "actions/upload-artifact@v3" + uses: "actions/upload-artifact@v4" with: name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage" path: "coverage*.xml" @@ -372,7 +372,7 @@ jobs: fetch-depth: 2 - name: "Download coverage files" - uses: "actions/download-artifact@v3" + uses: "actions/download-artifact@v4" with: path: "reports" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index f0bbf5b9e2a..bd9ebea8d28 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -27,7 +27,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: coverage: "none" - php-version: "8.2" + php-version: "8.3" - name: "Remove existing composer file" run: "rm composer.json" diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index c4389142616..d46dc4c36bb 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -7,7 +7,7 @@ on: jobs: release: - uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@3.0.0" + uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@4.0.0" secrets: GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 88b7196e357..a8765e23299 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -48,7 +48,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: coverage: "none" - php-version: "8.2" + php-version: "8.3" - name: "Require specific DBAL version" run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" @@ -89,7 +89,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: coverage: "none" - php-version: "8.2" + php-version: "8.3" - name: "Require specific persistence version" run: "composer require doctrine/persistence ^3.1 --no-update" From e3e96745cc2b1cbf4040b40a60949779eeaabdc9 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 3 Mar 2024 16:49:00 +0100 Subject: [PATCH 109/128] Fix annotation --- tests/Tests/ORM/Tools/SchemaToolTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Tests/ORM/Tools/SchemaToolTest.php b/tests/Tests/ORM/Tools/SchemaToolTest.php index bc0e811f68f..a3726f2d0b7 100644 --- a/tests/Tests/ORM/Tools/SchemaToolTest.php +++ b/tests/Tests/ORM/Tools/SchemaToolTest.php @@ -375,7 +375,7 @@ public function testConfigurationSchemaIgnoredEntity(): void self::assertFalse($schema->hasTable('second_entity'), 'Table second_entity should not exist.'); } - #[Group('11314')] + /** @group GH-11314 */ public function testLoadUniqueConstraintWithoutName(): void { $em = $this->getTestEntityManager(); From a809a71aa6a233a6c82e68ebaaf8954adc4998dc Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 3 Mar 2024 18:43:41 +0100 Subject: [PATCH 110/128] Prepare releases 2.19 and 3.1 (#11335) --- .doctrine-project.json | 30 +++++++++++++++++++++++++++--- README.md | 24 ++++++++++++------------ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/.doctrine-project.json b/.doctrine-project.json index 577fd732682..e761549298c 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -5,23 +5,47 @@ "slug": "orm", "docsSlug": "doctrine-orm", "versions": [ + { + "name": "4.0", + "branchName": "4.0.x", + "slug": "latest", + "upcoming": true + }, + { + "name": "3.2", + "branchName": "3.2.x", + "slug": "3.2", + "upcoming": true + }, + { + "name": "3.1", + "branchName": "3.1.x", + "slug": "3.1", + "current": true + }, { "name": "3.0", "branchName": "3.0.x", - "slug": "latest", + "slug": "3.0", + "maintained": false + }, + { + "name": "2.20", + "branchName": "2.20.x", + "slug": "2.20", "upcoming": true }, { "name": "2.19", "branchName": "2.19.x", "slug": "2.19", - "upcoming": true + "maintained": true }, { "name": "2.18", "branchName": "2.18.x", "slug": "2.18", - "current": true + "maintained": false }, { "name": "2.17", diff --git a/README.md b/README.md index c8e009fd5a5..75b3c34a18f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -| [4.0.x][4.0] | [3.1.x][3.1] | [3.0.x][3.0] | [2.19.x][2.19] | [2.18.x][2.18] | -|:------------------------------------------------------:|:------------------------------------------------------:|:-------------------------------------------------------:|:--------------------------------------------------------:|:---------------------------------------------------------:| -| [![Build status][4.0 image]][4.0] | [![Build status][3.1 image]][3.1] | [![Build status][3.0 image]][3.0] | [![Build status][2.19 image]][2.19] | [![Build status][2.18 image]][2.18] | -| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.1 coverage image]][3.1 coverage] | [![Coverage Status][3.0 coverage image]][3.0 coverage] | [![Coverage Status][2.19 coverage image]][2.19 coverage] | [![Coverage Status][2.18 coverage image]][2.18 coverage] | +| [4.0.x][4.0] | [3.2.x][3.2] | [3.1.x][3.1] | [2.20.x][2.20] | [2.19.x][2.19] | +|:------------------------------------------------------:|:------------------------------------------------------:|:------------------------------------------------------:|:--------------------------------------------------------:|:--------------------------------------------------------:| +| [![Build status][4.0 image]][4.0] | [![Build status][3.2 image]][3.2] | [![Build status][3.1 image]][3.1] | [![Build status][2.20 image]][2.20] | [![Build status][2.19 image]][2.19] | +| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.2 coverage image]][3.2 coverage] | [![Coverage Status][3.1 coverage image]][3.1 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] | [![Coverage Status][2.19 coverage image]][2.19 coverage] | [

πŸ‡ΊπŸ‡¦ UKRAINE NEEDS YOUR HELP NOW!

](https://www.doctrine-project.org/stop-war.html) @@ -22,19 +22,19 @@ without requiring unnecessary code duplication. [4.0]: https://github.com/doctrine/orm/tree/4.0.x [4.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/4.0.x/graph/badge.svg [4.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/4.0.x + [3.2 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.2.x + [3.2]: https://github.com/doctrine/orm/tree/3.2.x + [3.2 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.2.x/graph/badge.svg + [3.2 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.2.x [3.1 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.1.x [3.1]: https://github.com/doctrine/orm/tree/3.1.x [3.1 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.1.x/graph/badge.svg [3.1 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.1.x - [3.0 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.0.x - [3.0]: https://github.com/doctrine/orm/tree/3.0.x - [3.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.0.x/graph/badge.svg - [3.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.0.x + [2.20 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.20.x + [2.20]: https://github.com/doctrine/orm/tree/2.20.x + [2.20 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.20.x/graph/badge.svg + [2.20 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.20.x [2.19 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.19.x [2.19]: https://github.com/doctrine/orm/tree/2.19.x [2.19 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.19.x/graph/badge.svg [2.19 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.19.x - [2.18 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.18.x - [2.18]: https://github.com/doctrine/orm/tree/2.18.x - [2.18 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.18.x/graph/badge.svg - [2.18 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.18.x From 9acca2252f008b3b6013182b0e2c29b66532c626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Mon, 11 Mar 2024 20:31:22 +0100 Subject: [PATCH 111/128] Remove guides-specific markup doctrine/rst-parser does not appear to support orphan metadata yet, and renders it verbatim on the website. Let's move this to the CI job. --- .github/workflows/documentation.yml | 5 +++++ docs/en/reference/installation.rst | 2 -- docs/en/sidebar.rst | 2 -- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index bd9ebea8d28..ef8053a211c 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -40,5 +40,10 @@ jobs: with: dependency-versions: "highest" + - name: "Add orphan metadata where needed" + run: | + printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/sidebar.rst)" > docs/en/sidebar.rst + printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/reference/installation.rst)" > docs/en/reference/installation.rst + - name: "Run guides-cli" run: "vendor/bin/guides -vvv --no-progress docs/en 2>&1 | grep -v 'No template found for rendering directive' | ( ! grep WARNING )" diff --git a/docs/en/reference/installation.rst b/docs/en/reference/installation.rst index 2c0d5823009..dab1364f777 100644 --- a/docs/en/reference/installation.rst +++ b/docs/en/reference/installation.rst @@ -1,5 +1,3 @@ -:orphan: - Installation ============ diff --git a/docs/en/sidebar.rst b/docs/en/sidebar.rst index f67304e8457..df3032d65f2 100644 --- a/docs/en/sidebar.rst +++ b/docs/en/sidebar.rst @@ -1,5 +1,3 @@ -:orphan: - .. toc:: .. tocheader:: Tutorials From 16f355f0cc9180375c19755372210a11b7d6df1e Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 20:31:09 +0100 Subject: [PATCH 112/128] Remove tests for already working case as they add no value other than exploration, and we only need the regression test. --- .../AbstractRemoveControl.php | 2 +- .../MobileRemoteControl.php | 2 +- .../{WithFetchEager => }/User.php | 2 +- .../AbstractRemoveControl.php | 49 ------------------- .../WithoutFetchEager/MobileRemoteControl.php | 14 ------ .../WithoutFetchEager/User.php | 35 ------------- .../ORM/Functional/AbstractFetchEagerTest.php | 33 ++----------- 7 files changed, 6 insertions(+), 131 deletions(-) rename tests/Tests/Models/AbstractFetchEager/{WithFetchEager => }/AbstractRemoveControl.php (93%) rename tests/Tests/Models/AbstractFetchEager/{WithFetchEager => }/MobileRemoteControl.php (69%) rename tests/Tests/Models/AbstractFetchEager/{WithFetchEager => }/User.php (89%) delete mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php delete mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php delete mode 100644 tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/User.php diff --git a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php b/tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php similarity index 93% rename from tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php rename to tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php index 7c69c15d75a..a2874469304 100644 --- a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/AbstractRemoveControl.php +++ b/tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager; +namespace Doctrine\Tests\Models\AbstractFetchEager; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; diff --git a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php similarity index 69% rename from tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php rename to tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php index cdbca6f3f0f..adb7c22fd08 100644 --- a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/MobileRemoteControl.php +++ b/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager; +namespace Doctrine\Tests\Models\AbstractFetchEager; use Doctrine\ORM\Mapping as ORM; diff --git a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/User.php b/tests/Tests/Models/AbstractFetchEager/User.php similarity index 89% rename from tests/Tests/Models/AbstractFetchEager/WithFetchEager/User.php rename to tests/Tests/Models/AbstractFetchEager/User.php index 6c34501e730..0ee7b24891b 100644 --- a/tests/Tests/Models/AbstractFetchEager/WithFetchEager/User.php +++ b/tests/Tests/Models/AbstractFetchEager/User.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager; +namespace Doctrine\Tests\Models\AbstractFetchEager; use Doctrine\ORM\Mapping as ORM; diff --git a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php deleted file mode 100644 index 82bb2f705f6..00000000000 --- a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/AbstractRemoveControl.php +++ /dev/null @@ -1,49 +0,0 @@ - - */ - public $users; - - public function __construct(string $name) - { - $this->name = $name; - $this->users = new ArrayCollection(); - } -} diff --git a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php deleted file mode 100644 index 6628234450f..00000000000 --- a/tests/Tests/Models/AbstractFetchEager/WithoutFetchEager/MobileRemoteControl.php +++ /dev/null @@ -1,14 +0,0 @@ -remoteControl = $control; - } -} diff --git a/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php index 14e50f70b4b..975a97fa7a9 100644 --- a/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php +++ b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php @@ -4,12 +4,9 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager\AbstractRemoveControl; -use Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager\MobileRemoteControl; -use Doctrine\Tests\Models\AbstractFetchEager\WithFetchEager\User; -use Doctrine\Tests\Models\AbstractFetchEager\WithoutFetchEager\AbstractRemoveControl as AbstractRemoveControlWithoutFetchEager; -use Doctrine\Tests\Models\AbstractFetchEager\WithoutFetchEager\MobileRemoteControl as MobileRemoteControlWithoutFetchEager; -use Doctrine\Tests\Models\AbstractFetchEager\WithoutFetchEager\User as UserWithoutFetchEager; +use Doctrine\Tests\Models\AbstractFetchEager\AbstractRemoveControl; +use Doctrine\Tests\Models\AbstractFetchEager\MobileRemoteControl; +use Doctrine\Tests\Models\AbstractFetchEager\User; use Doctrine\Tests\OrmFunctionalTestCase; final class AbstractFetchEagerTest extends OrmFunctionalTestCase @@ -37,28 +34,4 @@ public function testWithAbstractFetchEager(): void self::assertEquals('smart', $user->remoteControl->name); self::assertTrue($user->remoteControl->users->contains($user)); } - - public function testWithoutAbstractFetchEager(): void - { - $this->createSchemaForModels( - AbstractRemoveControlWithoutFetchEager::class, - UserWithoutFetchEager::class - ); - - $control = new MobileRemoteControlWithoutFetchEager('smart'); - $user = new UserWithoutFetchEager($control); - - $entityManage = $this->getEntityManager(); - - $entityManage->persist($control); - $entityManage->persist($user); - $entityManage->flush(); - $entityManage->clear(); - - $user = $entityManage->find(UserWithoutFetchEager::class, $user->id); - - self::assertNotNull($user); - self::assertEquals('smart', $user->remoteControl->name); - self::assertTrue($user->remoteControl->users->contains($user)); - } } From e399d21fb3594599e322cab4695e732687f3a73c Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 20:41:24 +0100 Subject: [PATCH 113/128] Simplify condition, improve comment on this edge case. --- src/UnitOfWork.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index 07903c3e6c0..ba9765fbafa 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3252,8 +3252,10 @@ private function eagerLoadCollections(array $collections, array $mapping): void foreach ($found as $targetValue) { $sourceEntity = $targetProperty->getValue($targetValue); - // In cases where the hydration $targetValue has not yet fully completed - if ($sourceEntity === null && isset($targetClass->associationMappings[$mappedBy]['joinColumns'])) { + if ($sourceEntity === null) { + // case where the hydration $targetValue itself has not yet fully completed, for example + // in case a bi-directional association is being hydrated and deferring eager loading is + // not possible due to subclassing. $data = $this->getOriginalEntityData($targetValue); $id = []; foreach ($targetClass->associationMappings[$mappedBy]['joinColumns'] as $joinColumn) { From 6501890ab5fad43adfe259fbbbc3339b07185710 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 20:48:15 +0100 Subject: [PATCH 114/128] Static analysis enforces the extra isset() even though that just masks no sense. --- src/UnitOfWork.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index ba9765fbafa..0b14fba2dc4 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3252,7 +3252,7 @@ private function eagerLoadCollections(array $collections, array $mapping): void foreach ($found as $targetValue) { $sourceEntity = $targetProperty->getValue($targetValue); - if ($sourceEntity === null) { + if ($sourceEntity === null && isset($targetClass->associationMappings[$mappedBy]['joinColumns'])) { // case where the hydration $targetValue itself has not yet fully completed, for example // in case a bi-directional association is being hydrated and deferring eager loading is // not possible due to subclassing. From 1b6cf58a1aa19a403b587373de2b5d690734bf21 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 21:08:30 +0100 Subject: [PATCH 115/128] Rename tables to avoid pg related illegal table name --- ...AbstractRemoveControl.php => AbstractRemoteControl.php} | 3 ++- .../Models/AbstractFetchEager/MobileRemoteControl.php | 2 +- tests/Tests/Models/AbstractFetchEager/User.php | 7 ++++--- tests/Tests/ORM/Functional/AbstractFetchEagerTest.php | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) rename tests/Tests/Models/AbstractFetchEager/{AbstractRemoveControl.php => AbstractRemoteControl.php} (90%) diff --git a/tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php b/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php similarity index 90% rename from tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php rename to tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php index a2874469304..59d69da28a4 100644 --- a/tests/Tests/Models/AbstractFetchEager/AbstractRemoveControl.php +++ b/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php @@ -10,11 +10,12 @@ /** * @ORM\Entity() + * @ORM\Table(name="abstract_fetch_eager_remote_control") * @ORM\InheritanceType("SINGLE_TABLE") * @ORM\DiscriminatorColumn(name="type", type="string") * @ORM\DiscriminatorMap({"mobile"="MobileRemoteControl"}) */ -abstract class AbstractRemoveControl +abstract class AbstractRemoteControl { /** * @ORM\Id diff --git a/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php index adb7c22fd08..50bdc25470b 100644 --- a/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php +++ b/tests/Tests/Models/AbstractFetchEager/MobileRemoteControl.php @@ -9,6 +9,6 @@ /** * @ORM\Entity() */ -class MobileRemoteControl extends AbstractRemoveControl +class MobileRemoteControl extends AbstractRemoteControl { } diff --git a/tests/Tests/Models/AbstractFetchEager/User.php b/tests/Tests/Models/AbstractFetchEager/User.php index 0ee7b24891b..d8b7b2c012a 100644 --- a/tests/Tests/Models/AbstractFetchEager/User.php +++ b/tests/Tests/Models/AbstractFetchEager/User.php @@ -8,6 +8,7 @@ /** * @ORM\Entity() + * @ORM\Table(name="abstract_fetch_eager_user") */ class User { @@ -21,14 +22,14 @@ class User public $id; /** - * @ORM\ManyToOne(targetEntity="AbstractRemoveControl", inversedBy="users") + * @ORM\ManyToOne(targetEntity="AbstractRemoteControl", inversedBy="users") * @ORM\JoinColumn(nullable=false) * - * @var AbstractRemoveControl + * @var AbstractRemoteControl */ public $remoteControl; - public function __construct(AbstractRemoveControl $control) + public function __construct(AbstractRemoteControl $control) { $this->remoteControl = $control; } diff --git a/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php index 975a97fa7a9..24e100a684c 100644 --- a/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php +++ b/tests/Tests/ORM/Functional/AbstractFetchEagerTest.php @@ -4,7 +4,7 @@ namespace Doctrine\Tests\ORM\Functional; -use Doctrine\Tests\Models\AbstractFetchEager\AbstractRemoveControl; +use Doctrine\Tests\Models\AbstractFetchEager\AbstractRemoteControl; use Doctrine\Tests\Models\AbstractFetchEager\MobileRemoteControl; use Doctrine\Tests\Models\AbstractFetchEager\User; use Doctrine\Tests\OrmFunctionalTestCase; @@ -14,7 +14,7 @@ final class AbstractFetchEagerTest extends OrmFunctionalTestCase public function testWithAbstractFetchEager(): void { $this->createSchemaForModels( - AbstractRemoveControl::class, + AbstractRemoteControl::class, User::class ); From fcd02b1ee276635d4b39d55f492f7c8b0c1ebed4 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 23:04:57 +0100 Subject: [PATCH 116/128] Cleanup tests not to use model sets. --- .../EagerFetchOneToManyWithCompositeKeyTest.php | 10 +++------- tests/Tests/OrmFunctionalTestCase.php | 9 --------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php index 8ad78cb253d..82b9d0b8acb 100644 --- a/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php +++ b/tests/Tests/ORM/Functional/EagerFetchOneToManyWithCompositeKeyTest.php @@ -5,20 +5,16 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\RootEntity; +use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\SecondLevel; use Doctrine\Tests\OrmFunctionalTestCase; final class EagerFetchOneToManyWithCompositeKeyTest extends OrmFunctionalTestCase { - protected function setUp(): void - { - $this->useModelSet('eager_fetched_composite_one_to_many'); - - parent::setUp(); - } - /** @ticket 11154 */ public function testItDoesNotThrowAnExceptionWhenTriggeringALoad(): void { + $this->setUpEntitySchema([RootEntity::class, SecondLevel::class]); + $a1 = new RootEntity(1, 'A'); $this->_em->persist($a1); diff --git a/tests/Tests/OrmFunctionalTestCase.php b/tests/Tests/OrmFunctionalTestCase.php index ea2a0110405..4a64136f184 100644 --- a/tests/Tests/OrmFunctionalTestCase.php +++ b/tests/Tests/OrmFunctionalTestCase.php @@ -342,10 +342,6 @@ abstract class OrmFunctionalTestCase extends OrmTestCase Models\Issue9300\Issue9300Child::class, Models\Issue9300\Issue9300Parent::class, ], - 'eager_fetched_composite_one_to_many' => [ - Models\EagerFetchedCompositeOneToMany\RootEntity::class, - Models\EagerFetchedCompositeOneToMany\SecondLevel::class, - ], ]; /** @param class-string ...$models */ @@ -675,11 +671,6 @@ protected function tearDown(): void $conn->executeStatement('DELETE FROM issue5989_managers'); } - if (isset($this->_usedModelSets['eager_fetched_composite_one_to_many'])) { - $conn->executeStatement('DELETE FROM eager_composite_join_second_level'); - $conn->executeStatement('DELETE FROM eager_composite_join_root'); - } - $this->_em->clear(); } From 820a0da4c188fb96de6782fef53ed5639ff690b9 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 16 Mar 2024 23:05:28 +0100 Subject: [PATCH 117/128] Do not schedule batch loading for target classes with composite identifier. --- src/UnitOfWork.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index 00698e56c60..c5996613b48 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3169,9 +3169,9 @@ public function createEntity($className, array $data, &$hints = []) if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; - if (! $isIteration && $assoc['type'] === ClassMetadata::ONE_TO_MANY) { + if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $targetClass->isIdentifierComposite) { $this->scheduleCollectionForBatchLoading($pColl, $class); - } elseif (($isIteration && $assoc['type'] === ClassMetadata::ONE_TO_MANY) || $assoc['type'] === ClassMetadata::MANY_TO_MANY) { + } else { $this->loadCollection($pColl); $pColl->takeSnapshot(); } From 528ef40fc411ac3375ab8c9b5fb8f850fb9bbcd2 Mon Sep 17 00:00:00 2001 From: Marko Kaznovac Date: Sun, 17 Mar 2024 15:55:54 +0100 Subject: [PATCH 118/128] Minor code style fix in AbstractRemoteControl --- tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php b/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php index 59d69da28a4..5790cbe365d 100644 --- a/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php +++ b/tests/Tests/Models/AbstractFetchEager/AbstractRemoteControl.php @@ -27,8 +27,6 @@ abstract class AbstractRemoteControl public $id; /** - * /** - * * @ORM\Column(type="string") * * @var string From 1622b7877dcd8db015ff3d99fd662e0bc506ff37 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 17 Mar 2024 18:02:11 +0100 Subject: [PATCH 119/128] Fix entities and mapping. --- .../SecondLevel.php | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php index e67f3abc4fb..121a57ecc4c 100644 --- a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php @@ -12,14 +12,6 @@ */ class SecondLevel { - /** - * @ORM\Id - * @ORM\Column(type="integer", nullable=false) - * - * @var int|null - */ - private $id = null; - /** * @ORM\Id * @ORM\Column(type="integer", nullable=false) @@ -39,17 +31,16 @@ class SecondLevel /** * @ORM\ManyToOne(targetEntity=RootEntity::class, inversedBy="secondLevel") * @ORM\JoinColumns({ - * @ORM\JoinColumn(name="other_key", referencedColumnName="other_key"), - * @ORM\JoinColumn(name="upper_id", referencedColumnName="id") + * @ORM\JoinColumn(name="root_other_key", referencedColumnName="other_key"), + * @ORM\JoinColumn(name="root_id", referencedColumnName="id") * }) * * @var RootEntity */ private $root; - public function __construct(int $id, RootEntity $upper) + public function __construct(RootEntity $upper) { - $this->id = $id; $this->upperId = $upper->getId(); $this->otherKey = $upper->getOtherKey(); $this->root = $upper; From 5e6d5c06a987c073f01128577c78102dd468a608 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 17 Mar 2024 19:43:26 +0100 Subject: [PATCH 120/128] Key on fk --- .../Models/EagerFetchedCompositeOneToMany/SecondLevel.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php index 121a57ecc4c..99fed077723 100644 --- a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php @@ -8,7 +8,9 @@ /** * @ORM\Entity - * @ORM\Table(name="eager_composite_join_second_level") + * @ORM\Table(name="eager_composite_join_second_level", indexes={ + * @ORM\Index(name="root_other_key_idx", columns={"root_other_key", "root_id"}) + * }) */ class SecondLevel { From 3e3c023c95d6c7c848a1bcd71180baf7e033743a Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sun, 17 Mar 2024 19:50:56 +0100 Subject: [PATCH 121/128] Switch join columns around, otherwise index doesnt match --- .../Models/EagerFetchedCompositeOneToMany/SecondLevel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php index 99fed077723..33f878c8f41 100644 --- a/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php +++ b/tests/Tests/Models/EagerFetchedCompositeOneToMany/SecondLevel.php @@ -33,8 +33,8 @@ class SecondLevel /** * @ORM\ManyToOne(targetEntity=RootEntity::class, inversedBy="secondLevel") * @ORM\JoinColumns({ - * @ORM\JoinColumn(name="root_other_key", referencedColumnName="other_key"), - * @ORM\JoinColumn(name="root_id", referencedColumnName="id") + * @ORM\JoinColumn(name="root_id", referencedColumnName="id"), + * @ORM\JoinColumn(name="root_other_key", referencedColumnName="other_key") * }) * * @var RootEntity From 08a9e60ed04e7cf08023ee69b7d8c68a3bfeec66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Sun, 17 Mar 2024 23:06:30 +0100 Subject: [PATCH 122/128] Remove outdated git metadata files (#11362) Some of it seems related to the previous documentation build system, some of it seems related to IntelliJ. --- docs/.gitignore | 4 ---- docs/.gitmodules | 3 --- 2 files changed, 7 deletions(-) delete mode 100644 docs/.gitignore delete mode 100644 docs/.gitmodules diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 59cd005a9a4..00000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -en/_exts/configurationblock.pyc -build -en/_build -.idea diff --git a/docs/.gitmodules b/docs/.gitmodules deleted file mode 100644 index e38d44b0adf..00000000000 --- a/docs/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "en/_theme"] - path = en/_theme - url = https://github.com/doctrine/doctrine-sphinx-theme.git From 9d1a4973ae2d8ddedd6b66e958e32ebb58cdf3d6 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Tue, 19 Mar 2024 09:19:25 +0100 Subject: [PATCH 123/128] Improve lazy ghost performance by avoiding self-referencing closure. (#11376) * Improve lazy ghost performance by avoiding self-referencing closure. Co-authored-by: Nicolas Grekas * update baselien --------- Co-authored-by: Nicolas Grekas --- psalm-baseline.xml | 8 ++------ src/Proxy/ProxyFactory.php | 14 ++++++-------- tests/Tests/ORM/Proxy/ProxyFactoryTest.php | 6 +++--- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index c175642e62b..7a3b729e849 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1492,6 +1492,7 @@ + @@ -1501,13 +1502,8 @@ - + - - - diff --git a/src/Proxy/ProxyFactory.php b/src/Proxy/ProxyFactory.php index 0660c423f0d..5b2d2eca0c9 100644 --- a/src/Proxy/ProxyFactory.php +++ b/src/Proxy/ProxyFactory.php @@ -360,11 +360,11 @@ private function createInitializer(ClassMetadata $classMetadata, EntityPersister */ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersister $entityPersister, IdentifierFlattener $identifierFlattener): Closure { - return static function (InternalProxy $proxy, InternalProxy $original) use ($entityPersister, $classMetadata, $identifierFlattener): void { - $identifier = $classMetadata->getIdentifierValues($original); - $entity = $entityPersister->loadById($identifier, $original); + return static function (InternalProxy $proxy) use ($entityPersister, $classMetadata, $identifierFlattener): void { + $identifier = $classMetadata->getIdentifierValues($proxy); + $original = $entityPersister->loadById($identifier); - if ($entity === null) { + if ($original === null) { throw EntityNotFoundException::fromClassNameAndIdentifier( $classMetadata->getName(), $identifierFlattener->flattenIdentifier($classMetadata, $identifier) @@ -382,7 +382,7 @@ private function createLazyInitializer(ClassMetadata $classMetadata, EntityPersi continue; } - $property->setValue($proxy, $property->getValue($entity)); + $property->setValue($proxy, $property->getValue($original)); } }; } @@ -468,9 +468,7 @@ private function getProxyFactory(string $className): Closure $identifierFields = array_intersect_key($class->getReflectionProperties(), $identifiers); $proxyFactory = Closure::bind(static function (array $identifier) use ($initializer, $skippedProperties, $identifierFields, $className): InternalProxy { - $proxy = self::createLazyGhost(static function (InternalProxy $object) use ($initializer, &$proxy): void { - $initializer($object, $proxy); - }, $skippedProperties); + $proxy = self::createLazyGhost($initializer, $skippedProperties); foreach ($identifierFields as $idField => $reflector) { if (! isset($identifier[$idField])) { diff --git a/tests/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Tests/ORM/Proxy/ProxyFactoryTest.php index 3739aaf4dd5..d0989953def 100644 --- a/tests/Tests/ORM/Proxy/ProxyFactoryTest.php +++ b/tests/Tests/ORM/Proxy/ProxyFactoryTest.php @@ -65,7 +65,7 @@ public function testReferenceProxyDelegatesLoadingToThePersister(): void { $identifier = ['id' => 42]; $proxyClass = 'Proxies\__CG__\Doctrine\Tests\Models\ECommerce\ECommerceFeature'; - $persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['load']) + $persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['loadById']) ->disableOriginalConstructor() ->getMock(); @@ -75,8 +75,8 @@ public function testReferenceProxyDelegatesLoadingToThePersister(): void $persister ->expects(self::atLeastOnce()) - ->method('load') - ->with(self::equalTo($identifier), self::isInstanceOf($proxyClass)) + ->method('loadById') + ->with(self::equalTo($identifier)) ->will(self::returnValue($proxy)); $proxy->getDescription(); From d15624f72f920cfc79ea86b7d3c0a7586ad71574 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Wed, 20 Mar 2024 15:45:47 +0100 Subject: [PATCH 124/128] [GH-11185] Bugfix: do not use collection batch loading for indexBy assocations. (#11380) --- src/UnitOfWork.php | 2 +- .../Ticket/GH11149/EagerProduct.php | 41 ++++++++++++++++ .../GH11149/EagerProductTranslation.php | 45 ++++++++++++++++++ .../Functional/Ticket/GH11149/GH11149Test.php | 47 +++++++++++++++++++ .../ORM/Functional/Ticket/GH11149/Locale.php | 27 +++++++++++ 5 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11149/EagerProductTranslation.php create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11149/GH11149Test.php create mode 100644 tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index 3bb9b8efeb6..25b88221583 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -3166,7 +3166,7 @@ public function createEntity($className, array $data, &$hints = []) if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) { $isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION]; - if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $targetClass->isIdentifierComposite) { + if ($assoc['type'] === ClassMetadata::ONE_TO_MANY && ! $isIteration && ! $targetClass->isIdentifierComposite && ! isset($assoc['indexBy'])) { $this->scheduleCollectionForBatchLoading($pColl, $class); } else { $this->loadCollection($pColl); diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php new file mode 100644 index 00000000000..448f7d82eb6 --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php @@ -0,0 +1,41 @@ + + */ + public $translations; + + public function __construct(int $id) + { + $this->id = $id; + $this->translations = new ArrayCollection(); + } +} diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProductTranslation.php b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProductTranslation.php new file mode 100644 index 00000000000..32c501868ec --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProductTranslation.php @@ -0,0 +1,45 @@ +id = $id; + $this->product = $product; + $this->locale = $locale; + } +} diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/GH11149Test.php b/tests/Tests/ORM/Functional/Ticket/GH11149/GH11149Test.php new file mode 100644 index 00000000000..28bab541b90 --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/GH11149Test.php @@ -0,0 +1,47 @@ +setUpEntitySchema([ + Locale::class, + EagerProduct::class, + EagerProductTranslation::class, + ]); + } + + public function testFetchEagerModeWithIndexBy(): void + { + // Load entities into database + $this->_em->persist($product = new EagerProduct(11149)); + $this->_em->persist($locale = new Locale('fr_FR')); + $this->_em->persist(new EagerProductTranslation(11149, $product, $locale)); + $this->_em->flush(); + $this->_em->clear(); + + // Fetch entity from database + $product = $this->_em->find(EagerProduct::class, 11149); + + // Assert associated entity is loaded eagerly + static::assertInstanceOf(EagerProduct::class, $product); + static::assertInstanceOf(PersistentCollection::class, $product->translations); + static::assertTrue($product->translations->isInitialized()); + static::assertCount(1, $product->translations); + + // Assert associated entity is indexed by given property + $translation = $product->translations->get('fr_FR'); + static::assertInstanceOf(EagerProductTranslation::class, $translation); + static::assertNotInstanceOf(Proxy::class, $translation); + } +} diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php b/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php new file mode 100644 index 00000000000..d54eda636ff --- /dev/null +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php @@ -0,0 +1,27 @@ +code = $code; + } +} From 5ccbc201bff51cdc2006db8585b0d22d6695859d Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 20 Mar 2024 23:34:10 +0100 Subject: [PATCH 125/128] [Documentation] Removing "Doctrine Mapping Types" ... (#11384) ... in favor of https://www.doctrine-project.org/projects/doctrine-dbal/en/3.8/reference/types.html#reference Page: https://www.doctrine-project.org/projects/doctrine-orm/en/2.19/reference/basic-mapping.html#doctrine-mapping-types As announced in https://github.com/doctrine/dbal/pull/6336#issuecomment-2003720361 , the goal is to remove this duplicated type information from ORM and replace it with a link to DBAL. In https://github.com/doctrine/dbal/pull/6341 , I'm adding any detail which I'm deleting here to the DBAL. --- docs/en/reference/basic-mapping.rst | 48 +++-------------------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst index a61e5d8d0e4..32f8626806b 100644 --- a/docs/en/reference/basic-mapping.rst +++ b/docs/en/reference/basic-mapping.rst @@ -300,50 +300,12 @@ and a custom ``Doctrine\ORM\Mapping\TypedFieldMapper`` implementation. Doctrine Mapping Types ---------------------- -The ``type`` option used in the ``@Column`` accepts any of the existing -Doctrine types or even your own custom types. A Doctrine type defines +The ``type`` option used in the ``@Column`` accepts any of the +`existing Doctrine DBAL types `_ +or :doc:`your own custom mapping types +<../cookbook/custom-mapping-types>`. A Doctrine type defines the conversion between PHP and SQL types, independent from the database vendor -you are using. All Mapping Types that ship with Doctrine are fully portable -between the supported database systems. - -As an example, the Doctrine Mapping Type ``string`` defines the -mapping from a PHP string to a SQL VARCHAR (or VARCHAR2 etc. -depending on the RDBMS brand). Here is a quick overview of the -built-in mapping types: - -- ``string``: Type that maps a SQL VARCHAR to a PHP string. -- ``integer``: Type that maps a SQL INT to a PHP integer. -- ``smallint``: Type that maps a database SMALLINT to a PHP - integer. -- ``bigint``: Type that maps a database BIGINT to a PHP string. -- ``boolean``: Type that maps a SQL boolean or equivalent (TINYINT) to a PHP boolean. -- ``decimal``: Type that maps a SQL DECIMAL to a PHP string. -- ``date``: Type that maps a SQL DATETIME to a PHP DateTime - object. -- ``time``: Type that maps a SQL TIME to a PHP DateTime object. -- ``datetime``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP - DateTime object. -- ``datetimetz``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP - DateTime object with timezone. -- ``text``: Type that maps a SQL CLOB to a PHP string. -- ``object``: Type that maps a SQL CLOB to a PHP object using - ``serialize()`` and ``unserialize()`` -- ``array``: Type that maps a SQL CLOB to a PHP array using - ``serialize()`` and ``unserialize()`` -- ``simple_array``: Type that maps a SQL CLOB to a PHP array using - ``implode()`` and ``explode()``, with a comma as delimiter. *IMPORTANT* - Only use this type if you are sure that your values cannot contain a ",". -- ``json_array``: Type that maps a SQL CLOB to a PHP array using - ``json_encode()`` and ``json_decode()`` -- ``float``: Type that maps a SQL Float (Double Precision) to a - PHP double. *IMPORTANT*: Works only with locale settings that use - decimal points as separator. -- ``guid``: Type that maps a database GUID/UUID to a PHP string. Defaults to - varchar but uses a specific type if the platform supports it. -- ``blob``: Type that maps a SQL BLOB to a PHP resource stream - -A cookbook article shows how to define :doc:`your own custom mapping types -<../cookbook/custom-mapping-types>`. +you are using. .. note:: From db6e702088a251f7f0adc2fcdaa2003f46a5a4f6 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 21 Mar 2024 10:32:55 +0100 Subject: [PATCH 126/128] Remove unused variable (#11391) --- tests/Tests/ORM/Proxy/ProxyFactoryTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Tests/ORM/Proxy/ProxyFactoryTest.php index d0989953def..e6335c46c8f 100644 --- a/tests/Tests/ORM/Proxy/ProxyFactoryTest.php +++ b/tests/Tests/ORM/Proxy/ProxyFactoryTest.php @@ -64,7 +64,6 @@ protected function setUp(): void public function testReferenceProxyDelegatesLoadingToThePersister(): void { $identifier = ['id' => 42]; - $proxyClass = 'Proxies\__CG__\Doctrine\Tests\Models\ECommerce\ECommerceFeature'; $persister = $this->getMockBuilderWithOnlyMethods(BasicEntityPersister::class, ['loadById']) ->disableOriginalConstructor() ->getMock(); From 95795c87a8924fa28b1465dec67ad8a5b85d8213 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 21 Mar 2024 10:38:59 +0100 Subject: [PATCH 127/128] Add missing import --- tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php index 448f7d82eb6..e2528089abf 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/EagerProduct.php @@ -5,6 +5,7 @@ namespace Doctrine\Tests\ORM\Functional\Ticket\GH11149; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; /** From 1a5a4c674a416b4fdf76833c627c5e7f58bbb890 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Thu, 21 Mar 2024 12:01:42 +0100 Subject: [PATCH 128/128] Set column length explicitly (#11393) --- tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php b/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php index d54eda636ff..8ec8a548bf1 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php +++ b/tests/Tests/ORM/Functional/Ticket/GH11149/Locale.php @@ -14,7 +14,7 @@ class Locale { /** * @ORM\Id - * @ORM\Column(type="string") + * @ORM\Column(type="string", length=5) * * @var string */