Compare commits

...

62 Commits

Author SHA1 Message Date
Marco Pivetta
464b5fdbfb Release 2.5.2 2015-11-23 13:44:25 +01:00
Guilherme Blanco
04254a8e34 Merge pull request #1512 from neoglez/2.5
Backport of "LimitSubqueryOutputWalker: fix aliasing of property in OrderBy from MappedSuperclass"
2015-11-15 22:08:59 -05:00
Guilherme Blanco
1d213e6733 Merge pull request #1543 from nicolas-grekas/dep-30
Allow symfony 3.0 components on 2.5
2015-11-09 14:54:44 -05:00
Klein Thomas
bc82e94afc Move to 2.5 section 2015-11-09 03:56:16 +00:00
Klein Thomas
b9af1c8fa5 Update Upgrade.md after minor bc break in 2.5.1
The introduction of the second parameter in EntityRepository#createQueryBuilder generates a runtime notice if you have a sub-class of EntityRepository that has a second parameter in the createQueryBuilder method
2015-11-09 03:56:07 +00:00
Pantel
d606efd4eb [DDC-3711] add Test that check if the association key are composite 2015-11-09 03:46:06 +00:00
Pantel
581e1638a2 [DDC-3711] add Tests that check if the association key are composite 2015-11-09 03:45:56 +00:00
Pantel
17ae8d1b2d [DDC-3711] Correct Error on manyToMany with composite primary key 2015-11-09 03:45:46 +00:00
Guilherme Blanco
3a058f8522 Merge branch 'hotfix/#1375-prevent-duplicate-unique-index' into 2.5
Backported #1375 to 2.5
2015-11-07 16:47:26 +00:00
Michał Bundyra
567220ef71 prevent duplicate unique index 2015-11-07 16:46:22 +00:00
Marco Pivetta
39098ce415 Merge branch 'hotfix/#1507-fixed-wrong-property-name-in-resultset-mapping-builder' into 2.5
Backport merge #1507 into 2.5.x
Close #1507
2015-11-07 10:35:30 -05:00
François-Xavier de Guillebon
1eb9c8a7f6 Added test 2015-11-07 10:35:08 -05:00
François-Xavier de Guillebon
f2f53ba9dc Fixed wrong variable used as array key 2015-11-07 10:35:02 -05:00
François-Xavier de Guillebon
ebbc443ec3 Fixed wrong property name 2015-11-07 10:34:55 -05:00
Nicolas Grekas
16802d2614 Allow symfony 3.0 components
Tests should tell if any deprecated interfaces of Symfony are used. If not, then the bundle is defacto compatible with 3.0
2015-11-05 11:43:20 +01:00
neoglez
ef73249bc7 Entity to test a mapped superclass
Backport of https://github.com/doctrine/doctrine2/pull/1377/files to branch 2.5
2015-09-21 09:32:54 +02:00
neoglez
ed637e51b9 Backport of "fix aliasing of property in OrderBy from MappedSuperclass"
Backport of "LimitSubqueryOutputWalker: fix aliasing of property in OrderBy from MappedSuperclass" ( e501137d1a )
See my comment on a3ece3b419
2015-09-21 08:58:30 +02:00
neoglez
a3ece3b419 UnitTest backport of "Failing test case for broken paginator case"
UnitTest backport of "Failing test case for broken paginator case" ( 192da14842 ).
The branch 2.x is very important because it's related to ZF2 doctrine module (see https://github.com/doctrine/DoctrineORMModule/blob/master/composer.json ) and specially this issue affects the use case of extending the ZF2 user entity defined in ZfcUser ( https://github.com/ZF-Commons/ZfcUser ).
This test is meant to show the need of the backport of e501137d1a
2015-09-21 08:52:46 +02:00
Marco Pivetta
2d1bc78749 Merge branch 'hotfix/#1510-DDC-3908-fix-cache-related-tests-in-2.5' into 2.5
Close #1510
2015-09-19 10:45:24 +02:00
Matthias Pigulla
eaf8b1c7ca Fix tests related to caches, as per doctrine/cache 1.5.0 changes
Backports #1510
Fixes DDC-3908

dd47003641 removes the 'DoctrineNamespaceCacheKey[]' entry from the cache. Thus, all tests counting cache entries were off by one.
2015-09-19 10:44:47 +02:00
Benjamin Eberlei
8070b50150 Bump version to 2.5.2 2015-08-31 14:59:39 +02:00
Benjamin Eberlei
e6a83bedbe Release 2.5.1 2015-08-31 14:59:39 +02:00
Benjamin Eberlei
b6e5464b98 Fix version 2015-08-31 14:59:36 +02:00
Benjamin Eberlei
6366d190d7 [DCOM-293] Fix security misconfiguration vulnerability allowing local remote arbitrary code execution. 2015-08-31 14:58:12 +02:00
Bill Schaller
89eed31e79 Merge pull request #1463 from ehimen/paginate-order-by-subselect
Fixed issue when paginator orders by a subselect expression
Conflicts:
	tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
2015-08-04 14:31:08 -04:00
Marco Pivetta
4ca00f7a9d Merge branch 'hotfix/#1387-DDC-3699-do-not-merge-managed-uninitialized-entities-2.5' into 2.5
Close #1387
2015-07-15 21:52:41 +01:00
Marco Pivetta
6bc405455e DDC-3699 - #1387 - leveraging the OrmFunctionalTestCase API 2015-07-15 21:52:25 +01:00
Marco Pivetta
173729e560 DDC-3699 - #1387 - catching specific exceptions 2015-07-15 21:52:20 +01:00
Marco Pivetta
86abbb0e78 DDC-3699 - #1387 - simpifying tests, clarifying on test method names 2015-07-15 21:52:16 +01:00
Lenard Palko
69ef75ff2d Added test cases for both one-to-one and one-to-many cases. 2015-07-15 21:52:08 +01:00
Lenard Palko
c68edec0c2 Fix skipping properties if they are listed after a not loaded relation. 2015-07-15 21:51:55 +01:00
Marco Pivetta
f9bbd953a7 Merge branch 'hotfix/#1381-wakeup-reflection-with-embeddable-and-staticreflection-serialization-fix-2.5' into 2.5
Close #1381
2015-07-15 20:50:28 +01:00
Nico Vogelaar
9097014c3d Fixes ClassMetadata wakeupReflection with embeddable and StaticReflectionService 2015-07-15 20:50:05 +01:00
Marco Pivetta
12d178777a Merge branch 'hotfix/#1380-non-cache-persister-bug-2.5' into 2.5
Close #1380
2015-07-15 20:45:38 +01:00
Marco Pivetta
ed1c4de2b6 DDC-3683 - #1380 - reverting BC break, annotating correct types, cs fixes 2015-07-15 20:45:02 +01:00
Darien Hager
fff56c7f3f Remove runtime assertion 2015-07-15 20:44:55 +01:00
Darien Hager
97e90ddefc Clarify state-changes, replace array_key_exists() with isset() for speed 2015-07-15 20:44:50 +01:00
Darien Hager
d5adda954d Whitespace formatting tweaks 2015-07-15 20:44:39 +01:00
Darien Hager
c507b52f20 Remove now-superfluous EntityManager check 2015-07-15 20:44:33 +01:00
Darien Hager
08be905fc3 Refactor LoadClassMetadataEventArgs to ensure it contains an EntityManager 2015-07-15 20:44:24 +01:00
Darien Hager
d29cc3660f Change the test listener than layers on second-level-caching so that it is more conservative, only turning on caching-associations when it knows the target entity is cache-able. 2015-07-15 20:44:10 +01:00
Darien Hager
768c291cd1 Stumbled across a bug where signatures didn't match, but also the current persister-type didn't support getCacheRegion(). Unsure of exact mechanism, but clearly the constructor doesn't take the second argument anyway, may be old code. 2015-07-15 20:43:51 +01:00
Bill Schaller
10ed690d99 Backport Merge pull request #1430 from michael-lavaveshkul/master
"INSTANCE OF" example doesn't match description.
2015-06-18 10:41:56 -04:00
Benjamin Eberlei
e4e59d8064 Merge branch 'DDC-3756' into 2.5 2015-06-16 21:44:14 +02:00
Restless-ET
0e208f7538 [2.5][Bug] Fix ConvertDoctrine1Schema->getMetadata
This bug was introduced at #1205 while resolving #1200.
2015-06-16 21:43:54 +02:00
Guilherme Blanco
3e6c6af845 Merge pull request #1382 from holtkamp/patch-second-level-cache-association-hydration
Patch second level cache association hydration
2015-04-14 11:57:54 -04:00
Marco Pivetta
584345397b Merge branch 'hotfix/#1374-fix-ddc-767-test-php7-pg94-2.5' into 2.5 2015-04-06 04:23:17 +01:00
Matteo Beccati
786791b8fe Fix DDC767Test failing on php7 + pg94
The failure happens when running the full suite or even just:

phpunit tests/Doctrine/Tests/ORM/Functional/Ticket
2015-04-06 04:23:03 +01:00
Marco Pivetta
724dfa0de3 Merge branch 'hotfix/#1361-persistent-collection-collection-hint-fix' into 2.5 2015-04-05 01:30:32 +01:00
Marco Pivetta
39592ba59c Correcting ObjectHydrator logic: if an array is a default value for a collection-valued property, it should be cast to a Collection 2015-04-05 01:29:59 +01:00
Marco Pivetta
58a6013d15 Correcting static introspection issue in cache specific tests (null was being passed to a PersistentCollection) 2015-04-05 01:29:52 +01:00
Marco Pivetta
4580429616 Removing irrelevant tests (as per discussion with @guilhermeblanco and @stof 2015-04-05 01:29:42 +01:00
Marco Pivetta
6e563a313e a PersistentCollection should only allow another collection as a wrapped collection 2015-04-05 01:29:35 +01:00
Marco Pivetta
e8c9cb2f23 Reverting BC break: PersistentConnection#__construct() now accepts null|array|Collection again 2015-04-05 01:29:28 +01:00
Marco Pivetta
4792b4f974 FQCN reference (class was not imported correctly) 2015-04-05 01:29:19 +01:00
Marco Pivetta
c2f6b09ee0 PersistentCollection should still accept null and array as constructor argument, as it did before 2015-04-05 01:29:08 +01:00
Marco Pivetta
cb3179865b Minor docblock correction (discovered during testing) 2015-04-05 01:29:00 +01:00
Marco Pivetta
a1602bd91f Hydration of fetch-joined results fails when an entity has a default value of array for the collection property 2015-04-05 01:28:53 +01:00
Marco Pivetta
34696126e0 Merge branch 'hotfix/#1365-query-dql-function-test-determinism-2.5' into 2.5 2015-04-05 00:10:25 +01:00
Bill Schaller
aa4b2e59ce fix rare query test failures due to nondeterminism without order by clause 2015-04-05 00:10:11 +01:00
Marco Pivetta
2cd86deeb4 Merge branch 'hotfix/#1360-docs-fix-misleading-embeddable-documentation-prefix' into 2.5 2015-04-02 23:25:11 +01:00
Marco Pivetta
52288abf48 Merge branch 'docs/#1359-correcting-mapping-in-working-with-objects-reference' into 2.5 2015-04-02 21:56:03 +01:00
60 changed files with 935 additions and 95 deletions

View File

@@ -138,6 +138,10 @@ From now on, the resultset will look like this:
...
)
## Minor BC BREAK: added second parameter $indexBy in EntityRepository#createQueryBuilder method signature
Added way to access the underlying QueryBuilder#from() method's 'indexBy' parameter when using EntityRepository#createQueryBuilder()
# Upgrade to 2.4
## BC BREAK: Compatibility Bugfix in PersistentCollection#matching()

View File

@@ -20,10 +20,10 @@
"doctrine/instantiator": "~1.0.1",
"doctrine/common": ">=2.5-dev,<2.6-dev",
"doctrine/cache": "~1.4",
"symfony/console": "~2.5"
"symfony/console": "~2.5|~3.0"
},
"require-dev": {
"symfony/yaml": "~2.1",
"symfony/yaml": "~2.3|~3.0",
"phpunit/phpunit": "~4.0",
"satooshi/php-coveralls": "dev-master"
},

View File

@@ -601,5 +601,5 @@ Querying for the staffs without getting any technicians can be achieved by this
.. code-block:: php
<?php
$query = $em->createQuery("SELECT staff FROM MyProject\Model\Staff staff WHERE staff INSTANCE OF MyProject\Model\Staff");
$query = $em->createQuery("SELECT staff FROM MyProject\Model\Staff staff WHERE staff NOT INSTANCE OF MyProject\Model\Technician");
$staffs = $query->getResult();

View File

@@ -180,13 +180,7 @@ class DefaultCacheFactory implements CacheFactory
*/
public function buildCollectionHydrator(EntityManagerInterface $em, array $mapping)
{
/* @var $targetPersister \Doctrine\ORM\Cache\Persister\CachedPersister */
$targetPersister = $em->getUnitOfWork()->getEntityPersister($mapping['targetEntity']);
return new DefaultCollectionHydrator(
$em,
$targetPersister->getCacheRegion()
);
return new DefaultCollectionHydrator($em);
}
/**

View File

@@ -23,7 +23,7 @@ namespace Doctrine\ORM\Cache;
/**
* Defines a region that supports multi-get reading.
*
* With one method call we can get multipe items.
* With one method call we can get multiple items.
*
* @since 2.5
* @author Asmir Mustafic
@@ -31,7 +31,7 @@ namespace Doctrine\ORM\Cache;
interface MultiGetRegion
{
/**
* Get all items from the cache indentifed by $keys.
* Get all items from the cache identified by $keys.
* It returns NULL if some elements can not be found.
*
* @param CollectionCacheEntry $collection The collection of the items to be retrieved.

View File

@@ -57,8 +57,9 @@ class DefaultMultiGetRegion extends DefaultRegion
public function getMultiple(CollectionCacheEntry $collection)
{
$keysToRetrieve = array();
foreach ($collection->identifiers as $index => $key) {
$keysToRetrieve[$index] = $this->name . '_' . $key->hash;
$keysToRetrieve[$index] = $this->getCacheEntryKey($key);
}
$items = $this->cache->fetchMultiple($keysToRetrieve);
@@ -70,6 +71,7 @@ class DefaultMultiGetRegion extends DefaultRegion
foreach ($keysToRetrieve as $index => $key) {
$returnableItems[$index] = $items[$key];
}
return $returnableItems;
}
}

View File

@@ -36,6 +36,8 @@ use Doctrine\ORM\Cache\Region;
*/
class DefaultRegion implements Region
{
const REGION_KEY_SEPARATOR = '_';
/**
* @var CacheAdapter
*/
@@ -84,7 +86,7 @@ class DefaultRegion implements Region
*/
public function contains(CacheKey $key)
{
return $this->cache->contains($this->name . '_' . $key->hash);
return $this->cache->contains($this->getCacheEntryKey($key));
}
/**
@@ -92,7 +94,7 @@ class DefaultRegion implements Region
*/
public function get(CacheKey $key)
{
return $this->cache->fetch($this->name . '_' . $key->hash) ?: null;
return $this->cache->fetch($this->getCacheEntryKey($key)) ?: null;
}
/**
@@ -100,30 +102,29 @@ class DefaultRegion implements Region
*/
public function getMultiple(CollectionCacheEntry $collection)
{
$keysToRetrieve = array();
$result = array();
foreach ($collection->identifiers as $index => $key) {
$keysToRetrieve[$index] = $this->name . '_' . $key->hash;
}
foreach ($collection->identifiers as $key) {
$entryKey = $this->getCacheEntryKey($key);
$entryValue = $this->cache->fetch($entryKey);
$items = array_filter(
array_map([$this->cache, 'fetch'], $keysToRetrieve),
function ($retrieved) {
return false !== $retrieved;
if ($entryValue === false) {
return null;
}
);
if (count($items) !== count($keysToRetrieve)) {
return null;
$result[] = $entryValue;
}
$returnableItems = array();
return $result;
}
foreach ($keysToRetrieve as $index => $key) {
$returnableItems[$index] = $items[$key];
}
return $returnableItems;
/**
* @param CacheKey $key
* @return string
*/
protected function getCacheEntryKey(CacheKey $key)
{
return $this->name . self::REGION_KEY_SEPARATOR . $key->hash;
}
/**
@@ -131,7 +132,7 @@ class DefaultRegion implements Region
*/
public function put(CacheKey $key, CacheEntry $entry, Lock $lock = null)
{
return $this->cache->save($this->name . '_' . $key->hash, $entry, $this->lifetime);
return $this->cache->save($this->getCacheEntryKey($key), $entry, $this->lifetime);
}
/**
@@ -139,7 +140,7 @@ class DefaultRegion implements Region
*/
public function evict(CacheKey $key)
{
return $this->cache->delete($this->name . '_' . $key->hash);
return $this->cache->delete($this->getCacheEntryKey($key));
}
/**

View File

@@ -61,7 +61,7 @@ class FileLockRegion implements ConcurrentRegion
*/
public function __construct(Region $region, $directory, $lockLifetime)
{
if ( ! is_dir($directory) && ! @mkdir($directory, 0777, true)) {
if ( ! is_dir($directory) && ! @mkdir($directory, 0775, true)) {
throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $directory));
}
@@ -242,6 +242,7 @@ class FileLockRegion implements ConcurrentRegion
if ( ! @file_put_contents($filename, $lock->value, LOCK_EX)) {
return null;
}
chmod($filename, 0664);
return $lock;
}

View File

@@ -26,6 +26,11 @@ use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClas
*
* @author Jonathan H. Wage <jonwage@gmail.com>
* @since 2.0
*
* Note: method annotations are used instead of method overrides (due to BC policy)
*
* @method __construct(\Doctrine\ORM\Mapping\ClassMetadata $classMetadata, \Doctrine\ORM\EntityManager $objectManager)
* @method \Doctrine\ORM\EntityManager getClassMetadata()
*/
class LoadClassMetadataEventArgs extends BaseLoadClassMetadataEventArgs
{

View File

@@ -189,8 +189,8 @@ class ObjectHydrator extends AbstractHydrator
$relation = $class->associationMappings[$fieldName];
$value = $class->reflFields[$fieldName]->getValue($entity);
if ($value === null) {
$value = new ArrayCollection;
if ($value === null || is_array($value)) {
$value = new ArrayCollection((array) $value);
}
if ( ! $value instanceof PersistentCollection) {

View File

@@ -945,7 +945,7 @@ class ClassMetadataInfo implements ClassMetadata
}
foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declaredField'])) {
if (isset($mapping['declaredField']) && isset($parentReflFields[$mapping['declaredField']])) {
$this->reflFields[$field] = new ReflectionEmbeddedProperty(
$parentReflFields[$mapping['declaredField']],
$reflService->getAccessibleProperty($mapping['originalClass'], $mapping['originalField']),

View File

@@ -514,9 +514,8 @@ class YamlDriver extends FileDriver
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
if (isset($joinTableElement['inverseJoinColumns'])) {
@@ -524,9 +523,8 @@ class YamlDriver extends FileDriver
if ( ! isset($joinColumnElement['name'])) {
$joinColumnElement['name'] = $joinColumnName;
}
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumnElement);
}
$mapping['joinTable'] = $joinTable;

View File

@@ -101,13 +101,13 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
/**
* Creates a new persistent collection.
*
* @param EntityManagerInterface $em The EntityManager the collection will be associated with.
* @param ClassMetadata $class The class descriptor of the entity type of this collection.
* @param Collection $coll The collection elements.
* @param EntityManagerInterface $em The EntityManager the collection will be associated with.
* @param ClassMetadata $class The class descriptor of the entity type of this collection.
* @param Collection $collection The collection elements.
*/
public function __construct(EntityManagerInterface $em, $class, $coll)
public function __construct(EntityManagerInterface $em, $class, Collection $collection)
{
$this->collection = $coll;
$this->collection = $collection;
$this->em = $em;
$this->typeClass = $class;
$this->initialized = true;

View File

@@ -347,7 +347,7 @@ class ResultSetMapping
* @param string $class The class name of the joined entity.
* @param string $alias The unique alias to use for the joined entity.
* @param string $parentAlias The alias of the entity result that is the parent of this joined result.
* @param object $relation The association field that connects the parent entity result
* @param string $relation The association field that connects the parent entity result
* with the joined entity result.
*
* @return ResultSetMapping This ResultSetMapping instance.

View File

@@ -438,8 +438,8 @@ class ResultSetMappingBuilder extends ResultSetMapping
$sql .= $class->fieldMappings[$this->fieldMappings[$columnName]]['columnName'];
} else if (isset($this->metaMappings[$columnName])) {
$sql .= $this->metaMappings[$columnName];
} else if (isset($this->discriminatorColumn[$columnName])) {
$sql .= $this->discriminatorColumn[$columnName];
} else if (isset($this->discriminatorColumns[$dqlAlias])) {
$sql .= $this->discriminatorColumns[$dqlAlias];
}
$sql .= " AS " . $columnName;

View File

@@ -1093,6 +1093,10 @@ class SqlWalker implements TreeWalker
$this->orderedColumnsMap[$sql] = $type;
if ($expr instanceof AST\Subselect) {
return '(' . $sql . ') ' . $type;
}
return $sql . ' ' . $type;
}

View File

@@ -137,7 +137,7 @@ EOT
// Process destination directory
if ( ! is_dir($destPath = $input->getArgument('dest-path'))) {
mkdir($destPath, 0777, true);
mkdir($destPath, 0775, true);
}
$destPath = realpath($destPath);

View File

@@ -79,7 +79,7 @@ EOT
}
if ( ! is_dir($destPath)) {
mkdir($destPath, 0777, true);
mkdir($destPath, 0775, true);
}
$destPath = realpath($destPath);

View File

@@ -80,7 +80,7 @@ class ConvertDoctrine1Schema
$schema = array_merge($schema, (array) Yaml::parse(file_get_contents($file)));
}
} else {
$schema = array_merge($schema, (array) Yaml::parse(file_get_contents($file)));
$schema = array_merge($schema, (array) Yaml::parse(file_get_contents($path)));
}
}

View File

@@ -364,7 +364,7 @@ public function __construct(<params>)
$dir = dirname($path);
if ( ! is_dir($dir)) {
mkdir($dir, 0777, true);
mkdir($dir, 0775, true);
}
$this->isNew = !file_exists($path) || (file_exists($path) && $this->regenerateEntityIfExists);
@@ -389,6 +389,7 @@ public function __construct(<params>)
} elseif ( ! $this->isNew && $this->updateEntityIfExists) {
file_put_contents($path, $this->generateUpdatedEntityClass($metadata, $path));
}
chmod($path, 0664);
}
/**

View File

@@ -147,11 +147,12 @@ class <className> extends <repositoryName>
$dir = dirname($path);
if ( ! is_dir($dir)) {
mkdir($dir, 0777, true);
mkdir($dir, 0775, true);
}
if ( ! file_exists($path)) {
file_put_contents($path, $code);
chmod($path, 0664);
}
}

View File

@@ -130,7 +130,7 @@ abstract class AbstractExporter
public function export()
{
if ( ! is_dir($this->_outputDir)) {
mkdir($this->_outputDir, 0777, true);
mkdir($this->_outputDir, 0775, true);
}
foreach ($this->_metadata as $metadata) {
@@ -139,12 +139,13 @@ abstract class AbstractExporter
$path = $this->_generateOutputPath($metadata);
$dir = dirname($path);
if ( ! is_dir($dir)) {
mkdir($dir, 0777, true);
mkdir($dir, 0775, true);
}
if (file_exists($path) && !$this->_overwriteExistingFiles) {
throw ExportException::attemptOverwriteExistingFile($path);
}
file_put_contents($path, $output);
chmod($path, 0664);
}
}
}

View File

@@ -438,7 +438,10 @@ class LimitSubqueryOutputWalker extends SqlWalker
// Field was declared in a parent class, so we need to get the proper SQL table alias
// for the joined parent table.
$otherClassMetadata = $this->em->getClassMetadata($fieldMapping['declared']);
$sqlTableAliasForFieldAlias = $this->getSQLTableAlias($otherClassMetadata->getTableName(), $dqlAliasForFieldAlias);
if (!$otherClassMetadata->isMappedSuperclass) {
$sqlTableAliasForFieldAlias = $this->getSQLTableAlias($otherClassMetadata->getTableName(), $dqlAliasForFieldAlias);
}
}
// Compose search/replace patterns

View File

@@ -21,6 +21,7 @@ namespace Doctrine\ORM\Tools;
use Doctrine\ORM\ORMException;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
@@ -274,6 +275,15 @@ class SchemaTool
if (isset($class->table['uniqueConstraints'])) {
foreach ($class->table['uniqueConstraints'] as $indexName => $indexData) {
$uniqIndex = new Index($indexName, $indexData['columns'], true, false, [], isset($indexData['options']) ? $indexData['options'] : []);
foreach ($table->getIndexes() as $tableIndexName => $tableIndex) {
if ($tableIndex->isFullfilledBy($uniqIndex)) {
$table->dropIndex($tableIndexName);
break;
}
}
$table->addUniqueIndex($indexData['columns'], is_numeric($indexName) ? null : $indexName, isset($indexData['options']) ? $indexData['options'] : array());
}
}

View File

@@ -3378,7 +3378,7 @@ class UnitOfWork implements PropertyChangedListener
} else {
if ($other instanceof Proxy && !$other->__isInitialized()) {
// do not merge fields marked lazy that have not been fetched.
return;
continue;
}
if ( ! $assoc2['isCascadeMerge']) {
@@ -3406,7 +3406,7 @@ class UnitOfWork implements PropertyChangedListener
if ($mergeCol instanceof PersistentCollection && ! $mergeCol->isInitialized()) {
// do not merge fields marked lazy that have not been fetched.
// keep the lazy persistent collection of the managed copy.
return;
continue;
}
$managedCol = $prop->getValue($managedCopy);

View File

@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
const VERSION = '2.6.0-DEV';
const VERSION = '2.5.2';
/**
* Compares a Doctrine version with the current one.

View File

@@ -3,33 +3,87 @@
namespace Doctrine\Tests\EventListener;
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
class CacheMetadataListener
{
/**
* Tracks which entities we have already forced caching enabled on. This is
* important to avoid some potential infinite-recursion issues.
*
* Key is the name of the entity, payload is unimportant.
*
* @var array
*/
protected $enabledItems = array();
/**
* @param \Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs $event
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $event)
{
$metadata = $event->getClassMetadata();
$cache = array(
'usage' => ClassMetadata::CACHE_USAGE_NONSTRICT_READ_WRITE
);
$em = $event->getObjectManager();
/** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata */
if (strstr($metadata->name, 'Doctrine\Tests\Models\Cache')) {
return;
}
$this->enableCaching($metadata, $em);
}
/**
* @param ClassMetadata $metadata
*
* @return bool
*/
private function isVisited(ClassMetaData $metadata)
{
return isset($this->enabledItems[$metadata->getName()]);
}
/**
* @param ClassMetadata $metadata
*/
private function recordVisit(ClassMetaData $metadata)
{
$this->enabledItems[$metadata->getName()] = true;
}
/**
* @param ClassMetadata $metadata
* @param EntityManager $em
*/
protected function enableCaching(ClassMetadata $metadata, EntityManager $em)
{
if ($this->isVisited($metadata)) {
return; // Already handled in the past
}
$cache = array(
'usage' => ClassMetadata::CACHE_USAGE_NONSTRICT_READ_WRITE
);
if ($metadata->isVersioned) {
return;
}
$metadata->enableCache($cache);
$this->recordVisit($metadata);
// only enable association-caching when the target has already been
// given caching settings
foreach ($metadata->associationMappings as $mapping) {
$metadata->enableAssociationCache($mapping['fieldName'], $cache);
$targetMeta = $em->getClassMetadata($mapping['targetEntity']);
$this->enableCaching($targetMeta, $em);
if ($this->isVisited($targetMeta)) {
$metadata->enableAssociationCache($mapping['fieldName'], $cache);
}
}
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace Doctrine\Tests\Models\DDC3699;
/** @Entity @Table(name="ddc3699_child") */
class DDC3699Child extends DDC3699Parent
{
const CLASSNAME = __CLASS__;
/** @Id @Column(type="integer") */
public $id;
/** @Column(type="string") */
public $childField;
/** @OneToOne(targetEntity="DDC3699RelationOne", inversedBy="child") */
public $oneRelation;
/** @OneToMany(targetEntity="DDC3699RelationMany", mappedBy="child") */
public $relations;
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Models\DDC3699;
/** @MappedSuperclass */
abstract class DDC3699Parent
{
const CLASSNAME = __CLASS__;
/** @Column(type="string") */
public $parentField;
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Doctrine\Tests\Models\DDC3699;
/**
* @Entity
* @Table(name="ddc3699_relation_many")
*/
class DDC3699RelationMany
{
const CLASSNAME = __CLASS__;
/** @Id @Column(type="integer") */
public $id;
/** @ManyToOne(targetEntity="DDC3699Child", inversedBy="relations") */
public $child;
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Doctrine\Tests\Models\DDC3699;
/**
* @Entity
* @Table(name="ddc3699_relation_one")
*/
class DDC3699RelationOne
{
const CLASSNAME = __CLASS__;
/** @Id @Column(type="integer") */
public $id;
/** @OneToOne(targetEntity="DDC3699Child", mappedBy="oneRelation") */
public $child;
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* @author Marc Pantel <pantel.m@gmail.com>
*/
namespace Doctrine\Tests\Models\DDC3711;
use Doctrine\Common\Collections\ArrayCollection;
class DDC3711EntityA
{
/**
* @var int
*/
private $id1;
/**
* @var int
*/
private $id2;
/**
* @var ArrayCollection
*/
private $entityB;
/**
* @return mixed
*/
public function getId1()
{
return $this->id1;
}
/**
* @param mixed $id1
*/
public function setId1($id1)
{
$this->id1 = $id1;
}
/**
* @return mixed
*/
public function getId2()
{
return $this->id2;
}
/**
* @param mixed $id2
*/
public function setId2($id2)
{
$this->id2 = $id2;
}
/**
* @return ArrayCollection
*/
public function getEntityB()
{
return $this->entityB;
}
/**
* @param ArrayCollection $entityB
*
* @return DDC3711EntityA
*/
public function addEntityB($entityB)
{
$this->entityB[] = $entityB;
return $this;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* @author Marc Pantel <pantel.m@gmail.com>
*/
namespace Doctrine\Tests\Models\DDC3711;
use Doctrine\Common\Collections\ArrayCollection;
class DDC3711EntityB
{
/**
* @var int
*/
private $id1;
/**
* @var int
*/
private $id2;
/**
* @var ArrayCollection
*/
private $entityA;
/**
* @return int
*/
public function getId1()
{
return $this->id1;
}
/**
* @param int $id1
*/
public function setId1($id1)
{
$this->id1 = $id1;
}
/**
* @return int
*/
public function getId2()
{
return $this->id2;
}
/**
* @param int $id2
*/
public function setId2($id2)
{
$this->id2 = $id2;
}
/**
* @return ArrayCollection
*/
public function getEntityA()
{
return $this->entityA;
}
/**
* @param ArrayCollection $entityA
*/
public function addEntityA($entityA)
{
$this->entityA[] = $entityA;
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Doctrine\Tests\Models\DDC3899;
/**
* @Entity
* @Table(name="dc3899_contracts")
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({
* "fix" = "DDC3899FixContract",
* "flexible" = "DDC3899FlexContract"
* })
*/
abstract class DDC3899Contract
{
/** @Id @Column(type="integer") */
public $id;
/** @Column(type="boolean") */
public $completed = false;
/** @ManyToOne(targetEntity="DDC3899User", inversedBy="contract") */
public $user;
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Models\DDC3899;
/**
* @Entity
*/
class DDC3899FixContract extends DDC3899Contract
{
/** @column(type="integer") */
public $fixPrice = 0;
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Models\DDC3899;
/**
* @Entity
*/
class DDC3899FlexContract extends DDC3899Contract
{
/** @column(type="integer") */
public $hoursWorked = 0;
/** @column(type="integer") */
public $pricePerHour = 0;
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Doctrine\Tests\Models\DDC3899;
/**
* @Entity
* @Table(name="dc3899_users")
*/
class DDC3899User
{
/** @Id @Column(type="integer") */
public $id;
/** @OneToMany(targetEntity="DDC3899Contract", mappedBy="user") */
public $contracts;
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Doctrine\Tests\Models\Hydration;
/** @Entity */
class EntityWithArrayDefaultArrayValueM2M
{
const CLASSNAME = __CLASS__;
/** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
public $id;
/** @ManyToMany(targetEntity=SimpleEntity::class) */
public $collection = [];
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Models\Hydration;
/** @Entity */
class SimpleEntity
{
const CLASSNAME = __CLASS__;
/** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
public $id;
}

View File

@@ -3,10 +3,12 @@
namespace Doctrine\Tests\ORM\Cache;
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\ORM\Cache\CollectionCacheEntry;
use Doctrine\ORM\Cache\Region\DefaultRegion;
use Doctrine\Tests\Mocks\CacheEntryMock;
use Doctrine\Tests\Mocks\CacheKeyMock;
/**
* @group DDC-2183
*/
@@ -72,4 +74,27 @@ class DefaultRegionTest extends AbstractRegionTest
$region->evictAll();
}
public function testGetMulti()
{
$key1 = new CacheKeyMock('key.1');
$value1 = new CacheEntryMock(array('id' => 1, 'name' => 'bar'));
$key2 = new CacheKeyMock('key.2');
$value2 = new CacheEntryMock(array('id' => 2, 'name' => 'bar'));
$this->assertFalse($this->region->contains($key1));
$this->assertFalse($this->region->contains($key2));
$this->region->put($key1, $value1);
$this->region->put($key2, $value2);
$this->assertTrue($this->region->contains($key1));
$this->assertTrue($this->region->contains($key2));
$actual = $this->region->getMultiple(new CollectionCacheEntry(array($key1, $key2)));
$this->assertEquals($value1, $actual[0]);
$this->assertEquals($value2, $actual[1]);
}
}

View File

@@ -22,10 +22,10 @@ class MultiGetRegionTest extends AbstractRegionTest
public function testGetMulti()
{
$key1 = new CacheKeyMock('key.1');
$value1 = new CacheEntryMock(array('id'=>1, 'name' => 'bar'));
$value1 = new CacheEntryMock(array('id' => 1, 'name' => 'bar'));
$key2 = new CacheKeyMock('key.2');
$value2 = new CacheEntryMock(array('id'=>2, 'name' => 'bar'));
$value2 = new CacheEntryMock(array('id' => 2, 'name' => 'bar'));
$this->assertFalse($this->region->contains($key1));
$this->assertFalse($this->region->contains($key2));
@@ -33,6 +33,9 @@ class MultiGetRegionTest extends AbstractRegionTest
$this->region->put($key1, $value1);
$this->region->put($key2, $value2);
$this->assertTrue($this->region->contains($key1));
$this->assertTrue($this->region->contains($key2));
$actual = $this->region->getMultiple(new CollectionCacheEntry(array($key1, $key2)));
$this->assertEquals($value1, $actual[0]);

View File

@@ -11,6 +11,7 @@ use Doctrine\ORM\Persisters\Entity\EntityPersister;
use Doctrine\Tests\Models\Cache\Country;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\PersistentCollection;
@@ -390,7 +391,7 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
{
$mapping = $this->em->getClassMetadata('Doctrine\Tests\Models\Cache\Country');
$assoc = array('type' => 1);
$coll = new PersistentCollection($this->em, $mapping, null);
$coll = new PersistentCollection($this->em, $mapping, new ArrayCollection());
$persister = $this->createPersisterDefault();
$entity = new Country("Foo");
@@ -406,7 +407,7 @@ abstract class AbstractEntityPersisterTest extends OrmTestCase
{
$mapping = $this->em->getClassMetadata('Doctrine\Tests\Models\Cache\Country');
$assoc = array('type' => 1);
$coll = new PersistentCollection($this->em, $mapping, null);
$coll = new PersistentCollection($this->em, $mapping, new ArrayCollection());
$persister = $this->createPersisterDefault();
$entity = new Country("Foo");

View File

@@ -791,4 +791,20 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertSQLEquals('u.id AS id0, u.status AS status1, u.username AS username2, u.name AS name3, u.email_id AS email_id4', (string)$rsm);
}
/**
* @group DDC-3899
*/
public function testGenerateSelectClauseWithDiscriminatorColumn()
{
$rsm = new ResultSetMappingBuilder($this->_em, ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT);
$rsm->addEntityResult('Doctrine\Tests\Models\DDC3899\DDC3899User', 'u');
$rsm->addJoinedEntityResult('Doctrine\Tests\Models\DDC3899\DDC3899FixContract', 'c', 'u', 'contracts');
$rsm->addFieldResult('u', $this->platform->getSQLResultCasing('id'), 'id');
$rsm->setDiscriminatorColumn('c', $this->platform->getSQLResultCasing('discr'));
$selectClause = $rsm->generateSelectClause(array('u' => 'u1', 'c' => 'c1'));
$this->assertSQLEquals('u1.id as id, c1.discr as discr', $selectClause);
}
}

View File

@@ -669,6 +669,28 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertCount(9, $paginator);
}
/**
* @dataProvider useOutputWalkersAndFetchJoinCollection
*/
public function testPaginationWithSubSelectOrderByExpression($useOutputWalker, $fetchJoinCollection)
{
$query = $this->_em->createQuery(
"SELECT u,
(
SELECT MAX(a.version)
FROM Doctrine\\Tests\\Models\\CMS\\CmsArticle a
WHERE a.user = u
) AS HIDDEN max_version
FROM Doctrine\\Tests\\Models\\CMS\\CmsUser u
ORDER BY max_version DESC"
);
$paginator = new Paginator($query, $fetchJoinCollection);
$paginator->setUseOutputWalkers($useOutputWalker);
$this->assertCount(9, $paginator->getIterator());
}
public function populate()
{
$groups = array();

View File

@@ -45,12 +45,12 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
$query->setQueryCacheDriver($cache);
$query->getResult();
$this->assertEquals(2, $this->getCacheSize($cache));
$this->assertEquals(1, $this->getCacheSize($cache));
$query->setHint('foo', 'bar');
$query->getResult();
$this->assertEquals(3, $this->getCacheSize($cache));
$this->assertEquals(2, $this->getCacheSize($cache));
return $query;
}
@@ -112,7 +112,7 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
$users = $query->getResult();
$data = $this->cacheDataReflection->getValue($cache);
$this->assertEquals(2, count($data));
$this->assertEquals(1, count($data));
$this->assertInstanceOf('Doctrine\ORM\Query\ParserResult', array_pop($data));
}

View File

@@ -61,7 +61,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionAbs()
{
$result = $this->_em->createQuery('SELECT m, ABS(m.salary * -1) AS abs FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, ABS(m.salary * -1) AS abs FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getResult();
$this->assertEquals(4, count($result));
@@ -73,7 +73,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionConcat()
{
$arg = $this->_em->createQuery('SELECT m, CONCAT(m.name, m.department) AS namedep FROM Doctrine\Tests\Models\Company\CompanyManager m')
$arg = $this->_em->createQuery('SELECT m, CONCAT(m.name, m.department) AS namedep FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getArrayResult();
$this->assertEquals(4, count($arg));
@@ -85,7 +85,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionLength()
{
$result = $this->_em->createQuery('SELECT m, LENGTH(CONCAT(m.name, m.department)) AS namedeplength FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, LENGTH(CONCAT(m.name, m.department)) AS namedeplength FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getArrayResult();
$this->assertEquals(4, count($result));
@@ -98,7 +98,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionLocate()
{
$dql = "SELECT m, LOCATE('e', LOWER(m.name)) AS loc, LOCATE('e', LOWER(m.name), 7) AS loc2 ".
"FROM Doctrine\Tests\Models\Company\CompanyManager m";
"FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC";
$result = $this->_em->createQuery($dql)
->getArrayResult();
@@ -116,7 +116,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionLower()
{
$result = $this->_em->createQuery("SELECT m, LOWER(m.name) AS lowername FROM Doctrine\Tests\Models\Company\CompanyManager m")
$result = $this->_em->createQuery("SELECT m, LOWER(m.name) AS lowername FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC")
->getArrayResult();
$this->assertEquals(4, count($result));
@@ -128,7 +128,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionMod()
{
$result = $this->_em->createQuery("SELECT m, MOD(m.salary, 3500) AS amod FROM Doctrine\Tests\Models\Company\CompanyManager m")
$result = $this->_em->createQuery("SELECT m, MOD(m.salary, 3500) AS amod FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC")
->getArrayResult();
$this->assertEquals(4, count($result));
@@ -140,7 +140,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionSqrt()
{
$result = $this->_em->createQuery("SELECT m, SQRT(m.salary) AS sqrtsalary FROM Doctrine\Tests\Models\Company\CompanyManager m")
$result = $this->_em->createQuery("SELECT m, SQRT(m.salary) AS sqrtsalary FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC")
->getArrayResult();
$this->assertEquals(4, count($result));
@@ -152,7 +152,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFunctionUpper()
{
$result = $this->_em->createQuery("SELECT m, UPPER(m.name) AS uppername FROM Doctrine\Tests\Models\Company\CompanyManager m")
$result = $this->_em->createQuery("SELECT m, UPPER(m.name) AS uppername FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC")
->getArrayResult();
$this->assertEquals(4, count($result));
@@ -186,7 +186,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
$dql = "SELECT m, TRIM(TRAILING '.' FROM m.name) AS str1, ".
" TRIM(LEADING '.' FROM m.name) AS str2, TRIM(CONCAT(' ', CONCAT(m.name, ' '))) AS str3 ".
"FROM Doctrine\Tests\Models\Company\CompanyManager m";
"FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC";
$result = $this->_em->createQuery($dql)->getArrayResult();
@@ -207,7 +207,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testOperatorAdd()
{
$result = $this->_em->createQuery('SELECT m, m.salary+2500 AS add FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, m.salary+2500 AS add FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getResult();
$this->assertEquals(4, count($result));
@@ -219,7 +219,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testOperatorSub()
{
$result = $this->_em->createQuery('SELECT m, m.salary-2500 AS sub FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, m.salary-2500 AS sub FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getResult();
$this->assertEquals(4, count($result));
@@ -231,7 +231,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testOperatorMultiply()
{
$result = $this->_em->createQuery('SELECT m, m.salary*2 AS op FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, m.salary*2 AS op FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getResult();
$this->assertEquals(4, count($result));
@@ -246,7 +246,7 @@ class QueryDqlFunctionTest extends \Doctrine\Tests\OrmFunctionalTestCase
*/
public function testOperatorDiv()
{
$result = $this->_em->createQuery('SELECT m, (m.salary/0.5) AS op FROM Doctrine\Tests\Models\Company\CompanyManager m')
$result = $this->_em->createQuery('SELECT m, (m.salary/0.5) AS op FROM Doctrine\Tests\Models\Company\CompanyManager m ORDER BY m.salary ASC')
->getResult();
$this->assertEquals(4, count($result));

View File

@@ -141,7 +141,7 @@ class ResultCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, $this->getCacheSize($cache));
$query->getResult();
$this->assertEquals(2, $this->getCacheSize($cache));
$this->assertEquals(1, $this->getCacheSize($cache));
return $query;
}

View File

@@ -343,18 +343,18 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
$query->setQueryCacheDriver($cache);
$query->getResult();
$this->assertEquals(2, sizeof($cacheDataReflection->getValue($cache)));
$this->assertEquals(1, sizeof($cacheDataReflection->getValue($cache)));
$conf = $this->_em->getConfiguration();
$conf->addFilter("locale", "\Doctrine\Tests\ORM\Functional\MyLocaleFilter");
$this->_em->getFilters()->enable("locale");
$query->getResult();
$this->assertEquals(3, sizeof($cacheDataReflection->getValue($cache)));
$this->assertEquals(2, sizeof($cacheDataReflection->getValue($cache)));
// Another time doesn't add another cache entry
$query->getResult();
$this->assertEquals(3, sizeof($cacheDataReflection->getValue($cache)));
$this->assertEquals(2, sizeof($cacheDataReflection->getValue($cache)));
}
public function testQueryGeneration_DependsOnFilters()

View File

@@ -0,0 +1,104 @@
<?php
use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Tests\Models\DDC3699\DDC3699Parent;
use Doctrine\Tests\Models\DDC3699\DDC3699RelationOne;
use Doctrine\Tests\Models\DDC3699\DDC3699RelationMany;
use Doctrine\Tests\Models\DDC3699\DDC3699Child;
/**
* @group DDC-3699
*/
class DDC3597Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('ddc3699');
parent::setUp();
}
/**
* @group DDC-3699
*/
public function testMergingParentClassFieldsDoesNotStopMergingScalarFieldsForToOneUninitializedAssociations()
{
$id = 1;
$child = new DDC3699Child();
$child->id = $id;
$child->childField = 'childValue';
$child->parentField = 'parentValue';
$relation = new DDC3699RelationOne();
$relation->id = $id;
$relation->child = $child ;
$child->oneRelation = $relation;
$this->_em->persist($relation);
$this->_em->persist($child);
$this->_em->flush();
$this->_em->clear();
// fixtures loaded
/* @var $unManagedChild DDC3699Child */
$unManagedChild = $this->_em->find(DDC3699Child::CLASSNAME, $id);
$this->_em->detach($unManagedChild);
// make it managed again
$this->_em->find(DDC3699Child::CLASSNAME, $id);
$unManagedChild->childField = 'modifiedChildValue';
$unManagedChild->parentField = 'modifiedParentValue';
/* @var $mergedChild DDC3699Child */
$mergedChild = $this->_em->merge($unManagedChild);
$this->assertSame($mergedChild->childField, 'modifiedChildValue');
$this->assertSame($mergedChild->parentField, 'modifiedParentValue');
}
/**
* @group DDC-3699
*/
public function testMergingParentClassFieldsDoesNotStopMergingScalarFieldsForToManyUninitializedAssociations()
{
$id = 2;
$child = new DDC3699Child();
$child->id = $id;
$child->childField = 'childValue';
$child->parentField = 'parentValue';
$relation = new DDC3699RelationMany();
$relation->id = $id;
$relation->child = $child ;
$child->relations[] = $relation;
$this->_em->persist($relation);
$this->_em->persist($child);
$this->_em->flush();
$this->_em->clear();
/* @var $unmanagedChild DDC3699Child */
$unmanagedChild = $this->_em->find(DDC3699Child::CLASSNAME, $id);
$this->_em->detach($unmanagedChild);
// make it managed again
$this->_em->find(DDC3699Child::CLASSNAME, $id);
$unmanagedChild->childField = 'modifiedChildValue';
$unmanagedChild->parentField = 'modifiedParentValue';
/* @var $mergedChild DDC3699Child */
$mergedChild = $this->_em->merge($unmanagedChild);
$this->assertSame($mergedChild->childField, 'modifiedChildValue');
$this->assertSame($mergedChild->parentField, 'modifiedParentValue');
}
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* @author Marc Pantel <pantel.m@gmail.com>
*/
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Tests\ORM\Mapping\YamlMappingDriverTest;
class DDC3711Test extends YamlMappingDriverTest
{
public function testCompositeKeyForJoinTableInManyToManyCreation()
{
$yamlDriver = $this->_loadDriver();
$em = $this->_getTestEntityManager();
$em->getConfiguration()->setMetadataDriverImpl($yamlDriver);
$factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
$factory->setEntityManager($em);
$entityA = new ClassMetadata('Doctrine\Tests\Models\DDC3711\DDC3711EntityA');
$entityA = $factory->getMetadataFor('Doctrine\Tests\Models\DDC3711\DDC3711EntityA');
$this->assertEquals(array('link_a_id1' => "id1", 'link_a_id2' => "id2"), $entityA->associationMappings['entityB']['relationToSourceKeyColumns']);
$this->assertEquals(array('link_b_id1' => "id1", 'link_b_id2' => "id2"), $entityA->associationMappings['entityB']['relationToTargetKeyColumns']);
}
}

View File

@@ -49,7 +49,7 @@ class DDC767Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNotNull($pUser, "User not retrieved from database.");
$groups = array(2, 3);
$groups = array($group2->id, $group3->id);
try {
$this->_em->beginTransaction();

View File

@@ -8,6 +8,8 @@ use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\ORM\Mapping\AssociationMapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query;
use Doctrine\Tests\Models\Hydration\EntityWithArrayDefaultArrayValueM2M;
use Doctrine\Tests\Models\Hydration\SimpleEntity;
use Doctrine\Tests\Models\CMS\CmsUser;
@@ -1956,4 +1958,29 @@ class ObjectHydratorTest extends HydrationTestCase
$hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
$hydrator->hydrateAll($stmt, $rsm);
}
public function testFetchJoinCollectionValuedAssociationWithDefaultArrayValue()
{
$rsm = new ResultSetMapping;
$rsm->addEntityResult(EntityWithArrayDefaultArrayValueM2M::CLASSNAME, 'e1', null);
$rsm->addJoinedEntityResult(SimpleEntity::CLASSNAME, 'e2', 'e1', 'collection');
$rsm->addFieldResult('e1', 'a1__id', 'id');
$rsm->addFieldResult('e2', 'e2__id', 'id');
$result = (new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em))
->hydrateAll(
new HydratorMockStatement([[
'a1__id' => '1',
'e2__id' => '1',
]]),
$rsm
);
$this->assertCount(1, $result);
$this->assertInstanceOf(EntityWithArrayDefaultArrayValueM2M::CLASSNAME, $result[0]);
$this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $result[0]->collection);
$this->assertCount(1, $result[0]->collection);
$this->assertInstanceOf(SimpleEntity::CLASSNAME, $result[0]->collection[0]);
}
}

View File

@@ -3,6 +3,7 @@
namespace Doctrine\Tests\ORM\Mapping;
use Doctrine\Common\Persistence\Mapping\RuntimeReflectionService;
use Doctrine\Common\Persistence\Mapping\StaticReflectionService;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
@@ -1125,6 +1126,30 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertInstanceOf(__NAMESPACE__ . '\\MyArrayObjectEntity', $classMetadata->newInstance());
}
public function testWakeupReflectionWithEmbeddableAndStaticReflectionService()
{
$classMetadata = new ClassMetadata('Doctrine\Tests\ORM\Mapping\TestEntity1');
$classMetadata->mapEmbedded(array(
'fieldName' => 'test',
'class' => 'Doctrine\Tests\ORM\Mapping\TestEntity1',
'columnPrefix' => false,
));
$field = array(
'fieldName' => 'test.embeddedProperty',
'type' => 'string',
'originalClass' => 'Doctrine\Tests\ORM\Mapping\TestEntity1',
'declaredField' => 'test',
'originalField' => 'embeddedProperty'
);
$classMetadata->mapField($field);
$classMetadata->wakeupReflection(new StaticReflectionService());
$this->assertEquals(array('test' => null, 'test.embeddedProperty' => null), $classMetadata->getReflectionProperties());
}
}
/**

View File

@@ -0,0 +1,23 @@
Doctrine\Tests\Models\DDC3711\DDC3711EntityA:
type: entity
table: ddc3711.entityA
id:
id1:
type: int
id2:
type: int
manyToMany:
entityB:
targetEntity: Doctrine\Tests\Models\DDC3711\DDC3711EntityB
joinTable:
name: link
joinColumns:
link_a_id1:
referencedColumnName: id1
link_a_id2:
referencedColumnName: id2
inverseJoinColumns:
link_b_id1:
referencedColumnName: id1
link_b_id2:
referencedColumnName: id2

View File

@@ -0,0 +1,8 @@
Doctrine\Tests\Models\DDC3711\DDC3711EntityB:
type: entity
table: ddc3711.entityB
id:
id1:
type: int
id2:
type: int

View File

@@ -3,8 +3,10 @@
namespace Doctrine\Tests\ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\PersistentCollection;
use Doctrine\Tests\Mocks\ConnectionMock;
use Doctrine\Tests\Mocks\DriverMock;
use Doctrine\Tests\Mocks\EntityManagerMock;
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
use Doctrine\Tests\OrmTestCase;
@@ -21,15 +23,16 @@ class PersistentCollectionTest extends OrmTestCase
*/
protected $collection;
private $_connectionMock;
/**
* @var \Doctrine\ORM\EntityManagerInterface
*/
private $_emMock;
protected function setUp()
{
parent::setUp();
// SUT
$this->_connectionMock = new ConnectionMock(array(), new \Doctrine\Tests\Mocks\DriverMock());
$this->_emMock = EntityManagerMock::create($this->_connectionMock);
$this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock()));
}
/**

View File

@@ -350,5 +350,99 @@ ORDER BY b.id DESC'
$query->getSQL()
);
}
/**
* This tests ordering by property that has the 'declared' field.
*/
public function testLimitSubqueryOrderByFieldFromMappedSuperclass()
{
$this->entityManager->getConnection()->setDatabasePlatform(new MySqlPlatform());
// now use the third one in query
$query = $this->entityManager->createQuery(
'SELECT b FROM Doctrine\Tests\ORM\Tools\Pagination\Banner b ORDER BY b.id DESC'
);
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
'SELECT DISTINCT id_0 FROM (SELECT b0_.id AS id_0, b0_.name AS name_1 FROM Banner b0_) dctrn_result ORDER BY id_0 DESC',
$query->getSQL()
);
}
/**
* Tests order by on a subselect expression (mysql).
*/
public function testLimitSubqueryOrderBySubSelectOrderByExpression()
{
$this->entityManager->getConnection()->setDatabasePlatform(new MysqlPlatform());
$query = $this->entityManager->createQuery(
'SELECT a,
(
SELECT MIN(bp.title)
FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp
WHERE bp.author = a
) AS HIDDEN first_blog_post
FROM Doctrine\Tests\ORM\Tools\Pagination\Author a
ORDER BY first_blog_post DESC'
);
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
'SELECT DISTINCT id_0 FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS dctrn__1 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2 FROM Author a0_) dctrn_result ORDER BY sclr_2 DESC',
$query->getSQL()
);
}
/**
* Tests order by on a subselect expression invoking RowNumberOverFunction (postgres).
*/
public function testLimitSubqueryOrderBySubSelectOrderByExpressionPg()
{
$this->entityManager->getConnection()->setDatabasePlatform(new PostgreSqlPlatform());
$query = $this->entityManager->createQuery(
'SELECT a,
(
SELECT MIN(bp.title)
FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp
WHERE bp.author = a
) AS HIDDEN first_blog_post
FROM Doctrine\Tests\ORM\Tools\Pagination\Author a
ORDER BY first_blog_post DESC'
);
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
'SELECT DISTINCT id_0, MIN(sclr_3) AS dctrn_minrownum FROM (SELECT a0_.id AS id_0, a0_.name AS name_1, (SELECT MIN(m1_.title) AS dctrn__1 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS sclr_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS dctrn__2 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS sclr_3 FROM Author a0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
$query->getSQL()
);
}
/**
* Tests order by on a subselect expression invoking RowNumberOverFunction (oracle).
*/
public function testLimitSubqueryOrderBySubSelectOrderByExpressionOracle()
{
$this->entityManager->getConnection()->setDatabasePlatform(new OraclePlatform());
$query = $this->entityManager->createQuery(
'SELECT a,
(
SELECT MIN(bp.title)
FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost bp
WHERE bp.author = a
) AS HIDDEN first_blog_post
FROM Doctrine\Tests\ORM\Tools\Pagination\Author a
ORDER BY first_blog_post DESC'
);
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
'SELECT DISTINCT ID_0, MIN(SCLR_3) AS dctrn_minrownum FROM (SELECT a0_.id AS ID_0, a0_.name AS NAME_1, (SELECT MIN(m1_.title) AS dctrn__1 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) AS SCLR_2, ROW_NUMBER() OVER(ORDER BY (SELECT MIN(m1_.title) AS dctrn__2 FROM MyBlogPost m1_ WHERE m1_.author_id = a0_.id) DESC) AS SCLR_3 FROM Author a0_) dctrn_result GROUP BY ID_0 ORDER BY dctrn_minrownum ASC',
$query->getSQL()
);
}
}

View File

@@ -168,4 +168,22 @@ class Avatar
public $image_width;
/** @Column(type="string", length=255) */
public $image_alt_desc;
}
}
/** @MappedSuperclass */
abstract class Identified
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
public function getId()
{
return $this->id;
}
}
/** @Entity */
class Banner extends Identified
{
/** @Column(type="string") */
public $name;
}

View File

@@ -116,6 +116,28 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame(array(), $customSchemaOptions);
}
/**
* @group DDC-3671
*/
public function testSchemaHasProperIndexesFromUniqueConstraintAnnotation()
{
$em = $this->_getTestEntityManager();
$schemaTool = new SchemaTool($em);
$classes = [
$em->getClassMetadata(__NAMESPACE__ . '\\UniqueConstraintAnnotationModel'),
];
$schema = $schemaTool->getSchemaFromMetadata($classes);
$this->assertTrue($schema->hasTable('unique_constraint_annotation_table'));
$table = $schema->getTable('unique_constraint_annotation_table');
$this->assertEquals(2, count($table->getIndexes()));
$this->assertTrue($table->hasIndex('primary'));
$this->assertTrue($table->hasIndex('uniq_hash'));
}
}
/**
@@ -148,3 +170,20 @@ class GenerateSchemaEventListener
$this->schemaCalled = true;
}
}
/**
* @Entity
* @Table(name="unique_constraint_annotation_table", uniqueConstraints={
* @UniqueConstraint(name="uniq_hash", columns={"hash"})
* })
*/
class UniqueConstraintAnnotationModel
{
/** @Id @Column */
private $id;
/**
* @Column(name="hash", type="string", length=8, nullable=false, unique=true)
*/
private $hash;
}

View File

@@ -139,6 +139,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\DDC117\DDC117Editor',
'Doctrine\Tests\Models\DDC117\DDC117Link',
),
'ddc3699' => array(
'Doctrine\Tests\Models\DDC3699\DDC3699Parent',
'Doctrine\Tests\Models\DDC3699\DDC3699RelationOne',
'Doctrine\Tests\Models\DDC3699\DDC3699RelationMany',
'Doctrine\Tests\Models\DDC3699\DDC3699Child',
),
'stockexchange' => array(
'Doctrine\Tests\Models\StockExchange\Bond',
'Doctrine\Tests\Models\StockExchange\Stock',