Merge branch 'master' of github.com:doctrine/doctrine2
This commit is contained in:
commit
f5897d4b0b
@ -20,7 +20,7 @@ before_script:
|
|||||||
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
|
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
|
||||||
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
|
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
|
||||||
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
|
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
|
||||||
- composer install --prefer-dist --dev
|
- composer install --prefer-source --dev
|
||||||
|
|
||||||
script: phpunit -v --configuration tests/travis/$DB.travis.xml
|
script: phpunit -v --configuration tests/travis/$DB.travis.xml
|
||||||
|
|
||||||
|
@ -6,22 +6,6 @@ design generally refer to best practices when working with Doctrine
|
|||||||
and do not necessarily reflect best practices for database design
|
and do not necessarily reflect best practices for database design
|
||||||
in general.
|
in general.
|
||||||
|
|
||||||
|
|
||||||
Don't use public properties on entities
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
It is very important that you don't map public properties on
|
|
||||||
entities, but only protected or private ones. The reason for this
|
|
||||||
is simple, whenever you access a public property of a proxy object
|
|
||||||
that hasn't been initialized yet the return value will be null.
|
|
||||||
Doctrine cannot hook into this process and magically make the
|
|
||||||
entity lazy load.
|
|
||||||
|
|
||||||
This can create situations where it is very hard to debug the
|
|
||||||
current failure. We therefore urge you to map only private and
|
|
||||||
protected properties on entities and use getter methods or magic
|
|
||||||
\_\_get() to access them.
|
|
||||||
|
|
||||||
Constrain relationships as much as possible
|
Constrain relationships as much as possible
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ of several common elements:
|
|||||||
joinColumn:
|
joinColumn:
|
||||||
name: address_id
|
name: address_id
|
||||||
referencedColumnName: id
|
referencedColumnName: id
|
||||||
|
onDelete: CASCADE
|
||||||
oneToMany:
|
oneToMany:
|
||||||
phonenumbers:
|
phonenumbers:
|
||||||
targetEntity: Phonenumber
|
targetEntity: Phonenumber
|
||||||
|
@ -15,7 +15,9 @@ the first time its accessed. If you mark an association as extra lazy the follow
|
|||||||
can be called without triggering a full load of the collection:
|
can be called without triggering a full load of the collection:
|
||||||
|
|
||||||
- ``Collection#contains($entity)``
|
- ``Collection#contains($entity)``
|
||||||
|
- ``Collection#containsKey($key)`` (available with Doctrine 2.5)
|
||||||
- ``Collection#count()``
|
- ``Collection#count()``
|
||||||
|
- ``Collection#get($key)`` (available with Doctrine 2.4)
|
||||||
- ``Collection#slice($offset, $length = null)``
|
- ``Collection#slice($offset, $length = null)``
|
||||||
|
|
||||||
For each of this three methods the following semantics apply:
|
For each of this three methods the following semantics apply:
|
||||||
|
@ -29,7 +29,6 @@ use Doctrine\DBAL\Cache\QueryCacheProfile;
|
|||||||
|
|
||||||
use Doctrine\ORM\Cache;
|
use Doctrine\ORM\Cache;
|
||||||
use Doctrine\ORM\Query\QueryException;
|
use Doctrine\ORM\Query\QueryException;
|
||||||
use Doctrine\ORM\ORMInvalidArgumentException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM;
|
namespace Doctrine\ORM;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an API for querying/managing the second level cache regions.
|
* Provides an API for querying/managing the second level cache regions.
|
||||||
*
|
*
|
||||||
|
@ -21,10 +21,7 @@
|
|||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\ORMException;
|
use Doctrine\ORM\ORMException;
|
||||||
use Doctrine\ORM\Cache\CacheFactory;
|
|
||||||
use Doctrine\ORM\Cache\Logging\CacheLogger;
|
use Doctrine\ORM\Cache\Logging\CacheLogger;
|
||||||
use Doctrine\ORM\Cache\QueryCacheValidator;
|
|
||||||
use Doctrine\ORM\Cache\TimestampQueryCacheValidator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration container for second-level cache.
|
* Configuration container for second-level cache.
|
||||||
|
@ -22,8 +22,6 @@ namespace Doctrine\ORM\Cache;
|
|||||||
|
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Cache\CollectionCacheKey;
|
|
||||||
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hydrator cache entry for collections
|
* Hydrator cache entry for collections
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\Lock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines contract for concurrently managed data region.
|
* Defines contract for concurrently managed data region.
|
||||||
* It should be able to lock an specific cache entry in an atomic operation.
|
* It should be able to lock an specific cache entry in an atomic operation.
|
||||||
|
@ -24,8 +24,6 @@ use Doctrine\Common\Cache\CacheProvider;
|
|||||||
|
|
||||||
use Doctrine\ORM\Cache;
|
use Doctrine\ORM\Cache;
|
||||||
use Doctrine\ORM\Cache\Region;
|
use Doctrine\ORM\Cache\Region;
|
||||||
use Doctrine\ORM\Cache\TimestampRegion;
|
|
||||||
use Doctrine\ORM\Cache\RegionsConfiguration;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
use Doctrine\ORM\Cache\Region\DefaultRegion;
|
||||||
|
@ -24,8 +24,6 @@ use Doctrine\ORM\Query;
|
|||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Cache\CollectionCacheKey;
|
|
||||||
use Doctrine\ORM\Cache\CollectionCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default hydrator cache for collections
|
* Default hydrator cache for collections
|
||||||
|
@ -23,10 +23,8 @@ namespace Doctrine\ORM\Cache;
|
|||||||
use Doctrine\Common\Util\ClassUtils;
|
use Doctrine\Common\Util\ClassUtils;
|
||||||
|
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Cache\EntityCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default hydrator cache for entities
|
* Default hydrator cache for entities
|
||||||
|
@ -25,10 +25,7 @@ use Doctrine\ORM\Cache\Persister\CachedPersister;
|
|||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Query\ResultSetMapping;
|
use Doctrine\ORM\Query\ResultSetMapping;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Cache\QueryCacheEntry;
|
|
||||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
|
||||||
use Doctrine\ORM\PersistentCollection;
|
use Doctrine\ORM\PersistentCollection;
|
||||||
use Doctrine\ORM\Cache\CacheException;
|
|
||||||
use Doctrine\Common\Proxy\Proxy;
|
use Doctrine\Common\Proxy\Proxy;
|
||||||
use Doctrine\ORM\Cache;
|
use Doctrine\ORM\Cache;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
|
@ -20,9 +20,7 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\EntityCacheKey;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Cache\EntityCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hydrator cache entry for entities
|
* Hydrator cache entry for entities
|
||||||
|
@ -508,7 +508,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
|
|
||||||
$list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
|
$list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
|
||||||
|
|
||||||
if ($hasCache && ! empty($list)) {
|
if ($hasCache) {
|
||||||
$persister->storeCollectionCache($key, $list);
|
$persister->storeCollectionCache($key, $list);
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
@ -543,7 +543,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
|||||||
|
|
||||||
$list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
|
$list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
|
||||||
|
|
||||||
if ($hasCache && ! empty($list)) {
|
if ($hasCache) {
|
||||||
$persister->storeCollectionCache($key, $list);
|
$persister->storeCollectionCache($key, $list);
|
||||||
|
|
||||||
if ($this->cacheLogger) {
|
if ($this->cacheLogger) {
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\QueryCacheEntry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache query validator interface.
|
* Cache query validator interface.
|
||||||
*
|
*
|
||||||
|
@ -20,8 +20,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\Lock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a contract for accessing a particular named region.
|
* Defines a contract for accessing a particular named region.
|
||||||
*
|
*
|
||||||
|
@ -20,9 +20,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Cache;
|
namespace Doctrine\ORM\Cache;
|
||||||
|
|
||||||
use Doctrine\ORM\Cache\QueryCacheEntry;
|
|
||||||
use Doctrine\ORM\Cache\QueryCacheKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Event;
|
namespace Doctrine\ORM\Event;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManager;
|
|
||||||
use Doctrine\Common\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
|
use Doctrine\Common\Persistence\Event\LifecycleEventArgs as BaseLifecycleEventArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Event;
|
namespace Doctrine\ORM\Event;
|
||||||
|
|
||||||
use Doctrine\Common\EventArgs;
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
|
||||||
use Doctrine\ORM\EntityManager;
|
|
||||||
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetadataEventArgs;
|
use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClassMetadataEventArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Event;
|
namespace Doctrine\ORM\Event;
|
||||||
|
|
||||||
use Doctrine\Common\EventArgs;
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Mapping;
|
namespace Doctrine\ORM\Mapping;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2370,7 +2370,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
$queryMapping['isSelfClass'] = false;
|
$queryMapping['isSelfClass'] = false;
|
||||||
if (isset($queryMapping['resultClass'])) {
|
if (isset($queryMapping['resultClass'])) {
|
||||||
|
|
||||||
if($queryMapping['resultClass'] === '__CLASS__') {
|
if ($queryMapping['resultClass'] === '__CLASS__') {
|
||||||
|
|
||||||
$queryMapping['isSelfClass'] = true;
|
$queryMapping['isSelfClass'] = true;
|
||||||
$queryMapping['resultClass'] = $this->name;
|
$queryMapping['resultClass'] = $this->name;
|
||||||
@ -2410,7 +2410,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
$entityResult['isSelfClass'] = false;
|
$entityResult['isSelfClass'] = false;
|
||||||
if($entityResult['entityClass'] === '__CLASS__') {
|
if ($entityResult['entityClass'] === '__CLASS__') {
|
||||||
|
|
||||||
$entityResult['isSelfClass'] = true;
|
$entityResult['isSelfClass'] = true;
|
||||||
$entityResult['entityClass'] = $this->name;
|
$entityResult['entityClass'] = $this->name;
|
||||||
@ -2430,7 +2430,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
|
|
||||||
if (!isset($field['column'])) {
|
if (!isset($field['column'])) {
|
||||||
$fieldName = $field['name'];
|
$fieldName = $field['name'];
|
||||||
if(strpos($fieldName, '.')){
|
if (strpos($fieldName, '.')) {
|
||||||
list(, $fieldName) = explode('.', $fieldName);
|
list(, $fieldName) = explode('.', $fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2583,7 +2583,7 @@ class ClassMetadataInfo implements ClassMetadata
|
|||||||
*/
|
*/
|
||||||
public function addLifecycleCallback($callback, $event)
|
public function addLifecycleCallback($callback, $event)
|
||||||
{
|
{
|
||||||
if(isset($this->lifecycleCallbacks[$event]) && in_array($callback, $this->lifecycleCallbacks[$event])) {
|
if (isset($this->lifecycleCallbacks[$event]) && in_array($callback, $this->lifecycleCallbacks[$event])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Mapping;
|
namespace Doctrine\ORM\Mapping;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Mapping;
|
namespace Doctrine\ORM\Mapping;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@ use Doctrine\Common\Proxy\ProxyDefinition;
|
|||||||
use Doctrine\Common\Util\ClassUtils;
|
use Doctrine\Common\Util\ClassUtils;
|
||||||
use Doctrine\Common\Proxy\Proxy as BaseProxy;
|
use Doctrine\Common\Proxy\Proxy as BaseProxy;
|
||||||
use Doctrine\Common\Proxy\ProxyGenerator;
|
use Doctrine\Common\Proxy\ProxyGenerator;
|
||||||
use Doctrine\ORM\ORMInvalidArgumentException;
|
|
||||||
use Doctrine\ORM\Persisters\EntityPersister;
|
use Doctrine\ORM\Persisters\EntityPersister;
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Doctrine\ORM\EntityNotFoundException;
|
use Doctrine\ORM\EntityNotFoundException;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Query;
|
namespace Doctrine\ORM\Query;
|
||||||
|
|
||||||
use Doctrine\ORM\Configuration;
|
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,9 +26,6 @@ use Doctrine\Common\Collections\Expr\Comparison;
|
|||||||
use Doctrine\Common\Collections\Expr\CompositeExpression;
|
use Doctrine\Common\Collections\Expr\CompositeExpression;
|
||||||
use Doctrine\Common\Collections\Expr\Value;
|
use Doctrine\Common\Collections\Expr\Value;
|
||||||
|
|
||||||
use Doctrine\ORM\QueryBuilder;
|
|
||||||
use Doctrine\ORM\Query\Parameter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts Collection expressions to Query expressions.
|
* Converts Collection expressions to Query expressions.
|
||||||
*
|
*
|
||||||
|
@ -23,7 +23,6 @@ use Doctrine\DBAL\LockMode;
|
|||||||
use Doctrine\DBAL\Types\Type;
|
use Doctrine\DBAL\Types\Type;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Query;
|
use Doctrine\ORM\Query;
|
||||||
use Doctrine\ORM\Query\QueryException;
|
|
||||||
use Doctrine\ORM\OptimisticLockException;
|
use Doctrine\ORM\OptimisticLockException;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||||
|
|
||||||
@ -895,6 +894,8 @@ class SqlWalker implements TreeWalker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$targetTableJoin = null;
|
||||||
|
|
||||||
// This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot
|
// This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot
|
||||||
// be the owning side and previously we ensured that $assoc is always the owning side of the associations.
|
// be the owning side and previously we ensured that $assoc is always the owning side of the associations.
|
||||||
// The owning side is necessary at this point because only it contains the JoinColumn information.
|
// The owning side is necessary at this point because only it contains the JoinColumn information.
|
||||||
@ -929,7 +930,10 @@ class SqlWalker implements TreeWalker
|
|||||||
$conditions[] = $filterExpr;
|
$conditions[] = $filterExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ' . implode(' AND ', $conditions);
|
$targetTableJoin = array(
|
||||||
|
'table' => $targetTableName . ' ' . $targetTableAlias,
|
||||||
|
'condition' => implode(' AND ', $conditions),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ($assoc['type'] == ClassMetadata::MANY_TO_MANY):
|
case ($assoc['type'] == ClassMetadata::MANY_TO_MANY):
|
||||||
@ -981,20 +985,33 @@ class SqlWalker implements TreeWalker
|
|||||||
$conditions[] = $filterExpr;
|
$conditions[] = $filterExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql .= $targetTableName . ' ' . $targetTableAlias . ' ON ' . implode(' AND ', $conditions);
|
$targetTableJoin = array(
|
||||||
|
'table' => $targetTableName . ' ' . $targetTableAlias,
|
||||||
|
'condition' => implode(' AND ', $conditions),
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new \BadMethodCallException('Type of association must be one of *_TO_ONE or MANY_TO_MANY');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle WITH clause
|
// Handle WITH clause
|
||||||
if ($condExpr !== null) {
|
$withCondition = (null === $condExpr) ? '' : ('(' . $this->walkConditionalExpression($condExpr) . ')');
|
||||||
// Phase 2 AST optimization: Skip processing of ConditionalExpression
|
|
||||||
// if only one ConditionalTerm is defined
|
if ($targetClass->isInheritanceTypeJoined()) {
|
||||||
$sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
|
$ctiJoins = $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
|
||||||
|
// If we have WITH condition, we need to build nested joins for target class table and cti joins
|
||||||
|
if ($withCondition) {
|
||||||
|
$sql .= '(' . $targetTableJoin['table'] . $ctiJoins . ') ON ' . $targetTableJoin['condition'];
|
||||||
|
} else {
|
||||||
|
$sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'] . $ctiJoins;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: these should either be nested or all forced to be left joins (DDC-XXX)
|
if ($withCondition) {
|
||||||
if ($targetClass->isInheritanceTypeJoined()) {
|
$sql .= ' AND ' . $withCondition;
|
||||||
$sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply the indexes
|
// Apply the indexes
|
||||||
|
@ -74,11 +74,11 @@ class GenerateEntitiesCommand extends Command
|
|||||||
'Flag to define if generator should only update entity if it exists.', true
|
'Flag to define if generator should only update entity if it exists.', true
|
||||||
),
|
),
|
||||||
new InputOption(
|
new InputOption(
|
||||||
'extend', null, InputOption::VALUE_OPTIONAL,
|
'extend', null, InputOption::VALUE_REQUIRED,
|
||||||
'Defines a base class to be extended by generated entity classes.'
|
'Defines a base class to be extended by generated entity classes.'
|
||||||
),
|
),
|
||||||
new InputOption(
|
new InputOption(
|
||||||
'num-spaces', null, InputOption::VALUE_OPTIONAL,
|
'num-spaces', null, InputOption::VALUE_REQUIRED,
|
||||||
'Defines the number of indentation spaces', 4
|
'Defines the number of indentation spaces', 4
|
||||||
),
|
),
|
||||||
new InputOption(
|
new InputOption(
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
||||||
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
||||||
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
namespace Doctrine\ORM\Tools\Console\Command\SchemaTool;
|
||||||
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
namespace Doctrine\ORM\Tools\Export;
|
namespace Doctrine\ORM\Tools\Export;
|
||||||
|
|
||||||
use Doctrine\ORM\Tools\Export\ExportException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used for converting your mapping information between the
|
* Class used for converting your mapping information between the
|
||||||
* supported formats: yaml, xml, and php/annotation.
|
* supported formats: yaml, xml, and php/annotation.
|
||||||
|
@ -16,7 +16,6 @@ namespace Doctrine\ORM\Tools\Pagination;
|
|||||||
use Doctrine\ORM\Query\SqlWalker;
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
||||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the query in order to select root entity IDs for pagination.
|
* Wraps the query in order to select root entity IDs for pagination.
|
||||||
@ -164,11 +163,8 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
|||||||
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
|
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
|
||||||
implode(', ', $sqlIdentifier), $innerSql);
|
implode(', ', $sqlIdentifier), $innerSql);
|
||||||
|
|
||||||
if ($this->platform instanceof PostgreSqlPlatform ||
|
|
||||||
$this->platform instanceof OraclePlatform) {
|
|
||||||
// http://www.doctrine-project.org/jira/browse/DDC-1958
|
// http://www.doctrine-project.org/jira/browse/DDC-1958
|
||||||
$this->preserveSqlOrdering($AST, $sqlIdentifier, $innerSql, $sql);
|
$sql = $this->preserveSqlOrdering($AST, $sqlIdentifier, $innerSql, $sql);
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the limit and offset.
|
// Apply the limit and offset.
|
||||||
$sql = $this->platform->modifyLimitQuery(
|
$sql = $this->platform->modifyLimitQuery(
|
||||||
@ -196,7 +192,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function preserveSqlOrdering(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
|
public function preserveSqlOrdering(SelectStatement $AST, array $sqlIdentifier, $innerSql, $sql)
|
||||||
{
|
{
|
||||||
// For every order by, find out the SQL alias by inspecting the ResultSetMapping.
|
// For every order by, find out the SQL alias by inspecting the ResultSetMapping.
|
||||||
$sqlOrderColumns = array();
|
$sqlOrderColumns = array();
|
||||||
@ -219,11 +215,6 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
|||||||
$sqlOrderColumns = array_diff($sqlOrderColumns, $sqlIdentifier);
|
$sqlOrderColumns = array_diff($sqlOrderColumns, $sqlIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't need orderBy in inner query.
|
|
||||||
// However at least on 5.4.6 I'm getting a segmentation fault and thus we don't clear it for now.
|
|
||||||
/*$AST->orderByClause = null;
|
|
||||||
$innerSql = parent::walkSelectStatement($AST);*/
|
|
||||||
|
|
||||||
if (count($orderBy)) {
|
if (count($orderBy)) {
|
||||||
$sql = sprintf(
|
$sql = sprintf(
|
||||||
'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s',
|
'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s',
|
||||||
@ -232,5 +223,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
|||||||
implode(', ', $orderBy)
|
implode(', ', $orderBy)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $sql;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
namespace Doctrine\ORM\Tools;
|
namespace Doctrine\ORM\Tools;
|
||||||
|
|
||||||
use Doctrine\ORM\ORMException;
|
use Doctrine\ORM\ORMException;
|
||||||
use Doctrine\DBAL\Types\Type;
|
|
||||||
use Doctrine\DBAL\Schema\Comparator;
|
use Doctrine\DBAL\Schema\Comparator;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use Doctrine\DBAL\Schema\Table;
|
use Doctrine\DBAL\Schema\Table;
|
||||||
@ -28,7 +27,6 @@ use Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector;
|
|||||||
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
|
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||||
use Doctrine\ORM\Internal\CommitOrderCalculator;
|
|
||||||
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
|
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
|
||||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||||
|
|
||||||
|
@ -236,20 +236,6 @@ class SchemaValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($class->reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $publicAttr) {
|
|
||||||
if ($publicAttr->isStatic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! isset($class->fieldMappings[$publicAttr->getName()]) &&
|
|
||||||
! isset($class->associationMappings[$publicAttr->getName()])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ce[] = "Field '".$publicAttr->getName()."' in class '".$class->name."' must be private ".
|
|
||||||
"or protected. Public fields may break lazy-loading.";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($class->subClasses as $subClass) {
|
foreach ($class->subClasses as $subClass) {
|
||||||
if (!in_array($class->name, class_parents($subClass))) {
|
if (!in_array($class->name, class_parents($subClass))) {
|
||||||
$ce[] = "According to the discriminator map class '" . $subClass . "' has to be a child ".
|
$ce[] = "According to the discriminator map class '" . $subClass . "' has to be a child ".
|
||||||
|
@ -38,12 +38,6 @@ class SchemaValidatorTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
|||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
$ce = $validator->validateClass($class);
|
$ce = $validator->validateClass($class);
|
||||||
|
|
||||||
foreach ($ce as $key => $error) {
|
|
||||||
if (strpos($error, "must be private or protected. Public fields may break lazy-loading.") !== false) {
|
|
||||||
unset($ce[$key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->assertEquals(0, count($ce), "Invalid Modelset: " . $modelSet . " class " . $class->name . ": ". implode("\n", $ce));
|
$this->assertEquals(0, count($ce), "Invalid Modelset: " . $modelSet . " class " . $class->name . ": ". implode("\n", $ce));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ abstract class SecondLevelCacheAbstractTest extends OrmFunctionalTestCase
|
|||||||
{
|
{
|
||||||
$t1 = new Travel($this->travelers[0]);
|
$t1 = new Travel($this->travelers[0]);
|
||||||
$t2 = new Travel($this->travelers[1]);
|
$t2 = new Travel($this->travelers[1]);
|
||||||
|
$t3 = new Travel($this->travelers[1]);
|
||||||
|
|
||||||
$t1->addVisitedCity($this->cities[0]);
|
$t1->addVisitedCity($this->cities[0]);
|
||||||
$t1->addVisitedCity($this->cities[1]);
|
$t1->addVisitedCity($this->cities[1]);
|
||||||
@ -175,9 +176,11 @@ abstract class SecondLevelCacheAbstractTest extends OrmFunctionalTestCase
|
|||||||
|
|
||||||
$this->_em->persist($t1);
|
$this->_em->persist($t1);
|
||||||
$this->_em->persist($t2);
|
$this->_em->persist($t2);
|
||||||
|
$this->_em->persist($t3);
|
||||||
|
|
||||||
$this->travels[] = $t1;
|
$this->travels[] = $t1;
|
||||||
$this->travels[] = $t2;
|
$this->travels[] = $t2;
|
||||||
|
$this->travels[] = $t3;
|
||||||
|
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ class SecondLevelCacheManyToManyTest extends SecondLevelCacheAbstractTest
|
|||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
$this->_em->clear();
|
$this->_em->clear();
|
||||||
|
|
||||||
$this->assertTrue($this->cache->containsEntity(Traveler::CLASSNAME, $travel->getId()));
|
$this->assertTrue($this->cache->containsEntity(Travel::CLASSNAME, $travel->getId()));
|
||||||
$this->assertTrue($this->cache->containsEntity(Traveler::CLASSNAME, $traveler->getId()));
|
$this->assertTrue($this->cache->containsEntity(Traveler::CLASSNAME, $traveler->getId()));
|
||||||
$this->assertTrue($this->cache->containsEntity(City::CLASSNAME, $this->cities[0]->getId()));
|
$this->assertTrue($this->cache->containsEntity(City::CLASSNAME, $this->cities[0]->getId()));
|
||||||
$this->assertTrue($this->cache->containsEntity(City::CLASSNAME, $this->cities[1]->getId()));
|
$this->assertTrue($this->cache->containsEntity(City::CLASSNAME, $this->cities[1]->getId()));
|
||||||
@ -214,4 +214,33 @@ class SecondLevelCacheManyToManyTest extends SecondLevelCacheAbstractTest
|
|||||||
$this->_em->persist($travel);
|
$this->_em->persist($travel);
|
||||||
$this->_em->flush();
|
$this->_em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testManyToManyWithEmptyRelation()
|
||||||
|
{
|
||||||
|
$this->loadFixturesCountries();
|
||||||
|
$this->loadFixturesStates();
|
||||||
|
$this->loadFixturesCities();
|
||||||
|
$this->loadFixturesTraveler();
|
||||||
|
$this->loadFixturesTravels();
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$this->evictRegions();
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
|
||||||
|
$entitiId = $this->travels[2]->getId(); //empty travel
|
||||||
|
$entity = $this->_em->find(Travel::CLASSNAME, $entitiId);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $entity->getVisitedCities()->count());
|
||||||
|
$this->assertEquals($queryCount+2, $this->getCurrentQueryCount());
|
||||||
|
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$entity = $this->_em->find(Travel::CLASSNAME, $entitiId);
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$this->assertEquals(0, $entity->getVisitedCities()->count());
|
||||||
|
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
@ -284,6 +284,35 @@ class SecondLevelCacheOneToManyTest extends SecondLevelCacheAbstractTest
|
|||||||
$this->assertEquals(0, $this->secondLevelCacheLogger->getRegionHitCount($this->getCollectionRegion(State::CLASSNAME, 'cities')));
|
$this->assertEquals(0, $this->secondLevelCacheLogger->getRegionHitCount($this->getCollectionRegion(State::CLASSNAME, 'cities')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testOneToManyWithEmptyRelation()
|
||||||
|
{
|
||||||
|
$this->loadFixturesCountries();
|
||||||
|
$this->loadFixturesStates();
|
||||||
|
$this->loadFixturesCities();
|
||||||
|
|
||||||
|
$this->secondLevelCacheLogger->clearStats();
|
||||||
|
$this->cache->evictEntityRegion(City::CLASSNAME);
|
||||||
|
$this->cache->evictEntityRegion(State::CLASSNAME);
|
||||||
|
$this->cache->evictCollectionRegion(State::CLASSNAME, 'cities');
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$entitiId = $this->states[2]->getId(); // bavaria (cities count = 0)
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$entity = $this->_em->find(State::CLASSNAME, $entitiId);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $entity->getCities()->count());
|
||||||
|
$this->assertEquals($queryCount + 2, $this->getCurrentQueryCount());
|
||||||
|
|
||||||
|
$this->_em->clear();
|
||||||
|
|
||||||
|
$queryCount = $this->getCurrentQueryCount();
|
||||||
|
$entity = $this->_em->find(State::CLASSNAME, $entitiId);
|
||||||
|
|
||||||
|
$this->assertEquals(0, $entity->getCities()->count());
|
||||||
|
$this->assertEquals($queryCount, $this->getCurrentQueryCount());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function testOneToManyCount()
|
public function testOneToManyCount()
|
||||||
{
|
{
|
||||||
$this->loadFixturesCountries();
|
$this->loadFixturesCountries();
|
||||||
|
@ -2065,7 +2065,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
{
|
{
|
||||||
$this->assertSqlGeneration(
|
$this->assertSqlGeneration(
|
||||||
'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
|
'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
|
||||||
'SELECT c0_.id AS id0 FROM company_organizations c1_ INNER JOIN company_events c0_ ON c1_.id = c0_.org_id AND (c0_.id = ?) LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id',
|
'SELECT c0_.id AS id0 FROM company_organizations c1_ INNER JOIN (company_events c0_ LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id) ON c1_.id = c0_.org_id AND (c0_.id = ?)',
|
||||||
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
|
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user