mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a41b02c080 | ||
|
|
8b3c206bc1 | ||
|
|
e0feccc2e4 | ||
|
|
818d3d27fe | ||
|
|
98d3847a11 | ||
|
|
63918f214b | ||
|
|
acf21246c7 | ||
|
|
795e4a4b6b | ||
|
|
946a22f2c7 | ||
|
|
bdd7482b3f | ||
|
|
8e31107f86 | ||
|
|
209090d338 | ||
|
|
27117bbc98 | ||
|
|
0f2be50d8f | ||
|
|
193e74af05 | ||
|
|
bb6e4f2074 | ||
|
|
6063fe4adf | ||
|
|
846c6d2c5e | ||
|
|
1f257622a1 | ||
|
|
84257c9454 | ||
|
|
eedacc9822 | ||
|
|
3d9099e33b | ||
|
|
ad7b5871bf | ||
|
|
803f2740c9 | ||
|
|
ed3f375ef3 | ||
|
|
a188c88ef2 | ||
|
|
86e40a692b | ||
|
|
36b79309bd | ||
|
|
66b6b7169e | ||
|
|
7c7a8abe40 | ||
|
|
e5c68ab45c | ||
|
|
868bb68cc8 | ||
|
|
b3788c14ee | ||
|
|
3148d8aeac | ||
|
|
ae1f903080 | ||
|
|
07482bd624 | ||
|
|
8d78b90bca | ||
|
|
ca93400493 | ||
|
|
7152e5f72f | ||
|
|
279fcb6c81 | ||
|
|
7705105c5d | ||
|
|
cb70a8a8c4 | ||
|
|
8a2d7374b1 | ||
|
|
563fdb953b | ||
|
|
3daf824c9e | ||
|
|
aa4664687f | ||
|
|
550c1cf98c | ||
|
|
33799d094c | ||
|
|
304acf0a1a | ||
|
|
84996e0601 | ||
|
|
fdd0af34e6 | ||
|
|
f0312edb94 | ||
|
|
6d25c4e08a | ||
|
|
d9f51eb2fa | ||
|
|
88cebe1263 | ||
|
|
6829c464e8 | ||
|
|
fc2eebdf75 | ||
|
|
54193e7f82 | ||
|
|
8001cad573 | ||
|
|
c4c70d667a | ||
|
|
f5bb8be884 | ||
|
|
c5725dd6bb | ||
|
|
b59cd047ff | ||
|
|
019094655b | ||
|
|
88e817660c | ||
|
|
aee75d8f25 | ||
|
|
50132ddc18 | ||
|
|
f05bcbc17c | ||
|
|
f94b6c07c7 | ||
|
|
b68c6b3d2d | ||
|
|
0425e8452d | ||
|
|
c120700d89 | ||
|
|
22dc20c320 | ||
|
|
6d89875306 | ||
|
|
b666a62979 | ||
|
|
f2f8c4f2dd | ||
|
|
59aef2ca95 | ||
|
|
173b398b34 | ||
|
|
de22e726a4 | ||
|
|
dab2b505a4 | ||
|
|
0672688088 | ||
|
|
660f89f745 | ||
|
|
e0aa01ddb6 | ||
|
|
287b29aeaa | ||
|
|
86132283f1 | ||
|
|
f75c3b517d | ||
|
|
6e7e4dd35a | ||
|
|
faedbfc09a | ||
|
|
45269fe4f2 | ||
|
|
a3fea32e0e | ||
|
|
c90ed73b33 | ||
|
|
83943e86a2 | ||
|
|
1aab5feb4a | ||
|
|
469bd02b41 | ||
|
|
24f74bc935 | ||
|
|
77d060ab74 | ||
|
|
01148e52f3 | ||
|
|
5756021571 | ||
|
|
006d3833f6 | ||
|
|
8865a5b90d | ||
|
|
d0698754b2 | ||
|
|
4ea7a5dde4 | ||
|
|
ed11e61812 | ||
|
|
e7e69daabe | ||
|
|
c6eb04de14 | ||
|
|
8c2009c67e | ||
|
|
a7ed9e638b | ||
|
|
643ed0b8f5 | ||
|
|
57db88b62a | ||
|
|
3c944b34ca | ||
|
|
1618a3e393 | ||
|
|
a1094d352c | ||
|
|
e4ef9e03ae | ||
|
|
a3c98b1087 | ||
|
|
2ce877bf8a | ||
|
|
6d35fad70f | ||
|
|
612ed2b3a2 | ||
|
|
95a85d67ea | ||
|
|
edaab11a86 | ||
|
|
1627c974b9 | ||
|
|
c6118cb045 | ||
|
|
461d201e40 | ||
|
|
653aef2c83 | ||
|
|
045d058cec | ||
|
|
9dbf4d8480 | ||
|
|
2229a5e4c6 | ||
|
|
bbf092c6fd | ||
|
|
6fee945fda | ||
|
|
974f18da0c | ||
|
|
9b198be070 | ||
|
|
b610855248 | ||
|
|
994917aa23 | ||
|
|
d64be2888e | ||
|
|
737e47e155 | ||
|
|
ef4ff8be81 | ||
|
|
b53c81ae8d | ||
|
|
6bad010959 | ||
|
|
26cfbdd08b | ||
|
|
e8412b85df | ||
|
|
2e5d7416d8 | ||
|
|
1988944e7e | ||
|
|
564ec1ee2a | ||
|
|
cb0cddef83 | ||
|
|
8b2c92a6bd | ||
|
|
825a68bcba | ||
|
|
abd11374ee | ||
|
|
518357d987 | ||
|
|
4109f22000 | ||
|
|
c60e6523e9 | ||
|
|
04262e2b73 | ||
|
|
084101e287 | ||
|
|
ea2b288578 |
@@ -1,5 +1,13 @@
|
||||
# Upgrade to 2.3
|
||||
|
||||
## EntityManager#find() not calls EntityRepository#find() anymore
|
||||
|
||||
Previous to 2.3, calling ``EntityManager#find()`` would be delegated to
|
||||
``EntityRepository#find()``. This has lead to some unexpected behavior in the
|
||||
core of Doctrine when people have overwritten the find method in their
|
||||
repositories. That is why this behavior has been reversed in 2.3, and
|
||||
``EntityRepository#find()`` calls ``EntityManager#find()`` instead.
|
||||
|
||||
## EntityGenerator add*() method generation
|
||||
|
||||
When generating an add*() method for a collection the EntityGenerator will now not
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"type": "library","version":"2.3.0",
|
||||
"type": "library","version":"2.3.4",
|
||||
"description": "Object-Relational-Mapper for PHP",
|
||||
"keywords": ["orm", "database"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
|
||||
@@ -329,6 +329,7 @@
|
||||
<xs:attribute name="name" type="xs:NMTOKEN" use="required" />
|
||||
<xs:attribute name="type" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="column" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="length" type="xs:NMTOKEN" />
|
||||
<xs:attribute name="association-key" type="xs:boolean" default="false" />
|
||||
<xs:attribute name="column-definition" type="xs:string" />
|
||||
<xs:anyAttribute namespace="##other"/>
|
||||
|
||||
@@ -26,6 +26,7 @@ use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Cache\QueryCacheProfile;
|
||||
|
||||
use Doctrine\ORM\Query\QueryException;
|
||||
use Doctrine\ORM\Mapping;
|
||||
|
||||
/**
|
||||
* Base contract for ORM queries. Base class for Query and NativeQuery.
|
||||
@@ -259,6 +260,9 @@ abstract class AbstractQuery
|
||||
case is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value)):
|
||||
return $this->convertObjectParameterToScalarValue($value);
|
||||
|
||||
case ($value instanceof Mapping\ClassMetadata):
|
||||
return $value->name;
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
@@ -281,7 +285,7 @@ abstract class AbstractQuery
|
||||
|
||||
$value = $values[$class->getSingleIdentifierFieldName()];
|
||||
|
||||
if ( ! $value) {
|
||||
if (null === $value) {
|
||||
throw new \InvalidArgumentException(
|
||||
"Binding entities to query parameters only allowed for entities that have an identifier."
|
||||
);
|
||||
|
||||
@@ -161,13 +161,14 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
* Finds a single entity by a set of criteria.
|
||||
*
|
||||
* @param array $criteria
|
||||
* @param array|null $orderBy
|
||||
* @return object
|
||||
*/
|
||||
public function findOneBy(array $criteria)
|
||||
public function findOneBy(array $criteria, array $orderBy = null)
|
||||
{
|
||||
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
|
||||
|
||||
return $persister->load($criteria, null, null, array(), 0, 1);
|
||||
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,7 +216,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
case 3:
|
||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
|
||||
|
||||
case 4;
|
||||
case 4:
|
||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
|
||||
|
||||
default:
|
||||
|
||||
66
lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php
Normal file
66
lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* Id generator that obtains IDs from special "identity" columns. These are columns
|
||||
* that automatically get a database-generated, auto-incremented identifier on INSERT.
|
||||
* This generator obtains the last insert id after such an insert.
|
||||
*/
|
||||
class BigIntegerIdentityGenerator extends AbstractIdGenerator
|
||||
{
|
||||
/**
|
||||
* The name of the sequence to pass to lastInsertId(), if any.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sequenceName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string|null $seqName The name of the sequence to pass to lastInsertId()
|
||||
* to obtain the last generated identifier within the current
|
||||
* database session/connection, if any.
|
||||
*/
|
||||
public function __construct($sequenceName = null)
|
||||
{
|
||||
$this->sequenceName = $sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return (string)$em->getConnection()->lastInsertId($this->sequenceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isPostInsertGenerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,17 +28,21 @@ use Doctrine\ORM\EntityManager;
|
||||
*/
|
||||
class IdentityGenerator extends AbstractIdGenerator
|
||||
{
|
||||
/** @var string The name of the sequence to pass to lastInsertId(), if any. */
|
||||
private $_seqName;
|
||||
/**
|
||||
* The name of the sequence to pass to lastInsertId(), if any.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $sequenceName;
|
||||
|
||||
/**
|
||||
* @param string $seqName The name of the sequence to pass to lastInsertId()
|
||||
* to obtain the last generated identifier within the current
|
||||
* database session/connection, if any.
|
||||
*/
|
||||
public function __construct($seqName = null)
|
||||
public function __construct($sequenceName = null)
|
||||
{
|
||||
$this->_seqName = $seqName;
|
||||
$this->sequenceName = $sequenceName;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +50,7 @@ class IdentityGenerator extends AbstractIdGenerator
|
||||
*/
|
||||
public function generate(EntityManager $em, $entity)
|
||||
{
|
||||
return (int)$em->getConnection()->lastInsertId($this->_seqName);
|
||||
return (int)$em->getConnection()->lastInsertId($this->sequenceName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ use PDO,
|
||||
Doctrine\ORM\Events,
|
||||
Doctrine\Common\Collections\ArrayCollection,
|
||||
Doctrine\Common\Collections\Collection,
|
||||
Doctrine\ORM\UnitOfWork,
|
||||
Doctrine\ORM\Proxy\Proxy;
|
||||
|
||||
/**
|
||||
@@ -65,8 +66,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
$this->_resultCounter = 0;
|
||||
|
||||
if ( ! isset($this->_hints['deferEagerLoad'])) {
|
||||
$this->_hints['deferEagerLoad'] = true;
|
||||
if ( ! isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) {
|
||||
$this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] = true;
|
||||
}
|
||||
|
||||
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
|
||||
@@ -123,7 +124,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
*/
|
||||
protected function cleanup()
|
||||
{
|
||||
$eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
|
||||
$eagerLoad = (isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) && $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] == true;
|
||||
|
||||
parent::cleanup();
|
||||
|
||||
|
||||
@@ -178,10 +178,13 @@ class SimpleObjectHydrator extends AbstractHydrator
|
||||
// One solution is to load the association, but it might require extra efforts.
|
||||
return array('name' => $column);
|
||||
|
||||
default:
|
||||
case (isset($this->_rsm->metaMappings[$column])):
|
||||
return array(
|
||||
'name' => $this->_rsm->metaMappings[$column]
|
||||
);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use ReflectionException,
|
||||
Doctrine\ORM\ORMException,
|
||||
Doctrine\ORM\EntityManager,
|
||||
Doctrine\DBAL\Platforms,
|
||||
Doctrine\ORM\Events,
|
||||
Doctrine\Common\Persistence\Mapping\ReflectionService,
|
||||
Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface,
|
||||
Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory,
|
||||
Doctrine\ORM\Id\IdentityGenerator,
|
||||
Doctrine\ORM\Event\LoadClassMetadataEventArgs;
|
||||
use ReflectionException;
|
||||
use Doctrine\ORM\ORMException;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\DBAL\Platforms;
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\Common\Persistence\Mapping\ReflectionService;
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata as ClassMetadataInterface;
|
||||
use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory;
|
||||
use Doctrine\ORM\Id\IdentityGenerator;
|
||||
use Doctrine\ORM\Id\BigIntegerIdentityGenerator;
|
||||
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
|
||||
|
||||
/**
|
||||
* The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
|
||||
@@ -418,9 +419,9 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
|
||||
// Not pretty but necessary and the simplest solution that currently works.
|
||||
$sequenceName = null;
|
||||
$fieldName = $class->identifier ? $class->getSingleIdentifierFieldName() : null;
|
||||
|
||||
if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) {
|
||||
$fieldName = $class->getSingleIdentifierFieldName();
|
||||
$columnName = $class->getSingleIdentifierColumnName();
|
||||
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
|
||||
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
|
||||
@@ -435,7 +436,12 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
|
||||
}
|
||||
|
||||
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($sequenceName));
|
||||
$generator = ($fieldName && $class->fieldMappings[$fieldName]['type'] === "bigint")
|
||||
? new BigIntegerIdentityGenerator($sequenceName)
|
||||
: new IdentityGenerator($sequenceName);
|
||||
|
||||
$class->setIdGenerator($generator);
|
||||
|
||||
break;
|
||||
|
||||
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
|
||||
|
||||
@@ -1421,6 +1421,10 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
|
||||
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
|
||||
|
||||
if ($mapping['orphanRemoval']) {
|
||||
unset($mapping['unique']);
|
||||
}
|
||||
|
||||
if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) {
|
||||
throw MappingException::illegalInverseIdentifierAssocation($this->name, $mapping['fieldName']);
|
||||
}
|
||||
@@ -1478,6 +1482,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
'onDelete' => 'CASCADE'));
|
||||
}
|
||||
|
||||
$mapping['joinTableColumns'] = array();
|
||||
|
||||
foreach ($mapping['joinTable']['joinColumns'] as &$joinColumn) {
|
||||
if (empty($joinColumn['name'])) {
|
||||
$joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
|
||||
|
||||
@@ -217,7 +217,8 @@ class DatabaseDriver implements MappingDriver
|
||||
}
|
||||
|
||||
if ($ids) {
|
||||
if (count($ids) == 1) {
|
||||
// We need to check for the columns here, because we might have associations as id as well.
|
||||
if (count($primaryKeyColumns) == 1) {
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
}
|
||||
|
||||
@@ -297,6 +298,10 @@ class DatabaseDriver implements MappingDriver
|
||||
$associationMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $localColumn, true);
|
||||
$associationMapping['targetEntity'] = $this->getClassNameForTable($foreignTable);
|
||||
|
||||
if (isset($metadata->fieldMappings[$associationMapping['fieldName']])) {
|
||||
$associationMapping['fieldName'] = $associationMapping['fieldName'] . "2";
|
||||
}
|
||||
|
||||
if ($primaryKeyColumns && in_array($localColumn, $primaryKeyColumns)) {
|
||||
$associationMapping['id'] = true;
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class XmlDriver extends FileDriver
|
||||
if (isset($xmlRoot['repository-class'])) {
|
||||
$metadata->setCustomRepositoryClass((string)$xmlRoot['repository-class']);
|
||||
}
|
||||
if (isset($xmlRoot['read-only']) && $xmlRoot['read-only'] == "true") {
|
||||
if (isset($xmlRoot['read-only']) && $this->evaluateBoolean($xmlRoot['read-only'])) {
|
||||
$metadata->markReadOnly();
|
||||
}
|
||||
} else if ($xmlRoot->getName() == 'mapped-superclass') {
|
||||
@@ -230,18 +230,28 @@ class XmlDriver extends FileDriver
|
||||
if (isset($xmlRoot->field)) {
|
||||
foreach ($xmlRoot->field as $fieldMapping) {
|
||||
$mapping = $this->columnToArray($fieldMapping);
|
||||
|
||||
if (isset($mapping['version'])) {
|
||||
$metadata->setVersionMapping($mapping);
|
||||
unset($mapping['version']);
|
||||
}
|
||||
|
||||
$metadata->mapField($mapping);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($mappings as $mapping) {
|
||||
$metadata->mapField($mapping);
|
||||
if (isset($mapping['version'])) {
|
||||
$metadata->setVersionMapping($mapping);
|
||||
}
|
||||
|
||||
$metadata->mapField($mapping);
|
||||
}
|
||||
|
||||
// Evaluate <id ...> mappings
|
||||
$associationIds = array();
|
||||
foreach ($xmlRoot->id as $idElement) {
|
||||
if ((bool)$idElement['association-key'] == true) {
|
||||
if (isset($idElement['association-key']) && $this->evaluateBoolean($idElement['association-key'])) {
|
||||
$associationIds[(string)$idElement['name']] = true;
|
||||
continue;
|
||||
}
|
||||
@@ -334,7 +344,7 @@ class XmlDriver extends FileDriver
|
||||
}
|
||||
|
||||
if (isset($oneToOneElement['orphan-removal'])) {
|
||||
$mapping['orphanRemoval'] = (bool)$oneToOneElement['orphan-removal'];
|
||||
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToOneElement['orphan-removal']);
|
||||
}
|
||||
|
||||
$metadata->mapOneToOne($mapping);
|
||||
@@ -359,7 +369,7 @@ class XmlDriver extends FileDriver
|
||||
}
|
||||
|
||||
if (isset($oneToManyElement['orphan-removal'])) {
|
||||
$mapping['orphanRemoval'] = (bool)$oneToManyElement['orphan-removal'];
|
||||
$mapping['orphanRemoval'] = $this->evaluateBoolean($oneToManyElement['orphan-removal']);
|
||||
}
|
||||
|
||||
if (isset($oneToManyElement->{'order-by'})) {
|
||||
@@ -433,7 +443,7 @@ class XmlDriver extends FileDriver
|
||||
}
|
||||
|
||||
if (isset($manyToManyElement['orphan-removal'])) {
|
||||
$mapping['orphanRemoval'] = (bool)$manyToManyElement['orphan-removal'];
|
||||
$mapping['orphanRemoval'] = $this->evaluateBoolean($manyToManyElement['orphan-removal']);
|
||||
}
|
||||
|
||||
if (isset($manyToManyElement['mapped-by'])) {
|
||||
@@ -594,11 +604,11 @@ class XmlDriver extends FileDriver
|
||||
);
|
||||
|
||||
if (isset($joinColumnElement['unique'])) {
|
||||
$joinColumn['unique'] = ((string)$joinColumnElement['unique'] == "false") ? false : true;
|
||||
$joinColumn['unique'] = $this->evaluateBoolean($joinColumnElement['unique']);
|
||||
}
|
||||
|
||||
if (isset($joinColumnElement['nullable'])) {
|
||||
$joinColumn['nullable'] = ((string)$joinColumnElement['nullable'] == "false") ? false : true;
|
||||
$joinColumn['nullable'] = $this->evaluateBoolean($joinColumnElement['nullable']);
|
||||
}
|
||||
|
||||
if (isset($joinColumnElement['on-delete'])) {
|
||||
@@ -645,15 +655,15 @@ class XmlDriver extends FileDriver
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['unique'])) {
|
||||
$mapping['unique'] = ((string) $fieldMapping['unique'] == "false") ? false : true;
|
||||
$mapping['unique'] = $this->evaluateBoolean($fieldMapping['unique']);
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['nullable'])) {
|
||||
$mapping['nullable'] = ((string) $fieldMapping['nullable'] == "false") ? false : true;
|
||||
$mapping['nullable'] = $this->evaluateBoolean($fieldMapping['nullable']);
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['version']) && $fieldMapping['version']) {
|
||||
$mapping['version'] = $fieldMapping['version'];
|
||||
$mapping['version'] = $this->evaluateBoolean($fieldMapping['version']);
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['column-definition'])) {
|
||||
@@ -710,4 +720,12 @@ class XmlDriver extends FileDriver
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function evaluateBoolean($element)
|
||||
{
|
||||
$flag = (string)$element;
|
||||
|
||||
return ($flag === true || $flag == "true" || $flag == "1");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -198,6 +198,7 @@ class YamlDriver extends FileDriver
|
||||
|
||||
if (is_string($index['columns'])) {
|
||||
$columns = explode(',', $index['columns']);
|
||||
$columns = array_map('trim', $columns);
|
||||
} else {
|
||||
$columns = $index['columns'];
|
||||
}
|
||||
@@ -217,6 +218,7 @@ class YamlDriver extends FileDriver
|
||||
|
||||
if (is_string($unique['columns'])) {
|
||||
$columns = explode(',', $unique['columns']);
|
||||
$columns = array_map('trim', $columns);
|
||||
} else {
|
||||
$columns = $unique['columns'];
|
||||
}
|
||||
@@ -295,6 +297,11 @@ class YamlDriver extends FileDriver
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($mapping['version'])) {
|
||||
$metadata->setVersionMapping($mapping);
|
||||
unset($mapping['version']);
|
||||
}
|
||||
|
||||
$metadata->mapField($mapping);
|
||||
}
|
||||
}
|
||||
@@ -628,7 +635,7 @@ class YamlDriver extends FileDriver
|
||||
$mapping['type'] = $column['type'];
|
||||
|
||||
if (isset($params[1])) {
|
||||
$column['length'] = substr($params[1], 0, strlen($params[1]) - 1);
|
||||
$column['length'] = (integer) substr($params[1], 0, strlen($params[1]) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
|
||||
public static function identifierRequired($entityName)
|
||||
{
|
||||
if (null !== ($parent = get_parent_class($entityName))) {
|
||||
if (false !== ($parent = get_parent_class($entityName))) {
|
||||
return new self(sprintf(
|
||||
'No identifier/primary key specified for Entity "%s" sub class of "%s". Every Entity must have an identifier/primary key.',
|
||||
$entityName, $parent
|
||||
@@ -206,7 +206,7 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
|
||||
public static function classIsNotAValidEntityOrMappedSuperClass($className)
|
||||
{
|
||||
if (null !== ($parent = get_parent_class($className))) {
|
||||
if (false !== ($parent = get_parent_class($className))) {
|
||||
return new self(sprintf(
|
||||
'Class "%s" sub class of "%s" is not a valid entity or mapped super class.',
|
||||
$className, $parent
|
||||
|
||||
@@ -655,7 +655,7 @@ final class PersistentCollection implements Collection, Selectable
|
||||
|
||||
$this->initialized = true; // direct call, {@link initialize()} is too expensive
|
||||
|
||||
if ($this->association['isOwningSide']) {
|
||||
if ($this->association['isOwningSide'] && $this->owner) {
|
||||
$this->changed();
|
||||
|
||||
$uow->scheduleCollectionDeletion($this);
|
||||
@@ -805,6 +805,10 @@ final class PersistentCollection implements Collection, Selectable
|
||||
*/
|
||||
public function matching(Criteria $criteria)
|
||||
{
|
||||
if ($this->isDirty) {
|
||||
$this->initialize();
|
||||
}
|
||||
|
||||
if ($this->initialized) {
|
||||
return $this->coll->matching($criteria);
|
||||
}
|
||||
@@ -813,16 +817,10 @@ final class PersistentCollection implements Collection, Selectable
|
||||
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany assocations at the moment.");
|
||||
}
|
||||
|
||||
// If there are NEW objects we have to check if any of them matches the criteria
|
||||
$newObjects = array();
|
||||
|
||||
if ($this->isDirty) {
|
||||
$newObjects = $this->coll->matching($criteria)->toArray();
|
||||
}
|
||||
|
||||
$targetClass = $this->em->getClassMetadata(get_class($this->owner));
|
||||
|
||||
$id = $targetClass->getSingleIdReflectionProperty()->getValue($this->owner);
|
||||
$id = $this->em
|
||||
->getClassMetadata(get_class($this->owner))
|
||||
->getSingleIdReflectionProperty()
|
||||
->getValue($this->owner);
|
||||
$builder = Criteria::expr();
|
||||
$ownerExpression = $builder->eq($this->backRefFieldName, $id);
|
||||
$expression = $criteria->getWhereExpression();
|
||||
@@ -832,7 +830,7 @@ final class PersistentCollection implements Collection, Selectable
|
||||
|
||||
$persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']);
|
||||
|
||||
return new ArrayCollection(array_merge($persister->loadCriteria($criteria), $newObjects));
|
||||
return new ArrayCollection($persister->loadCriteria($criteria));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class BasicEntityPersister
|
||||
*/
|
||||
static private $comparisonMap = array(
|
||||
Comparison::EQ => '= %s',
|
||||
Comparison::IS => '= %s',
|
||||
Comparison::IS => 'IS %s',
|
||||
Comparison::NEQ => '!= %s',
|
||||
Comparison::GT => '> %s',
|
||||
Comparison::GTE => '>= %s',
|
||||
@@ -659,12 +659,13 @@ class BasicEntityPersister
|
||||
* @param array $hints Hints for entity creation.
|
||||
* @param int $lockMode
|
||||
* @param int $limit Limit number of results
|
||||
* @param array $orderBy Criteria to order by
|
||||
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
|
||||
* @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
|
||||
*/
|
||||
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null)
|
||||
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null, array $orderBy = null)
|
||||
{
|
||||
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit);
|
||||
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy);
|
||||
list($params, $types) = $this->expandParameters($criteria);
|
||||
$stmt = $this->_conn->executeQuery($sql, $params, $types);
|
||||
|
||||
@@ -789,7 +790,7 @@ class BasicEntityPersister
|
||||
|
||||
$hydrator = $this->_em->newHydrator(($this->_selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
|
||||
|
||||
return $hydrator->hydrateAll($stmt, $this->_rsm, array('deferEagerLoads' => true));
|
||||
return $hydrator->hydrateAll($stmt, $this->_rsm, array(UnitOfWork::HINT_DEFEREAGERLOAD => true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -844,7 +845,7 @@ class BasicEntityPersister
|
||||
|
||||
$hydrator = $this->_em->newHydrator(($this->_selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
|
||||
|
||||
return $hydrator->hydrateAll($stmt, $this->_rsm, array('deferEagerLoads' => true));
|
||||
return $hydrator->hydrateAll($stmt, $this->_rsm, array(UnitOfWork::HINT_DEFEREAGERLOAD => true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -873,7 +874,7 @@ class BasicEntityPersister
|
||||
*/
|
||||
private function loadArrayFromStatement($assoc, $stmt)
|
||||
{
|
||||
$hints = array('deferEagerLoads' => true);
|
||||
$hints = array(UnitOfWork::HINT_DEFEREAGERLOAD => true);
|
||||
|
||||
if (isset($assoc['indexBy'])) {
|
||||
$rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed.
|
||||
@@ -898,7 +899,7 @@ class BasicEntityPersister
|
||||
*/
|
||||
private function loadCollectionFromStatement($assoc, $stmt, $coll)
|
||||
{
|
||||
$hints = array('deferEagerLoads' => true, 'collection' => $coll);
|
||||
$hints = array(UnitOfWork::HINT_DEFEREAGERLOAD => true, 'collection' => $coll);
|
||||
|
||||
if (isset($assoc['indexBy'])) {
|
||||
$rsm = clone ($this->_rsm); // this is necessary because the "default rsm" should be changed.
|
||||
@@ -1699,7 +1700,11 @@ class BasicEntityPersister
|
||||
$idValues = $class->getIdentifierValues($value);
|
||||
}
|
||||
|
||||
$value = $idValues[key($idValues)];
|
||||
$key = key($idValues);
|
||||
|
||||
if (null !== $key){
|
||||
$value = $idValues[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -227,8 +227,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
|
||||
// Make sure the table with the version column is updated even if no columns on that
|
||||
// table were affected.
|
||||
if ($isVersioned && ! isset($updateData[$versionedTable])) {
|
||||
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
|
||||
if ($isVersioned) {
|
||||
if ( ! isset($updateData[$versionedTable])) {
|
||||
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
|
||||
}
|
||||
|
||||
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
|
||||
$this->assignDefaultVersionValue($entity, $id);
|
||||
@@ -468,7 +470,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
}
|
||||
} else if ($this->_class->name != $this->_class->rootEntityName ||
|
||||
! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
|
||||
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
|
||||
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
|
||||
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,22 +186,22 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*/
|
||||
protected function _getDeleteSQLParameters(PersistentCollection $coll)
|
||||
{
|
||||
$identifier = $this->_uow->getEntityIdentifier($coll->getOwner());
|
||||
$mapping = $coll->getMapping();
|
||||
$params = array();
|
||||
$identifier = $this->_uow->getEntityIdentifier($coll->getOwner());
|
||||
|
||||
// Optimization for single column identifier
|
||||
if (count($mapping['relationToSourceKeyColumns']) === 1) {
|
||||
$params[] = array_pop($identifier);
|
||||
|
||||
return $params;
|
||||
return array(reset($identifier));
|
||||
}
|
||||
|
||||
// Composite identifier
|
||||
$sourceClass = $this->_em->getClassMetadata(get_class($coll->getOwner()));
|
||||
$params = array();
|
||||
|
||||
foreach ($mapping['relationToSourceKeyColumns'] as $srcColumn) {
|
||||
$params[] = $identifier[$sourceClass->fieldNames[$srcColumn]];
|
||||
foreach ($mapping['relationToSourceKeyColumns'] as $columnName => $refColumnName) {
|
||||
$params[] = isset($sourceClass->fieldNames[$refColumnName])
|
||||
? $identifier[$sourceClass->fieldNames[$refColumnName]]
|
||||
: $identifier[$sourceClass->getFieldForColumn($columnName)];
|
||||
}
|
||||
|
||||
return $params;
|
||||
|
||||
@@ -40,6 +40,6 @@ class JoinClassPathExpression extends Node
|
||||
|
||||
public function dispatch($walker)
|
||||
{
|
||||
return $sqlWalker->walkJoinPathExpression($this);
|
||||
return $walker->walkJoinPathExpression($this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,19 +104,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
|
||||
|
||||
$updateSql .= $sqlWalker->walkUpdateItem($updateItem);
|
||||
|
||||
//FIXME: parameters can be more deeply nested. traverse the tree.
|
||||
//FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
|
||||
if ($newValue instanceof AST\InputParameter) {
|
||||
$parameterName = $newValue->name;
|
||||
$parameter = $sqlWalker->getQuery()->getParameter($parameterName);
|
||||
|
||||
$value = $sqlWalker->getQuery()->processParameterValue($parameter->getValue());
|
||||
$type = ($parameter->getValue() === $value)
|
||||
? $parameter->getType()
|
||||
: ParameterTypeInferer::inferType($value);
|
||||
|
||||
$this->_sqlParameters[$i]['parameters'][] = $value;
|
||||
$this->_sqlParameters[$i]['types'][] = $type;
|
||||
$this->_sqlParameters[$i][] = $newValue->name;
|
||||
|
||||
++$this->_numParametersInUpdateClause;
|
||||
}
|
||||
@@ -168,16 +157,18 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
|
||||
);
|
||||
|
||||
// Execute UPDATE statements
|
||||
for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) {
|
||||
$parameters = array();
|
||||
$types = array();
|
||||
foreach ($this->_sqlStatements as $key => $statement) {
|
||||
$paramValues = array();
|
||||
$paramTypes = array();
|
||||
|
||||
if (isset($this->_sqlParameters[$i])) {
|
||||
$parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array();
|
||||
$types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array();
|
||||
if (isset($this->_sqlParameters[$key])) {
|
||||
foreach ($this->_sqlParameters[$key] as $parameterKey => $parameterName) {
|
||||
$paramValues[] = $params[$parameterKey];
|
||||
$paramTypes[] = isset($types[$parameterKey]) ? $types[$parameterKey] : ParameterTypeInferer::inferType($params[$parameterKey]);
|
||||
}
|
||||
}
|
||||
|
||||
$conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types);
|
||||
$conn->executeUpdate($statement, $paramValues, $paramTypes);
|
||||
}
|
||||
} catch (\Exception $exception) {
|
||||
// FAILURE! Drop temporary table to avoid possible collisions
|
||||
|
||||
@@ -83,7 +83,7 @@ abstract class Base
|
||||
*/
|
||||
public function add($arg)
|
||||
{
|
||||
if ( $arg !== null || ($arg instanceof self && $arg->count() > 0) ) {
|
||||
if ( $arg !== null && (!$arg instanceof self || $arg->count() > 0) ) {
|
||||
// If we decide to keep Expr\Base instances, we can use this check
|
||||
if ( ! is_string($arg)) {
|
||||
$class = get_class($arg);
|
||||
|
||||
@@ -141,7 +141,7 @@ class Join
|
||||
{
|
||||
return strtoupper($this->joinType) . ' JOIN ' . $this->join
|
||||
. ($this->alias ? ' ' . $this->alias : '')
|
||||
. ($this->condition ? ' ' . strtoupper($this->conditionType) . ' ' . $this->condition : '')
|
||||
. ($this->indexBy ? ' INDEX BY ' . $this->indexBy : '');
|
||||
. ($this->indexBy ? ' INDEX BY ' . $this->indexBy : '')
|
||||
. ($this->condition ? ' ' . strtoupper($this->conditionType) . ' ' . $this->condition : '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
|
||||
namespace Doctrine\ORM\Query\Filter;
|
||||
|
||||
use Doctrine\ORM\EntityManager,
|
||||
Doctrine\ORM\Mapping\ClassMetaData,
|
||||
Doctrine\ORM\Query\ParameterTypeInferer;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Query\ParameterTypeInferer;
|
||||
|
||||
/**
|
||||
* The base class that user defined filters should extend.
|
||||
|
||||
@@ -750,7 +750,10 @@ class SqlWalker implements TreeWalker
|
||||
$sqlParts = array();
|
||||
|
||||
foreach ($identificationVarDecls as $identificationVariableDecl) {
|
||||
$sql = $this->walkRangeVariableDeclaration($identificationVariableDecl->rangeVariableDeclaration);
|
||||
$sql = $this->platform->appendLockHint(
|
||||
$this->walkRangeVariableDeclaration($identificationVariableDecl->rangeVariableDeclaration),
|
||||
$this->query->getHint(Query::HINT_LOCK_MODE)
|
||||
);
|
||||
|
||||
foreach ($identificationVariableDecl->joins as $join) {
|
||||
$sql .= $this->walkJoin($join);
|
||||
@@ -770,7 +773,7 @@ class SqlWalker implements TreeWalker
|
||||
}
|
||||
}
|
||||
|
||||
$sqlParts[] = $this->platform->appendLockHint($sql, $this->query->getHint(Query::HINT_LOCK_MODE));
|
||||
$sqlParts[] = $sql;
|
||||
}
|
||||
|
||||
return ' FROM ' . implode(', ', $sqlParts);
|
||||
@@ -1007,8 +1010,13 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
switch (true) {
|
||||
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\RangeVariableDeclaration):
|
||||
$class = $this->em->getClassMetadata($joinDeclaration->abstractSchemaName);
|
||||
$condExprConjunction = $class->isInheritanceTypeJoined() && $joinType != AST\Join::JOIN_TYPE_LEFT && $joinType != AST\Join::JOIN_TYPE_LEFTOUTER
|
||||
? ' AND '
|
||||
: ' ON ';
|
||||
|
||||
$sql .= $this->walkRangeVariableDeclaration($joinDeclaration)
|
||||
. ' ON (' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
|
||||
. $condExprConjunction . '(' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
|
||||
break;
|
||||
|
||||
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\JoinAssociationDeclaration):
|
||||
@@ -1147,7 +1155,7 @@ class SqlWalker implements TreeWalker
|
||||
switch (true) {
|
||||
case ($expr instanceof AST\PathExpression):
|
||||
if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) {
|
||||
throw QueryException::invalidPathExpression($expr->type);
|
||||
throw QueryException::invalidPathExpression($expr);
|
||||
}
|
||||
|
||||
$fieldName = $expr->field;
|
||||
@@ -1188,7 +1196,6 @@ class SqlWalker implements TreeWalker
|
||||
case ($expr instanceof AST\SimpleArithmeticExpression):
|
||||
case ($expr instanceof AST\ArithmeticTerm):
|
||||
case ($expr instanceof AST\ArithmeticFactor):
|
||||
case ($expr instanceof AST\ArithmeticPrimary):
|
||||
case ($expr instanceof AST\Literal):
|
||||
case ($expr instanceof AST\NullIfExpression):
|
||||
case ($expr instanceof AST\CoalesceExpression):
|
||||
@@ -1363,13 +1370,16 @@ class SqlWalker implements TreeWalker
|
||||
$sqlParts = array ();
|
||||
|
||||
foreach ($identificationVarDecls as $subselectIdVarDecl) {
|
||||
$sql = $this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration);
|
||||
$sql = $this->platform->appendLockHint(
|
||||
$this->walkRangeVariableDeclaration($subselectIdVarDecl->rangeVariableDeclaration),
|
||||
$this->query->getHint(Query::HINT_LOCK_MODE)
|
||||
);
|
||||
|
||||
foreach ($subselectIdVarDecl->joins as $join) {
|
||||
$sql .= $this->walkJoin($join);
|
||||
}
|
||||
|
||||
$sqlParts[] = $this->platform->appendLockHint($sql, $this->query->getHint(Query::HINT_LOCK_MODE));
|
||||
$sqlParts[] = $sql;
|
||||
}
|
||||
|
||||
return ' FROM ' . implode(', ', $sqlParts);
|
||||
@@ -1422,7 +1432,6 @@ class SqlWalker implements TreeWalker
|
||||
case ($expr instanceof AST\SimpleArithmeticExpression):
|
||||
case ($expr instanceof AST\ArithmeticTerm):
|
||||
case ($expr instanceof AST\ArithmeticFactor):
|
||||
case ($expr instanceof AST\ArithmeticPrimary):
|
||||
case ($expr instanceof AST\Literal):
|
||||
case ($expr instanceof AST\NullIfExpression):
|
||||
case ($expr instanceof AST\CoalesceExpression):
|
||||
@@ -1609,7 +1618,7 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
if (count($filterClauses)) {
|
||||
if ($condSql) {
|
||||
$condSql .= ' AND ';
|
||||
$condSql = '(' . $condSql . ') AND ';
|
||||
}
|
||||
|
||||
$condSql .= implode(' AND ', $filterClauses);
|
||||
@@ -1907,31 +1916,22 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
foreach ($instanceOfExpr->value as $parameter) {
|
||||
if ($parameter instanceof AST\InputParameter) {
|
||||
// We need to modify the parameter value to be its correspondent mapped value
|
||||
$dqlParamKey = $parameter->name;
|
||||
$dqlParam = $this->query->getParameter($dqlParamKey);
|
||||
$paramValue = $this->query->processParameterValue($dqlParam->getValue());
|
||||
|
||||
if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
|
||||
throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
|
||||
}
|
||||
|
||||
$entityClassName = $paramValue->name;
|
||||
$sqlParameterList[] = $this->walkInputParameter($parameter);
|
||||
} else {
|
||||
// Get name from ClassMetadata to resolve aliases.
|
||||
$entityClassName = $this->em->getClassMetadata($parameter)->name;
|
||||
}
|
||||
|
||||
if ($entityClassName == $class->name) {
|
||||
$sqlParameterList[] = $this->conn->quote($class->discriminatorValue);
|
||||
} else {
|
||||
$discrMap = array_flip($class->discriminatorMap);
|
||||
if ($entityClassName == $class->name) {
|
||||
$sqlParameterList[] = $this->conn->quote($class->discriminatorValue);
|
||||
} else {
|
||||
$discrMap = array_flip($class->discriminatorMap);
|
||||
|
||||
if (!isset($discrMap[$entityClassName])) {
|
||||
throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
|
||||
if (!isset($discrMap[$entityClassName])) {
|
||||
throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
|
||||
}
|
||||
|
||||
$sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]);
|
||||
}
|
||||
|
||||
$sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,38 @@ class EntityGenerator
|
||||
Type::SIMPLE_ARRAY => 'array',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Hash-map to handle generator types string.
|
||||
*/
|
||||
protected static $generatorStrategyMap = array(
|
||||
ClassMetadataInfo::GENERATOR_TYPE_AUTO => 'AUTO',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE => 'SEQUENCE',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_TABLE => 'TABLE',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_IDENTITY => 'IDENTITY',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_NONE => 'NONE',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_UUID => 'UUID',
|
||||
ClassMetadataInfo::GENERATOR_TYPE_CUSTOM => 'CUSTOM'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Hash-map to handle the change tracking policy string.
|
||||
*/
|
||||
protected static $changeTrackingPolicyMap = array(
|
||||
ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT => 'DEFERRED_IMPLICIT',
|
||||
ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT => 'DEFERRED_EXPLICIT',
|
||||
ClassMetadataInfo::CHANGETRACKING_NOTIFY => 'NOTIFY',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Hash-map to handle the inheritance type string.
|
||||
*/
|
||||
protected static $inheritanceTypeMap = array(
|
||||
ClassMetadataInfo::INHERITANCE_TYPE_NONE => 'NONE',
|
||||
ClassMetadataInfo::INHERITANCE_TYPE_JOINED => 'JOINED',
|
||||
ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE => 'SINGLE_TABLE',
|
||||
ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS => 'TABLE_PER_CLASS',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
@@ -672,7 +704,7 @@ public function __construct()
|
||||
{
|
||||
$lines = array();
|
||||
$lines[] = '/**';
|
||||
$lines[] = ' * '.$metadata->name;
|
||||
$lines[] = ' * ' . $this->getClassName($metadata);
|
||||
|
||||
if ($this->generateAnnotations) {
|
||||
$lines[] = ' *';
|
||||
@@ -909,9 +941,14 @@ public function __construct()
|
||||
$var = sprintf('%sMethodTemplate', $type);
|
||||
$template = self::$$var;
|
||||
|
||||
$methodTypeHint = null;
|
||||
$types = Type::getTypesMap();
|
||||
$variableType = $typeHint ? $this->getType($typeHint) . ' ' : null;
|
||||
$methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
|
||||
|
||||
if ($typeHint && ! isset($types[$typeHint])) {
|
||||
$variableType = '\\' . ltrim($variableType, '\\');
|
||||
$methodTypeHint = '\\' . $typeHint . ' ';
|
||||
}
|
||||
|
||||
$replacements = array(
|
||||
'<description>' => ucfirst($type) . ' ' . $fieldName,
|
||||
@@ -991,9 +1028,9 @@ public function __construct()
|
||||
$lines[] = $this->spaces . '/**';
|
||||
|
||||
if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
|
||||
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\ArrayCollection';
|
||||
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\Collection';
|
||||
} else {
|
||||
$lines[] = $this->spaces . ' * @var ' . $associationMapping['targetEntity'];
|
||||
$lines[] = $this->spaces . ' * @var \\' . ltrim($associationMapping['targetEntity'], '\\');
|
||||
}
|
||||
|
||||
if ($this->generateAnnotations) {
|
||||
@@ -1052,6 +1089,15 @@ public function __construct()
|
||||
$typeOptions[] = 'orphanRemoval=' . ($associationMapping['orphanRemoval'] ? 'true' : 'false');
|
||||
}
|
||||
|
||||
if (isset($associationMapping['fetch']) && $associationMapping['fetch'] !== ClassMetadataInfo::FETCH_LAZY) {
|
||||
$fetchMap = array(
|
||||
ClassMetadataInfo::FETCH_EXTRA_LAZY => 'EXTRA_LAZY',
|
||||
ClassMetadataInfo::FETCH_EAGER => 'EAGER',
|
||||
);
|
||||
|
||||
$typeOptions[] = 'fetch="' . $fetchMap[$associationMapping['fetch']] . '"';
|
||||
}
|
||||
|
||||
$lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . '' . $type . '(' . implode(', ', $typeOptions) . ')';
|
||||
|
||||
if (isset($associationMapping['joinColumns']) && $associationMapping['joinColumns']) {
|
||||
@@ -1080,17 +1126,23 @@ public function __construct()
|
||||
$lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . 'JoinTable(' . implode(', ', $joinTable) . ',';
|
||||
$lines[] = $this->spaces . ' * joinColumns={';
|
||||
|
||||
$joinColumnsLines = array();
|
||||
|
||||
foreach ($associationMapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||
$lines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
|
||||
$joinColumnsLines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
|
||||
}
|
||||
|
||||
$lines[] = implode(",". PHP_EOL, $joinColumnsLines);
|
||||
$lines[] = $this->spaces . ' * },';
|
||||
$lines[] = $this->spaces . ' * inverseJoinColumns={';
|
||||
|
||||
$inverseJoinColumnsLines = array();
|
||||
|
||||
foreach ($associationMapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
|
||||
$lines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
|
||||
$inverseJoinColumnsLines[] = $this->spaces . ' * ' . $this->generateJoinColumnAnnotation($joinColumn);
|
||||
}
|
||||
|
||||
$lines[] = implode(",". PHP_EOL, $inverseJoinColumnsLines);
|
||||
$lines[] = $this->spaces . ' * }';
|
||||
$lines[] = $this->spaces . ' * )';
|
||||
}
|
||||
@@ -1116,7 +1168,7 @@ public function __construct()
|
||||
{
|
||||
$lines = array();
|
||||
$lines[] = $this->spaces . '/**';
|
||||
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']) . ' $' . $fieldMapping['fieldName'];
|
||||
$lines[] = $this->spaces . ' * @var ' . $this->getType($fieldMapping['type']);
|
||||
|
||||
if ($this->generateAnnotations) {
|
||||
$lines[] = $this->spaces . ' *';
|
||||
@@ -1203,63 +1255,45 @@ public function __construct()
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
private function getInheritanceTypeString($type)
|
||||
/**
|
||||
* @param integer $type The inheritance type used by the class and it's subclasses.
|
||||
* @return string The literal string for the inheritance type.
|
||||
* @throws \InvalidArgumentException When the inheritance type does not exists.
|
||||
*/
|
||||
protected function getInheritanceTypeString($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
|
||||
return 'NONE';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_JOINED:
|
||||
return 'JOINED';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE:
|
||||
return 'SINGLE_TABLE';
|
||||
|
||||
case ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS:
|
||||
return 'PER_CLASS';
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
|
||||
if ( ! isset(self::$inheritanceTypeMap[$type])) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid provided InheritanceType: %s', $type));
|
||||
}
|
||||
|
||||
return self::$inheritanceTypeMap[$type];
|
||||
}
|
||||
|
||||
private function getChangeTrackingPolicyString($policy)
|
||||
/**
|
||||
* @param integer $type The policy used for change-tracking for the mapped class.
|
||||
* @return string The literal string for the change-tracking type.
|
||||
* @throws \InvalidArgumentException When the change-tracking type does not exists.
|
||||
*/
|
||||
protected function getChangeTrackingPolicyString($type)
|
||||
{
|
||||
switch ($policy) {
|
||||
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
|
||||
return 'DEFERRED_IMPLICIT';
|
||||
|
||||
case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
|
||||
return 'DEFERRED_EXPLICIT';
|
||||
|
||||
case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
|
||||
return 'NOTIFY';
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
|
||||
if ( ! isset(self::$changeTrackingPolicyMap[$type])) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid provided ChangeTrackingPolicy: %s', $type));
|
||||
}
|
||||
|
||||
return self::$changeTrackingPolicyMap[$type];
|
||||
}
|
||||
|
||||
private function getIdGeneratorTypeString($type)
|
||||
/**
|
||||
* @param integer $type The generator to use for the mapped class.
|
||||
* @return string The literal string for the generetor type.
|
||||
* @throws \InvalidArgumentException When the generator type does not exists.
|
||||
*/
|
||||
protected function getIdGeneratorTypeString($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
|
||||
return 'AUTO';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE:
|
||||
return 'SEQUENCE';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_TABLE:
|
||||
return 'TABLE';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
|
||||
return 'IDENTITY';
|
||||
|
||||
case ClassMetadataInfo::GENERATOR_TYPE_NONE:
|
||||
return 'NONE';
|
||||
|
||||
default:
|
||||
throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
|
||||
if ( ! isset(self::$generatorStrategyMap[$type])) {
|
||||
throw new \InvalidArgumentException(sprintf('Invalid provided IdGeneratorType: %s', $type));
|
||||
}
|
||||
|
||||
return self::$generatorStrategyMap[$type];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,10 +76,12 @@ class XmlExporter extends AbstractExporter
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorColumn) {
|
||||
$discriminatorColumnXml = $root->addChild('discriminiator-column');
|
||||
$discriminatorColumnXml = $root->addChild('discriminator-column');
|
||||
$discriminatorColumnXml->addAttribute('name', $metadata->discriminatorColumn['name']);
|
||||
$discriminatorColumnXml->addAttribute('type', $metadata->discriminatorColumn['type']);
|
||||
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
|
||||
if (isset($metadata->discriminatorColumn['length'])) {
|
||||
$discriminatorColumnXml->addAttribute('length', $metadata->discriminatorColumn['length']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($metadata->discriminatorMap) {
|
||||
@@ -109,9 +111,9 @@ class XmlExporter extends AbstractExporter
|
||||
if (isset($metadata->table['uniqueConstraints'])) {
|
||||
$uniqueConstraintsXml = $root->addChild('unique-constraints');
|
||||
|
||||
foreach ($metadata->table['uniqueConstraints'] as $unique) {
|
||||
foreach ($metadata->table['uniqueConstraints'] as $name => $unique) {
|
||||
$uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint');
|
||||
$uniqueConstraintXml->addAttribute('name', $unique['name']);
|
||||
$uniqueConstraintXml->addAttribute('name', $name);
|
||||
$uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns']));
|
||||
}
|
||||
}
|
||||
@@ -138,9 +140,15 @@ class XmlExporter extends AbstractExporter
|
||||
if (isset($field['columnName'])) {
|
||||
$idXml->addAttribute('column', $field['columnName']);
|
||||
}
|
||||
|
||||
if (isset($field['length'])) {
|
||||
$idXml->addAttribute('length', $field['length']);
|
||||
}
|
||||
|
||||
if (isset($field['associationKey']) && $field['associationKey']) {
|
||||
$idXml->addAttribute('association-key', 'true');
|
||||
}
|
||||
|
||||
if ($idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
|
||||
$generatorXml = $idXml->addChild('generator');
|
||||
$generatorXml->addAttribute('strategy', $idGeneratorType);
|
||||
|
||||
@@ -74,6 +74,10 @@ class CountOutputWalker extends SqlWalker
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
if ($this->platform->getName() === "mssql") {
|
||||
$AST->orderByClause = null;
|
||||
}
|
||||
|
||||
$sql = parent::walkSelectStatement($AST);
|
||||
|
||||
// Find out the SQL alias of the identifier column of the root entity
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
|
||||
namespace Doctrine\ORM\Tools\Pagination;
|
||||
|
||||
use Doctrine\ORM\Query\SqlWalker,
|
||||
Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use Doctrine\ORM\Query\AST\SelectStatement;
|
||||
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
|
||||
|
||||
/**
|
||||
* Wrap the query in order to select root entity IDs for pagination
|
||||
@@ -85,7 +86,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
||||
*/
|
||||
public function walkSelectStatement(SelectStatement $AST)
|
||||
{
|
||||
$sql = parent::walkSelectStatement($AST);
|
||||
$innerSql = parent::walkSelectStatement($AST);
|
||||
|
||||
// Find out the SQL alias of the identifier column of the root entity
|
||||
// It may be possible to make this work with multiple root entities but that
|
||||
@@ -133,7 +134,12 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
||||
|
||||
// Build the counter query
|
||||
$sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
|
||||
implode(', ', $sqlIdentifier), $sql);
|
||||
implode(', ', $sqlIdentifier), $innerSql);
|
||||
|
||||
if ($this->platform instanceof PostgreSqlPlatform) {
|
||||
//http://www.doctrine-project.org/jira/browse/DDC-1958
|
||||
$this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql);
|
||||
}
|
||||
|
||||
// Apply the limit and offset
|
||||
$sql = $this->platform->modifyLimitQuery(
|
||||
@@ -150,4 +156,47 @@ class LimitSubqueryOutputWalker extends SqlWalker
|
||||
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate new SQL for postgresql if necessary
|
||||
*
|
||||
* @param SelectStatement $AST
|
||||
* @param array sqlIdentifier
|
||||
* @param string $sql
|
||||
*/
|
||||
public function getPostgresqlSql(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
|
||||
{
|
||||
// For every order by, find out the SQL alias by inspecting the ResultSetMapping
|
||||
$sqlOrderColumns = array();
|
||||
$orderBy = array();
|
||||
if (isset($AST->orderByClause)) {
|
||||
foreach ($AST->orderByClause->orderByItems as $item) {
|
||||
$possibleAliases = array_keys($this->rsm->fieldMappings, $item->expression->field);
|
||||
|
||||
foreach ($possibleAliases as $alias) {
|
||||
if ($this->rsm->columnOwnerMap[$alias] == $item->expression->identificationVariable) {
|
||||
$sqlOrderColumns[] = $alias;
|
||||
$orderBy[] = $alias . ' ' . $item->type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//remove identifier aliases
|
||||
$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)) {
|
||||
$sql = sprintf(
|
||||
'SELECT DISTINCT %s FROM (%s) dctrn_result ORDER BY %s',
|
||||
implode(', ', array_merge($sqlIdentifier, $sqlOrderColumns)),
|
||||
$innerSql,
|
||||
implode(', ', $orderBy)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,15 +178,10 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
return new \ArrayIterator(array());
|
||||
}
|
||||
|
||||
$namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
|
||||
|
||||
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
|
||||
$whereInQuery->setFirstResult(null)->setMaxResults(null);
|
||||
foreach ($ids as $i => $id) {
|
||||
$i++;
|
||||
$whereInQuery->setParameter("{$namespace}_{$i}", $id);
|
||||
}
|
||||
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
|
||||
|
||||
$result = $whereInQuery->getResult($this->query->getHydrationMode());
|
||||
} else {
|
||||
|
||||
@@ -102,11 +102,8 @@ class WhereInWalker extends TreeWalkerAdapter
|
||||
array($pathExpression)
|
||||
);
|
||||
$expression = new InExpression($arithmeticExpression);
|
||||
$ns = self::PAGINATOR_ID_ALIAS;
|
||||
$expression->literals[] = new InputParameter(":" . self::PAGINATOR_ID_ALIAS);
|
||||
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$expression->literals[] = new InputParameter(":{$ns}_$i");
|
||||
}
|
||||
} else {
|
||||
$expression = new NullComparisonExpression($pathExpression);
|
||||
$expression->not = false;
|
||||
|
||||
@@ -73,6 +73,7 @@ class ResolveTargetEntityListener
|
||||
$newMapping = $this->resolveTargetEntities[$mapping['targetEntity']];
|
||||
$newMapping = array_replace_recursive($mapping, $newMapping);
|
||||
$newMapping['fieldName'] = $mapping['fieldName'];
|
||||
|
||||
unset($classMetadata->associationMappings[$mapping['fieldName']]);
|
||||
|
||||
switch ($mapping['type']) {
|
||||
|
||||
@@ -385,6 +385,16 @@ class SchemaTool
|
||||
}
|
||||
|
||||
if (isset($mapping['options'])) {
|
||||
$knownOptions = array('comment', 'unsigned', 'fixed', 'default');
|
||||
|
||||
foreach ($knownOptions as $knownOption) {
|
||||
if ( isset($mapping['options'][$knownOption])) {
|
||||
$options[$knownOption] = $mapping['options'][$knownOption];
|
||||
|
||||
unset($mapping['options'][$knownOption]);
|
||||
}
|
||||
}
|
||||
|
||||
$options['customSchemaOptions'] = $mapping['options'];
|
||||
}
|
||||
|
||||
@@ -546,6 +556,11 @@ class SchemaTool
|
||||
if (isset($joinColumn['nullable'])) {
|
||||
$columnOptions['notnull'] = !$joinColumn['nullable'];
|
||||
}
|
||||
|
||||
if (isset($fieldMapping['options'])) {
|
||||
$columnOptions['options'] = $fieldMapping['options'];
|
||||
}
|
||||
|
||||
if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
|
||||
$columnOptions['length'] = $fieldMapping['length'];
|
||||
} else if ($fieldMapping['type'] == "decimal") {
|
||||
|
||||
@@ -63,6 +63,9 @@ class Setup
|
||||
* Use this method to register all autoloaders for a setup where Doctrine is installed
|
||||
* though {@link http://pear.doctrine-project.org}.
|
||||
*
|
||||
* This method registers autoloaders for both Doctrine and Symfony top
|
||||
* level namespaces.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static public function registerAutoloadPEAR()
|
||||
@@ -74,15 +77,8 @@ class Setup
|
||||
$loader = new ClassLoader("Doctrine");
|
||||
$loader->register();
|
||||
|
||||
$parts = explode(PATH_SEPARATOR, get_include_path());
|
||||
|
||||
foreach ($parts as $includePath) {
|
||||
if ($includePath != "." && file_exists($includePath . "/Doctrine")) {
|
||||
$loader = new ClassLoader("Symfony\Component", $includePath . "/Doctrine");
|
||||
$loader->register();
|
||||
return;
|
||||
}
|
||||
}
|
||||
$loader = new ClassLoader("Symfony");
|
||||
$loader->register();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,6 +67,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*/
|
||||
const STATE_REMOVED = 4;
|
||||
|
||||
/**
|
||||
* Hint used to collect all primary keys of associated entities during hydration
|
||||
* and execute it in a dedicated query afterwards
|
||||
* @see https://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html?highlight=eager#temporarily-change-fetch-mode-in-dql
|
||||
*/
|
||||
const HINT_DEFEREAGERLOAD = 'deferEagerLoad';
|
||||
|
||||
/**
|
||||
* The identity map that holds references to all managed entities that have
|
||||
* an identity. The entities are grouped by their class name.
|
||||
@@ -400,13 +407,15 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*/
|
||||
private function computeSingleEntityChangeSet($entity)
|
||||
{
|
||||
if ( $this->getEntityState($entity) !== self::STATE_MANAGED) {
|
||||
throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity));
|
||||
$state = $this->getEntityState($entity);
|
||||
|
||||
if ($state !== self::STATE_MANAGED && $state !== self::STATE_REMOVED) {
|
||||
throw new \InvalidArgumentException("Entity has to be managed or scheduled for removal for single computation " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
$class = $this->em->getClassMetadata(get_class($entity));
|
||||
|
||||
if ($class->isChangeTrackingDeferredImplicit()) {
|
||||
if ($state === self::STATE_MANAGED && $class->isChangeTrackingDeferredImplicit()) {
|
||||
$this->persist($entity);
|
||||
}
|
||||
|
||||
@@ -980,7 +989,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->entityChangeSets[$oid]) {
|
||||
if (!empty($this->entityChangeSets[$oid])) {
|
||||
$persister->update($entity);
|
||||
}
|
||||
|
||||
@@ -1376,6 +1385,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
return self::STATE_NEW;
|
||||
}
|
||||
|
||||
if ($class->containsForeignIdentifier) {
|
||||
$id = $this->flattenIdentifier($class, $id);
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case ($class->isIdentifierNatural());
|
||||
// Check for a version field, if available, to avoid a db lookup.
|
||||
@@ -1688,6 +1701,29 @@ class UnitOfWork implements PropertyChangedListener
|
||||
return $this->doMerge($entity, $visited);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert foreign identifiers into scalar foreign key values to avoid object to string conversion failures.
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param array $id
|
||||
* @return array
|
||||
*/
|
||||
private function flattenIdentifier($class, $id)
|
||||
{
|
||||
$flatId = array();
|
||||
|
||||
foreach ($id as $idField => $idValue) {
|
||||
if (isset($class->associationMappings[$idField])) {
|
||||
$targetClassMetadata = $this->em->getClassMetadata($class->associationMappings[$idField]['targetEntity']);
|
||||
$associatedId = $this->getEntityIdentifier($idValue);
|
||||
|
||||
$flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]];
|
||||
}
|
||||
}
|
||||
|
||||
return $flatId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a merge operation on an entity.
|
||||
*
|
||||
@@ -1735,19 +1771,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
$this->persistNew($class, $managedCopy);
|
||||
} else {
|
||||
$flatId = $id;
|
||||
if ($class->containsForeignIdentifier) {
|
||||
// convert foreign identifiers into scalar foreign key
|
||||
// values to avoid object to string conversion failures.
|
||||
foreach ($id as $idField => $idValue) {
|
||||
if (isset($class->associationMappings[$idField])) {
|
||||
$targetClassMetadata = $this->em->getClassMetadata($class->associationMappings[$idField]['targetEntity']);
|
||||
$associatedId = $this->getEntityIdentifier($idValue);
|
||||
|
||||
$flatId[$idField] = $associatedId[$targetClassMetadata->identifier[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
$flatId = ($class->containsForeignIdentifier)
|
||||
? $this->flattenIdentifier($class, $id)
|
||||
: $id;
|
||||
|
||||
$managedCopy = $this->tryGetById($flatId, $class->rootEntityName);
|
||||
|
||||
@@ -1807,7 +1833,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
// do not merge fields marked lazy that have not been fetched.
|
||||
continue;
|
||||
} else if ( ! $assoc2['isCascadeMerge']) {
|
||||
if ($this->getEntityState($other, self::STATE_DETACHED) !== self::STATE_MANAGED) {
|
||||
if ($this->getEntityState($other) === self::STATE_DETACHED) {
|
||||
$targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
|
||||
$relatedId = $targetClass->getIdentifierValues($other);
|
||||
|
||||
@@ -1818,6 +1844,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->registerManaged($other, $relatedId, array());
|
||||
}
|
||||
}
|
||||
|
||||
$prop->setValue($managedCopy, $other);
|
||||
}
|
||||
} else {
|
||||
@@ -2209,6 +2236,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*/
|
||||
public function lock($entity, $lockMode, $lockVersion = null)
|
||||
{
|
||||
if ($entity === null) {
|
||||
throw new \InvalidArgumentException("No entity passed to UnitOfWork#lock().");
|
||||
}
|
||||
|
||||
if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) {
|
||||
throw ORMInvalidArgumentException::entityNotManaged($entity);
|
||||
}
|
||||
@@ -2415,17 +2446,23 @@ class UnitOfWork implements PropertyChangedListener
|
||||
if ($entity instanceof NotifyPropertyChanged) {
|
||||
$entity->addPropertyChangedListener($this);
|
||||
}
|
||||
|
||||
// inject ObjectManager into just loaded proxies.
|
||||
if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
|
||||
$entity->injectObjectManager($this->em, $class);
|
||||
}
|
||||
|
||||
} else {
|
||||
$overrideLocalValues = isset($hints[Query::HINT_REFRESH]);
|
||||
|
||||
// If only a specific entity is set to refresh, check that it's the one
|
||||
if(isset($hints[Query::HINT_REFRESH_ENTITY])) {
|
||||
$overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity;
|
||||
}
|
||||
|
||||
// inject ObjectManager into just loaded proxies.
|
||||
if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
|
||||
$entity->injectObjectManager($this->em, $class);
|
||||
}
|
||||
// inject ObjectManager upon refresh.
|
||||
if ($overrideLocalValues && $entity instanceof ObjectManagerAware) {
|
||||
$entity->injectObjectManager($this->em, $class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2529,7 +2566,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
// this association is marked as eager fetch, and its an uninitialized proxy (wtf!)
|
||||
// then we can append this entity for eager loading!
|
||||
if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER &&
|
||||
isset($hints['deferEagerLoad']) &&
|
||||
isset($hints[self::HINT_DEFEREAGERLOAD]) &&
|
||||
!$targetClass->isIdentifierComposite &&
|
||||
$newValue instanceof Proxy &&
|
||||
$newValue->__isInitialized__ === false) {
|
||||
@@ -2554,7 +2591,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
break;
|
||||
|
||||
// Deferred eager load only works for single identifier classes
|
||||
case (isset($hints['deferEagerLoad']) && ! $targetClass->isIdentifierComposite):
|
||||
case (isset($hints[self::HINT_DEFEREAGERLOAD]) && ! $targetClass->isIdentifierComposite):
|
||||
// TODO: Is there a faster approach?
|
||||
$this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
|
||||
|
||||
@@ -2571,6 +2608,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$newValueOid = spl_object_hash($newValue);
|
||||
$this->entityIdentifiers[$newValueOid] = $associatedId;
|
||||
$this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue;
|
||||
|
||||
if ($newValue instanceof NotifyPropertyChanged) {
|
||||
$newValue->addPropertyChangedListener($this);
|
||||
}
|
||||
$this->entityStates[$newValueOid] = self::STATE_MANAGED;
|
||||
// make sure that when an proxy is then finally loaded, $this->originalEntityData is set also!
|
||||
break;
|
||||
|
||||
@@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.3.0';
|
||||
const VERSION = '2.3.4';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
||||
2
lib/vendor/doctrine-dbal
vendored
2
lib/vendor/doctrine-dbal
vendored
Submodule lib/vendor/doctrine-dbal updated: 30dc433ea0...2a37b007dd
@@ -1118,7 +1118,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$user->username = 'domnikl';
|
||||
$user->status = 'developer';
|
||||
|
||||
$this->setExpectedException('InvalidArgumentException', 'Entity has to be managed for single computation');
|
||||
$this->setExpectedException('InvalidArgumentException', 'Entity has to be managed or scheduled for removal for single computation');
|
||||
$this->_em->flush($user);
|
||||
}
|
||||
|
||||
@@ -1202,8 +1202,9 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
/**
|
||||
* @group DDC-720
|
||||
* @group DDC-1612
|
||||
* @group DDC-2267
|
||||
*/
|
||||
public function testFlushSingleNewEntity()
|
||||
public function testFlushSingleNewEntityThenRemove()
|
||||
{
|
||||
$user = new CmsUser;
|
||||
$user->name = 'Dominik';
|
||||
@@ -1212,6 +1213,14 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush($user);
|
||||
|
||||
$userId = $user->id;
|
||||
|
||||
$this->_em->remove($user);
|
||||
$this->_em->flush($user);
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertNull($this->_em->find(get_class($user), $userId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,12 +2,9 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo,
|
||||
Doctrine\Common\Util\Inflector;
|
||||
|
||||
class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
class DatabaseDriverTest extends DatabaseDriverTestCase
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Schema\AbstractSchemaManager
|
||||
@@ -22,6 +19,31 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_sm = $this->_em->getConnection()->getSchemaManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2059
|
||||
*/
|
||||
public function testIssue2059()
|
||||
{
|
||||
if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
|
||||
$this->markTestSkipped('Platform does not support foreign keys.');
|
||||
}
|
||||
|
||||
$user = new \Doctrine\DBAL\Schema\Table("ddc2059_user");
|
||||
$user->addColumn('id', 'integer');
|
||||
$user->setPrimaryKey(array('id'));
|
||||
$project = new \Doctrine\DBAL\Schema\Table("ddc2059_project");
|
||||
$project->addColumn('id', 'integer');
|
||||
$project->addColumn('user_id', 'integer');
|
||||
$project->addColumn('user', 'string');
|
||||
$project->setPrimaryKey(array('id'));
|
||||
$project->addForeignKeyConstraint('ddc2059_user', array('user_id'), array('id'));
|
||||
|
||||
$metadata = $this->convertToClassMetadata(array($project, $user), array());
|
||||
|
||||
$this->assertTrue(isset($metadata['Ddc2059Project']->fieldMappings['user']));
|
||||
$this->assertTrue(isset($metadata['Ddc2059Project']->associationMappings['user2']));
|
||||
}
|
||||
|
||||
public function testLoadMetadataFromDatabase()
|
||||
{
|
||||
if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
|
||||
@@ -123,44 +145,4 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->assertEquals(0, count($metadatas['DbdriverBaz']->associationMappings), "no association mappings should be detected.");
|
||||
}
|
||||
|
||||
protected function convertToClassMetadata(array $entityTables, array $manyTables = array())
|
||||
{
|
||||
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($this->_sm);
|
||||
$driver->setTables($entityTables, $manyTables);
|
||||
|
||||
$metadatas = array();
|
||||
foreach ($driver->getAllClassNames() AS $className) {
|
||||
$class = new ClassMetadataInfo($className);
|
||||
$driver->loadMetadataForClass($className, $class);
|
||||
$metadatas[$className] = $class;
|
||||
}
|
||||
|
||||
return $metadatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @return ClassMetadata
|
||||
*/
|
||||
protected function extractClassMetadata(array $classNames)
|
||||
{
|
||||
$classNames = array_map('strtolower', $classNames);
|
||||
$metadatas = array();
|
||||
|
||||
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($this->_sm);
|
||||
foreach ($driver->getAllClassNames() as $className) {
|
||||
if (!in_array(strtolower($className), $classNames)) {
|
||||
continue;
|
||||
}
|
||||
$class = new ClassMetadataInfo($className);
|
||||
$driver->loadMetadataForClass($className, $class);
|
||||
$metadatas[$className] = $class;
|
||||
}
|
||||
|
||||
if (count($metadatas) != count($classNames)) {
|
||||
$this->fail("Have not found all classes matching the names '" . implode(", ", $classNames) . "' only tables " . implode(", ", array_keys($metadatas)));
|
||||
}
|
||||
return $metadatas;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
/**
|
||||
* Common BaseClass for DatabaseDriver Tests
|
||||
*/
|
||||
abstract class DatabaseDriverTestCase extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function convertToClassMetadata(array $entityTables, array $manyTables = array())
|
||||
{
|
||||
$sm = $this->_em->getConnection()->getSchemaManager();
|
||||
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($sm);
|
||||
$driver->setTables($entityTables, $manyTables);
|
||||
|
||||
$metadatas = array();
|
||||
foreach ($driver->getAllClassNames() AS $className) {
|
||||
$class = new ClassMetadataInfo($className);
|
||||
$driver->loadMetadataForClass($className, $class);
|
||||
$metadatas[$className] = $class;
|
||||
}
|
||||
|
||||
return $metadatas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
* @return ClassMetadata
|
||||
*/
|
||||
protected function extractClassMetadata(array $classNames)
|
||||
{
|
||||
$classNames = array_map('strtolower', $classNames);
|
||||
$metadatas = array();
|
||||
|
||||
$sm = $this->_em->getConnection()->getSchemaManager();
|
||||
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($sm);
|
||||
|
||||
foreach ($driver->getAllClassNames() as $className) {
|
||||
if (!in_array(strtolower($className), $classNames)) {
|
||||
continue;
|
||||
}
|
||||
$class = new ClassMetadataInfo($className);
|
||||
$driver->loadMetadataForClass($className, $class);
|
||||
$metadatas[$className] = $class;
|
||||
}
|
||||
|
||||
if (count($metadatas) != count($classNames)) {
|
||||
$this->fail("Have not found all classes matching the names '" . implode(", ", $classNames) . "' only tables " . implode(", ", array_keys($metadatas)));
|
||||
}
|
||||
return $metadatas;
|
||||
}
|
||||
}
|
||||
@@ -344,6 +344,20 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals($addressId, $address->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1241
|
||||
*/
|
||||
public function testFindOneByOrderBy()
|
||||
{
|
||||
$this->loadFixture();
|
||||
|
||||
$repos = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$userAsc = $repos->findOneBy(array(), array("username" => "ASC"));
|
||||
$userDesc = $repos->findOneBy(array(), array("username" => "DESC"));
|
||||
|
||||
$this->assertNotSame($userAsc, $userDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-817
|
||||
*/
|
||||
|
||||
@@ -173,14 +173,36 @@ class OneToManyBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctiona
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertEquals(2, count($results));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group DDC-2340
|
||||
*/
|
||||
public function testMatchingOnDirtyCollection()
|
||||
{
|
||||
$this->_createFixture();
|
||||
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->product->getId());
|
||||
|
||||
$thirdFeature = new ECommerceFeature();
|
||||
$thirdFeature->setDescription('Model writing tutorial');
|
||||
|
||||
$features = $product->getFeatures();
|
||||
$features->add($thirdFeature);
|
||||
|
||||
$results = $features->matching(new Criteria(
|
||||
Criteria::expr()->eq('description', 'Model writing tutorial')
|
||||
));
|
||||
|
||||
$this->assertEquals(2, count($results));
|
||||
}
|
||||
|
||||
public function testMatchingBis()
|
||||
{
|
||||
$this->_createFixture();
|
||||
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->product->getId());
|
||||
$features = $product->getFeatures();
|
||||
|
||||
|
||||
$thirdFeature = new ECommerceFeature();
|
||||
$thirdFeature->setDescription('Third feature');
|
||||
$product->addFeature($thirdFeature);
|
||||
|
||||
@@ -453,6 +453,22 @@ class SQLFilterTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals(1, count($query->getResult()));
|
||||
}
|
||||
|
||||
public function testWhereOrFilter()
|
||||
{
|
||||
$this->loadFixtureData();
|
||||
$query = $this->_em->createQuery('select ug from Doctrine\Tests\Models\CMS\CmsGroup ug WHERE 1=1 OR 1=1');
|
||||
|
||||
// We get two users before enabling the filter
|
||||
$this->assertEquals(2, count($query->getResult()));
|
||||
|
||||
$conf = $this->_em->getConfiguration();
|
||||
$conf->addFilter("group_prefix", "\Doctrine\Tests\ORM\Functional\CMSGroupPrefixFilter");
|
||||
$this->_em->getFilters()->enable("group_prefix")->setParameter("prefix", "bar_%", DBALType::STRING);
|
||||
|
||||
// We get one user after enabling the filter
|
||||
$this->assertEquals(1, count($query->getResult()));
|
||||
}
|
||||
|
||||
|
||||
private function loadLazyFixtureData()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\SchemaTool;
|
||||
|
||||
use Doctrine\ORM\Tools;
|
||||
|
||||
class DBAL483Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$conn = $this->_em->getConnection();
|
||||
|
||||
if ($conn->getDatabasePlatform()->getName() === 'sqlite') {
|
||||
$this->markTestSkipped('Sqlite does not support ALTER TABLE');
|
||||
}
|
||||
|
||||
$this->schemaTool = new Tools\SchemaTool($this->_em);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DBAL-483
|
||||
*/
|
||||
public function testDefaultValueIsComparedCorrectly()
|
||||
{
|
||||
$class = $this->_em->getClassMetadata(__NAMESPACE__ . '\\DBAL483Default');
|
||||
|
||||
$this->schemaTool->createSchema(array($class));
|
||||
|
||||
$updateSql = $this->schemaTool->getUpdateSchemaSql(array($class));
|
||||
|
||||
$updateSql = array_filter($updateSql, function ($sql) {
|
||||
return strpos($sql, 'DBAL483') !== false;
|
||||
});
|
||||
|
||||
$this->assertEquals(0, count($updateSql));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DBAL483Default
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer") @GeneratedValue
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="integer", options={"default": 0})
|
||||
*/
|
||||
public $num;
|
||||
|
||||
/**
|
||||
* @Column(type="string", options={"default": "foo"})
|
||||
*/
|
||||
public $str = "foo";
|
||||
}
|
||||
@@ -4,9 +4,6 @@ namespace Doctrine\Tests\ORM\Functional\SchemaTool;
|
||||
|
||||
use Doctrine\ORM\Tools;
|
||||
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* WARNING: This test should be run as last test! It can affect others very easily!
|
||||
*/
|
||||
@@ -15,7 +12,8 @@ class DDC214Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
private $classes = array();
|
||||
private $schemaTool = null;
|
||||
|
||||
public function setUp() {
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$conn = $this->_em->getConnection();
|
||||
@@ -88,4 +86,4 @@ class DDC214Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->assertEquals(0, count($sql), "SQL: " . implode(PHP_EOL, $sql));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,4 +461,22 @@ class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
|
||||
$this->assertEquals($before + 3, count($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2246
|
||||
*/
|
||||
public function testGetEntityState()
|
||||
{
|
||||
$this->article1 = $this->_em->find("Doctrine\Tests\Models\DDC117\DDC117Article", $this->article1->id());
|
||||
$this->article2 = $this->_em->find("Doctrine\Tests\Models\DDC117\DDC117Article", $this->article2->id());
|
||||
|
||||
$this->reference = new DDC117Reference($this->article2, $this->article1, "Test-Description");
|
||||
|
||||
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($this->reference));
|
||||
|
||||
$idCriteria = array('source' => $this->article1->id(), 'target' => $this->article2->id());
|
||||
$reference = $this->_em->find("Doctrine\Tests\Models\DDC117\DDC117Reference", $idCriteria);
|
||||
|
||||
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($reference));
|
||||
}
|
||||
}
|
||||
|
||||
40
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1666Test.php
Normal file
40
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1666Test.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsEmail;
|
||||
|
||||
/**
|
||||
* @group DDC-1666
|
||||
*/
|
||||
class DDC1666Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testGivenOrphanRemovalOneToOne_WhenReplacing_ThenNoUniqueConstraintError()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$user->name = "Benjamin";
|
||||
$user->username = "beberlei";
|
||||
$user->status = "something";
|
||||
$user->setEmail($email = new CmsEmail());
|
||||
$email->setEmail("kontakt@beberlei.de");
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertTrue($this->_em->contains($email));
|
||||
|
||||
$user->setEmail($newEmail = new CmsEmail());
|
||||
$newEmail->setEmail("benjamin.eberlei@googlemail.com");
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertFalse($this->_em->contains($email));
|
||||
}
|
||||
}
|
||||
153
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php
Normal file
153
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\NotifyPropertyChanged,
|
||||
Doctrine\Common\PropertyChangedListener;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC1690Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Parent'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Child')
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
// Swallow all exceptions. We do not test the schema tool here.
|
||||
}
|
||||
}
|
||||
|
||||
public function testChangeTracking()
|
||||
{
|
||||
$parent = new DDC1690Parent();
|
||||
$child = new DDC1690Child();
|
||||
$parent->setName('parent');
|
||||
$child->setName('child');
|
||||
|
||||
$parent->setChild($child);
|
||||
$child->setParent($parent);
|
||||
|
||||
$this->_em->persist($parent);
|
||||
$this->_em->persist($child);
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
|
||||
$parentId = $parent->getId();
|
||||
$childId = $child->getId();
|
||||
unset($parent, $child);
|
||||
|
||||
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
|
||||
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
unset($parent, $child);
|
||||
|
||||
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
|
||||
$child = $parent->getChild();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
unset($parent, $child);
|
||||
|
||||
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
|
||||
$parent = $child->getParent();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
}
|
||||
}
|
||||
|
||||
class NotifyBaseEntity implements NotifyPropertyChanged {
|
||||
public $listeners = array();
|
||||
|
||||
public function addPropertyChangedListener(PropertyChangedListener $listener) {
|
||||
if (!in_array($listener, $this->listeners)) {
|
||||
$this->listeners[] = $listener;
|
||||
}
|
||||
}
|
||||
|
||||
protected function onPropertyChanged($propName, $oldValue, $newValue) {
|
||||
if ($this->listeners) {
|
||||
foreach ($this->listeners as $listener) {
|
||||
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity @ChangeTrackingPolicy("NOTIFY") */
|
||||
class DDC1690Parent extends NotifyBaseEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
|
||||
/** @Column */
|
||||
private $name;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC1690Child") */
|
||||
private $child;
|
||||
|
||||
function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name) {
|
||||
$this->onPropertyChanged('name', $this->name, $name);
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function setChild($child) {
|
||||
$this->child = $child;
|
||||
}
|
||||
|
||||
function getChild() {
|
||||
return $this->child;
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class DDC1690Child extends NotifyBaseEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
|
||||
/** @Column */
|
||||
private $name;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC1690Parent", mappedBy="child") */
|
||||
private $parent;
|
||||
|
||||
function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name) {
|
||||
$this->onPropertyChanged('name', $this->name, $name);
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function setParent($parent) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
function getParent() {
|
||||
return $this->parent;
|
||||
}
|
||||
}
|
||||
177
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php
Executable file
177
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php
Executable file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* @group DDC-2012
|
||||
*/
|
||||
class DDC2012Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Type::addType(DDC2012TsVectorType::MYTYPE, __NAMESPACE__ . '\DDC2012TsVectorType');
|
||||
|
||||
DDC2012TsVectorType::$calls = array();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012Item'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012ItemPerson'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$item = new DDC2012ItemPerson();
|
||||
$item->tsv = array('word1', 'word2', 'word3');
|
||||
|
||||
$this->_em->persist($item);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$item = $this->_em->find(get_class($item), $item->id);
|
||||
|
||||
$this->assertArrayHasKey('convertToDatabaseValueSQL', DDC2012TsVectorType::$calls);
|
||||
$this->assertArrayHasKey('convertToDatabaseValue', DDC2012TsVectorType::$calls);
|
||||
$this->assertArrayHasKey('convertToPHPValue', DDC2012TsVectorType::$calls);
|
||||
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToPHPValue']);
|
||||
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
|
||||
$this->assertEquals(array('word1', 'word2', 'word3'), $item->tsv);
|
||||
|
||||
|
||||
$item->tsv = array('word1', 'word2');
|
||||
|
||||
$this->_em->persist($item);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$item = $this->_em->find(get_class($item), $item->id);
|
||||
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToPHPValue']);
|
||||
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
|
||||
$this->assertEquals(array('word1', 'word2'), $item->tsv);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2010_item")
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="type_id", type="smallint")
|
||||
* @DiscriminatorMap({
|
||||
* 1 = "DDC2012ItemPerson"
|
||||
* })
|
||||
*/
|
||||
class DDC2012Item
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(name="tsv", type="tsvector", nullable=true)
|
||||
*/
|
||||
public $tsv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2010_item_person")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2012ItemPerson extends DDC2012Item
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class DDC2012TsVectorType extends Type
|
||||
{
|
||||
const MYTYPE = 'tsvector';
|
||||
|
||||
public static $calls = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = implode(" ", $value);
|
||||
}
|
||||
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return explode(" ", strtolower($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
|
||||
{
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'sqlExpr' => $sqlExpr,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
// changed to upper expression to keep the test compatible with other Databases
|
||||
//sprintf('to_tsvector(%s)', $sqlExpr);
|
||||
|
||||
return $platform->getUpperExpression($sqlExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRequireSQLConversion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return self::MYTYPE;
|
||||
}
|
||||
}
|
||||
29
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php
Normal file
29
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCategory;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
|
||||
/**
|
||||
* @group DDC-2074
|
||||
*/
|
||||
class DDC2074Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testShouldNotScheduleDeletionOnClonedInstances()
|
||||
{
|
||||
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
|
||||
$product = new ECommerceProduct();
|
||||
$category = new ECommerceCategory();
|
||||
$collection = new PersistentCollection($this->_em, $class, new ArrayCollection(array($category)));
|
||||
$collection->setOwner($product, $class->associationMappings['categories']);
|
||||
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
$clonedCollection = clone $collection;
|
||||
$clonedCollection->clear();
|
||||
|
||||
$this->assertEquals(0, count($uow->getScheduledCollectionDeletions()));
|
||||
}
|
||||
}
|
||||
110
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php
Normal file
110
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\Company\CompanyEmployee;
|
||||
|
||||
/**
|
||||
* @group DDC-2090
|
||||
*/
|
||||
class DDC2090Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('company');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$className = 'Doctrine\Tests\Models\Company\CompanyEmployee';
|
||||
$date1 = new \DateTime('2011-11-11 11:11:11');
|
||||
$date2 = new \DateTime('2012-12-12 12:12:12');
|
||||
$employee1 = new CompanyEmployee;
|
||||
$employee2 = new CompanyEmployee;
|
||||
|
||||
$employee1->setName("Fabio B. Silva");
|
||||
$employee1->setStartDate(new \DateTime('yesterday'));
|
||||
$employee1->setDepartment("R&D");
|
||||
$employee1->setSalary(100);
|
||||
|
||||
$employee2->setName("Doctrine Bot");
|
||||
$employee1->setStartDate(new \DateTime('yesterday'));
|
||||
$employee2->setDepartment("QA");
|
||||
$employee2->setSalary(100);
|
||||
|
||||
$this->_em->persist($employee1);
|
||||
$this->_em->persist($employee2);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->_em->createQueryBuilder()
|
||||
->update($className, 'e')
|
||||
->set('e.startDate', ':date')
|
||||
->set('e.salary', ':salary')
|
||||
->where('e = :e')
|
||||
->setParameters(array(
|
||||
'e' => $employee1,
|
||||
'date' => $date1,
|
||||
'salary' => 101,
|
||||
))
|
||||
->getQuery()
|
||||
->useQueryCache(true)
|
||||
->execute();
|
||||
|
||||
$this->_em->createQueryBuilder()
|
||||
->update($className, 'e')
|
||||
->set('e.startDate', ':date')
|
||||
->set('e.salary', ':salary')
|
||||
->where('e = :e')
|
||||
->setParameters(array(
|
||||
'e' => $employee2,
|
||||
'date' => $date2,
|
||||
'salary' => 102,
|
||||
))
|
||||
->getQuery()
|
||||
->useQueryCache(true)
|
||||
->execute();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$e1 = $this->_em->find($className, $employee1->getId());
|
||||
$e2 = $this->_em->find($className, $employee2->getId());
|
||||
|
||||
$this->assertEquals(101, $e1->getSalary());
|
||||
$this->assertEquals(102, $e2->getSalary());
|
||||
$this->assertEquals($date1, $e1->getStartDate());
|
||||
$this->assertEquals($date2, $e2->getStartDate());
|
||||
|
||||
$this->_em->createQueryBuilder()
|
||||
->update($className, 'e')
|
||||
->set('e.startDate', '?1')
|
||||
->set('e.salary', '?2')
|
||||
->where('e = ?0')
|
||||
->setParameters(array($employee1, $date1, 101))
|
||||
->getQuery()
|
||||
->useQueryCache(true)
|
||||
->execute();
|
||||
|
||||
$this->_em->createQueryBuilder()
|
||||
->update($className, 'e')
|
||||
->set('e.startDate', '?1')
|
||||
->set('e.salary', '?2')
|
||||
->where('e = ?0')
|
||||
->setParameters(array($employee2, $date2, 102))
|
||||
->getQuery()
|
||||
->useQueryCache(true)
|
||||
->execute();
|
||||
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$e1 = $this->_em->find($className, $employee1->getId());
|
||||
$e2 = $this->_em->find($className, $employee2->getId());
|
||||
|
||||
$this->assertEquals(101, $e1->getSalary());
|
||||
$this->assertEquals(102, $e2->getSalary());
|
||||
$this->assertEquals($date1, $e1->getStartDate());
|
||||
$this->assertEquals($date2, $e2->getStartDate());
|
||||
}
|
||||
}
|
||||
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php
Normal file
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
/**
|
||||
* @group DDC-2175
|
||||
*/
|
||||
class DDC2175Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2175Entity'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$entity = new DDC2175Entity();
|
||||
$entity->field = "foo";
|
||||
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $entity->version);
|
||||
|
||||
$entity->field = "bar";
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(2, $entity->version);
|
||||
|
||||
$entity->field = "baz";
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(3, $entity->version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorMap({"entity": "DDC2175Entity"})
|
||||
*/
|
||||
class DDC2175Entity
|
||||
{
|
||||
/**
|
||||
* @Id @GeneratedValue @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string")
|
||||
*/
|
||||
public $field;
|
||||
|
||||
/**
|
||||
* @Version
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $version;
|
||||
}
|
||||
52
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php
Normal file
52
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC2182Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testPassColumnOptionsToJoinColumns()
|
||||
{
|
||||
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'mysql') {
|
||||
$this->markTestSkipped("This test is useful for all databases, but designed only for mysql.");
|
||||
}
|
||||
|
||||
$sql = $this->_schemaTool->getCreateSchemaSql(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionParent'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionChild'),
|
||||
));
|
||||
|
||||
$this->assertEquals("CREATE TABLE DDC2182OptionParent (id INT UNSIGNED NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE DDC2182OptionChild (id VARCHAR(255) NOT NULL, parent_id INT UNSIGNED DEFAULT NULL, INDEX IDX_B314D4AD727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("ALTER TABLE DDC2182OptionChild ADD CONSTRAINT FK_B314D4AD727ACA70 FOREIGN KEY (parent_id) REFERENCES DDC2182OptionParent (id)", $sql[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table
|
||||
*/
|
||||
class DDC2182OptionParent
|
||||
{
|
||||
/** @Id @Column(type="integer", options={"unsigned": true}) */
|
||||
private $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table
|
||||
*/
|
||||
class DDC2182OptionChild
|
||||
{
|
||||
/** @Id @Column */
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="DDC2182OptionParent")
|
||||
* @JoinColumn(referencedColumnName="id")
|
||||
*/
|
||||
private $parent;
|
||||
}
|
||||
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2231Test.php
Normal file
71
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2231Test.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManagerAware;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-2231
|
||||
*/
|
||||
class DDC2231Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2231EntityY'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testInjectObjectManagerInProxyIfInitializedInUow()
|
||||
{
|
||||
$y1 = new DDC2231EntityY;
|
||||
|
||||
$this->_em->persist($y1);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$y1ref = $this->_em->getReference(get_class($y1), $y1->id);
|
||||
|
||||
$this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $y1ref);
|
||||
$this->assertFalse($y1ref->__isInitialized__);
|
||||
|
||||
$id = $y1ref->doSomething();
|
||||
|
||||
$this->assertTrue($y1ref->__isInitialized__);
|
||||
$this->assertEquals($this->_em, $y1ref->om);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @Entity @Table(name="ddc2231_y") */
|
||||
class DDC2231EntityY implements ObjectManagerAware
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer") @GeneratedValue
|
||||
*/
|
||||
public $id;
|
||||
|
||||
public $om;
|
||||
|
||||
public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
|
||||
{
|
||||
$this->om = $objectManager;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function doSomething()
|
||||
{
|
||||
}
|
||||
}
|
||||
229
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2252Test.php
Normal file
229
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2252Test.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @group DDC-2252
|
||||
*/
|
||||
class DDC2252Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
private $user;
|
||||
private $merchant;
|
||||
private $membership;
|
||||
private $privileges = array();
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Ticket\DDC2252User'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Ticket\DDC2252Privilege'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Ticket\DDC2252Membership'),
|
||||
$this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\Ticket\DDC2252MerchantAccount'),
|
||||
));
|
||||
|
||||
$this->loadFixtures();
|
||||
}
|
||||
|
||||
public function loadFixtures()
|
||||
{
|
||||
$this->user = new DDC2252User;
|
||||
$this->merchant = new DDC2252MerchantAccount;
|
||||
$this->membership = new DDC2252Membership($this->user, $this->merchant);
|
||||
|
||||
$this->privileges[] = new DDC2252Privilege;
|
||||
$this->privileges[] = new DDC2252Privilege;
|
||||
$this->privileges[] = new DDC2252Privilege;
|
||||
|
||||
$this->membership->addPrivilege($this->privileges[0]);
|
||||
$this->membership->addPrivilege($this->privileges[1]);
|
||||
$this->membership->addPrivilege($this->privileges[2]);
|
||||
|
||||
$this->_em->persist($this->user);
|
||||
$this->_em->persist($this->merchant);
|
||||
$this->_em->persist($this->privileges[0]);
|
||||
$this->_em->persist($this->privileges[1]);
|
||||
$this->_em->persist($this->privileges[2]);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->persist($this->membership);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$identifier = array(
|
||||
'merchantAccount' => $this->merchant->getAccountid(),
|
||||
'userAccount' => $this->user->getUid(),
|
||||
);
|
||||
|
||||
$class = 'Doctrine\Tests\ORM\Functional\Ticket\DDC2252Membership';
|
||||
$membership = $this->_em->find($class, $identifier);
|
||||
|
||||
$this->assertInstanceOf($class, $membership);
|
||||
$this->assertCount(3, $membership->getPrivileges());
|
||||
|
||||
$membership->getPrivileges()->remove(2);
|
||||
$this->_em->persist($membership);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$membership = $this->_em->find($class, $identifier);
|
||||
|
||||
$this->assertInstanceOf($class, $membership);
|
||||
$this->assertCount(2, $membership->getPrivileges());
|
||||
|
||||
$membership->getPrivileges()->clear();
|
||||
$this->_em->persist($membership);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$membership = $this->_em->find($class, $identifier);
|
||||
|
||||
$this->assertInstanceOf($class, $membership);
|
||||
$this->assertCount(0, $membership->getPrivileges());
|
||||
|
||||
$membership->addPrivilege($privilege3 = new DDC2252Privilege);
|
||||
$this->_em->persist($privilege3);
|
||||
$this->_em->persist($membership);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$membership = $this->_em->find($class, $identifier);
|
||||
|
||||
$this->assertInstanceOf($class, $membership);
|
||||
$this->assertCount(1, $membership->getPrivileges());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity()
|
||||
* @Table(name="ddc2252_acl_privilege")
|
||||
*/
|
||||
class DDC2252Privilege
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
protected $privilegeid;
|
||||
|
||||
public function getPrivilegeid()
|
||||
{
|
||||
return $this->privilegeid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="ddc2252_mch_account")
|
||||
*/
|
||||
class DDC2252MerchantAccount
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
protected $accountid = 111;
|
||||
|
||||
public function getAccountid()
|
||||
{
|
||||
return $this->accountid;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="ddc2252_user_account")
|
||||
*/
|
||||
class DDC2252User {
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
protected $uid = 222;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="DDC2252Membership", mappedBy="userAccount", cascade={"persist"})
|
||||
* @JoinColumn(name="uid", referencedColumnName="uid")
|
||||
*/
|
||||
protected $memberships;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->memberships = new ArrayCollection;
|
||||
}
|
||||
|
||||
public function getUid()
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getMemberships()
|
||||
{
|
||||
return $this->memberships;
|
||||
}
|
||||
|
||||
public function addMembership(DDC2252Membership $membership)
|
||||
{
|
||||
$this->memberships[] = $membership;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="ddc2252_mch_account_member")
|
||||
* @HasLifecycleCallbacks
|
||||
*/
|
||||
class DDC2252Membership
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="DDC2252User", inversedBy="memberships")
|
||||
* @JoinColumn(name="uid", referencedColumnName="uid")
|
||||
*/
|
||||
protected $userAccount;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="DDC2252MerchantAccount")
|
||||
* @JoinColumn(name="mch_accountid", referencedColumnName="accountid")
|
||||
*/
|
||||
protected $merchantAccount;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="DDC2252Privilege", indexBy="privilegeid")
|
||||
* @JoinTable(name="ddc2252_user_mch_account_privilege",
|
||||
* joinColumns={
|
||||
* @JoinColumn(name="mch_accountid", referencedColumnName="mch_accountid"),
|
||||
* @JoinColumn(name="uid", referencedColumnName="uid")
|
||||
* },
|
||||
* inverseJoinColumns={
|
||||
* @JoinColumn(name="privilegeid", referencedColumnName="privilegeid")
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
protected $privileges;
|
||||
|
||||
public function __construct(DDC2252User $user, DDC2252MerchantAccount $merchantAccount)
|
||||
{
|
||||
$this->userAccount = $user;
|
||||
$this->merchantAccount = $merchantAccount;
|
||||
$this->privileges = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addPrivilege($privilege)
|
||||
{
|
||||
$this->privileges[] = $privilege;
|
||||
}
|
||||
|
||||
public function getPrivileges()
|
||||
{
|
||||
return $this->privileges;
|
||||
}
|
||||
}
|
||||
109
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php
Normal file
109
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2346Test.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\DBAL\Logging\DebugStack;
|
||||
|
||||
/**
|
||||
* @group DDC-2346
|
||||
*/
|
||||
class DDC2346Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @var \Doctrine\DBAL\Logging\DebugStack
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2346Foo'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2346Bar'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2346Baz'),
|
||||
));
|
||||
|
||||
$this->logger = new DebugStack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that fetching a OneToMany association with fetch="EAGER" does not cause N+1 queries
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
$foo1 = new DDC2346Foo();
|
||||
$foo2 = new DDC2346Foo();
|
||||
|
||||
$baz1 = new DDC2346Baz();
|
||||
$baz2 = new DDC2346Baz();
|
||||
|
||||
$baz1->foo = $foo1;
|
||||
$baz2->foo = $foo2;
|
||||
|
||||
$foo1->bars[] = $baz1;
|
||||
$foo1->bars[] = $baz2;
|
||||
|
||||
$this->_em->persist($foo1);
|
||||
$this->_em->persist($foo2);
|
||||
$this->_em->persist($baz1);
|
||||
$this->_em->persist($baz2);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->_em->getConnection()->getConfiguration()->setSQLLogger($this->logger);
|
||||
|
||||
$fetchedBazs = $this->_em->getRepository(__NAMESPACE__ . '\\DDC2346Baz')->findAll();
|
||||
|
||||
$this->assertCount(2, $fetchedBazs);
|
||||
$this->assertCount(2, $this->logger->queries, 'The total number of executed queries is 2, and not n+1');
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class DDC2346Foo
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var DDC2346Bar[]|\Doctrine\Common\Collections\Collection
|
||||
*
|
||||
* @OneToMany(targetEntity="DDC2346Bar", mappedBy="foo")
|
||||
*/
|
||||
public $bars;
|
||||
|
||||
/** Constructor */
|
||||
public function __construct() {
|
||||
$this->bars = new ArrayCollection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"baz" = "DDC2346Baz"})
|
||||
*/
|
||||
class DDC2346Bar
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @ManyToOne(targetEntity="DDC2346Foo", inversedBy="bars", fetch="EAGER") */
|
||||
public $foo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2346Baz extends DDC2346Bar
|
||||
{
|
||||
|
||||
}
|
||||
30
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php
Normal file
30
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\ORM\Functional\DatabaseDriverTestCase;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
|
||||
class DDC2387Test extends DatabaseDriverTestCase
|
||||
{
|
||||
/**
|
||||
* @group DDC-2387
|
||||
*/
|
||||
public function testCompositeAssociationKeyDetection()
|
||||
{
|
||||
$product = new \Doctrine\DBAL\Schema\Table('ddc2387_product');
|
||||
$product->addColumn('id', 'integer');
|
||||
$product->setPrimaryKey(array('id'));
|
||||
|
||||
$attributes = new \Doctrine\DBAL\Schema\Table('ddc2387_attributes');
|
||||
$attributes->addColumn('product_id', 'integer');
|
||||
$attributes->addColumn('attribute_name', 'string');
|
||||
$attributes->setPrimaryKey(array('product_id', 'attribute_name'));
|
||||
$attributes->addForeignKeyConstraint('ddc2387_product', array('product_id'), array('product_id'));
|
||||
|
||||
$metadata = $this->convertToClassMetadata(array($product, $attributes), array());
|
||||
|
||||
$this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_NONE, $metadata['Ddc2387Attributes']->generatorType);
|
||||
$this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_AUTO, $metadata['Ddc2387Product']->generatorType);
|
||||
}
|
||||
}
|
||||
72
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php
Normal file
72
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsArticle;
|
||||
|
||||
/**
|
||||
* @group DDC-2409
|
||||
*/
|
||||
class DDC2409Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$em = $this->_em;
|
||||
$uow = $em->getUnitOfWork();
|
||||
|
||||
$originalArticle = new CmsArticle();
|
||||
$originalUser = new CmsUser();
|
||||
|
||||
$originalArticle->topic = 'Unit Test';
|
||||
$originalArticle->text = 'How to write a test';
|
||||
|
||||
$originalUser->name = 'Doctrine Bot';
|
||||
$originalUser->username = 'DoctrineBot';
|
||||
$originalUser->status = 'active';
|
||||
|
||||
$originalUser->addArticle($originalArticle);
|
||||
|
||||
$em->persist($originalUser);
|
||||
$em->persist($originalArticle);
|
||||
$em->flush();
|
||||
$em->clear();
|
||||
|
||||
$article = $em->find('Doctrine\Tests\Models\CMS\CmsArticle', $originalArticle->id);
|
||||
$user = new CmsUser();
|
||||
|
||||
$user->name = 'Doctrine Bot 2.0';
|
||||
$user->username = 'BotDoctrine2';
|
||||
$user->status = 'new';
|
||||
|
||||
$article->setAuthor($user);
|
||||
|
||||
$this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($originalArticle));
|
||||
$this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($originalUser));
|
||||
$this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($article));
|
||||
$this->assertEquals(UnitOfWork::STATE_NEW, $uow->getEntityState($user));
|
||||
|
||||
$em->detach($user);
|
||||
$em->detach($article);
|
||||
|
||||
$userMerged = $em->merge($user);
|
||||
$articleMerged = $em->merge($article);
|
||||
|
||||
$this->assertEquals(UnitOfWork::STATE_NEW, $uow->getEntityState($user));
|
||||
$this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($article));
|
||||
$this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($userMerged));
|
||||
$this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($articleMerged));
|
||||
|
||||
$this->assertNotSame($user, $userMerged);
|
||||
$this->assertNotSame($article, $articleMerged);
|
||||
$this->assertNotSame($userMerged, $articleMerged->user);
|
||||
$this->assertSame($user, $articleMerged->user);
|
||||
}
|
||||
}
|
||||
@@ -34,4 +34,28 @@ class SimpleObjectHydratorTest extends HydrationTestCase
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator($this->_em);
|
||||
$hydrator->hydrateAll($stmt, $rsm);
|
||||
}
|
||||
|
||||
public function testExtraFieldInResultSetShouldBeIgnore()
|
||||
{
|
||||
$rsm = new ResultSetMapping;
|
||||
$rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsAddress', 'a');
|
||||
$rsm->addFieldResult('a', 'a__id', 'id');
|
||||
$rsm->addFieldResult('a', 'a__city', 'city');
|
||||
$resultSet = array(
|
||||
array(
|
||||
'a__id' => '1',
|
||||
'a__city' => 'Cracow',
|
||||
'doctrine_rownum' => '1'
|
||||
),
|
||||
);
|
||||
|
||||
$expectedEntity = new \Doctrine\Tests\Models\CMS\CmsAddress();
|
||||
$expectedEntity->id = 1;
|
||||
$expectedEntity->city = 'Cracow';
|
||||
|
||||
$stmt = new HydratorMockStatement($resultSet);
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator($this->_em);
|
||||
$result = $hydrator->hydrateAll($stmt, $rsm);
|
||||
$this->assertEquals($result[0], $expectedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,14 +139,27 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
*/
|
||||
public function testFieldMappings($class)
|
||||
{
|
||||
$this->assertEquals(3, count($class->fieldMappings));
|
||||
$this->assertEquals(4, count($class->fieldMappings));
|
||||
$this->assertTrue(isset($class->fieldMappings['id']));
|
||||
$this->assertTrue(isset($class->fieldMappings['name']));
|
||||
$this->assertTrue(isset($class->fieldMappings['email']));
|
||||
$this->assertTrue(isset($class->fieldMappings['version']));
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testFieldMappings
|
||||
* @param ClassMetadata $class
|
||||
*/
|
||||
public function testVersionedField($class)
|
||||
{
|
||||
$this->assertTrue($class->isVersioned);
|
||||
$this->assertEquals("version", $class->versionField);
|
||||
|
||||
$this->assertFalse(isset($class->fieldMappings['version']['version']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testEntityTableNameAndInheritance
|
||||
* @param ClassMetadata $class
|
||||
@@ -464,24 +477,22 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
/**
|
||||
* @group DDC-889
|
||||
* @expectedException Doctrine\ORM\Mapping\MappingException
|
||||
* @expectedExceptionMessage Class "Doctrine\Tests\Models\DDC889\DDC889Class" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass" is not a valid entity or mapped super class.
|
||||
*/
|
||||
public function testInvalidEntityOrMappedSuperClassShouldMentionParentClasses()
|
||||
{
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'Class "Doctrine\Tests\Models\DDC889\DDC889Class" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass" is not a valid entity or mapped super class.');
|
||||
|
||||
$this->createClassMetadata('Doctrine\Tests\Models\DDC889\DDC889Class');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-889
|
||||
* @expectedException Doctrine\ORM\Mapping\MappingException
|
||||
* @expectedExceptionMessage No identifier/primary key specified for Entity "Doctrine\Tests\Models\DDC889\DDC889Entity" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass". Every Entity must have an identifier/primary key.
|
||||
*/
|
||||
public function testIdentifierRequiredShouldMentionParentClasses()
|
||||
{
|
||||
|
||||
$factory = $this->createClassMetadataFactory();
|
||||
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', 'No identifier/primary key specified for Entity "Doctrine\Tests\Models\DDC889\DDC889Entity" sub class of "Doctrine\Tests\Models\DDC889\DDC889SuperClass". Every Entity must have an identifier/primary key.');
|
||||
$factory->getMetadataFor('Doctrine\Tests\Models\DDC889\DDC889Entity');
|
||||
}
|
||||
|
||||
@@ -498,7 +509,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
*/
|
||||
public function testNamedNativeQuery()
|
||||
{
|
||||
|
||||
|
||||
$class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
|
||||
|
||||
//named native query
|
||||
@@ -527,7 +538,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertArrayHasKey('mapping-count', $class->sqlResultSetMappings);
|
||||
$this->assertArrayHasKey('mapping-find-all', $class->sqlResultSetMappings);
|
||||
$this->assertArrayHasKey('mapping-without-fields', $class->sqlResultSetMappings);
|
||||
|
||||
|
||||
$findAllMapping = $class->getSqlResultSetMapping('mapping-find-all');
|
||||
$this->assertEquals('mapping-find-all', $findAllMapping['name']);
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $findAllMapping['entities'][0]['entityClass']);
|
||||
@@ -539,7 +550,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('mapping-without-fields', $withoutFieldsMapping['name']);
|
||||
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsAddress', $withoutFieldsMapping['entities'][0]['entityClass']);
|
||||
$this->assertEquals(array(), $withoutFieldsMapping['entities'][0]['fields']);
|
||||
|
||||
|
||||
$countMapping = $class->getSqlResultSetMapping('mapping-count');
|
||||
$this->assertEquals('mapping-count', $countMapping['name']);
|
||||
$this->assertEquals(array('name'=>'count'), $countMapping['columns'][0]);
|
||||
@@ -627,7 +638,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$adminMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Admin');
|
||||
$guestMetadata = $factory->getMetadataFor('Doctrine\Tests\Models\DDC964\DDC964Guest');
|
||||
|
||||
|
||||
|
||||
// assert groups association mappings
|
||||
$this->assertArrayHasKey('groups', $guestMetadata->associationMappings);
|
||||
$this->assertArrayHasKey('groups', $adminMetadata->associationMappings);
|
||||
@@ -686,7 +697,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals($guestAddress['isCascadeRefresh'], $adminAddress['isCascadeRefresh']);
|
||||
$this->assertEquals($guestAddress['isCascadeMerge'], $adminAddress['isCascadeMerge']);
|
||||
$this->assertEquals($guestAddress['isCascadeDetach'], $adminAddress['isCascadeDetach']);
|
||||
|
||||
|
||||
// assert override
|
||||
$this->assertEquals('address_id', $guestAddress['joinColumns'][0]['name']);
|
||||
$this->assertEquals(array('address_id'=>'id'), $guestAddress['sourceToTargetKeyColumns']);
|
||||
@@ -793,6 +804,12 @@ class User
|
||||
*/
|
||||
public $groups;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @Version
|
||||
*/
|
||||
public $version;
|
||||
|
||||
|
||||
/**
|
||||
* @PrePersist
|
||||
@@ -847,6 +864,9 @@ class User
|
||||
'columnName' => 'user_email',
|
||||
'columnDefinition' => 'CHAR(32) NOT NULL',
|
||||
));
|
||||
$mapping = array('fieldName' => 'version', 'type' => 'integer');
|
||||
$metadata->setVersionMapping($mapping);
|
||||
$metadata->mapField($mapping);
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
$metadata->mapOneToOne(array(
|
||||
'fieldName' => 'address',
|
||||
@@ -1051,7 +1071,7 @@ class DDC807Entity
|
||||
* @GeneratedValue(strategy="NONE")
|
||||
**/
|
||||
public $id;
|
||||
|
||||
|
||||
public static function loadMetadata(ClassMetadataInfo $metadata)
|
||||
{
|
||||
$metadata->mapField(array(
|
||||
|
||||
@@ -54,4 +54,35 @@ class YamlMappingDriverTest extends AbstractMappingDriverTest
|
||||
$this->createClassMetadata('Doctrine\Tests\Models\Generic\SerializationModel');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2069
|
||||
*/
|
||||
public function testSpacesShouldBeIgnoredWhenUseExplode()
|
||||
{
|
||||
$metadata = $this->createClassMetadata(__NAMESPACE__.'\DDC2069Entity');
|
||||
$unique = $metadata->table['uniqueConstraints'][0]['columns'];
|
||||
$indexes = $metadata->table['indexes'][0]['columns'];
|
||||
|
||||
$nameField = $metadata->fieldMappings['name'];
|
||||
$valueField = $metadata->fieldMappings['value'];
|
||||
|
||||
$this->assertEquals('name', $unique[0]);
|
||||
$this->assertEquals('value', $unique[1]);
|
||||
|
||||
$this->assertEquals('value', $indexes[0]);
|
||||
$this->assertEquals('name', $indexes[1]);
|
||||
|
||||
$this->assertEquals(255, $nameField['length']);
|
||||
$this->assertEquals(255, $valueField['length']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DDC2069Entity
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $name;
|
||||
|
||||
public $value;
|
||||
}
|
||||
@@ -35,6 +35,9 @@ $metadata->mapField(array(
|
||||
'columnName' => 'user_email',
|
||||
'columnDefinition' => 'CHAR(32) NOT NULL',
|
||||
));
|
||||
$mapping = array('fieldName' => 'version', 'type' => 'integer');
|
||||
$metadata->setVersionMapping($mapping);
|
||||
$metadata->mapField($mapping);
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
$metadata->mapOneToOne(array(
|
||||
'fieldName' => 'address',
|
||||
@@ -121,4 +124,4 @@ $metadata->setSequenceGeneratorDefinition(array(
|
||||
'sequenceName' => 'tablename_seq',
|
||||
'allocationSize' => 100,
|
||||
'initialValue' => 1,
|
||||
));
|
||||
));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
|
||||
<options>
|
||||
<option name="foo">bar</option>
|
||||
@@ -36,7 +36,7 @@
|
||||
<generator strategy="AUTO"/>
|
||||
<sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
|
||||
</id>
|
||||
|
||||
|
||||
<field name="name" column="name" type="string" length="50" nullable="true" unique="true">
|
||||
<options>
|
||||
<option name="foo">bar</option>
|
||||
@@ -46,12 +46,14 @@
|
||||
</options>
|
||||
</field>
|
||||
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
|
||||
|
||||
|
||||
<field name="version" type="integer" version="true" />
|
||||
|
||||
<one-to-one field="address" target-entity="Address" inversed-by="user">
|
||||
<cascade><cascade-remove /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
|
||||
</one-to-one>
|
||||
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user" index-by="number" orphan-removal="true">
|
||||
<cascade>
|
||||
<cascade-persist/>
|
||||
@@ -60,7 +62,7 @@
|
||||
<order-by-field name="number" direction="ASC" />
|
||||
</order-by>
|
||||
</one-to-many>
|
||||
|
||||
|
||||
<many-to-many field="groups" target-entity="Group">
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
@@ -74,7 +76,7 @@
|
||||
</inverse-join-columns>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
@@ -5,4 +5,4 @@ Doctrine\Tests\Models\DDC1476\DDC1476EntityWithDefaultFieldType:
|
||||
generator:
|
||||
strategy: NONE
|
||||
fields:
|
||||
name:
|
||||
name: ~
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
Doctrine\Tests\ORM\Mapping\DDC2069Entity:
|
||||
type: entity
|
||||
id:
|
||||
id: ~
|
||||
fields:
|
||||
name:
|
||||
type: string ( 255 )
|
||||
value:
|
||||
type: string ( 255 )
|
||||
uniqueConstraints:
|
||||
0:
|
||||
columns: name, value
|
||||
indexes:
|
||||
0:
|
||||
columns: value, name
|
||||
@@ -30,6 +30,9 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||
type: string
|
||||
column: user_email
|
||||
columnDefinition: CHAR(32) NOT NULL
|
||||
version:
|
||||
type: integer
|
||||
version: true
|
||||
oneToOne:
|
||||
address:
|
||||
targetEntity: Address
|
||||
@@ -73,4 +76,4 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||
name_idx:
|
||||
columns: name
|
||||
0:
|
||||
columns: user_email
|
||||
columns: user_email
|
||||
|
||||
@@ -7,6 +7,7 @@ use Doctrine\ORM\Persisters\BasicEntityPersister;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeFriend;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
@@ -88,4 +89,13 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals('t0."simple-entity-id" AS simpleentityid1, t0."simple-entity-value" AS simpleentityvalue2', $method->invoke($persister));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2073
|
||||
*/
|
||||
public function testSelectConditionStatementIsNull()
|
||||
{
|
||||
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS);
|
||||
$this->assertEquals('test IS ?', $statement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,4 +409,18 @@ class ExprTest extends \Doctrine\Tests\OrmTestCase
|
||||
$select = new Expr\Select(array('foo', 'bar'));
|
||||
$this->assertEquals(array('foo', 'bar'), $select->getParts());
|
||||
}
|
||||
|
||||
public function testAddEmpty() {
|
||||
$andExpr = $this->_expr->andx();
|
||||
$andExpr->add($this->_expr->andx());
|
||||
|
||||
$this->assertEquals(0, $andExpr->count());
|
||||
}
|
||||
|
||||
public function testAddNull() {
|
||||
$andExpr = $this->_expr->andx();
|
||||
$andExpr->add(null);
|
||||
|
||||
$this->assertEquals(0, $andExpr->count());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,4 +163,16 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('cities', $parameter->getName());
|
||||
$this->assertEquals($cities, $parameter->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2224
|
||||
*/
|
||||
public function testProcessParameterValueClassMetadata()
|
||||
{
|
||||
$query = $this->_em->createQuery("SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)");
|
||||
$this->assertEquals(
|
||||
'Doctrine\Tests\Models\CMS\CmsAddress',
|
||||
$query->processParameterValue($this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,19 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testSupportsJoinOnMultipleComponentsWithJoinedInheritanceType()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
|
||||
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN company_managers c2_ INNER JOIN company_employees c3_ ON c2_.id = c3_.id INNER JOIN company_persons c4_ ON c2_.id = c4_.id AND (c0_.id = c4_.id)'
|
||||
);
|
||||
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e LEFT JOIN Doctrine\Tests\Models\Company\CompanyManager m WITH e.id = m.id',
|
||||
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ INNER JOIN company_employees c3_ ON c2_.id = c3_.id INNER JOIN company_persons c4_ ON c2_.id = c4_.id ON (c0_.id = c4_.id)'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSupportsSelectWithCollectionAssociationJoin()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
@@ -461,7 +474,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1",
|
||||
"SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')",
|
||||
"SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN (?)",
|
||||
array(), array(1 => $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee'))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -137,6 +137,19 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a ON u.id = a.author_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function testComplexInnerJoinWithIndexBy()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder()
|
||||
->select('u', 'a')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->innerJoin('u.articles', 'a', 'ON', 'u.id = a.author_id', 'a.name');
|
||||
|
||||
$this->assertValidQueryBuilder(
|
||||
$qb,
|
||||
'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INDEX BY a.name ON u.id = a.author_id'
|
||||
);
|
||||
}
|
||||
|
||||
public function testLeftJoin()
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$metadata->mapManyToMany(array(
|
||||
'fieldName' => 'comments',
|
||||
'targetEntity' => 'Doctrine\Tests\ORM\Tools\EntityGeneratorComment',
|
||||
'fetch' => ClassMetadataInfo::FETCH_EXTRA_LAZY,
|
||||
'joinTable' => array(
|
||||
'name' => 'book_comment',
|
||||
'joinColumns' => array(array('name' => 'book_id', 'referencedColumnName' => 'id')),
|
||||
@@ -167,6 +168,24 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2121
|
||||
*/
|
||||
public function testMethodDocBlockShouldStartWithBackSlash()
|
||||
{
|
||||
$metadata = $this->generateBookEntityFixture();
|
||||
$book = $this->newInstance($metadata);
|
||||
|
||||
$this->assertPhpDocVarType('\Doctrine\Common\Collections\Collection', new \ReflectionProperty($book, 'comments'));
|
||||
$this->assertPhpDocReturnType('\Doctrine\Common\Collections\Collection', new \ReflectionMethod($book, 'getComments'));
|
||||
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new \ReflectionMethod($book, 'addComment'));
|
||||
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorComment', new \ReflectionMethod($book, 'removeComment'));
|
||||
|
||||
$this->assertPhpDocVarType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionProperty($book, 'author'));
|
||||
$this->assertPhpDocReturnType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'getAuthor'));
|
||||
$this->assertPhpDocParamType('\Doctrine\Tests\ORM\Tools\EntityGeneratorAuthor', new \ReflectionMethod($book, 'setAuthor'));
|
||||
}
|
||||
|
||||
public function testEntityExtendsStdClass()
|
||||
{
|
||||
$this->_generator->setClassToExtend('stdClass');
|
||||
@@ -205,6 +224,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals($cm->identifier, $metadata->identifier);
|
||||
$this->assertEquals($cm->idGenerator, $metadata->idGenerator);
|
||||
$this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
|
||||
|
||||
$this->assertEquals(ClassMetadataInfo::FETCH_EXTRA_LAZY, $cm->associationMappings['comments']['fetch']);
|
||||
}
|
||||
|
||||
public function testLoadPrefixedMetadata()
|
||||
@@ -278,6 +299,131 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertContains('@SequenceGenerator(sequenceName="DDC1784_ID_SEQ", allocationSize=1, initialValue=2)', $docComment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2079
|
||||
*/
|
||||
public function testGenerateEntityWithMultipleInverseJoinColumns()
|
||||
{
|
||||
$metadata = new ClassMetadataInfo($this->_namespace . '\DDC2079Entity');
|
||||
$metadata->namespace = $this->_namespace;
|
||||
$metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
|
||||
$metadata->mapManyToMany(array(
|
||||
'fieldName' => 'centroCustos',
|
||||
'targetEntity' => 'DDC2079CentroCusto',
|
||||
'joinTable' => array(
|
||||
'name' => 'unidade_centro_custo',
|
||||
'joinColumns' => array(
|
||||
array('name' => 'idorcamento', 'referencedColumnName' => 'idorcamento'),
|
||||
array('name' => 'idunidade', 'referencedColumnName' => 'idunidade')
|
||||
),
|
||||
'inverseJoinColumns' => array(
|
||||
array('name' => 'idcentrocusto', 'referencedColumnName' => 'idcentrocusto'),
|
||||
array('name' => 'idpais', 'referencedColumnName' => 'idpais'),
|
||||
),
|
||||
),
|
||||
));
|
||||
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
|
||||
|
||||
$filename = $this->_tmpDir . DIRECTORY_SEPARATOR
|
||||
. $this->_namespace . DIRECTORY_SEPARATOR . 'DDC2079Entity.php';
|
||||
|
||||
$this->assertFileExists($filename);
|
||||
require_once $filename;
|
||||
|
||||
$property = new \ReflectionProperty($metadata->name, 'centroCustos');
|
||||
$docComment = $property->getDocComment();
|
||||
|
||||
//joinColumns
|
||||
$this->assertContains('@JoinColumn(name="idorcamento", referencedColumnName="idorcamento"),', $docComment);
|
||||
$this->assertContains('@JoinColumn(name="idunidade", referencedColumnName="idunidade")', $docComment);
|
||||
//inverseJoinColumns
|
||||
$this->assertContains('@JoinColumn(name="idcentrocusto", referencedColumnName="idcentrocusto"),', $docComment);
|
||||
$this->assertContains('@JoinColumn(name="idpais", referencedColumnName="idpais")', $docComment);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2172
|
||||
*/
|
||||
public function testGetInheritanceTypeString()
|
||||
{
|
||||
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
|
||||
$method = new \ReflectionMethod($this->_generator, 'getInheritanceTypeString');
|
||||
$constants = $reflection->getConstants();
|
||||
$pattern = '/^INHERITANCE_TYPE_/';
|
||||
|
||||
$method->setAccessible(true);
|
||||
|
||||
foreach ($constants as $name => $value) {
|
||||
if( ! preg_match($pattern, $name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$expected = preg_replace($pattern, '', $name);
|
||||
$actual = $method->invoke($this->_generator, $value);
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided InheritanceType: INVALID');
|
||||
$method->invoke($this->_generator, 'INVALID');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2172
|
||||
*/
|
||||
public function testGetChangeTrackingPolicyString()
|
||||
{
|
||||
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
|
||||
$method = new \ReflectionMethod($this->_generator, 'getChangeTrackingPolicyString');
|
||||
$constants = $reflection->getConstants();
|
||||
$pattern = '/^CHANGETRACKING_/';
|
||||
|
||||
$method->setAccessible(true);
|
||||
|
||||
foreach ($constants as $name => $value) {
|
||||
if( ! preg_match($pattern, $name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$expected = preg_replace($pattern, '', $name);
|
||||
$actual = $method->invoke($this->_generator, $value);
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided ChangeTrackingPolicy: INVALID');
|
||||
$method->invoke($this->_generator, 'INVALID');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2172
|
||||
*/
|
||||
public function testGetIdGeneratorTypeString()
|
||||
{
|
||||
$reflection = new \ReflectionClass('\Doctrine\ORM\Mapping\ClassMetadata');
|
||||
$method = new \ReflectionMethod($this->_generator, 'getIdGeneratorTypeString');
|
||||
$constants = $reflection->getConstants();
|
||||
$pattern = '/^GENERATOR_TYPE_/';
|
||||
|
||||
$method->setAccessible(true);
|
||||
|
||||
foreach ($constants as $name => $value) {
|
||||
if( ! preg_match($pattern, $name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$expected = preg_replace($pattern, '', $name);
|
||||
$actual = $method->invoke($this->_generator, $value);
|
||||
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
$this->setExpectedException('\InvalidArgumentException', 'Invalid provided IdGeneratorType: INVALID');
|
||||
$method->invoke($this->_generator, 'INVALID');
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider getEntityTypeAliasDataProvider
|
||||
*
|
||||
|
||||
@@ -41,5 +41,22 @@ class CountOutputWalkerTest extends PaginationTestCase
|
||||
"SELECT COUNT(*) AS dctrn_count FROM (SELECT DISTINCT id1 FROM (SELECT count(u0_.id) AS sclr0, g1_.id AS id1, u0_.id AS id2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr0 > 0) dctrn_result) dctrn_table", $query->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountQueryOrderBySqlServer()
|
||||
{
|
||||
if ($this->entityManager->getConnection()->getDatabasePlatform()->getName() !== "mssql") {
|
||||
$this->markTestSkipped('SQLServer only test.');
|
||||
}
|
||||
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p FROM Doctrine\Tests\ORM\Tools\Pagination\BlogPost p ORDER BY p.id');
|
||||
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker');
|
||||
$query->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT COUNT(*) AS dctrn_count FROM (SELECT DISTINCT id0 FROM (SELECT b0_.id AS id0, b0_.author_id AS author_id1, b0_.category_id AS category_id2 FROM BlogPost b0_) dctrn_result) dctrn_table",
|
||||
$query->getSql()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,42 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a');
|
||||
$query->expireQueryCache(true);
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
|
||||
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryWithSortPg()
|
||||
{
|
||||
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
|
||||
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
|
||||
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT id0, title1 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC) dctrn_result ORDER BY title1 ASC", $limitQuery->getSql()
|
||||
);
|
||||
|
||||
$this->entityManager->getConnection()->setDatabasePlatform($odp);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryPg()
|
||||
{
|
||||
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
|
||||
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
|
||||
|
||||
$this->testLimitSubquery();
|
||||
|
||||
$this->entityManager->getConnection()->setDatabasePlatform($odp);
|
||||
}
|
||||
|
||||
public function testCountQuery_MixedResultsWithName()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
|
||||
@@ -21,6 +21,18 @@ class LimitSubqueryWalkerTest extends PaginationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryWithSort()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'));
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT m0_.id AS id0, m0_.title AS title1 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC", $limitQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountQuery_MixedResultsWithName()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
|
||||
@@ -31,6 +31,8 @@ class MyBlogPost
|
||||
* @ManyToOne(targetEntity="Category")
|
||||
*/
|
||||
public $category;
|
||||
/** @column(type="string") */
|
||||
public $title;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,31 @@ class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\ResolveTargetEntity', $meta['oneToMany']['targetEntity']);
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['oneToOne']['targetEntity']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2109
|
||||
*/
|
||||
public function testAssertTableColumnsAreNotAddedInManyToMany()
|
||||
{
|
||||
$evm = $this->em->getEventManager();
|
||||
$this->listener->addResolveTargetEntity(
|
||||
'Doctrine\Tests\ORM\Tools\ResolveTargetInterface',
|
||||
'Doctrine\Tests\ORM\Tools\ResolveTargetEntity',
|
||||
array()
|
||||
);
|
||||
$this->listener->addResolveTargetEntity(
|
||||
'Doctrine\Tests\ORM\Tools\TargetInterface',
|
||||
'Doctrine\Tests\ORM\Tools\TargetEntity',
|
||||
array()
|
||||
);
|
||||
|
||||
$evm->addEventListener(Events::loadClassMetadata, $this->listener);
|
||||
$cm = $this->factory->getMetadataFor('Doctrine\Tests\ORM\Tools\ResolveTargetEntity');
|
||||
$meta = $cm->associationMappings['manyToMany'];
|
||||
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['targetEntity']);
|
||||
$this->assertEquals(array('resolvetargetentity_id', 'targetinterface_id'), $meta['joinTableColumns']);
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolveTargetInterface
|
||||
|
||||
@@ -44,8 +44,8 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
|
||||
$schema = $schemaTool->getSchemaFromMetadata($classes);
|
||||
|
||||
$expected = array('foo' => 'bar', 'baz' => array('key' => 'val'));
|
||||
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables optionss");
|
||||
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,38 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals(UnitOfWork::STATE_DETACHED, $this->_unitOfWork->getEntityState($ph2));
|
||||
$this->assertFalse($persister->isExistsCalled());
|
||||
}
|
||||
|
||||
/**
|
||||
* DDC-2086 [GH-484] Prevented "Undefined index" notice when updating.
|
||||
*/
|
||||
public function testNoUndefinedIndexNoticeOnScheduleForUpdateWithoutChanges()
|
||||
{
|
||||
// Setup fake persister and id generator
|
||||
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
|
||||
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
|
||||
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
|
||||
|
||||
// Create a test user
|
||||
$user = new ForumUser();
|
||||
$user->name = 'Jasper';
|
||||
$this->_unitOfWork->persist($user);
|
||||
$this->_unitOfWork->commit();
|
||||
|
||||
// Schedule user for update without changes
|
||||
$this->_unitOfWork->scheduleForUpdate($user);
|
||||
|
||||
// This commit should not raise an E_NOTICE
|
||||
$this->_unitOfWork->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1984
|
||||
*/
|
||||
public function testLockWithoutEntityThrowsException()
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$this->_unitOfWork->lock(null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,4 +341,4 @@ class VersionedAssignedIdentifierEntity
|
||||
* @Version @Column(type="integer")
|
||||
*/
|
||||
public $version;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user