mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
261 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c31ec4809 | ||
|
|
47daa48e1f | ||
|
|
1a30e0a2e0 | ||
|
|
550f25f0c0 | ||
|
|
4863e996db | ||
|
|
08e6363684 | ||
|
|
4fdd1b9c2b | ||
|
|
11f4c90d07 | ||
|
|
66d8b43f69 | ||
|
|
5ded61466b | ||
|
|
8d3617a773 | ||
|
|
71d5f85ce0 | ||
|
|
0e3abb4d79 | ||
|
|
b1ba11c06f | ||
|
|
d349e37ce9 | ||
|
|
fd178d0e0d | ||
|
|
6f1b8259d8 | ||
|
|
9e54ddca31 | ||
|
|
465bf0f411 | ||
|
|
794a6bea1b | ||
|
|
e4fdfb0b35 | ||
|
|
cba05708a9 | ||
|
|
f1f5163394 | ||
|
|
7816025077 | ||
|
|
6fd4e8f470 | ||
|
|
beed62045f | ||
|
|
f23656e468 | ||
|
|
76694239fa | ||
|
|
6da540ac10 | ||
|
|
a0a66431ea | ||
|
|
8956cfcf2a | ||
|
|
063280b0bd | ||
|
|
9e67efa37b | ||
|
|
00f62dd6c3 | ||
|
|
b880452ab1 | ||
|
|
de59307b8e | ||
|
|
6c74d8ad33 | ||
|
|
0633aa54c8 | ||
|
|
db0c1fad78 | ||
|
|
9787b27518 | ||
|
|
4f83e7e6c4 | ||
|
|
425f375899 | ||
|
|
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 | ||
|
|
b5e19dca18 | ||
|
|
585c9fd208 | ||
|
|
c6101317cd | ||
|
|
477642a171 | ||
|
|
75e968b250 | ||
|
|
3294900faa | ||
|
|
2353736e8f | ||
|
|
586aea0236 | ||
|
|
18a7fc5726 | ||
|
|
44a56e8e49 | ||
|
|
c2b82fa529 | ||
|
|
d7da012918 | ||
|
|
85e5398354 | ||
|
|
3fd8392ccf | ||
|
|
0da0d02dec | ||
|
|
387516f144 | ||
|
|
53e164ba5d | ||
|
|
4d9f24b2ee | ||
|
|
a96bbbbe0a | ||
|
|
8edecfdcad | ||
|
|
741080dc17 | ||
|
|
30ad1b0706 | ||
|
|
9cdee12ccf | ||
|
|
c76280be42 | ||
|
|
0dcfabbc4d | ||
|
|
366c6a7dd6 | ||
|
|
2597192f22 | ||
|
|
bbf527a273 | ||
|
|
9308afc9a5 | ||
|
|
1a81444b04 | ||
|
|
d181fbc98d | ||
|
|
114e233d87 | ||
|
|
bdb36a71c5 | ||
|
|
8c1d64372c | ||
|
|
f4ba58358c | ||
|
|
131d3003a0 | ||
|
|
48e94343fd | ||
|
|
9d909cd583 | ||
|
|
3aaa90e1a8 | ||
|
|
971865f271 | ||
|
|
af08f05164 | ||
|
|
2e6b50bb53 | ||
|
|
17862d9a2a | ||
|
|
c99c7b6694 | ||
|
|
3f2ddc60d4 | ||
|
|
3b3d762277 | ||
|
|
992b51eba7 | ||
|
|
5527e121ec | ||
|
|
c55394c616 | ||
|
|
1676cf23c0 | ||
|
|
6dd3078153 | ||
|
|
1e2eca1a7e | ||
|
|
7029d3738d | ||
|
|
7f68347c1f | ||
|
|
e63575ea18 | ||
|
|
d7bdae3bbb | ||
|
|
e2c40dc365 | ||
|
|
dfa6ff64c4 | ||
|
|
ef27721db2 | ||
|
|
13d32e6de5 | ||
|
|
bd1e6ac309 | ||
|
|
369a30ad3d | ||
|
|
ac9df05c92 | ||
|
|
2158a0788e | ||
|
|
2389f77d91 | ||
|
|
5b55739990 | ||
|
|
3e53d9d79c |
14
UPGRADE.md
14
UPGRADE.md
@@ -1,5 +1,19 @@
|
||||
# Upgrade to 2.3
|
||||
|
||||
## Auto Discriminator Map breaks userland implementations with Listener
|
||||
|
||||
The new feature to detect discriminator maps automatically when none
|
||||
are provided breaks userland implementations doing this with a
|
||||
listener in ``loadClassMetadata`` event.
|
||||
|
||||
## 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",
|
||||
"type": "library","version":"2.3.5",
|
||||
"description": "Object-Relational-Mapper for PHP",
|
||||
"keywords": ["orm", "database"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
@@ -14,7 +14,7 @@
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/dbal": ">=2.3-dev,<2.5-dev",
|
||||
"doctrine/dbal": "2.3.*",
|
||||
"symfony/console": "2.*"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -26,7 +26,7 @@
|
||||
"bin": ["bin/doctrine", "bin/doctrine.php"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4.x-dev"
|
||||
"dev-master": "2.3.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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."
|
||||
);
|
||||
@@ -658,6 +662,18 @@ abstract class AbstractQuery
|
||||
return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the query has a hint
|
||||
*
|
||||
* @param string $name The name of the hint
|
||||
*
|
||||
* @return bool False if the query does not have any hint
|
||||
*/
|
||||
public function hasHint($name)
|
||||
{
|
||||
return isset($this->_hints[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key value map of query hints that are currently set.
|
||||
*
|
||||
|
||||
@@ -25,6 +25,7 @@ use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\ExpressionBuilder;
|
||||
|
||||
/**
|
||||
* An EntityRepository serves as a repository for entities with generic as well as
|
||||
@@ -160,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,6 +118,7 @@ class ArrayHydrator extends AbstractHydrator
|
||||
$baseElement =& $this->_resultPointers[$parent];
|
||||
} else {
|
||||
unset($this->_resultPointers[$dqlAlias]); // Ticket #1228
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -139,6 +140,7 @@ class ArrayHydrator extends AbstractHydrator
|
||||
|
||||
if ( ! $indexExists || ! $indexIsValid) {
|
||||
$element = $data;
|
||||
|
||||
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
|
||||
$baseElement[$relationAlias][$row[$this->_rsm->indexByMap[$dqlAlias]]] = $element;
|
||||
} else {
|
||||
@@ -155,7 +157,10 @@ class ArrayHydrator extends AbstractHydrator
|
||||
} else {
|
||||
$oneToOne = true;
|
||||
|
||||
if ( ! isset($nonemptyComponents[$dqlAlias]) && ! isset($baseElement[$relationAlias])) {
|
||||
if (
|
||||
( ! isset($nonemptyComponents[$dqlAlias])) &&
|
||||
( ! isset($baseElement[$relationAlias]))
|
||||
) {
|
||||
$baseElement[$relationAlias] = null;
|
||||
} else if ( ! isset($baseElement[$relationAlias])) {
|
||||
$baseElement[$relationAlias] = $data;
|
||||
@@ -164,10 +169,9 @@ class ArrayHydrator extends AbstractHydrator
|
||||
|
||||
$coll =& $baseElement[$relationAlias];
|
||||
|
||||
if ($coll !== null) {
|
||||
if (is_array($coll)) {
|
||||
$this->updateResultPointer($coll, $index, $dqlAlias, $oneToOne);
|
||||
}
|
||||
|
||||
} else {
|
||||
// It's a root result element
|
||||
|
||||
@@ -176,22 +180,21 @@ class ArrayHydrator extends AbstractHydrator
|
||||
|
||||
// if this row has a NULL value for the root result id then make it a null result.
|
||||
if ( ! isset($nonemptyComponents[$dqlAlias]) ) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result[] = array($entityKey => null);
|
||||
} else {
|
||||
$result[] = null;
|
||||
}
|
||||
$result[] = $this->_rsm->isMixed
|
||||
? array($entityKey => null)
|
||||
: null;
|
||||
|
||||
$resultKey = $this->_resultCounter;
|
||||
++$this->_resultCounter;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for an existing element
|
||||
if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
|
||||
$element = $rowData[$dqlAlias];
|
||||
if ($this->_rsm->isMixed) {
|
||||
$element = array($entityKey => $element);
|
||||
}
|
||||
$element = $this->_rsm->isMixed
|
||||
? array($entityKey => $rowData[$dqlAlias])
|
||||
: $rowData[$dqlAlias];
|
||||
|
||||
if (isset($this->_rsm->indexByMap[$dqlAlias])) {
|
||||
$resultKey = $row[$this->_rsm->indexByMap[$dqlAlias]];
|
||||
@@ -199,6 +202,7 @@ class ArrayHydrator extends AbstractHydrator
|
||||
} else {
|
||||
$resultKey = $this->_resultCounter;
|
||||
$result[] = $element;
|
||||
|
||||
++$this->_resultCounter;
|
||||
}
|
||||
|
||||
@@ -206,11 +210,13 @@ class ArrayHydrator extends AbstractHydrator
|
||||
} else {
|
||||
$index = $this->_identifierMap[$dqlAlias][$id[$dqlAlias]];
|
||||
$resultKey = $index;
|
||||
|
||||
/*if ($this->_rsm->isMixed) {
|
||||
$result[] =& $result[$index];
|
||||
++$this->_resultCounter;
|
||||
}*/
|
||||
}
|
||||
|
||||
$this->updateResultPointer($result, $index, $dqlAlias, false);
|
||||
}
|
||||
}
|
||||
@@ -219,11 +225,9 @@ class ArrayHydrator extends AbstractHydrator
|
||||
if (isset($scalars)) {
|
||||
if ( ! isset($resultKey) ) {
|
||||
// this only ever happens when no object is fetched (scalar result only)
|
||||
if (isset($this->_rsm->indexByMap['scalars'])) {
|
||||
$resultKey = $row[$this->_rsm->indexByMap['scalars']];
|
||||
} else {
|
||||
$resultKey = $this->_resultCounter - 1;
|
||||
}
|
||||
$resultKey = isset($this->_rsm->indexByMap['scalars'])
|
||||
? $row[$this->_rsm->indexByMap['scalars']]
|
||||
: $this->_resultCounter - 1;
|
||||
}
|
||||
|
||||
foreach ($scalars as $name => $value) {
|
||||
@@ -249,6 +253,12 @@ class ArrayHydrator extends AbstractHydrator
|
||||
return;
|
||||
}
|
||||
|
||||
if ($oneToOne) {
|
||||
$this->_resultPointers[$dqlAlias] =& $coll;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($index !== false) {
|
||||
$this->_resultPointers[$dqlAlias] =& $coll[$index];
|
||||
|
||||
@@ -259,12 +269,6 @@ class ArrayHydrator extends AbstractHydrator
|
||||
return;
|
||||
}
|
||||
|
||||
if ($oneToOne) {
|
||||
$this->_resultPointers[$dqlAlias] =& $coll;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
end($coll);
|
||||
$this->_resultPointers[$dqlAlias] =& $coll[key($coll)];
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -1188,7 +1188,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
// Complete fieldName and columnName mapping
|
||||
if ( ! isset($mapping['columnName'])) {
|
||||
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName'], $this->name);
|
||||
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']);
|
||||
}
|
||||
|
||||
if ($mapping['columnName'][0] === '`') {
|
||||
@@ -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']);
|
||||
}
|
||||
@@ -1465,7 +1469,6 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
if ( ! isset($mapping['joinTable']['name'])) {
|
||||
$mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
|
||||
}
|
||||
|
||||
if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
$mapping['joinTable']['joinColumns'] = array(array(
|
||||
'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']),
|
||||
@@ -1479,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']);
|
||||
@@ -2601,8 +2606,12 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*/
|
||||
public function setSequenceGeneratorDefinition(array $definition)
|
||||
{
|
||||
if (isset($definition['name']) && $definition['name'] == '`') {
|
||||
$definition['name'] = trim($definition['name'], '`');
|
||||
if ( ! isset($definition['sequenceName'])) {
|
||||
throw MappingException::missingSequenceName($this->name);
|
||||
}
|
||||
|
||||
if ($definition['sequenceName'][0] == '`') {
|
||||
$definition['sequenceName'] = trim($definition['sequenceName'], '`');
|
||||
$definition['quoted'] = true;
|
||||
}
|
||||
|
||||
@@ -2725,7 +2734,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
// Association defined as Id field
|
||||
$joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
|
||||
$assocQuotedColumnNames = array_map(
|
||||
function ($joinColumn) {
|
||||
function ($joinColumn) use ($platform) {
|
||||
return isset($joinColumn['quoted'])
|
||||
? $platform->quoteIdentifier($joinColumn['name'])
|
||||
: $joinColumn['name'];
|
||||
|
||||
@@ -45,7 +45,7 @@ class DefaultNamingStrategy implements NamingStrategy
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $propertyName;
|
||||
}
|
||||
|
||||
@@ -197,43 +197,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
}
|
||||
}
|
||||
|
||||
$associationOverrides = array();
|
||||
// Evaluate AssociationOverrides annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
|
||||
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
|
||||
|
||||
foreach ($associationOverridesAnnot->value as $associationOverride) {
|
||||
// Check for JoinColummn/JoinColumns annotations
|
||||
if ($associationOverride->joinColumns) {
|
||||
$joinColumns = array();
|
||||
foreach ($associationOverride->joinColumns as $joinColumn) {
|
||||
$joinColumns[] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
$associationOverrides[$associationOverride->name]['joinColumns'] = $joinColumns;
|
||||
}
|
||||
|
||||
// Check for JoinTable annotations
|
||||
if ($associationOverride->joinTable) {
|
||||
$joinTable = null;
|
||||
$joinTableAnnot = $associationOverride->joinTable;
|
||||
$joinTable = array(
|
||||
'name' => $joinTableAnnot->name,
|
||||
'schema' => $joinTableAnnot->schema
|
||||
);
|
||||
|
||||
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
|
||||
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
|
||||
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
|
||||
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
|
||||
$associationOverrides[$associationOverride->name]['joinTable'] = $joinTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate InheritanceType annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
|
||||
$inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
|
||||
|
||||
@@ -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
|
||||
@@ -438,4 +438,16 @@ class MappingException extends \Doctrine\ORM\ORMException
|
||||
$cascades
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $className
|
||||
*
|
||||
* @return MappingException
|
||||
*/
|
||||
public static function missingSequenceName($className)
|
||||
{
|
||||
return new self(
|
||||
sprintf('Missing "sequenceName" attribute for sequence id generator definition on class "%s".', $className)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,9 @@ interface NamingStrategy
|
||||
* Return a column name for a property
|
||||
*
|
||||
* @param string $propertyName A property
|
||||
* @param string $className The fully-qualified class name
|
||||
* @return string A column name
|
||||
*/
|
||||
function propertyToColumnName($propertyName, $className = null);
|
||||
function propertyToColumnName($propertyName);
|
||||
|
||||
/**
|
||||
* Return the default reference column name
|
||||
|
||||
@@ -80,7 +80,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $this->underscore($propertyName);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
|
||||
static public function entityWithoutIdentity($className, $entity)
|
||||
{
|
||||
throw new self(
|
||||
return new self(
|
||||
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
|
||||
"id values set. It cannot be added to the identity map."
|
||||
);
|
||||
@@ -70,30 +70,30 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
|
||||
static public function detachedEntityFoundThroughRelationship(array $assoc, $entry)
|
||||
{
|
||||
throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
|
||||
return new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
|
||||
. " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' "
|
||||
. "during cascading a persist operation.");
|
||||
}
|
||||
|
||||
static public function entityNotManaged($entity)
|
||||
{
|
||||
throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
|
||||
return new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
|
||||
"from the database or registered as new through EntityManager#persist");
|
||||
}
|
||||
|
||||
static public function entityHasNoIdentity($entity, $operation)
|
||||
{
|
||||
throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
return new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function entityIsRemoved($entity, $operation)
|
||||
{
|
||||
throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
return new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function detachedEntityCannot($entity, $operation)
|
||||
{
|
||||
throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
return new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
public static function invalidObject($context, $given, $parameterIndex = 1)
|
||||
|
||||
@@ -54,6 +54,8 @@ class OptimisticLockException extends ORMException
|
||||
|
||||
public static function lockFailedVersionMissmatch($entity, $expectedLockVersion, $actualLockVersion)
|
||||
{
|
||||
$expectedLockVersion = ($expectedLockVersion instanceof \DateTime) ? $expectedLockVersion->getTimestamp() : $expectedLockVersion;
|
||||
$actualLockVersion = ($actualLockVersion instanceof \DateTime) ? $actualLockVersion->getTimestamp() : $actualLockVersion;
|
||||
return new self("The optimistic lock failed, version " . $expectedLockVersion . " was expected, but is actually ".$actualLockVersion, $entity);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ use Closure;
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
|
||||
* @author Stefano Rodriguez <stefano.rodriguez@fubles.com>
|
||||
* @todo Design for inheritance to allow custom implementations?
|
||||
*/
|
||||
final class PersistentCollection implements Collection, Selectable
|
||||
@@ -654,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);
|
||||
@@ -716,6 +717,8 @@ final class PersistentCollection implements Collection, Selectable
|
||||
|
||||
public function key()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->coll->key();
|
||||
}
|
||||
|
||||
@@ -724,6 +727,8 @@ final class PersistentCollection implements Collection, Selectable
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->coll->current();
|
||||
}
|
||||
|
||||
@@ -732,6 +737,8 @@ final class PersistentCollection implements Collection, Selectable
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
$this->initialize();
|
||||
|
||||
return $this->coll->next();
|
||||
}
|
||||
|
||||
@@ -804,6 +811,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);
|
||||
}
|
||||
@@ -812,9 +823,10 @@ final class PersistentCollection implements Collection, Selectable
|
||||
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany assocations at the moment.");
|
||||
}
|
||||
|
||||
$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();
|
||||
|
||||
@@ -518,13 +518,34 @@ class BasicEntityPersister
|
||||
*/
|
||||
public function delete($entity)
|
||||
{
|
||||
$class = $this->_class;
|
||||
$em = $this->_em;
|
||||
|
||||
$identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
|
||||
$tableName = $this->quoteStrategy->getTableName($class, $this->_platform);
|
||||
$idColumns = $this->quoteStrategy->getIdentifierColumnNames($class, $this->_platform);
|
||||
$id = array_combine($idColumns, $identifier);
|
||||
$types = array_map(function ($identifier) use ($class, $em) {
|
||||
|
||||
if (isset($class->fieldMappings[$identifier])) {
|
||||
return $class->fieldMappings[$identifier]['type'];
|
||||
}
|
||||
|
||||
$targetMapping = $em->getClassMetadata($class->associationMappings[$identifier]['targetEntity']);
|
||||
|
||||
if (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])) {
|
||||
return $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
|
||||
}
|
||||
|
||||
if (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])) {
|
||||
return $targetMapping->associationMappings[$targetMapping->identifier[0]]['type'];
|
||||
}
|
||||
|
||||
throw ORMException::unrecognizedField($targetMapping->identifier[0]);
|
||||
}, $class->identifier);
|
||||
|
||||
$this->deleteJoinTableRecords($identifier);
|
||||
|
||||
$id = array_combine($this->quoteStrategy->getIdentifierColumnNames($this->_class, $this->_platform), $identifier);
|
||||
|
||||
$this->_conn->delete($this->quoteStrategy->getTableName($this->_class, $this->_platform), $id);
|
||||
$this->_conn->delete($tableName, $id, $types);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,12 +680,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 +811,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -808,10 +830,23 @@ class BasicEntityPersister
|
||||
return array(array(), array());
|
||||
}
|
||||
|
||||
$valueVisitor = new SqlValueVisitor($this->_class);
|
||||
$valueVisitor = new SqlValueVisitor();
|
||||
$valueVisitor->dispatch($expression);
|
||||
|
||||
return $valueVisitor->getParamsAndTypes();
|
||||
list($values, $types) = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
$sqlValues = array();
|
||||
foreach ($values as $value) {
|
||||
$sqlValues[] = $this->getValue($value);
|
||||
}
|
||||
|
||||
$sqlTypes = array();
|
||||
foreach ($types as $type) {
|
||||
list($field, $value) = $type;
|
||||
$sqlTypes[] = $this->getType($field, $value);
|
||||
}
|
||||
|
||||
return array($sqlValues, $sqlTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -831,7 +866,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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -860,7 +895,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.
|
||||
@@ -885,7 +920,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.
|
||||
@@ -1443,6 +1478,18 @@ class BasicEntityPersister
|
||||
$placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->_platform);
|
||||
}
|
||||
|
||||
if ($comparison !== null) {
|
||||
|
||||
// special case null value handling
|
||||
if (($comparison === Comparison::EQ || $comparison === Comparison::IS) && $value === null) {
|
||||
return $conditionSql . ' IS NULL';
|
||||
} else if ($comparison === Comparison::NEQ && $value === null) {
|
||||
return $conditionSql . ' IS NOT NULL';
|
||||
}
|
||||
|
||||
return $conditionSql . ' ' . sprintf(self::$comparisonMap[$comparison], $placeholder);
|
||||
}
|
||||
|
||||
$conditionSql .= ($comparison === null)
|
||||
? ((is_array($value)) ? ' IN (?)' : (($value === null) ? ' IS NULL' : ' = ' . $placeholder))
|
||||
: ' ' . sprintf(self::$comparisonMap[$comparison], $placeholder);
|
||||
@@ -1686,7 +1733,11 @@ class BasicEntityPersister
|
||||
$idValues = $class->getIdentifierValues($value);
|
||||
}
|
||||
|
||||
$value = $idValues[key($idValues)];
|
||||
$key = key($idValues);
|
||||
|
||||
if (null !== $key){
|
||||
$value = $idValues[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -184,7 +184,9 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
}
|
||||
|
||||
foreach ($data as $columnName => $value) {
|
||||
$stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
|
||||
if (!is_array($id) || !isset($id[$columnName])) {
|
||||
$stmt->bindValue($paramIndex++, $value, $this->_columnTypes[$columnName]);
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
@@ -227,8 +229,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 +472,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;
|
||||
|
||||
@@ -46,19 +46,6 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
*/
|
||||
private $types = array();
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
private $class;
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
public function __construct(ClassMetadata $class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a comparison expression into the target query language output
|
||||
*
|
||||
@@ -70,9 +57,16 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
{
|
||||
$value = $comparison->getValue()->getValue();
|
||||
$field = $comparison->getField();
|
||||
$operator = $comparison->getOperator();
|
||||
|
||||
if (($operator === Comparison::EQ || $operator === Comparison::IS) && $value === null) {
|
||||
return;
|
||||
} else if ($operator === Comparison::NEQ && $value === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->values[] = $value;
|
||||
$this->types[] = $this->getType($field, $value);
|
||||
$this->types[] = array($field, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,17 +104,4 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
{
|
||||
return array($this->values, $this->types);
|
||||
}
|
||||
|
||||
private function getType($field, $value)
|
||||
{
|
||||
$type = isset($this->class->fieldMappings[$field])
|
||||
? Type::getType($this->class->fieldMappings[$field]['type'])->getBindingType()
|
||||
: \PDO::PARAM_STR;
|
||||
|
||||
if (is_array($value)) {
|
||||
$type += Connection::ARRAY_PARAM_OFFSET;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -101,7 +101,13 @@ class ResultSetMappingBuilder extends ResultSetMapping
|
||||
if (isset($this->metaMappings[$renamedColumnName])) {
|
||||
throw new \InvalidArgumentException("The column '$renamedColumnName' conflicts with another column in the mapper.");
|
||||
}
|
||||
$this->addMetaResult($alias, $renamedColumnName, $columnName);
|
||||
|
||||
$this->addMetaResult(
|
||||
$alias,
|
||||
$renamedColumnName,
|
||||
$columnName,
|
||||
(isset($associationMapping['id']) && $associationMapping['id'] === true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -801,9 +804,13 @@ class SqlWalker implements TreeWalker
|
||||
/**
|
||||
* Walks down a JoinAssociationDeclaration AST node, thereby generating the appropriate SQL.
|
||||
*
|
||||
* @param AST\JoinAssociationDeclaration $joinAssociationDeclaration
|
||||
* @param int $joinType
|
||||
* @param AST\ConditionalExpression $condExpr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joinType = AST\Join::JOIN_TYPE_INNER)
|
||||
public function walkJoinAssociationDeclaration($joinAssociationDeclaration, $joinType = AST\Join::JOIN_TYPE_INNER, $condExpr = null)
|
||||
{
|
||||
$sql = '';
|
||||
|
||||
@@ -918,6 +925,13 @@ class SqlWalker implements TreeWalker
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle WITH clause
|
||||
if ($condExpr !== null) {
|
||||
// Phase 2 AST optimization: Skip processing of ConditionalExpression
|
||||
// if only one ConditionalTerm is defined
|
||||
$sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
|
||||
}
|
||||
|
||||
// FIXME: these should either be nested or all forced to be left joins (DDC-XXX)
|
||||
if ($targetClass->isInheritanceTypeJoined()) {
|
||||
$sql .= $this->_generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias);
|
||||
@@ -1007,19 +1021,17 @@ 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):
|
||||
$sql .= $this->walkJoinAssociationDeclaration($joinDeclaration, $joinType);
|
||||
|
||||
// Handle WITH clause
|
||||
if (($condExpr = $join->conditionalExpression) !== null) {
|
||||
// Phase 2 AST optimization: Skip processment of ConditionalExpression
|
||||
// if only one ConditionalTerm is defined
|
||||
$sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
|
||||
}
|
||||
$sql .= $this->walkJoinAssociationDeclaration($joinDeclaration, $joinType, $join->conditionalExpression);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1147,7 +1159,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 +1200,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 +1374,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 +1436,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 +1622,7 @@ class SqlWalker implements TreeWalker
|
||||
|
||||
if (count($filterClauses)) {
|
||||
if ($condSql) {
|
||||
$condSql .= ' AND ';
|
||||
$condSql = '(' . $condSql . ') AND ';
|
||||
}
|
||||
|
||||
$condSql .= implode(' AND ', $filterClauses);
|
||||
@@ -1907,31 +1920,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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -152,11 +152,43 @@ class EntityGenerator
|
||||
Type::SMALLINT => 'integer',
|
||||
Type::TEXT => 'string',
|
||||
Type::BLOB => 'string',
|
||||
Type::DECIMAL => 'float',
|
||||
Type::DECIMAL => 'string',
|
||||
Type::JSON_ARRAY => 'array',
|
||||
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);
|
||||
@@ -180,6 +188,9 @@ class XmlExporter extends AbstractExporter
|
||||
if (isset($field['columnDefinition'])) {
|
||||
$fieldXml->addAttribute('column-definition', $field['columnDefinition']);
|
||||
}
|
||||
if (isset($field['nullable'])) {
|
||||
$fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
$orderMap = array(
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
/* @var $countQuery Query */
|
||||
$countQuery = $this->cloneQuery($this->query);
|
||||
|
||||
if ( ! $countQuery->getHint(CountWalker::HINT_DISTINCT)) {
|
||||
if ( ! $countQuery->hasHint(CountWalker::HINT_DISTINCT)) {
|
||||
$countQuery->setHint(CountWalker::HINT_DISTINCT, true);
|
||||
}
|
||||
|
||||
@@ -174,18 +174,15 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
|
||||
$whereInQuery = $this->cloneQuery($this->query);
|
||||
// don't do this for an empty id array
|
||||
if (count($ids) > 0) {
|
||||
$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);
|
||||
}
|
||||
if (count($ids) == 0) {
|
||||
return new \ArrayIterator(array());
|
||||
}
|
||||
|
||||
$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);
|
||||
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
|
||||
|
||||
$result = $whereInQuery->getResult($this->query->getHydrationMode());
|
||||
} else {
|
||||
$result = $this->cloneQuery($this->query)
|
||||
|
||||
@@ -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.
|
||||
@@ -206,7 +213,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* The EventManager used for dispatching events.
|
||||
*
|
||||
* @var EventManager
|
||||
* @var \Doctrine\Common\EventManager
|
||||
*/
|
||||
private $evm;
|
||||
|
||||
@@ -256,6 +263,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* 5) All entity deletions
|
||||
*
|
||||
* @param null|object|array $entity
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commit($entity = null)
|
||||
@@ -390,17 +400,22 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* 4. Only if entity is properly managed.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -440,6 +455,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets the changeset for an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEntityChangeSet($entity)
|
||||
@@ -708,8 +725,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Computes the changes of an association.
|
||||
*
|
||||
* @param AssociationMapping $assoc
|
||||
* @param array $assoc
|
||||
* @param mixed $value The value of the association.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws ORMException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function computeAssociationChanges($assoc, $value)
|
||||
{
|
||||
@@ -779,6 +801,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadata $class
|
||||
* @param object $entity
|
||||
*/
|
||||
private function persistNew($class, $entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
@@ -822,7 +848,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param ClassMetadata $class The class descriptor of the entity.
|
||||
* @param object $entity The entity for which to (re)calculate the change set.
|
||||
* @throws InvalidArgumentException If the passed entity is not MANAGED.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the passed entity is not MANAGED.
|
||||
*/
|
||||
public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity)
|
||||
{
|
||||
@@ -962,7 +989,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->entityChangeSets[$oid]) {
|
||||
if (!empty($this->entityChangeSets[$oid])) {
|
||||
$persister->update($entity);
|
||||
}
|
||||
|
||||
@@ -1025,6 +1052,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets the commit order.
|
||||
*
|
||||
* @param array $entityChangeSet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getCommitOrder(array $entityChangeSet = null)
|
||||
@@ -1099,6 +1128,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* If the entity already has an identifier, it will be added to the identity map.
|
||||
*
|
||||
* @param object $entity The entity to schedule for insertion.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function scheduleForInsert($entity)
|
||||
{
|
||||
@@ -1134,6 +1166,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is scheduled for insertion.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForInsert($entity)
|
||||
@@ -1145,6 +1178,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Schedules an entity for being updated.
|
||||
*
|
||||
* @param object $entity The entity to schedule for being updated.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*/
|
||||
public function scheduleForUpdate($entity)
|
||||
{
|
||||
@@ -1194,6 +1229,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* at commit time.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForUpdate($entity)
|
||||
@@ -1206,6 +1242,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is registered to be checked in the unit of work.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForDirtyCheck($entity)
|
||||
@@ -1256,6 +1293,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* of work.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForDelete($entity)
|
||||
@@ -1267,6 +1305,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is scheduled for insertion, update or deletion.
|
||||
*
|
||||
* @param $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEntityScheduled($entity)
|
||||
@@ -1286,6 +1325,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @ignore
|
||||
* @param object $entity The entity to register.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return boolean TRUE if the registration was successful, FALSE if the identity of
|
||||
* the entity in question is already managed.
|
||||
*/
|
||||
@@ -1317,6 +1359,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* This parameter can be set to improve performance of entity state detection
|
||||
* by potentially avoiding a database lookup if the distinction between NEW and DETACHED
|
||||
* is either known or does not matter for the caller of the method.
|
||||
*
|
||||
* @return int The entity state.
|
||||
*/
|
||||
public function getEntityState($entity, $assume = null)
|
||||
@@ -1342,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.
|
||||
@@ -1392,6 +1439,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @ignore
|
||||
* @param object $entity
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function removeFromIdentityMap($entity)
|
||||
@@ -1425,6 +1475,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getByIdHash($idHash, $rootClassName)
|
||||
@@ -1440,6 +1491,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return mixed The found entity or FALSE.
|
||||
*/
|
||||
public function tryGetByIdHash($idHash, $rootClassName)
|
||||
@@ -1455,6 +1507,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is registered in the identity map of this UnitOfWork.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInIdentityMap($entity)
|
||||
@@ -1482,6 +1535,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function containsIdHash($idHash, $rootClassName)
|
||||
@@ -1509,6 +1563,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to persist.
|
||||
* @param array $visited The already visited entities.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
private function doPersist($entity, array &$visited)
|
||||
{
|
||||
@@ -1578,7 +1635,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to delete.
|
||||
* @param array $visited The map of the already visited entities.
|
||||
* @throws InvalidArgumentException If the instance is a detached entity.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the instance is a detached entity.
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
private function doRemove($entity, array &$visited)
|
||||
{
|
||||
@@ -1627,10 +1686,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Merges the state of the given detached entity into this UnitOfWork.
|
||||
*
|
||||
* @param object $entity
|
||||
* @return object The managed copy of the entity.
|
||||
*
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
*
|
||||
* @return object The managed copy of the entity.
|
||||
*
|
||||
* @todo Require active transaction!? OptimisticLockException may result in undefined state!?
|
||||
*/
|
||||
public function merge($entity)
|
||||
@@ -1640,15 +1701,43 @@ 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.
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $visited
|
||||
* @return object The managed copy of the entity.
|
||||
* @param object $prevManagedCopy
|
||||
* @param array $assoc
|
||||
*
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
* @throws InvalidArgumentException If the entity instance is NEW.
|
||||
* @throws ORMInvalidArgumentException If the entity instance is NEW.
|
||||
* @throws EntityNotFoundException
|
||||
*
|
||||
* @return object The managed copy of the entity.
|
||||
*/
|
||||
private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
|
||||
{
|
||||
@@ -1682,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);
|
||||
|
||||
@@ -1754,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);
|
||||
|
||||
@@ -1765,6 +1844,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->registerManaged($other, $relatedId, array());
|
||||
}
|
||||
}
|
||||
|
||||
$prop->setValue($managedCopy, $other);
|
||||
}
|
||||
} else {
|
||||
@@ -1895,6 +1975,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* any local, unpersisted changes.
|
||||
*
|
||||
* @param object $entity The entity to refresh.
|
||||
*
|
||||
* @throws InvalidArgumentException If the entity is not MANAGED.
|
||||
*/
|
||||
public function refresh($entity)
|
||||
@@ -1909,7 +1990,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to refresh.
|
||||
* @param array $visited The already visited entities during cascades.
|
||||
* @throws InvalidArgumentException If the entity is not MANAGED.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the entity is not MANAGED.
|
||||
*/
|
||||
private function doRefresh($entity, array &$visited)
|
||||
{
|
||||
@@ -2060,7 +2142,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $visited
|
||||
* @param array $insertNow
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cascadePersist($entity, array &$visited)
|
||||
{
|
||||
@@ -2144,9 +2227,19 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @param object $entity
|
||||
* @param int $lockMode
|
||||
* @param int $lockVersion
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws TransactionRequiredException
|
||||
* @throws OptimisticLockException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
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);
|
||||
}
|
||||
@@ -2225,6 +2318,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->collectionUpdates =
|
||||
$this->extraUpdates =
|
||||
$this->readOnlyObjects =
|
||||
$this->visitedCollections =
|
||||
$this->orphanRemovals = array();
|
||||
|
||||
if ($this->commitOrderCalculator !== null) {
|
||||
@@ -2279,13 +2373,20 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->collectionDeletions[$coid] = $coll;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PersistentCollection $coll
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCollectionScheduledForDeletion(PersistentCollection $coll)
|
||||
{
|
||||
return isset($this->collectionsDeletions[spl_object_hash($coll)]);
|
||||
return isset($this->collectionDeletions[spl_object_hash($coll)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadata $class
|
||||
*
|
||||
* @return \Doctrine\Common\Persistence\ObjectManagerAware|object
|
||||
*/
|
||||
private function newInstance($class)
|
||||
{
|
||||
@@ -2306,6 +2407,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @param string $className The name of the entity class.
|
||||
* @param array $data The data for the entity.
|
||||
* @param array $hints Any hints to account for during reconstitution/lookup of the entity.
|
||||
*
|
||||
* @return object The managed entity instance.
|
||||
* @internal Highly performance-sensitive method.
|
||||
*
|
||||
@@ -2345,17 +2447,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2459,7 +2567,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) {
|
||||
@@ -2484,7 +2592,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);
|
||||
|
||||
@@ -2501,6 +2609,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;
|
||||
@@ -2578,7 +2690,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Initializes (loads) an uninitialized persistent collection of an entity.
|
||||
*
|
||||
* @param PeristentCollection $collection The collection to initialize.
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection The collection to initialize.
|
||||
*
|
||||
* @return void
|
||||
* @todo Maybe later move to EntityManager#initialize($proxyOrCollection). See DDC-733.
|
||||
*/
|
||||
public function loadCollection(PersistentCollection $collection)
|
||||
@@ -2595,6 +2709,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$persister->loadManyToManyCollection($assoc, $collection->getOwner(), $collection);
|
||||
break;
|
||||
}
|
||||
|
||||
$collection->setInitialized(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2612,6 +2728,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* present at the time the entity was reconstituted from the database.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOriginalEntityData($entity)
|
||||
@@ -2654,6 +2771,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array The identifier values.
|
||||
*/
|
||||
public function getEntityIdentifier($entity)
|
||||
@@ -2667,6 +2785,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param mixed $id The entity identifier to look for.
|
||||
* @param string $rootClassName The name of the root class of the mapped entity hierarchy.
|
||||
*
|
||||
* @return mixed Returns the entity with the specified identifier if it exists in
|
||||
* this UnitOfWork, FALSE otherwise.
|
||||
*/
|
||||
@@ -2757,9 +2876,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets a collection persister for a collection-valued association.
|
||||
*
|
||||
* @param AssociationMapping $association
|
||||
* @param array $association
|
||||
*
|
||||
* @return AbstractCollectionPersister
|
||||
* @return \Doctrine\ORM\Persisters\AbstractCollectionPersister
|
||||
*/
|
||||
public function getCollectionPersister(array $association)
|
||||
{
|
||||
@@ -2901,6 +3020,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Helper method to initialize a lazy loading proxy or persistent collection.
|
||||
*
|
||||
* @param object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeObject($obj)
|
||||
@@ -2920,6 +3040,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Helper method to show an object as string.
|
||||
*
|
||||
* @param object $obj
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function objToStr($obj)
|
||||
@@ -2931,10 +3052,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Marks an entity as read-only so that it will not be considered for updates during UnitOfWork#commit().
|
||||
*
|
||||
* This operation cannot be undone as some parts of the UnitOfWork now keep gathering information
|
||||
* on this object that might be necessary to perform a correct udpate.
|
||||
* on this object that might be necessary to perform a correct update.
|
||||
*
|
||||
*
|
||||
* @param object $object
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @param $object
|
||||
* @return void
|
||||
*/
|
||||
public function markReadOnly($object)
|
||||
@@ -2949,9 +3073,11 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Is this entity read only?
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @param $object
|
||||
* @return void
|
||||
* @param object $object
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadOnly($object)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.4.0-DEV';
|
||||
const VERSION = '2.3.5';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
||||
2
lib/vendor/doctrine-common
vendored
2
lib/vendor/doctrine-common
vendored
Submodule lib/vendor/doctrine-common updated: 0f7ba7fa71...d1c7d4334e
2
lib/vendor/doctrine-dbal
vendored
2
lib/vendor/doctrine-dbal
vendored
Submodule lib/vendor/doctrine-dbal updated: 659de9a189...2a37b007dd
@@ -10,7 +10,7 @@ namespace Doctrine\Tests\Mocks;
|
||||
class StatementMock implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
|
||||
{
|
||||
public function bindValue($param, $value, $type = null){}
|
||||
public function bindParam($column, &$variable, $type = null){}
|
||||
public function bindParam($column, &$variable, $type = null, $length = null){}
|
||||
public function errorCode(){}
|
||||
public function errorInfo(){}
|
||||
public function execute($params = null){}
|
||||
|
||||
42
tests/Doctrine/Tests/Models/Taxi/Car.php
Normal file
42
tests/Doctrine/Tests/Models/Taxi/Car.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Taxi;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="taxi_car")
|
||||
*/
|
||||
class Car
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="string", length=25)
|
||||
* @GeneratedValue(strategy="NONE")
|
||||
*/
|
||||
private $brand;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=255);
|
||||
*/
|
||||
private $model;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Ride", mappedBy="car")
|
||||
*/
|
||||
private $freeCarRides;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="PaidRide", mappedBy="car")
|
||||
*/
|
||||
private $carRides;
|
||||
|
||||
public function setBrand($brand)
|
||||
{
|
||||
$this->brand = $brand;
|
||||
}
|
||||
|
||||
public function setModel($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
}
|
||||
37
tests/Doctrine/Tests/Models/Taxi/Driver.php
Normal file
37
tests/Doctrine/Tests/Models/Taxi/Driver.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Taxi;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="taxi_driver")
|
||||
*/
|
||||
class Driver
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=255);
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Ride", mappedBy="driver")
|
||||
*/
|
||||
private $freeDriverRides;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="PaidRide", mappedBy="driver")
|
||||
*/
|
||||
private $driverRides;
|
||||
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
42
tests/Doctrine/Tests/Models/Taxi/PaidRide.php
Normal file
42
tests/Doctrine/Tests/Models/Taxi/PaidRide.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Taxi;
|
||||
|
||||
/**
|
||||
* Same as Ride but with an extra column that is not part of the composite primary key
|
||||
*
|
||||
* @Entity
|
||||
* @Table(name="taxi_paid_ride")
|
||||
*/
|
||||
class PaidRide
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="Driver", inversedBy="driverRides")
|
||||
* @JoinColumn(name="driver_id", referencedColumnName="id")
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="Car", inversedBy="carRides")
|
||||
* @JoinColumn(name="car", referencedColumnName="brand")
|
||||
*/
|
||||
private $car;
|
||||
|
||||
/**
|
||||
* @Column(type="decimal", precision=6, scale=2)
|
||||
*/
|
||||
private $fare;
|
||||
|
||||
public function __construct(Driver $driver, Car $car)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
$this->car = $car;
|
||||
}
|
||||
|
||||
public function setFare($fare)
|
||||
{
|
||||
$this->fare = $fare;
|
||||
}
|
||||
}
|
||||
32
tests/Doctrine/Tests/Models/Taxi/Ride.php
Normal file
32
tests/Doctrine/Tests/Models/Taxi/Ride.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Models\Taxi;
|
||||
|
||||
/**
|
||||
* Test model that contains only Id-columns
|
||||
*
|
||||
* @Entity
|
||||
* @Table(name="taxi_ride")
|
||||
*/
|
||||
class Ride
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="Driver", inversedBy="freeDriverRides")
|
||||
* @JoinColumn(name="driver_id", referencedColumnName="id")
|
||||
*/
|
||||
private $driver;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="Car", inversedBy="freeCarRides")
|
||||
* @JoinColumn(name="car", referencedColumnName="brand")
|
||||
*/
|
||||
private $car;
|
||||
|
||||
public function __construct(Driver $driver, Car $car)
|
||||
{
|
||||
$this->driver = $driver;
|
||||
$this->car = $car;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?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\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\Generic\DateTimeModel;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
/**
|
||||
* @author Josiah <josiah@jjs.id.au>
|
||||
*/
|
||||
class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('generic');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->_em) {
|
||||
$this->_em->getConfiguration()->setEntityNamespaces(array());
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function loadFixture()
|
||||
{
|
||||
$today = new DateTimeModel();
|
||||
$today->datetime =
|
||||
$today->date =
|
||||
$today->time =
|
||||
new \DateTime('today');
|
||||
$this->_em->persist($today);
|
||||
|
||||
$tomorrow = new DateTimeModel();
|
||||
$tomorrow->datetime =
|
||||
$tomorrow->date =
|
||||
$tomorrow->time =
|
||||
new \DateTime('tomorrow');
|
||||
$this->_em->persist($tomorrow);
|
||||
|
||||
$yesterday = new DateTimeModel();
|
||||
$yesterday->datetime =
|
||||
$yesterday->date =
|
||||
$yesterday->time =
|
||||
new \DateTime('yesterday');
|
||||
$this->_em->persist($yesterday);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
unset($today);
|
||||
unset($tomorrow);
|
||||
unset($yesterday);
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testLteDateComparison()
|
||||
{
|
||||
$this->loadFixture();
|
||||
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
|
||||
$dates = $repository->matching(new Criteria(
|
||||
Criteria::expr()->lte('datetime', new \DateTime('today'))
|
||||
));
|
||||
|
||||
$this->assertEquals(2, count($dates));
|
||||
}
|
||||
|
||||
private function loadNullFieldFixtures()
|
||||
{
|
||||
$today = new DateTimeModel();
|
||||
$today->datetime =
|
||||
$today->date =
|
||||
new \DateTime('today');
|
||||
|
||||
$this->_em->persist($today);
|
||||
|
||||
$tomorrow = new DateTimeModel();
|
||||
$tomorrow->datetime =
|
||||
$tomorrow->date =
|
||||
$tomorrow->time =
|
||||
new \DateTime('tomorrow');
|
||||
$this->_em->persist($tomorrow);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testIsNullComparison()
|
||||
{
|
||||
$this->loadNullFieldFixtures();
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
|
||||
|
||||
$dates = $repository->matching(new Criteria(
|
||||
Criteria::expr()->isNull('time')
|
||||
));
|
||||
|
||||
$this->assertEquals(1, count($dates));
|
||||
}
|
||||
|
||||
public function testEqNullComparison()
|
||||
{
|
||||
$this->loadNullFieldFixtures();
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
|
||||
|
||||
$dates = $repository->matching(new Criteria(
|
||||
Criteria::expr()->eq('time', null)
|
||||
));
|
||||
|
||||
$this->assertEquals(1, count($dates));
|
||||
}
|
||||
|
||||
public function testNotEqNullComparison()
|
||||
{
|
||||
$this->loadNullFieldFixtures();
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
|
||||
|
||||
$dates = $repository->matching(new Criteria(
|
||||
Criteria::expr()->neq('time', null)
|
||||
));
|
||||
|
||||
$this->assertEquals(1, count($dates));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -7,6 +7,8 @@ use Doctrine\ORM\OptimisticLockException;
|
||||
use Doctrine\Common\EventManager;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\Tests\TestUtil;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
use DateTime;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
@@ -181,13 +183,44 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->_conn->executeQuery('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date($format, strtotime($test->version->format($format)) + 3600), $test->id));
|
||||
|
||||
// Try and update the record and it should throw an exception
|
||||
$caughtException = null;
|
||||
$test->name = 'Testing again';
|
||||
try {
|
||||
$this->_em->flush();
|
||||
} catch (OptimisticLockException $e) {
|
||||
$this->assertSame($test, $e->getEntity());
|
||||
$caughtException = $e;
|
||||
}
|
||||
|
||||
$this->assertNotNull($caughtException, "No OptimisticLockingException was thrown");
|
||||
$this->assertSame($test, $caughtException->getEntity());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testOptimisticTimestampSetsDefaultValue
|
||||
*/
|
||||
public function testOptimisticTimestampLockFailureThrowsException(OptimisticTimestamp $entity)
|
||||
{
|
||||
$q = $this->_em->createQuery('SELECT t FROM Doctrine\Tests\ORM\Functional\Locking\OptimisticTimestamp t WHERE t.id = :id');
|
||||
$q->setParameter('id', $entity->id);
|
||||
$test = $q->getSingleResult();
|
||||
|
||||
$this->assertInstanceOf('DateTime', $test->version);
|
||||
|
||||
// Try to lock the record with an older timestamp and it should throw an exception
|
||||
$caughtException = null;
|
||||
try {
|
||||
$expectedVersionExpired = DateTime::createFromFormat('U', $test->version->getTimestamp()-3600);
|
||||
$this->_em->lock($test, LockMode::OPTIMISTIC, $expectedVersionExpired);
|
||||
} catch (OptimisticLockException $e) {
|
||||
$caughtException = $e;
|
||||
}
|
||||
|
||||
$this->assertNotNull($caughtException, "No OptimisticLockingException was thrown");
|
||||
$this->assertSame($test, $caughtException->getEntity());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -174,6 +174,52 @@ class OneToManyBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctiona
|
||||
$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);
|
||||
|
||||
$results = $features->matching(new Criteria(
|
||||
Criteria::expr()->eq('description', 'Third feature')
|
||||
));
|
||||
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertCount(1, $results);
|
||||
|
||||
$results = $features->matching(new Criteria());
|
||||
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertCount(3, $results);
|
||||
}
|
||||
|
||||
private function _createFixture()
|
||||
{
|
||||
$this->product->addFeature($this->firstFeature);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,12 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$tool = new SchemaTool($this->_em);
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[2]);
|
||||
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[3]);
|
||||
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[4]);
|
||||
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[5]);
|
||||
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[2]);
|
||||
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[3]);
|
||||
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[4]);
|
||||
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[5]);
|
||||
$this->assertEquals("ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id)", $sql[6]);
|
||||
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id)", $sql[7]);
|
||||
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id)", $sql[8]);
|
||||
@@ -54,7 +54,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals(1, count($sql));
|
||||
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
}
|
||||
|
||||
public function testGetCreateSchemaSql3()
|
||||
@@ -67,7 +67,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals(1, count($sql));
|
||||
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
158
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1884Test.php
Normal file
158
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1884Test.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\Taxi\Car,
|
||||
Doctrine\Tests\Models\Taxi\Driver,
|
||||
Doctrine\Tests\Models\Taxi\Ride,
|
||||
Doctrine\Tests\Models\Taxi\PaidRide;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-1884
|
||||
* @author Sander Coolen <sander@jibber.nl>
|
||||
*/
|
||||
class DDC1884Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('taxi');
|
||||
parent::setUp();
|
||||
|
||||
list($bimmer, $crysler, $merc, $volvo) = $this->createCars('Doctrine\Tests\Models\Taxi\Car');
|
||||
list($john, $foo) = $this->createDrivers('Doctrine\Tests\Models\Taxi\Driver');
|
||||
$this->_em->flush();
|
||||
|
||||
$ride1 = new Ride($john, $bimmer);
|
||||
$ride2 = new Ride($john, $merc);
|
||||
$ride3 = new Ride($john, $volvo);
|
||||
$ride4 = new Ride($foo, $merc);
|
||||
|
||||
$this->_em->persist($ride1);
|
||||
$this->_em->persist($ride2);
|
||||
$this->_em->persist($ride3);
|
||||
$this->_em->persist($ride4);
|
||||
|
||||
$ride5 = new PaidRide($john, $bimmer);
|
||||
$ride5->setFare(10.50);
|
||||
|
||||
$ride6 = new PaidRide($john, $merc);
|
||||
$ride6->setFare(16.00);
|
||||
|
||||
$ride7 = new PaidRide($john, $volvo);
|
||||
$ride7->setFare(20.70);
|
||||
|
||||
$ride8 = new PaidRide($foo, $merc);
|
||||
$ride8->setFare(32.15);
|
||||
|
||||
$this->_em->persist($ride5);
|
||||
$this->_em->persist($ride6);
|
||||
$this->_em->persist($ride7);
|
||||
$this->_em->persist($ride8);
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
private function createCars($class)
|
||||
{
|
||||
$bimmer = new $class;
|
||||
$bimmer->setBrand('BMW');
|
||||
$bimmer->setModel('7-Series');
|
||||
|
||||
$crysler = new $class;
|
||||
$crysler->setBrand('Crysler');
|
||||
$crysler->setModel('300');
|
||||
|
||||
$merc = new $class;
|
||||
$merc->setBrand('Mercedes');
|
||||
$merc->setModel('C-Class');
|
||||
|
||||
$volvo = new $class;
|
||||
$volvo->setBrand('Volvo');
|
||||
$volvo->setModel('XC90');
|
||||
|
||||
$this->_em->persist($bimmer);
|
||||
$this->_em->persist($crysler);
|
||||
$this->_em->persist($merc);
|
||||
$this->_em->persist($volvo);
|
||||
|
||||
return array($bimmer, $crysler, $merc, $volvo);
|
||||
}
|
||||
|
||||
private function createDrivers($class)
|
||||
{
|
||||
$john = new $class;
|
||||
$john->setName('John Doe');
|
||||
|
||||
$foo = new $class;
|
||||
$foo->setName('Foo Bar');
|
||||
|
||||
$this->_em->persist($foo);
|
||||
$this->_em->persist($john);
|
||||
|
||||
return array($john, $foo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 1) Ride contains only columns that are part of its composite primary key
|
||||
* 2) We use fetch joins here
|
||||
*/
|
||||
public function testSelectFromInverseSideWithCompositePkAndSolelyIdentifierColumnsUsingFetchJoins()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
|
||||
$result = $qb->select('d, dr, c')
|
||||
->from('Doctrine\Tests\Models\Taxi\Driver', 'd')
|
||||
->leftJoin('d.freeDriverRides', 'dr')
|
||||
->leftJoin('dr.car', 'c')
|
||||
->where('d.name = ?1')
|
||||
->setParameter(1, 'John Doe')
|
||||
->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertArrayHasKey('freeDriverRides', $result[0]);
|
||||
$this->assertCount(3, $result[0]['freeDriverRides']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 1) PaidRide contains an extra column that is not part of the composite primary key
|
||||
* 2) Again we will use fetch joins
|
||||
*/
|
||||
public function testSelectFromInverseSideWithCompositePkUsingFetchJoins()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
|
||||
$result = $qb->select('d, dr, c')
|
||||
->from('Doctrine\Tests\Models\Taxi\Driver', 'd')
|
||||
->leftJoin('d.driverRides', 'dr')
|
||||
->leftJoin('dr.car', 'c')
|
||||
->where('d.name = ?1')
|
||||
->setParameter(1, 'John Doe')
|
||||
->getQuery()->getArrayResult();
|
||||
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertArrayHasKey('driverRides', $result[0]);
|
||||
$this->assertCount(3, $result[0]['driverRides']);
|
||||
}
|
||||
|
||||
/**
|
||||
* The other way around will fail too
|
||||
*/
|
||||
public function testSelectFromOwningSideUsingFetchJoins()
|
||||
{
|
||||
$qb = $this->_em->createQueryBuilder();
|
||||
|
||||
$result = $qb->select('r, d, c')
|
||||
->from('Doctrine\Tests\Models\Taxi\PaidRide', 'r')
|
||||
->leftJoin('r.driver', 'd')
|
||||
->leftJoin('r.car', 'c')
|
||||
->where('d.name = ?1')
|
||||
->setParameter(1, 'John Doe')
|
||||
->getQuery()->getArrayResult();
|
||||
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertArrayHasKey('driver', $result[0]);
|
||||
$this->assertArrayHasKey('car', $result[0]);
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
use Doctrine\Tests\Models\Quote\Group;
|
||||
use Doctrine\Tests\Models\Quote\User;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-1845
|
||||
* @group DDC-1885
|
||||
@@ -170,4 +168,4 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0));
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php
Normal file
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
|
||||
/**
|
||||
* @group DDC-1918
|
||||
*/
|
||||
class DDC1918Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testLastPageCorrect()
|
||||
{
|
||||
$groups = array();
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$group = new CmsGroup();
|
||||
$group->name = "test";
|
||||
$this->_em->persist($group);
|
||||
|
||||
$groups[] = $group;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$user = new CmsUser();
|
||||
$user->username = "user$i";
|
||||
$user->name = "user$i";
|
||||
$user->status = "active";
|
||||
$user->groups = $groups;
|
||||
|
||||
$this->_em->persist($user);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$query = $this->_em->createQuery('SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
|
||||
$query->setFirstResult(6);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(3, count(iterator_to_array($paginator)));
|
||||
|
||||
$query->setFirstResult(8);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(2, count(iterator_to_array($paginator)));
|
||||
|
||||
$query->setFirstResult(10);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(0, count(iterator_to_array($paginator)));
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-1925
|
||||
* @group DDC-1210
|
||||
*/
|
||||
class DDC1925Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testIssue()
|
||||
{
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925User'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925Product'),
|
||||
));
|
||||
|
||||
$user = new DDC1925User();
|
||||
$user->setTitle("Test User");
|
||||
$this->_em->persist($user);
|
||||
|
||||
$product = new DDC1925Product();
|
||||
$product->setTitle("Test product");
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$product->addBuyer($user);
|
||||
|
||||
$this->_em->getUnitOfWork()->computeChangeSets();
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table
|
||||
* @Entity
|
||||
*/
|
||||
class DDC1925Product
|
||||
{
|
||||
/**
|
||||
* @var integer $id
|
||||
*
|
||||
* @Column(name="id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string $title
|
||||
*
|
||||
* @Column(name="title", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="DDC1925User")
|
||||
* @JoinTable(
|
||||
* name="user_purchases",
|
||||
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
|
||||
* inverseJoinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}
|
||||
* )
|
||||
*/
|
||||
private $buyers;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->buyers = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $buyers
|
||||
*/
|
||||
public function setBuyers($buyers)
|
||||
{
|
||||
$this->buyers = $buyers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBuyers()
|
||||
{
|
||||
return $this->buyers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DDC1925User $buyer
|
||||
*/
|
||||
public function addBuyer(DDC1925User $buyer)
|
||||
{
|
||||
$this->buyers[] = $buyer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table
|
||||
* @Entity
|
||||
*/
|
||||
class DDC1925User
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @Column(name="id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @Column(name="title", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* Get id
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
68
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php
Normal file
68
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group DDC-2350
|
||||
*/
|
||||
class DDC2350Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2350User'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2350Bug'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testEagerCollectionsAreOnlyRetrievedOnce()
|
||||
{
|
||||
$user = new DDC2350User();
|
||||
$bug1 = new DDC2350Bug();
|
||||
$bug1->user = $user;
|
||||
$bug2 = new DDC2350Bug();
|
||||
$bug2->user = $user;
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->persist($bug1);
|
||||
$this->_em->persist($bug2);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->clear();
|
||||
|
||||
$cnt = $this->getCurrentQueryCount();
|
||||
$user = $this->_em->find(__NAMESPACE__ . '\DDC2350User', $user->id);
|
||||
|
||||
$this->assertEquals($cnt + 2, $this->getCurrentQueryCount());
|
||||
|
||||
$this->assertEquals(2, count($user->reportedBugs));
|
||||
|
||||
$this->assertEquals($cnt + 2, $this->getCurrentQueryCount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2350User
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
/** @OneToMany(targetEntity="DDC2350Bug", mappedBy="user", fetch="EAGER") */
|
||||
public $reportedBugs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2350Bug
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
/** @ManyToOne(targetEntity="DDC2350User", inversedBy="reportedBugs") */
|
||||
public $user;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
180
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2579Test.php
Normal file
180
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2579Test.php
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\DBAL\Types\StringType;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* @group DDC-2579
|
||||
*/
|
||||
class DDC2579Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Type::addType(DDC2579Type::NAME, DDC2579Type::CLASSNAME);
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(DDC2579Entity::CLASSNAME),
|
||||
$this->_em->getClassMetadata(DDC2579EntityAssoc::CLASSNAME),
|
||||
$this->_em->getClassMetadata(DDC2579AssocAssoc::CLASSNAME),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$id = new DDC2579Id("foo");
|
||||
$assoc = new DDC2579AssocAssoc($id);
|
||||
$assocAssoc = new DDC2579EntityAssoc($assoc);
|
||||
$entity = new DDC2579Entity($assocAssoc);
|
||||
$repository = $this->_em->getRepository(DDC2579Entity::CLASSNAME);
|
||||
|
||||
$this->_em->persist($assoc);
|
||||
$this->_em->persist($assocAssoc);
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
|
||||
$entity->value++;
|
||||
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$id = $entity->id;
|
||||
$value = $entity->value;
|
||||
$criteria = array('assoc' => $assoc, 'id' => $id);
|
||||
$entity = $repository->findOneBy($criteria);
|
||||
|
||||
$this->assertInstanceOf(DDC2579Entity::CLASSNAME, $entity);
|
||||
$this->assertEquals($value, $entity->value);
|
||||
|
||||
$this->_em->remove($entity);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertNull($repository->findOneBy($criteria));
|
||||
$this->assertCount(0, $repository->findAll());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2579Entity
|
||||
{
|
||||
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="ddc2579")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="DDC2579EntityAssoc")
|
||||
* @JoinColumn(name="relation_id", referencedColumnName="association_id")
|
||||
*/
|
||||
public $assoc;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $value;
|
||||
|
||||
public function __construct(DDC2579EntityAssoc $assoc, $value = 0)
|
||||
{
|
||||
$this->id = $assoc->assocAssoc->associationId;
|
||||
$this->assoc = $assoc;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2579EntityAssoc
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="DDC2579AssocAssoc")
|
||||
* @JoinColumn(name="association_id", referencedColumnName="associationId")
|
||||
*/
|
||||
public $assocAssoc;
|
||||
|
||||
public function __construct(DDC2579AssocAssoc $assocAssoc)
|
||||
{
|
||||
$this->assocAssoc = $assocAssoc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2579AssocAssoc
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="ddc2579")
|
||||
*/
|
||||
public $associationId;
|
||||
|
||||
public function __construct(DDC2579Id $id)
|
||||
{
|
||||
$this->associationId = $id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DDC2579Type extends StringType
|
||||
{
|
||||
const NAME = 'ddc2579';
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return (string)$value;
|
||||
}
|
||||
|
||||
public function convertToPhpValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
return new DDC2579Id($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return self::NAME;
|
||||
}
|
||||
}
|
||||
|
||||
class DDC2579Id
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
private $val;
|
||||
|
||||
public function __construct($val)
|
||||
{
|
||||
$this->val = $val;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->val;
|
||||
}
|
||||
}
|
||||
122
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2660Test.php
Normal file
122
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2660Test.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @group
|
||||
*/
|
||||
class DDC2660Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2660Product'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2660Customer'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2660CustomerOrder')
|
||||
));
|
||||
} catch(\Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$product = new DDC2660Product();
|
||||
$customer = new DDC2660Customer();
|
||||
$order = new DDC2660CustomerOrder($product, $customer, 'name' . $i);
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->persist($customer);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->_em->persist($order);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testIssueWithExtraColumn()
|
||||
{
|
||||
$sql = "SELECT o.product_id, o.customer_id, o.name FROM ddc_2660_customer_order o";
|
||||
|
||||
$rsm = new ResultSetMappingBuilder($this->_getEntityManager());
|
||||
$rsm->addRootEntityFromClassMetadata(__NAMESPACE__ . '\DDC2660CustomerOrder', 'c');
|
||||
|
||||
$query = $this->_em->createNativeQuery($sql, $rsm);
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertCount(5, $result);
|
||||
|
||||
foreach ($result as $order) {
|
||||
$this->assertNotNull($order);
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\\DDC2660CustomerOrder', $order);
|
||||
}
|
||||
}
|
||||
|
||||
public function testIssueWithoutExtraColumn()
|
||||
{
|
||||
$sql = "SELECT o.product_id, o.customer_id FROM ddc_2660_customer_order o";
|
||||
|
||||
$rsm = new ResultSetMappingBuilder($this->_getEntityManager());
|
||||
$rsm->addRootEntityFromClassMetadata(__NAMESPACE__ . '\DDC2660CustomerOrder', 'c');
|
||||
|
||||
$query = $this->_em->createNativeQuery($sql, $rsm);
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertCount(5, $result);
|
||||
|
||||
foreach ($result as $order) {
|
||||
$this->assertNotNull($order);
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\\DDC2660CustomerOrder', $order);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Entity @Table(name="ddc_2660_product")
|
||||
*/
|
||||
class DDC2660Product
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2660_customer") */
|
||||
class DDC2660Customer
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2660_customer_order") */
|
||||
class DDC2660CustomerOrder
|
||||
{
|
||||
/**
|
||||
* @Id @ManyToOne(targetEntity="DDC2660Product")
|
||||
*/
|
||||
public $product;
|
||||
|
||||
/**
|
||||
* @Id @ManyToOne(targetEntity="DDC2660Customer")
|
||||
*/
|
||||
public $customer;
|
||||
|
||||
/**
|
||||
* @Column(type="string")
|
||||
*/
|
||||
public $name;
|
||||
|
||||
public function __construct(DDC2660Product $product, DDC2660Customer $customer, $name)
|
||||
{
|
||||
$this->product = $product;
|
||||
$this->customer = $customer;
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
121
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2759Test.php
Normal file
121
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2759Test.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
/**
|
||||
* @group DDC-2759
|
||||
*/
|
||||
class DDC2759Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setup()
|
||||
{
|
||||
parent::setup();
|
||||
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759Qualification'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759Category'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759QualificationMetadata'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2759MetadataCategory'),
|
||||
));
|
||||
} catch(\Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$qualification = new DDC2759Qualification();
|
||||
$qualificationMetadata = new DDC2759QualificationMetadata($qualification);
|
||||
|
||||
$category1 = new DDC2759Category();
|
||||
$category2 = new DDC2759Category();
|
||||
|
||||
$metadataCategory1 = new DDC2759MetadataCategory($qualificationMetadata, $category1);
|
||||
$metadataCategory2 = new DDC2759MetadataCategory($qualificationMetadata, $category2);
|
||||
|
||||
$this->_em->persist($qualification);
|
||||
$this->_em->persist($qualificationMetadata);
|
||||
|
||||
$this->_em->persist($category1);
|
||||
$this->_em->persist($category2);
|
||||
|
||||
$this->_em->persist($metadataCategory1);
|
||||
$this->_em->persist($metadataCategory2);
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testCorrectNumberOfAssociationsIsReturned()
|
||||
{
|
||||
$repository = $this->_em->getRepository(__NAMESPACE__ . '\DDC2759Qualification');
|
||||
|
||||
$builder = $repository->createQueryBuilder('q')
|
||||
->select('q, qm, qmc')
|
||||
->innerJoin('q.metadata', 'qm')
|
||||
->innerJoin('qm.metadataCategories', 'qmc');
|
||||
|
||||
$result = $builder->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$this->assertCount(2, $result[0]['metadata']['metadataCategories']);
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2759_qualification") */
|
||||
class DDC2759Qualification
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC2759QualificationMetadata", mappedBy="content") */
|
||||
public $metadata;
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2759_category") */
|
||||
class DDC2759Category
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @OneToMany(targetEntity="DDC2759MetadataCategory", mappedBy="category") */
|
||||
public $metadataCategories;
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2759_qualification_metadata") */
|
||||
class DDC2759QualificationMetadata
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC2759Qualification", inversedBy="metadata") */
|
||||
public $content;
|
||||
|
||||
/** @OneToMany(targetEntity="DDC2759MetadataCategory", mappedBy="metadata") */
|
||||
protected $metadataCategories;
|
||||
|
||||
public function __construct(DDC2759Qualification $content)
|
||||
{
|
||||
$this->content = $content;
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity @Table(name="ddc_2759_metadata_category") */
|
||||
class DDC2759MetadataCategory
|
||||
{
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @ManyToOne(targetEntity="DDC2759QualificationMetadata", inversedBy="metadataCategories") */
|
||||
public $metadata;
|
||||
|
||||
/** @ManyToOne(targetEntity="DDC2759Category", inversedBy="metadataCategories") */
|
||||
public $category;
|
||||
|
||||
public function __construct(DDC2759QualificationMetadata $metadata, DDC2759Category $category)
|
||||
{
|
||||
$this->metadata = $metadata;
|
||||
$this->category = $category;
|
||||
}
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
@@ -922,26 +922,6 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('doctrineglobal_article_cms_cmsuser', $articleMetadata->associationMappings['author']['joinTable']['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-984
|
||||
* @group DDC-559
|
||||
*/
|
||||
public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategyPropertyToColumnName()
|
||||
{
|
||||
$namingStrategy = new MyPrefixNamingStrategy();
|
||||
$metadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
|
||||
|
||||
$metadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$metadata->mapField(array('fieldName'=>'country'));
|
||||
$metadata->mapField(array('fieldName'=>'city'));
|
||||
|
||||
$this->assertEquals($metadata->fieldNames, array(
|
||||
'cmsaddress_country' => 'country',
|
||||
'cmsaddress_city' => 'city'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1746
|
||||
*/
|
||||
@@ -997,6 +977,31 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$cm->setAttributeOverride('name', array('type'=>'date'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2608
|
||||
*/
|
||||
public function testSetSequenceGeneratorThrowsExceptionWhenSequenceNameIsMissing()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException');
|
||||
$cm->setSequenceGeneratorDefinition(array());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2662
|
||||
*/
|
||||
public function testQuotedSequenceName()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$cm->setSequenceGeneratorDefinition(array('sequenceName' => '`foo`'));
|
||||
|
||||
$this->assertEquals(array('sequenceName' => 'foo', 'quoted' => true), $cm->sequenceGeneratorDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
|
||||
@@ -1013,14 +1018,3 @@ class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStra
|
||||
return strtolower($className);
|
||||
}
|
||||
}
|
||||
|
||||
class MyPrefixNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
{
|
||||
return strtolower($this->classToTableName($className)) . '_' . $propertyName;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -6,16 +6,21 @@ use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\Tests\Mocks\ConnectionMock;
|
||||
use Doctrine\Tests\Mocks\EntityManagerMock;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
|
||||
require_once __DIR__ . '/../TestInit.php';
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCart;
|
||||
use Doctrine\Tests\OrmTestCase;
|
||||
|
||||
/**
|
||||
* Tests the lazy-loading capabilities of the PersistentCollection.
|
||||
* Tests the lazy-loading capabilities of the PersistentCollection and the initialization of collections.
|
||||
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
|
||||
* @author Austin Morris <austin.morris@gmail.com>
|
||||
*/
|
||||
class PersistentCollectionTest extends \Doctrine\Tests\OrmTestCase
|
||||
class PersistentCollectionTest extends OrmTestCase
|
||||
{
|
||||
/**
|
||||
* @var PersistentCollection
|
||||
*/
|
||||
protected $collection;
|
||||
|
||||
private $_connectionMock;
|
||||
private $_emMock;
|
||||
|
||||
@@ -27,6 +32,17 @@ class PersistentCollectionTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->_emMock = EntityManagerMock::create($this->_connectionMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the PersistentCollection used for collection initialization tests.
|
||||
*/
|
||||
public function setUpPersistentCollection()
|
||||
{
|
||||
$classMetaData = $this->_emMock->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceCart');
|
||||
$this->collection = new PersistentCollection($this->_emMock, $classMetaData, new ArrayCollection);
|
||||
$this->collection->setInitialized(false);
|
||||
$this->collection->setOwner(new ECommerceCart(), $classMetaData->getAssociationMapping('products'));
|
||||
}
|
||||
|
||||
public function testCanBePutInLazyLoadingMode()
|
||||
{
|
||||
$class = $this->_emMock->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
|
||||
@@ -34,4 +50,34 @@ class PersistentCollectionTest extends \Doctrine\Tests\OrmTestCase
|
||||
$collection->setInitialized(false);
|
||||
$this->assertFalse($collection->isInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that PersistentCollection::current() initializes the collection.
|
||||
*/
|
||||
public function testCurrentInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->current();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that PersistentCollection::key() initializes the collection.
|
||||
*/
|
||||
public function testKeyInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->key();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that PersistentCollection::next() initializes the collection.
|
||||
*/
|
||||
public function testNextInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->next();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,25 @@ 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 NULL', $statement);
|
||||
}
|
||||
|
||||
public function testSelectConditionStatementEqNull()
|
||||
{
|
||||
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::EQ);
|
||||
$this->assertEquals('test IS NULL', $statement);
|
||||
}
|
||||
|
||||
public function testSelectConditionStatementNeqNull()
|
||||
{
|
||||
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::NEQ);
|
||||
$this->assertEquals('test IS NOT NULL', $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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,8 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('bar', $q->getHint('foo'));
|
||||
$this->assertEquals('baz', $q->getHint('bar'));
|
||||
$this->assertEquals(array('foo' => 'bar', 'bar' => 'baz'), $q->getHints());
|
||||
$this->assertTrue($q->hasHint('foo'));
|
||||
$this->assertFalse($q->hasHint('barFooBaz'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,4 +165,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'))
|
||||
);
|
||||
}
|
||||
@@ -1697,6 +1710,18 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
'SELECT q0_."group-id" AS groupid0, q0_."group-name" AS groupname1, q1_."group-id" AS groupid2, q1_."group-name" AS groupname3 FROM "quote-group" q0_ INNER JOIN "quote-group" q1_ ON q0_."parent-id" = q1_."group-id"'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2506
|
||||
*/
|
||||
public function testClassTableInheritanceJoinWithConditionAppliesToBaseTable()
|
||||
{
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT e.id FROM Doctrine\Tests\Models\Company\CompanyOrganization o JOIN o.events e WITH e.id = ?1',
|
||||
'SELECT c0_.id AS id0 FROM company_organizations c1_ INNER JOIN company_events c0_ ON c1_.id = c0_.org_id AND (c0_.id = ?) LEFT JOIN company_auctions c2_ ON c0_.id = c2_.id LEFT JOIN company_raffles c3_ ON c0_.id = c3_.id',
|
||||
array(Query::HINT_FORCE_PARTIAL_LOAD => false)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -370,9 +516,9 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
)),
|
||||
array(array(
|
||||
'fieldName' => 'decimal',
|
||||
'phpType' => 'float',
|
||||
'phpType' => 'string',
|
||||
'dbType' => 'decimal',
|
||||
'value' => 33.33
|
||||
'value' => '12.34'
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user