Compare commits

..

95 Commits

Author SHA1 Message Date
Marco Pivetta bc4ddbfb01 Release 2.5.4 2016-01-05 22:34:58 +01:00
Marco Pivetta 14499f5021 Removing coveralls installation/reporting from 2.5: not required 2016-01-05 22:25:57 +01:00
Marco Pivetta aae43cbb77 Merge branch 'hotfix/#1568-identifier-type-cached-incorrectly-backport-2-5' into 2.5
Backport #1568 to 2.5
2016-01-05 22:14:40 +01:00
Jan Langer db6cb8dedc Second level cache stores identifier with correct type even if findById is called with wrong identifier type 2016-01-05 22:13:03 +01:00
Guido Contreras Woda 5092da074a Test that reflects the issue described in http://www.doctrine-project.org/jira/browse/DDC-3967 2016-01-05 22:12:55 +01:00
Marco Pivetta 1c6524db55 Bumping to development version 2.5.4-DEV 2015-12-25 16:50:31 +01:00
Marco Pivetta d9fc5388f1 2.5.3 release 2015-12-25 16:50:05 +01:00
Marco Pivetta d2e51eacff Reverting incorrect DBAL 2.6 bump 2015-12-25 16:49:48 +01:00
Marco Pivetta 5a6ae4686f Allowing doctrine/common 2.6 2015-12-25 15:58:40 +01:00
Marco Pivetta 8b8a1cbe81 Merge branch 'hotfix/common-2.6-upgrade-compat-2.5' into 2.5 2015-12-25 15:26:15 +01:00
Marco Pivetta 27a5284899 doctrine/common 2.6.0 compat
Less strict assertion - no need to check the exact file name
2015-12-25 15:24:37 +01:00
Marco Pivetta 0086d17afe Common 2.6 compatibility
Internal structure of the ArrayCache has changed, therefore we should fix the tests depending on it instead
2015-12-25 15:24:32 +01:00
Marco Pivetta ab62167c8a Merge branch 'hotfix/#4884-support-proxy-php7-hints-generation-2.5' into 2.5
Close #4884
2015-12-25 14:47:12 +01:00
Marco Pivetta 6d43195669 #4884 - allow installation of doctrine/common 2.6.x, which allows generating type-hints on proxies 2015-12-25 14:46:59 +01:00
Marco Pivetta 7065ff0ac9 Merge branch 'hotfix/#1572-target-entity-resolver-dql-with-interfaces-support' into 2.5
Close #1572
2015-12-11 21:35:18 +01:00
Marco Pivetta aa61328e90 #1572 - test coverage - interfaces should also resolve to target entities when in DQL 2015-12-11 21:30:19 +01:00
Marco Pivetta 62719f2a97 Merge branch 'hotfix/#1573-merge-associated-versioned-entity-2.5.x' into 2.5
Close #1573
2015-12-11 20:19:10 +01:00
Marco Pivetta 66770c5bfe #1573 - correcting test asset namespace, removing unused properties and bi-directional association 2015-12-11 20:18:53 +01:00
Marco Pivetta 42691c21b4 Removing empty newline 2015-12-11 20:18:48 +01:00
Marco Pivetta 596e895763 #1573 - correcting docblock arguments/description 2015-12-11 20:18:42 +01:00
Marco Pivetta d5c82094df #1573 removing unused API 2015-12-11 20:18:37 +01:00
bilouwan 4148220f9c Refactor testing Proxy not initilized 2015-12-11 20:18:31 +01:00
bilouwan e173c930ec Fix superflous whitespaces & empty lines 2015-12-11 20:18:25 +01:00
bilouwan 7071984559 Fix compatibility with php5.4 2015-12-11 20:18:19 +01:00
bilouwan 216c466233 Unit test & fix for merge versionned entity 2015-12-11 20:18:12 +01:00
Marco Pivetta 65f5777e60 Merge branch 'hotfix/php7-xdebug-incompatibility-fixes-2.5.x' into 2.5
Close #5547
2015-12-11 19:35:42 +01:00
Marco Pivetta 6e3ce26429 Correcting minor test case incompatibility with XDebug 2.4.x
In PHP 5.x + XDebug < 2.4, the output would be "string:..."
In PHP 7.x + XDebug >= 2.4, the output would be "the/file/name.php:11:string:..."

This is an improvement in XDebug that is quite annoying for our purposes, but is actually welcome to most users anyway.

This commit simply fixes that incompatibility
2015-12-11 19:35:28 +01:00
oprokidnev 752d4f9eac Target entity resolver for DQL
Since we have target entity resolver in doctrine this class check is not enought.
To gain interface resolution it is better to add interface check in addition to class_check here.
2015-11-27 16:00:56 +05:00
Marco Pivetta 2983081a60 Bumping current dev version to 2.5.3-DEV 2015-11-23 13:44:56 +01:00
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" ( https://github.com/doctrine/doctrine2/commit/e501137d1afff2c08963828b61b0b8b6668edd83 )
See my comment on https://github.com/neoglez/doctrine2/commit/a3ece3b419fa7bfe50ccf2a48d83545aa007fbe8
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" ( https://github.com/doctrine/doctrine2/commit/192da148428e62cea53fa2b918daf14f85cd7286 ).
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 https://github.com/doctrine/doctrine2/commit/e501137d1afff2c08963828b61b0b8b6668edd83
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

https://github.com/doctrine/cache/commit/dd47003641aa5425820c0ec8a6f4a85e7412ffcd 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
Stefan Blanke 293c6f6313 Fixed misleading typo in Embeddables tutorial 2015-04-02 23:19:26 +02: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
Marco Pivetta f495dfcc9c Merge branch 'docs/#1359-correcting-mapping-in-working-with-objects-reference' 2015-04-02 21:55:57 +01:00
Juti Noppornpitak 3b6616fe65 Fixed typo in the documentation 2015-04-02 16:46:25 -04:00
Marco Pivetta f20de54281 Bumping version to 2.6.0-DEV 2015-04-02 21:42:47 +01:00
73 changed files with 1179 additions and 121 deletions
-3
View File
@@ -23,9 +23,6 @@ script:
- ENABLE_SECOND_LEVEL_CACHE=0 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml $PHPUNIT_FLAGS
- ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional
after_script:
- php vendor/bin/coveralls -v
matrix:
exclude:
- php: hhvm
+4
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()
+4 -5
View File
@@ -18,14 +18,13 @@
"doctrine/collections": "~1.2",
"doctrine/dbal": ">=2.5-dev,<2.6-dev",
"doctrine/instantiator": "~1.0.1",
"doctrine/common": ">=2.5-dev,<2.6-dev",
"doctrine/common": ">=2.5-dev,<2.7-dev",
"doctrine/cache": "~1.4",
"symfony/console": "~2.5"
"symfony/console": "~2.5|~3.0"
},
"require-dev": {
"symfony/yaml": "~2.1",
"phpunit/phpunit": "~4.0",
"satooshi/php-coveralls": "dev-master"
"symfony/yaml": "~2.3|~3.0",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
+1 -1
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();
+2 -1
View File
@@ -821,9 +821,10 @@ in a central location.
namespace MyDomain\Model;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* @entity(repositoryClass="MyDomain\Model\UserRepository")
* @ORM\Entity(repositoryClass="MyDomain\Model\UserRepository")
*/
class User
{
+1 -1
View File
@@ -86,7 +86,7 @@ Following the example above, your columns would be named as ``address_street``,
``address_postalCode``...
You can change this behaviour to meet your needs by changing the
``columnPrefix`` attribute in the ``@Embeddable`` notation.
``columnPrefix`` attribute in the ``@Embedded`` notation.
The following example shows you how to set your prefix to ``myPrefix_``:
@@ -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);
}
/**
@@ -73,7 +73,7 @@ class DefaultEntityHydrator implements EntityHydrator
public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity)
{
$data = $this->uow->getOriginalEntityData($entity);
$data = array_merge($data, $key->identifier); // why update has no identifier values ?
$data = array_merge($data, $metadata->getIdentifierValues($entity)); // why update has no identifier values ?
foreach ($metadata->associationMappings as $name => $assoc) {
+2 -2
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.
@@ -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;
}
}
+22 -21
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));
}
/**
@@ -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;
}
@@ -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
{
@@ -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) {
@@ -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']),
@@ -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;
+5 -5
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;
+1 -1
View File
@@ -965,7 +965,7 @@ class Parser
$schemaName = $this->em->getConfiguration()->getEntityNamespace($namespaceAlias) . '\\' . $simpleClassName;
}
$exists = class_exists($schemaName, true);
$exists = class_exists($schemaName, true) || interface_exists($schemaName, true);
if ( ! $exists) {
$this->semanticalError("Class '$schemaName' is not defined.", $this->lexer->token);
+1 -1
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.
@@ -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;
+4
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;
}
@@ -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);
@@ -79,7 +79,7 @@ EOT
}
if ( ! is_dir($destPath)) {
mkdir($destPath, 0777, true);
mkdir($destPath, 0775, true);
}
$destPath = realpath($destPath);
@@ -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)));
}
}
+2 -1
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);
}
/**
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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
+10
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());
}
}
+16 -4
View File
@@ -1870,7 +1870,7 @@ class UnitOfWork implements PropertyChangedListener
}
}
if ($class->isVersioned) {
if ($class->isVersioned && $this->isLoaded($managedCopy) && $this->isLoaded($entity)) {
$reflField = $class->reflFields[$class->versionField];
$managedCopyVersion = $reflField->getValue($managedCopy);
$entityVersion = $reflField->getValue($entity);
@@ -1883,7 +1883,7 @@ class UnitOfWork implements PropertyChangedListener
$visited[$oid] = $managedCopy; // mark visited
if (!($entity instanceof Proxy && ! $entity->__isInitialized())) {
if ($this->isLoaded($entity)) {
if ($managedCopy instanceof Proxy && ! $managedCopy->__isInitialized()) {
$managedCopy->__load();
}
@@ -1908,6 +1908,18 @@ class UnitOfWork implements PropertyChangedListener
return $managedCopy;
}
/**
* Tests if an entity is loaded - must either be a loaded proxy or not a proxy
*
* @param object $entity
*
* @return bool
*/
private function isLoaded($entity)
{
return !($entity instanceof Proxy) || $entity->__isInitialized();
}
/**
* Sets/adds associated managed copies into the previous entity's association field
*
@@ -3378,7 +3390,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 +3418,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);
+1 -1
View File
@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
const VERSION = '2.5.0';
const VERSION = '2.5.4';
/**
* Compares a Doctrine version with the current one.
@@ -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);
}
}
}
}
@@ -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;
}
@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Models\DDC3699;
/** @MappedSuperclass */
abstract class DDC3699Parent
{
const CLASSNAME = __CLASS__;
/** @Column(type="string") */
public $parentField;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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;
}
@@ -0,0 +1,12 @@
<?php
namespace Doctrine\Tests\Models\DDC3899;
/**
* @Entity
*/
class DDC3899FixContract extends DDC3899Contract
{
/** @column(type="integer") */
public $fixPrice = 0;
}
@@ -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;
}
@@ -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;
}
@@ -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 = [];
}
@@ -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;
}
@@ -0,0 +1,37 @@
<?php
namespace Doctrine\Tests\Models\VersionedManyToOne;
/**
* @Entity
* @Table(name="versioned_many_to_one_article")
*/
class Article
{
const CLASSNAME = __CLASS__;
/**
* @Id
* @Column(name="id", type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @Column(name="name")
*/
public $name;
/**
* @ManyToOne(targetEntity="Category", cascade={"merge", "persist"})
*/
public $category;
/**
* Version column
*
* @Column(type="integer", name="version")
* @Version
*/
public $version;
}
@@ -0,0 +1,27 @@
<?php
namespace Doctrine\Tests\Models\VersionedManyToOne;
/**
* @Entity
* @Table(name="versioned_many_to_one_category")
*/
class Category
{
const CLASSNAME = __CLASS__;
/**
* @Id
* @Column(name="id", type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* Version column
*
* @Column(type="integer", name="version")
* @Version
*/
public $version;
}
@@ -119,7 +119,7 @@ class DefaultEntityHydratorTest extends OrmTestCase
$this->assertArrayHasKey('name', $cache->data);
$this->assertArrayHasKey('country', $cache->data);
$this->assertEquals(array(
'id' => 11,
'id' => 12,
'name' => 'Bar',
'country' => new AssociationCacheEntry(Country::CLASSNAME, array('id' => 11)),
), $cache->data);
@@ -147,9 +147,39 @@ class DefaultEntityHydratorTest extends OrmTestCase
$this->assertArrayHasKey('name', $cache->data);
$this->assertArrayHasKey('country', $cache->data);
$this->assertEquals(array(
'id' => 11,
'id' => 12,
'name' => 'Bar',
'country' => new AssociationCacheEntry(Country::CLASSNAME, array('id' => 11)),
), $cache->data);
}
}
public function testCacheEntryWithWrongIdentifierType()
{
$proxy = $this->em->getReference(Country::CLASSNAME, 11);
$entity = new State('Bat', $proxy);
$uow = $this->em->getUnitOfWork();
$entityData = array('id'=> 12, 'name'=>'Bar', 'country' => $proxy);
$metadata = $this->em->getClassMetadata(State::CLASSNAME);
$key = new EntityCacheKey($metadata->name, array('id'=>'12'));
$entity->setId(12);
$uow->registerManaged($entity, array('id'=>12), $entityData);
$cache = $this->structure->buildCacheEntry($metadata, $key, $entity);
$this->assertInstanceOf('Doctrine\ORM\Cache\CacheEntry', $cache);
$this->assertInstanceOf('Doctrine\ORM\Cache\EntityCacheEntry', $cache);
$this->assertArrayHasKey('id', $cache->data);
$this->assertArrayHasKey('name', $cache->data);
$this->assertArrayHasKey('country', $cache->data);
$this->assertSame($entity->getId(), $cache->data['id']);
$this->assertEquals(array(
'id' => 12,
'name' => 'Bar',
'country' => new AssociationCacheEntry(Country::CLASSNAME, array('id' => 11)),
), $cache->data);
}
}
@@ -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]);
}
}
@@ -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]);
@@ -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");
@@ -0,0 +1,45 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\Tests\Models\VersionedManyToOne\Article;
use Doctrine\Tests\Models\VersionedManyToOne\Category;
/**
* @group MergeVersionedOneToMany
*/
class MergeVersionedManyToOneTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('versioned_many_to_one');
parent::setUp();
}
/**
* This test case asserts that a detached and unmodified entity could be merge without firing
* OptimisticLockException.
*/
public function testSetVersionOnCreate()
{
$category = new Category();
$article = new Article();
$article->name = 'Article';
$article->category = $category;
$this->_em->persist($article);
$this->_em->flush();
$this->_em->clear();
$articleMerged = $this->_em->merge($article);
$articleMerged->name = 'Article Merged';
$this->_em->flush();
$this->assertEquals(2, $articleMerged->version);
}
}
@@ -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);
}
}
@@ -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();
@@ -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;
}
@@ -105,16 +105,16 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
$query = $this->_em->createQuery('select ux from Doctrine\Tests\Models\CMS\CmsUser ux');
$cache = new \Doctrine\Common\Cache\ArrayCache();
$cache = $this->getMock('Doctrine\Common\Cache\Cache');
$query->setQueryCacheDriver($cache);
$users = $query->getResult();
$cache
->expects(self::once())
->method('save')
->with(self::isType('string'), self::isInstanceOf('Doctrine\ORM\Query\ParserResult'));
$data = $this->cacheDataReflection->getValue($cache);
$this->assertEquals(2, count($data));
$this->assertInstanceOf('Doctrine\ORM\Query\ParserResult', array_pop($data));
$query->getResult();
}
public function testQueryCache_HitDoesNotSaveParserResult()
@@ -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));
@@ -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;
}
@@ -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()
@@ -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');
}
}
@@ -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']);
}
}
@@ -0,0 +1,35 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Cache\Country;
use Doctrine\Tests\ORM\Functional\SecondLevelCacheAbstractTest;
class DDC3967Test extends SecondLevelCacheAbstractTest
{
protected function setUp()
{
parent::setUp();
$this->loadFixturesCountries();
$this->_em->getCache()->evictEntityRegion(Country::CLASSNAME);
$this->_em->clear();
}
public function testIdentifierCachedWithProperType()
{
$country = array_pop($this->countries);
$id = $country->getId();
// First time, loaded from database
$this->_em->find(Country::CLASSNAME, "$id");
$this->_em->clear();
// Second time, loaded from cache
/** @var Country $country */
$country = $this->_em->find(Country::CLASSNAME, "$id");
// Identifier type should be integer
$this->assertSame($country->getId(), $id);
}
}
@@ -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();
@@ -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]);
}
}
@@ -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());
}
}
/**
@@ -49,7 +49,7 @@ abstract class AbstractDriverTest extends \PHPUnit_Framework_TestCase
{
$this->setExpectedException(
'Doctrine\Common\Persistence\Mapping\MappingException',
"No mapping file found named '".$this->dir."/Foo".$this->getFileExtension()."' for class 'MyNamespace\MySubnamespace\Entity\Foo'."
"No mapping file found named"
);
$driver = $this->getDriver(array(
@@ -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
@@ -0,0 +1,8 @@
Doctrine\Tests\Models\DDC3711\DDC3711EntityB:
type: entity
table: ddc3711.entityB
id:
id1:
type: int
id2:
type: int
@@ -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()));
}
/**
@@ -85,6 +85,6 @@ class RunDqlCommandTest extends OrmFunctionalTestCase
))
);
$this->assertStringMatchesFormat('string%sSELECT %a', $this->tester->getDisplay());
$this->assertStringMatchesFormat('%Astring%sSELECT %a', $this->tester->getDisplay());
}
}
@@ -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()
);
}
}
@@ -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;
}
@@ -9,19 +9,19 @@ use Doctrine\ORM\Events;
class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
{
/**
* @var EntityManager
* @var \Doctrine\ORM\EntityManager
*/
private $em = null;
private $em;
/**
* @var ResolveTargetEntityListener
*/
private $listener = null;
private $listener;
/**
* @var ClassMetadataFactory
*/
private $factory = null;
private $factory;
public function setUp()
{
@@ -106,6 +106,32 @@ class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['targetEntity']);
$this->assertEquals(array('resolvetargetentity_id', 'targetinterface_id'), $meta['joinTableColumns']);
}
/**
* @group 1572
* @group functional
*
* @coversNothing
*/
public function testDoesResolveTargetEntitiesInDQLAlsoWithInterfaces()
{
$evm = $this->em->getEventManager();
$this->listener->addResolveTargetEntity(
'Doctrine\Tests\ORM\Tools\ResolveTargetInterface',
'Doctrine\Tests\ORM\Tools\ResolveTargetEntity',
array()
);
$evm->addEventSubscriber($this->listener);
$this->assertStringMatchesFormat(
'SELECT%AFROM ResolveTargetEntity%A',
$this
->em
->createQuery('SELECT f FROM Doctrine\Tests\ORM\Tools\ResolveTargetInterface f')
->getSQL()
);
}
}
interface ResolveTargetInterface
@@ -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;
}
@@ -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',
@@ -274,6 +280,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\Pagination\User',
'Doctrine\Tests\Models\Pagination\User1',
),
'versioned_many_to_one' => array(
'Doctrine\Tests\Models\VersionedManyToOne\Category',
'Doctrine\Tests\Models\VersionedManyToOne\Article',
),
);
/**
@@ -529,6 +539,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$conn->executeUpdate('DELETE FROM pagination_user');
}
if (isset($this->_usedModelSets['versioned_many_to_one'])) {
$conn->executeUpdate('DELETE FROM versioned_many_to_one_article');
$conn->executeUpdate('DELETE FROM versioned_many_to_one_category');
}
$this->_em->clear();
}