mirror of
https://github.com/doctrine/orm.git
synced 2026-04-23 22:48:08 +02:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93103f44a3 | |||
| ffdb769564 | |||
| 95344d019f | |||
| 640d9af50f | |||
| a23e909158 | |||
| a857a610db | |||
| f0006eb42d | |||
| 7ea97e69ca | |||
| de4b40b29f | |||
| e21217dd0e | |||
| b82aef2748 | |||
| 44b3405714 | |||
| e874d93f61 | |||
| bb31472727 | |||
| fd72aa08d2 | |||
| 21f73cf923 | |||
| 2701f5058e | |||
| 4bd2f68483 | |||
| 823da6d839 | |||
| 6318796965 | |||
| c811c3ac84 | |||
| aba62edcc8 | |||
| 0b4e5b42e1 | |||
| 3d4f236052 | |||
| 049470c787 | |||
| cfaad4fedc | |||
| e8a89c3bc3 | |||
| 497be59f5c | |||
| e1b851f2e9 | |||
| 984535cadc | |||
| 35a579efdc | |||
| a2b4e5b293 | |||
| 24d95796bb | |||
| 249b737094 | |||
| 36dc28d43e | |||
| 0ec9e53c8d | |||
| aa80f6c0b5 | |||
| fd6d4890c4 | |||
| c78afd5172 | |||
| fb7b78c004 | |||
| 0de69e5a80 | |||
| d7e1f883d8 | |||
| 82e0d7e21a | |||
| 26880983fc | |||
| d9899732ca | |||
| 4f96fc62ce | |||
| 6184343fd5 | |||
| ee22be27a5 | |||
| 8f77210955 | |||
| f736acc8f5 | |||
| f1534610e1 | |||
| 6622bbbbf3 | |||
| 1554af0c07 | |||
| 814aa9f322 | |||
| f311dd1dd1 | |||
| e3aa3f2d1d | |||
| c83f479633 | |||
| 741f1db198 | |||
| 22546a3811 | |||
| efa058bd8f | |||
| 767577cec6 | |||
| c0f593e422 | |||
| d89d238594 | |||
| 2337b7aedd | |||
| 9e6f061bfb | |||
| bf1188127e | |||
| c73ec2aa76 | |||
| 095611c4b6 | |||
| 96c6f4cf1d | |||
| 5cacb6e14f | |||
| ab63628960 | |||
| 15731c7bde | |||
| abb429a0c9 | |||
| 61cb03bf30 | |||
| d6bcb5b1f8 | |||
| bdae362777 | |||
| 59c5574554 | |||
| 9545bf9d8c | |||
| 5521d1f325 | |||
| 49694dc335 | |||
| 3155d970d3 | |||
| 09189fc021 | |||
| 5a0d3e5fb8 | |||
| b9ba4e3207 | |||
| d7919678e5 | |||
| 8b185eb822 | |||
| 693a0546d3 | |||
| 5c5c8fc487 | |||
| 85dc707cc8 | |||
| 64a1251b61 | |||
| 65ed6a2c2f | |||
| d27a9fce7a | |||
| 11659f5cfe | |||
| 68dad26482 | |||
| b3ceef0fb6 | |||
| 095b365146 | |||
| 7c1ebd99bc | |||
| c06f19db8d | |||
| 0be9be4e24 | |||
| b2bf5ee92e | |||
| 698bd813a2 | |||
| b2ac8fdfd7 | |||
| 9c2b54b748 | |||
| 910784213f | |||
| 1d1de7de80 | |||
| 741da6eed7 | |||
| ad5397b581 | |||
| 57bb46ca9d | |||
| 0416d5e036 | |||
| a14432117a | |||
| 824f62d3bb | |||
| c0f0fe060f | |||
| caffbe04a2 | |||
| d2c805b071 | |||
| 04fc7a9a1c | |||
| 149b8f4e09 | |||
| 48e8c02cb8 | |||
| e218866a69 |
+6
-13
@@ -5,8 +5,6 @@ php:
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
- hhvm-nightly
|
||||
|
||||
env:
|
||||
- DB=mysql
|
||||
@@ -15,7 +13,7 @@ env:
|
||||
|
||||
before_script:
|
||||
- if [[ $TRAVIS_PHP_VERSION = '5.6' && $DB = 'sqlite' ]]; then PHPUNIT_FLAGS="--coverage-clover ./build/logs/clover.xml"; else PHPUNIT_FLAGS=""; fi
|
||||
- if [[ $TRAVIS_PHP_VERSION != '5.6' && $TRAVIS_PHP_VERSION != 'hhvm' && $TRAVIS_PHP_VERSION != 'hhvm-nightly' && $TRAVIS_PHP_VERSION != '7.0' ]]; then phpenv config-rm xdebug.ini; fi
|
||||
- if [[ $PHPUNIT_FLAGS == "" ]]; then phpenv config-rm xdebug.ini; fi
|
||||
- composer self-update
|
||||
- composer install --prefer-source --dev
|
||||
|
||||
@@ -24,15 +22,10 @@ script:
|
||||
- ENABLE_SECOND_LEVEL_CACHE=1 ./vendor/bin/phpunit -v -c tests/travis/$DB.travis.xml --exclude-group performance,non-cacheable,locking_functional
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- php: hhvm
|
||||
env: DB=pgsql # driver currently unsupported by HHVM
|
||||
- php: hhvm
|
||||
env: DB=mysqli # driver currently unsupported by HHVM
|
||||
- php: hhvm-nightly
|
||||
env: DB=pgsql # driver currently unsupported by HHVM
|
||||
- php: hhvm-nightly
|
||||
env: DB=mysqli # driver currently unsupported by HHVM
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: 7.0
|
||||
- php: hhvm-nightly # hhvm-nightly currently chokes on composer installation
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.composer/cache
|
||||
|
||||
+5
-5
@@ -16,14 +16,14 @@
|
||||
"php": ">=5.4",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/collections": "~1.2",
|
||||
"doctrine/dbal": ">=2.5-dev,<2.6-dev",
|
||||
"doctrine/instantiator": "~1.0.1",
|
||||
"doctrine/common": ">=2.5-dev,<2.8-dev",
|
||||
"doctrine/dbal": ">=2.5-dev,<2.7-dev",
|
||||
"doctrine/instantiator": "^1.0.1",
|
||||
"doctrine/common": ">=2.5-dev,<2.9-dev",
|
||||
"doctrine/cache": "~1.4",
|
||||
"symfony/console": "~2.5|~3.0"
|
||||
"symfony/console": "~2.5|~3.0|~4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/yaml": "~2.3|~3.0",
|
||||
"symfony/yaml": "~2.3|~3.0|~4.0",
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
|
||||
@@ -325,14 +325,14 @@ abstract class AbstractQuery
|
||||
public function getParameter($key)
|
||||
{
|
||||
$filteredParameters = $this->parameters->filter(
|
||||
function ($parameter) use ($key)
|
||||
{
|
||||
// Must not be identical because of string to integer conversion
|
||||
return ($key == $parameter->getName());
|
||||
function (Query\Parameter $parameter) use ($key) {
|
||||
$parameterName = $parameter->getName();
|
||||
|
||||
return $key === $parameterName || (string) $key === (string) $parameterName;
|
||||
}
|
||||
);
|
||||
|
||||
return count($filteredParameters) ? $filteredParameters->first() : null;
|
||||
return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,17 +373,10 @@ abstract class AbstractQuery
|
||||
*/
|
||||
public function setParameter($key, $value, $type = null)
|
||||
{
|
||||
$filteredParameters = $this->parameters->filter(
|
||||
function ($parameter) use ($key)
|
||||
{
|
||||
// Must not be identical because of string to integer conversion
|
||||
return ($key == $parameter->getName());
|
||||
}
|
||||
);
|
||||
$existingParameter = $this->getParameter($key);
|
||||
|
||||
if (count($filteredParameters)) {
|
||||
$parameter = $filteredParameters->first();
|
||||
$parameter->setValue($value, $type);
|
||||
if ($existingParameter !== null) {
|
||||
$existingParameter->setValue($value, $type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ use Doctrine\Common\Persistence\Event\LoadClassMetadataEventArgs as BaseLoadClas
|
||||
* Note: method annotations are used instead of method overrides (due to BC policy)
|
||||
*
|
||||
* @method __construct(\Doctrine\ORM\Mapping\ClassMetadata $classMetadata, \Doctrine\ORM\EntityManager $objectManager)
|
||||
* @method \Doctrine\ORM\EntityManager getClassMetadata()
|
||||
* @method \Doctrine\ORM\Mapping\ClassMetadata getClassMetadata()
|
||||
*/
|
||||
class LoadClassMetadataEventArgs extends BaseLoadClassMetadataEventArgs
|
||||
{
|
||||
|
||||
@@ -76,7 +76,8 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
|
||||
$conn = $em->getConnection();
|
||||
$sql = $conn->getDatabasePlatform()->getSequenceNextValSQL($this->_sequenceName);
|
||||
|
||||
$this->_nextValue = (int)$conn->fetchColumn($sql);
|
||||
// Using `query` to force usage of the master server in MasterSlaveConnection
|
||||
$this->_nextValue = (int) $conn->query($sql)->fetchColumn();
|
||||
$this->_maxValue = $this->_nextValue + $this->_allocationSize;
|
||||
}
|
||||
|
||||
@@ -108,10 +109,12 @@ class SequenceGenerator extends AbstractIdGenerator implements Serializable
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
return serialize(
|
||||
[
|
||||
'allocationSize' => $this->_allocationSize,
|
||||
'sequenceName' => $this->_sequenceName
|
||||
));
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -142,6 +142,9 @@ abstract class AbstractHydrator
|
||||
$this->_rsm = $resultSetMapping;
|
||||
$this->_hints = $hints;
|
||||
|
||||
$evm = $this->_em->getEventManager();
|
||||
$evm->addEventListener(array(Events::onClear), $this);
|
||||
|
||||
$this->prepare();
|
||||
|
||||
$result = $this->hydrateAllData();
|
||||
@@ -210,6 +213,9 @@ abstract class AbstractHydrator
|
||||
$this->_rsm = null;
|
||||
$this->_cache = array();
|
||||
$this->_metadataCache = array();
|
||||
|
||||
$evm = $this->_em->getEventManager();
|
||||
$evm->removeEventListener(array(Events::onClear), $this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -360,8 +360,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
// Get a reference to the parent object to which the joined element belongs.
|
||||
if ($this->_rsm->isMixed && isset($this->rootAliases[$parentAlias])) {
|
||||
$first = reset($this->resultPointers);
|
||||
$parentObject = $first[key($first)];
|
||||
$objectClass = $this->resultPointers[$parentAlias];
|
||||
$parentObject = $objectClass[key($objectClass)];
|
||||
} else if (isset($this->resultPointers[$parentAlias])) {
|
||||
$parentObject = $this->resultPointers[$parentAlias];
|
||||
} else {
|
||||
|
||||
@@ -2949,7 +2949,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*/
|
||||
public function setSequenceGeneratorDefinition(array $definition)
|
||||
{
|
||||
if ( ! isset($definition['sequenceName'])) {
|
||||
if ( ! isset($definition['sequenceName']) || trim($definition['sequenceName']) === '') {
|
||||
throw MappingException::missingSequenceName($this->name);
|
||||
}
|
||||
|
||||
@@ -2958,6 +2958,14 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
$definition['quoted'] = true;
|
||||
}
|
||||
|
||||
if ( ! isset($definition['allocationSize']) || trim($definition['allocationSize']) === '') {
|
||||
$definition['allocationSize'] = '1';
|
||||
}
|
||||
|
||||
if ( ! isset($definition['initialValue']) || trim($definition['initialValue']) === '') {
|
||||
$definition['initialValue'] = '1';
|
||||
}
|
||||
|
||||
$this->sequenceGeneratorDefinition = $definition;
|
||||
}
|
||||
|
||||
|
||||
@@ -811,7 +811,8 @@ class XmlDriver extends FileDriver
|
||||
protected function loadMappingFile($file)
|
||||
{
|
||||
$result = array();
|
||||
$xmlElement = simplexml_load_file($file);
|
||||
// Note: we do not use `simplexml_load_file()` because of https://bugs.php.net/bug.php?id=62577
|
||||
$xmlElement = simplexml_load_string(file_get_contents($file));
|
||||
|
||||
if (isset($xmlElement->entity)) {
|
||||
foreach ($xmlElement->entity as $entityElement) {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
namespace Doctrine\ORM;
|
||||
|
||||
use Closure;
|
||||
use Doctrine\Common\Collections\AbstractLazyCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
@@ -375,11 +374,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
|
||||
$persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
|
||||
|
||||
if ($persister->removeElement($this, $element)) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
return null;
|
||||
return $persister->removeElement($this, $element);
|
||||
}
|
||||
|
||||
$removed = parent::removeElement($element);
|
||||
@@ -689,21 +684,41 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
protected function doInitialize()
|
||||
{
|
||||
// Has NEW objects added through add(). Remember them.
|
||||
$newObjects = array();
|
||||
$newlyAddedDirtyObjects = array();
|
||||
|
||||
if ($this->isDirty) {
|
||||
$newObjects = $this->collection->toArray();
|
||||
$newlyAddedDirtyObjects = $this->collection->toArray();
|
||||
}
|
||||
|
||||
$this->collection->clear();
|
||||
$this->em->getUnitOfWork()->loadCollection($this);
|
||||
$this->takeSnapshot();
|
||||
|
||||
// Reattach NEW objects added through add(), if any.
|
||||
if ($newObjects) {
|
||||
foreach ($newObjects as $obj) {
|
||||
$this->collection->add($obj);
|
||||
}
|
||||
if ($newlyAddedDirtyObjects) {
|
||||
$this->restoreNewObjectsInDirtyCollection($newlyAddedDirtyObjects);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object[] $newObjects
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* Note: the only reason why this entire looping/complexity is performed via `spl_object_hash`
|
||||
* is because we want to prevent using `array_udiff()`, which is likely to cause very
|
||||
* high overhead (complexity of O(n^2)). `array_diff_key()` performs the operation in
|
||||
* core, which is faster than using a callback for comparisons
|
||||
*/
|
||||
private function restoreNewObjectsInDirtyCollection(array $newObjects)
|
||||
{
|
||||
$loadedObjects = $this->collection->toArray();
|
||||
$newObjectsByOid = \array_combine(\array_map('spl_object_hash', $newObjects), $newObjects);
|
||||
$loadedObjectsByOid = \array_combine(\array_map('spl_object_hash', $loadedObjects), $loadedObjects);
|
||||
$newObjectsThatWereNotLoaded = \array_diff_key($newObjectsByOid, $loadedObjectsByOid);
|
||||
|
||||
if ($newObjectsThatWereNotLoaded) {
|
||||
// Reattach NEW objects added through add(), if any.
|
||||
\array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']);
|
||||
|
||||
$this->isDirty = true;
|
||||
}
|
||||
|
||||
@@ -239,9 +239,10 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
$parameters = $this->expandCriteriaParameters($criteria);
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
list($name, $value) = $parameter;
|
||||
$whereClauses[] = sprintf('te.%s = ?', $name);
|
||||
$params[] = $value;
|
||||
list($name, $value, $operator) = $parameter;
|
||||
|
||||
$whereClauses[] = sprintf('te.%s %s ?', $name, $operator);
|
||||
$params[] = $value;
|
||||
}
|
||||
|
||||
$mapping = $collection->getMapping();
|
||||
|
||||
@@ -820,7 +820,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
? $this->expandCriteriaParameters($criteria)
|
||||
: $this->expandParameters($criteria);
|
||||
|
||||
return $this->conn->executeQuery($sql, $params, $types)->fetchColumn();
|
||||
return (int) $this->conn->executeQuery($sql, $params, $types)->fetchColumn();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -61,7 +61,7 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
}
|
||||
|
||||
$this->values[] = $value;
|
||||
$this->types[] = array($field, $value);
|
||||
$this->types[] = array($field, $value, $operator);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,7 +91,9 @@ class ProxyFactory extends AbstractProxyFactory
|
||||
protected function skipClass(ClassMetadata $metadata)
|
||||
{
|
||||
/* @var $metadata \Doctrine\ORM\Mapping\ClassMetadataInfo */
|
||||
return $metadata->isMappedSuperclass || $metadata->getReflectionClass()->isAbstract();
|
||||
return $metadata->isMappedSuperclass
|
||||
|| $metadata->isEmbeddedClass
|
||||
|| $metadata->getReflectionClass()->isAbstract();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,7 +110,7 @@ class ResultSetMappingBuilder extends ResultSetMapping
|
||||
* @param string $class The class name of the joined entity.
|
||||
* @param string $alias The unique alias to use for the joined entity.
|
||||
* @param string $parentAlias The alias of the entity result that is the parent of this joined result.
|
||||
* @param object $relation The association field that connects the parent entity result
|
||||
* @param string $relation The association field that connects the parent entity result
|
||||
* with the joined entity result.
|
||||
* @param array $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName).
|
||||
* @param int|null $renameMode One of the COLUMN_RENAMING_* constants or array for BC reasons (CUSTOM).
|
||||
|
||||
@@ -870,6 +870,19 @@ class SqlWalker implements TreeWalker
|
||||
* @return string
|
||||
*/
|
||||
public function walkRangeVariableDeclaration($rangeVariableDeclaration)
|
||||
{
|
||||
return $this->generateRangeVariableDeclarationSQL($rangeVariableDeclaration, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate appropriate SQL for RangeVariableDeclaration AST node
|
||||
*
|
||||
* @param AST\RangeVariableDeclaration $rangeVariableDeclaration
|
||||
* @param bool $buildNestedJoins
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function generateRangeVariableDeclarationSQL($rangeVariableDeclaration, $buildNestedJoins)
|
||||
{
|
||||
$class = $this->em->getClassMetadata($rangeVariableDeclaration->abstractSchemaName);
|
||||
$dqlAlias = $rangeVariableDeclaration->aliasIdentificationVariable;
|
||||
@@ -885,7 +898,11 @@ class SqlWalker implements TreeWalker
|
||||
);
|
||||
|
||||
if ($class->isInheritanceTypeJoined()) {
|
||||
$sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
|
||||
if ($buildNestedJoins) {
|
||||
$sql = '(' . $sql . $this->_generateClassTableInheritanceJoins($class, $dqlAlias) . ')';
|
||||
} else {
|
||||
$sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
|
||||
}
|
||||
}
|
||||
|
||||
return $sql;
|
||||
@@ -1121,16 +1138,17 @@ class SqlWalker implements TreeWalker
|
||||
: ' INNER JOIN ';
|
||||
|
||||
switch (true) {
|
||||
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\RangeVariableDeclaration):
|
||||
case ($joinDeclaration instanceof AST\RangeVariableDeclaration):
|
||||
$class = $this->em->getClassMetadata($joinDeclaration->abstractSchemaName);
|
||||
$dqlAlias = $joinDeclaration->aliasIdentificationVariable;
|
||||
$tableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias);
|
||||
$condition = '(' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
|
||||
$condExprConjunction = ($class->isInheritanceTypeJoined() && $joinType != AST\Join::JOIN_TYPE_LEFT && $joinType != AST\Join::JOIN_TYPE_LEFTOUTER)
|
||||
$isUnconditionalJoin = empty($condition);
|
||||
$condExprConjunction = ($class->isInheritanceTypeJoined() && $joinType != AST\Join::JOIN_TYPE_LEFT && $joinType != AST\Join::JOIN_TYPE_LEFTOUTER && $isUnconditionalJoin)
|
||||
? ' AND '
|
||||
: ' ON ';
|
||||
|
||||
$sql .= $this->walkRangeVariableDeclaration($joinDeclaration);
|
||||
$sql .= $this->generateRangeVariableDeclarationSQL($joinDeclaration, !$isUnconditionalJoin);
|
||||
|
||||
$conditions = array($condition);
|
||||
|
||||
@@ -1151,7 +1169,7 @@ class SqlWalker implements TreeWalker
|
||||
$sql .= $condExprConjunction . implode(' AND ', $conditions);
|
||||
break;
|
||||
|
||||
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\JoinAssociationDeclaration):
|
||||
case ($joinDeclaration instanceof AST\JoinAssociationDeclaration):
|
||||
$sql .= $this->walkJoinAssociationDeclaration($joinDeclaration, $joinType, $join->conditionalExpression);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -529,24 +529,15 @@ class QueryBuilder
|
||||
*/
|
||||
public function setParameter($key, $value, $type = null)
|
||||
{
|
||||
$filteredParameters = $this->parameters->filter(
|
||||
function ($parameter) use ($key)
|
||||
{
|
||||
// Must not be identical because of string to integer conversion
|
||||
return ($key == $parameter->getName());
|
||||
}
|
||||
);
|
||||
$existingParameter = $this->getParameter($key);
|
||||
|
||||
if (count($filteredParameters)) {
|
||||
$parameter = $filteredParameters->first();
|
||||
$parameter->setValue($value, $type);
|
||||
if ($existingParameter !== null) {
|
||||
$existingParameter->setValue($value, $type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
$parameter = new Query\Parameter($key, $value, $type);
|
||||
|
||||
$this->parameters->add($parameter);
|
||||
$this->parameters->add(new Query\Parameter($key, $value, $type));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -609,14 +600,14 @@ class QueryBuilder
|
||||
public function getParameter($key)
|
||||
{
|
||||
$filteredParameters = $this->parameters->filter(
|
||||
function ($parameter) use ($key)
|
||||
{
|
||||
// Must not be identical because of string to integer conversion
|
||||
return ($key == $parameter->getName());
|
||||
function (Query\Parameter $parameter) use ($key) {
|
||||
$parameterName = $parameter->getName();
|
||||
|
||||
return $key === $parameterName || (string) $key === (string) $parameterName;
|
||||
}
|
||||
);
|
||||
|
||||
return count($filteredParameters) ? $filteredParameters->first() : null;
|
||||
return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,10 +84,6 @@ class MetadataFilter extends \FilterIterator implements \Countable
|
||||
);
|
||||
}
|
||||
|
||||
if ($pregResult === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($pregResult) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,6 +85,14 @@ class CountOutputWalker extends SqlWalker
|
||||
|
||||
$sql = parent::walkSelectStatement($AST);
|
||||
|
||||
if ($AST->groupByClause) {
|
||||
return sprintf(
|
||||
'SELECT %s AS dctrn_count FROM (%s) dctrn_table',
|
||||
$this->platform->getCountExpression('*'),
|
||||
$sql
|
||||
);
|
||||
}
|
||||
|
||||
// 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
|
||||
// would probably require issuing multiple queries or doing a UNION SELECT
|
||||
|
||||
@@ -345,7 +345,7 @@ class SchemaTool
|
||||
$discrColumn = $class->discriminatorColumn;
|
||||
|
||||
if ( ! isset($discrColumn['type']) ||
|
||||
(strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)
|
||||
(strtolower($discrColumn['type']) == 'string' && ! isset($discrColumn['length']))
|
||||
) {
|
||||
$discrColumn['type'] = 'string';
|
||||
$discrColumn['length'] = 255;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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\Tools;
|
||||
|
||||
@@ -122,32 +122,7 @@ class Setup
|
||||
public static function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
|
||||
{
|
||||
$proxyDir = $proxyDir ?: sys_get_temp_dir();
|
||||
|
||||
if ($isDevMode === false && $cache === null) {
|
||||
if (extension_loaded('apc')) {
|
||||
$cache = new \Doctrine\Common\Cache\ApcCache();
|
||||
} elseif (extension_loaded('xcache')) {
|
||||
$cache = new \Doctrine\Common\Cache\XcacheCache();
|
||||
} elseif (extension_loaded('memcache')) {
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect('127.0.0.1');
|
||||
$cache = new \Doctrine\Common\Cache\MemcacheCache();
|
||||
$cache->setMemcache($memcache);
|
||||
} elseif (extension_loaded('redis')) {
|
||||
$redis = new \Redis();
|
||||
$redis->connect('127.0.0.1');
|
||||
$cache = new \Doctrine\Common\Cache\RedisCache();
|
||||
$cache->setRedis($redis);
|
||||
} else {
|
||||
$cache = new ArrayCache();
|
||||
}
|
||||
} elseif ($cache === null) {
|
||||
$cache = new ArrayCache();
|
||||
}
|
||||
|
||||
if ($cache instanceof CacheProvider) {
|
||||
$cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
|
||||
}
|
||||
$cache = self::createCacheConfiguration($isDevMode, $proxyDir, $cache);
|
||||
|
||||
$config = new Configuration();
|
||||
$config->setMetadataCacheImpl($cache);
|
||||
@@ -159,4 +134,77 @@ class Setup
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isDevMode
|
||||
* @param string $proxyDir
|
||||
* @param Cache|null $cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
private static function createCacheConfiguration($isDevMode, $proxyDir, Cache $cache = null)
|
||||
{
|
||||
$cache = self::createCacheInstance($isDevMode, $cache);
|
||||
|
||||
if ( ! $cache instanceof CacheProvider) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
$namespace = $cache->getNamespace();
|
||||
|
||||
if ($namespace !== '') {
|
||||
$namespace .= ':';
|
||||
}
|
||||
|
||||
$cache->setNamespace($namespace . 'dc2_' . md5($proxyDir) . '_'); // to avoid collisions
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $isDevMode
|
||||
* @param Cache|null $cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
private static function createCacheInstance($isDevMode, Cache $cache = null)
|
||||
{
|
||||
if ($cache !== null) {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
if ($isDevMode === true) {
|
||||
return new ArrayCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('apc')) {
|
||||
return new \Doctrine\Common\Cache\ApcCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('xcache')) {
|
||||
return new \Doctrine\Common\Cache\XcacheCache();
|
||||
}
|
||||
|
||||
if (extension_loaded('memcache')) {
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect('127.0.0.1');
|
||||
|
||||
$cache = new \Doctrine\Common\Cache\MemcacheCache();
|
||||
$cache->setMemcache($memcache);
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
if (extension_loaded('redis')) {
|
||||
$redis = new \Redis();
|
||||
$redis->connect('127.0.0.1');
|
||||
|
||||
$cache = new \Doctrine\Common\Cache\RedisCache();
|
||||
$cache->setRedis($redis);
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
return new ArrayCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Doctrine\ORM;
|
||||
/**
|
||||
* Class to store and retrieve the version of Doctrine
|
||||
*
|
||||
*
|
||||
*
|
||||
* @link www.doctrine-project.org
|
||||
* @since 2.0
|
||||
* @version $Revision$
|
||||
@@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.5.5-DEV';
|
||||
const VERSION = '2.5.13';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
||||
@@ -2,16 +2,29 @@
|
||||
|
||||
namespace Doctrine\Tests\Mocks;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
|
||||
/**
|
||||
* Mock class for Connection.
|
||||
*/
|
||||
class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
class ConnectionMock extends Connection
|
||||
{
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $_fetchOneResult;
|
||||
|
||||
/**
|
||||
* @var \Exception|null
|
||||
*/
|
||||
private $_fetchOneException;
|
||||
|
||||
/**
|
||||
* @var Statement|null
|
||||
*/
|
||||
private $_queryResult;
|
||||
|
||||
/**
|
||||
* @var DatabasePlatformMock
|
||||
*/
|
||||
@@ -25,12 +38,12 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_inserts = array();
|
||||
private $_inserts = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_executeUpdates = array();
|
||||
private $_executeUpdates = [];
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
@@ -59,7 +72,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function insert($tableName, array $data, array $types = array())
|
||||
public function insert($tableName, array $data, array $types = [])
|
||||
{
|
||||
$this->_inserts[$tableName][] = $data;
|
||||
}
|
||||
@@ -67,9 +80,9 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function executeUpdate($query, array $params = array(), array $types = array())
|
||||
public function executeUpdate($query, array $params = [], array $types = [])
|
||||
{
|
||||
$this->_executeUpdates[] = array('query' => $query, 'params' => $params, 'types' => $types);
|
||||
$this->_executeUpdates[] = ['query' => $query, 'params' => $params, 'types' => $types];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,11 +96,23 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fetchColumn($statement, array $params = array(), $colnum = 0, array $types = array())
|
||||
public function fetchColumn($statement, array $params = [], $colnum = 0, array $types = [])
|
||||
{
|
||||
if (null !== $this->_fetchOneException) {
|
||||
throw $this->_fetchOneException;
|
||||
}
|
||||
|
||||
return $this->_fetchOneResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return $this->_queryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -111,6 +136,16 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
$this->_fetchOneResult = $fetchOneResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Exception|null $exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFetchOneException(\Exception $exception = null)
|
||||
{
|
||||
$this->_fetchOneException = $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform
|
||||
*
|
||||
@@ -131,6 +166,14 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
$this->_lastInsertId = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Statement $result
|
||||
*/
|
||||
public function setQueryResult(Statement $result)
|
||||
{
|
||||
$this->_queryResult = $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
@@ -152,7 +195,7 @@ class ConnectionMock extends \Doctrine\DBAL\Connection
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->_inserts = array();
|
||||
$this->_inserts = [];
|
||||
$this->_lastInsertId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\Mocks;
|
||||
|
||||
|
||||
/**
|
||||
* Simple statement mock that returns result based on array.
|
||||
* Doesn't support fetch modes
|
||||
*/
|
||||
class StatementArrayMock extends StatementMock
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $_result;
|
||||
|
||||
public function __construct($result)
|
||||
{
|
||||
$this->_result = $result;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->_result);
|
||||
}
|
||||
|
||||
public function columnCount()
|
||||
{
|
||||
$row = reset($this->_result);
|
||||
if ($row) {
|
||||
return count($row);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
|
||||
{
|
||||
return $this->_result;
|
||||
}
|
||||
|
||||
public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
|
||||
{
|
||||
$current = current($this->_result);
|
||||
next($this->_result);
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
public function fetchColumn($columnIndex = 0)
|
||||
{
|
||||
$current = current($this->_result);
|
||||
if ($current) {
|
||||
next($this->_result);
|
||||
return reset($current);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function rowCount()
|
||||
{
|
||||
return count($this->_result);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ class DefaultRegionTest extends AbstractRegionTest
|
||||
|
||||
public function testSharedRegion()
|
||||
{
|
||||
if ( ! extension_loaded('apc') || false === @apc_cache_info()) {
|
||||
if ( ! extension_loaded('apc') || ! is_array(@apc_cache_info("user"))) {
|
||||
$this->markTestSkipped('The ' . __CLASS__ .' requires the use of APC');
|
||||
}
|
||||
|
||||
@@ -97,4 +97,4 @@ class DefaultRegionTest extends AbstractRegionTest
|
||||
$this->assertEquals($value1, $actual[0]);
|
||||
$this->assertEquals($value2, $actual[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -28,7 +28,7 @@ class NonStrictReadWriteCachedEntityPersisterTest extends AbstractEntityPersiste
|
||||
{
|
||||
$entity = new Country("Foo");
|
||||
$persister = $this->createPersisterDefault();
|
||||
$property = new \ReflectionProperty('Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister', 'queuedCache');
|
||||
$property = new \ReflectionProperty($persister, 'queuedCache');
|
||||
|
||||
$property->setAccessible(true);
|
||||
|
||||
@@ -50,7 +50,7 @@ class NonStrictReadWriteCachedEntityPersisterTest extends AbstractEntityPersiste
|
||||
$persister = $this->createPersisterDefault();
|
||||
$key = new EntityCacheKey(Country::CLASSNAME, array('id'=>1));
|
||||
$entry = new EntityCacheEntry(Country::CLASSNAME, array('id'=>1, 'name'=>'Foo'));
|
||||
$property = new \ReflectionProperty('Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister', 'queuedCache');
|
||||
$property = new \ReflectionProperty($persister, 'queuedCache');
|
||||
|
||||
$property->setAccessible(true);
|
||||
|
||||
@@ -87,7 +87,7 @@ class NonStrictReadWriteCachedEntityPersisterTest extends AbstractEntityPersiste
|
||||
$persister = $this->createPersisterDefault();
|
||||
$key = new EntityCacheKey(Country::CLASSNAME, array('id'=>1));
|
||||
$entry = new EntityCacheEntry(Country::CLASSNAME, array('id'=>1, 'name'=>'Foo'));
|
||||
$property = new \ReflectionProperty('Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister', 'queuedCache');
|
||||
$property = new \ReflectionProperty($persister, 'queuedCache');
|
||||
|
||||
$property->setAccessible(true);
|
||||
|
||||
@@ -115,7 +115,7 @@ class NonStrictReadWriteCachedEntityPersisterTest extends AbstractEntityPersiste
|
||||
$entity = new Country("Foo");
|
||||
$persister = $this->createPersisterDefault();
|
||||
$key = new EntityCacheKey(Country::CLASSNAME, array('id'=>1));
|
||||
$property = new \ReflectionProperty('Doctrine\ORM\Cache\Persister\Entity\ReadWriteCachedEntityPersister', 'queuedCache');
|
||||
$property = new \ReflectionProperty($persister, 'queuedCache');
|
||||
|
||||
$property->setAccessible(true);
|
||||
|
||||
|
||||
@@ -636,11 +636,13 @@ class ExtraLazyCollectionTest extends OrmFunctionalTestCase
|
||||
$group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
|
||||
$queryCount = $this->getCurrentQueryCount();
|
||||
|
||||
$user->groups->removeElement($group);
|
||||
$this->assertTrue($user->groups->removeElement($group));
|
||||
|
||||
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
|
||||
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
|
||||
|
||||
$this->assertFalse($user->groups->removeElement($group), "Removing an already removed element returns false");
|
||||
|
||||
// Test Many to Many removal with Entity state as new
|
||||
$group = new \Doctrine\Tests\Models\CMS\CmsGroup();
|
||||
$group->name = "A New group!";
|
||||
|
||||
@@ -129,6 +129,7 @@ class QueryCacheTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
->will($this->returnValue( 10 ));
|
||||
|
||||
$parserResultMock = $this->getMock('Doctrine\ORM\Query\ParserResult');
|
||||
$parserResultMock->method('getParameterMappings')->willReturn(array());
|
||||
$parserResultMock->expects($this->once())
|
||||
->method('getSqlExecutor')
|
||||
->will($this->returnValue($sqlExecMock));
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
/**
|
||||
* @group DDC-3146
|
||||
* @author Emiel Nijpels <emiel@silverstreet.com>
|
||||
*/
|
||||
class DDC3146Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* Verify that the number of added events to the event listener from the abstract hydrator class is equal to the number of removed events
|
||||
*/
|
||||
public function testEventListeners()
|
||||
{
|
||||
// Create mock connection to be returned from the entity manager interface
|
||||
$mockConnection = $this->getMockBuilder('Doctrine\DBAL\Connection')->disableOriginalConstructor()->getMock();
|
||||
$mockEntityManagerInterface = $this->getMockBuilder('Doctrine\ORM\EntityManagerInterface')->disableOriginalConstructor()->getMock();
|
||||
$mockEntityManagerInterface->expects($this->any())->method('getConnection')->will($this->returnValue($mockConnection));
|
||||
|
||||
// Create mock event manager to be returned from the entity manager interface
|
||||
$mockEventManager = $this->getMockBuilder('Doctrine\Common\EventManager')->disableOriginalConstructor()->getMock();
|
||||
$mockEntityManagerInterface->expects($this->any())->method('getEventManager')->will($this->returnValue($mockEventManager));
|
||||
|
||||
// Create mock statement and result mapping
|
||||
$mockStatement = $this->getMockBuilder('Doctrine\DBAL\Driver\Statement')->disableOriginalConstructor()->getMock();
|
||||
$mockStatement->expects($this->once())->method('fetch')->will($this->returnValue(false));
|
||||
$mockResultMapping = $this->getMockBuilder('Doctrine\ORM\Query\ResultSetMapping')->disableOriginalConstructor()->getMock();
|
||||
|
||||
// Create mock abstract hydrator
|
||||
$mockAbstractHydrator = $this->getMockBuilder('Doctrine\ORM\Internal\Hydration\AbstractHydrator')
|
||||
->setConstructorArgs(array($mockEntityManagerInterface))
|
||||
->setMethods(array('hydrateAllData'))
|
||||
->getMock();
|
||||
|
||||
// Increase counter every time the event listener is added and decrease the counter every time the event listener is removed
|
||||
$eventCounter = 0;
|
||||
$mockEventManager->expects($this->any())
|
||||
->method('addEventListener')
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function () use (&$eventCounter) {
|
||||
$eventCounter++;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
$mockEventManager->expects($this->any())
|
||||
->method('removeEventListener')
|
||||
->will(
|
||||
$this->returnCallback(
|
||||
function () use (&$eventCounter) {
|
||||
$eventCounter--;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// Create iterable result
|
||||
$iterableResult = $mockAbstractHydrator->iterate($mockStatement, $mockResultMapping, array());
|
||||
$iterableResult->next();
|
||||
|
||||
// Number of added events listeners should be equal or less than the number of removed events
|
||||
$this->assertLessThanOrEqual(0, $eventCounter, 'More events added to the event listener than removed; this can create a memory leak when references are not cleaned up');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\Query\ResultSetMapping;
|
||||
use Doctrine\Tests\Mocks\HydratorMockStatement;
|
||||
|
||||
final class GH6362Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(
|
||||
[
|
||||
$this->_em->getClassMetadata(GH6362Start::CLASSNAME),
|
||||
$this->_em->getClassMetadata(GH6362Base::CLASSNAME),
|
||||
$this->_em->getClassMetadata(GH6362Child::CLASSNAME),
|
||||
$this->_em->getClassMetadata(GH6362Join::CLASSNAME),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6362
|
||||
*
|
||||
* SELECT a as base, b, c, d
|
||||
* FROM Start a
|
||||
* LEFT JOIN a.bases b
|
||||
* LEFT JOIN Child c WITH b.id = c.id
|
||||
* LEFT JOIN c.joins d
|
||||
*/
|
||||
public function testInheritanceJoinAlias()
|
||||
{
|
||||
$rsm = new ResultSetMapping;
|
||||
$rsm->addEntityResult(GH6362Start::CLASSNAME, 'a', 'base');
|
||||
$rsm->addJoinedEntityResult(GH6362Base::CLASSNAME, 'b', 'a', 'bases');
|
||||
$rsm->addEntityResult(GH6362Child::CLASSNAME, 'c');
|
||||
$rsm->addJoinedEntityResult(GH6362Join::CLASSNAME, 'd', 'c', 'joins');
|
||||
|
||||
$rsm->addFieldResult('a', 'id_0', 'id');
|
||||
$rsm->addFieldResult('b', 'id_1', 'id');
|
||||
$rsm->addFieldResult('c', 'id_2', 'id');
|
||||
$rsm->addFieldResult('d', 'id_3', 'id');
|
||||
|
||||
$rsm->addMetaResult('a', 'bases_id_4', 'bases_id', false, 'integer');
|
||||
$rsm->addMetaResult('b', 'type_5', 'type');
|
||||
$rsm->addMetaResult('c', 'type_6', 'type');
|
||||
$rsm->addMetaResult('d', 'child_id_7', 'child_id', false, 'integer');
|
||||
|
||||
$rsm->setDiscriminatorColumn('b', 'type_5');
|
||||
$rsm->setDiscriminatorColumn('c', 'type_6');
|
||||
|
||||
$resultSet = [
|
||||
[
|
||||
'id_0' => '1',
|
||||
'id_1' => '1',
|
||||
'id_2' => '1',
|
||||
'id_3' => '1',
|
||||
'bases_id_4' => '1',
|
||||
'type_5' => 'child',
|
||||
'type_6' => 'child',
|
||||
'child_id_7' => '1',
|
||||
],
|
||||
];
|
||||
|
||||
$stmt = new HydratorMockStatement($resultSet);
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
|
||||
$result = $hydrator->hydrateAll($stmt, $rsm, [Query::HINT_FORCE_PARTIAL_LOAD => true]);
|
||||
|
||||
$this->assertInstanceOf(GH6362Start::CLASSNAME, $result[0]['base']);
|
||||
$this->assertInstanceOf(GH6362Child::CLASSNAME, $result[1][0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH6362Start
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="GH6362Base", inversedBy="starts")
|
||||
*/
|
||||
private $bases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @InheritanceType("SINGLE_TABLE")
|
||||
* @DiscriminatorColumn(name="type", type="string")
|
||||
* @DiscriminatorMap({"child" = "GH6362Child"})
|
||||
* @Entity
|
||||
*/
|
||||
abstract class GH6362Base
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="GH6362Start", mappedBy="bases")
|
||||
*/
|
||||
private $starts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH6362Child extends GH6362Base
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="GH6362Join", mappedBy="child")
|
||||
*/
|
||||
private $joins;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class GH6362Join
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="GH6362Child", inversedBy="joins")
|
||||
*/
|
||||
private $child;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group GH-6464
|
||||
*/
|
||||
class GH6464Test extends OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema([
|
||||
$this->_em->getClassMetadata(GH6464Post::CLASS_NAME),
|
||||
$this->_em->getClassMetadata(GH6464User::CLASS_NAME),
|
||||
$this->_em->getClassMetadata(GH6464Author::CLASS_NAME),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that SqlWalker generates valid SQL for an INNER JOIN to CTI table
|
||||
*
|
||||
* SqlWalker needs to generate nested INNER JOIN statements, otherwise there would be INNER JOIN
|
||||
* statements without an ON clause, which are valid on e.g. MySQL but rejected by PostgreSQL.
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
$query = $this->_em->createQueryBuilder()
|
||||
->select('p')
|
||||
->from(GH6464Post::CLASS_NAME, 'p')
|
||||
->innerJoin(GH6464Author::CLASS_NAME, 'a', 'WITH', 'p.authorId = a.id')
|
||||
->getQuery();
|
||||
|
||||
$this->assertNotRegExp(
|
||||
'/INNER JOIN \w+ \w+ INNER JOIN/',
|
||||
$query->getSQL(),
|
||||
'As of GH-6464, every INNER JOIN should have an ON clause, which is missing here'
|
||||
);
|
||||
|
||||
// Query shouldn't yield a result, yet it shouldn't crash (anymore)
|
||||
$this->assertEquals([], $query->getResult());
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class GH6464Post
|
||||
{
|
||||
const CLASS_NAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
|
||||
/** @Column(type="integer") */
|
||||
public $authorId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"author" = "GH6464Author"})
|
||||
*/
|
||||
abstract class GH6464User
|
||||
{
|
||||
const CLASS_NAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
public $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class GH6464Author extends GH6464User
|
||||
{
|
||||
const CLASS_NAME = __CLASS__;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Test\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadataInfo;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
final class GH6682Test extends OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @group 6682
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
$parsedDefinition = [
|
||||
'sequenceName' => 'test_sequence',
|
||||
'allocationSize' => '',
|
||||
'initialValue' => '',
|
||||
];
|
||||
|
||||
$classMetadataInfo = new ClassMetadataInfo('test_entity');
|
||||
$classMetadataInfo->setSequenceGeneratorDefinition($parsedDefinition);
|
||||
|
||||
self::assertSame(
|
||||
['sequenceName' => 'test_sequence', 'allocationSize' => '1', 'initialValue' => '1'],
|
||||
$classMetadataInfo->sequenceGeneratorDefinition
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
final class GH6699Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testMixedParametersWithZeroNumber()
|
||||
{
|
||||
$query = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->andWhere('u.username = :username')
|
||||
->andWhere('u.id = ?0')
|
||||
->getQuery();
|
||||
|
||||
$query->setParameter('username', 'bar');
|
||||
$query->setParameter(0, 0);
|
||||
|
||||
$query->execute();
|
||||
|
||||
self::assertCount(2, $query->getParameters());
|
||||
self::assertSame(0, $query->getParameter(0)->getValue());
|
||||
self::assertSame('bar', $query->getParameter('username')->getValue());
|
||||
}
|
||||
|
||||
public function testMixedParametersWithZeroNumberOnQueryBuilder()
|
||||
{
|
||||
$query = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->andWhere('u.username = :username')
|
||||
->andWhere('u.id = ?0')
|
||||
->setParameter('username', 'bar')
|
||||
->setParameter(0, 0)
|
||||
->getQuery();
|
||||
|
||||
$query->execute();
|
||||
|
||||
self::assertCount(2, $query->getParameters());
|
||||
self::assertSame(0, $query->getParameter(0)->getValue());
|
||||
self::assertSame('bar', $query->getParameter('username')->getValue());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCategory;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
final class GH6740Test extends OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $productId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $firstCategoryId;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $secondCategoryId;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
$this->useModelSet('ecommerce');
|
||||
|
||||
parent::setUp();
|
||||
|
||||
$product = new ECommerceProduct();
|
||||
$product->setName('First Product');
|
||||
|
||||
$firstCategory = new ECommerceCategory();
|
||||
$secondCategory = new ECommerceCategory();
|
||||
|
||||
$firstCategory->setName('Business');
|
||||
$secondCategory->setName('Home');
|
||||
|
||||
$product->addCategory($firstCategory);
|
||||
$product->addCategory($secondCategory);
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->productId = $product->getId();
|
||||
$this->firstCategoryId = $firstCategory->getId();
|
||||
$this->secondCategoryId = $secondCategory->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6740
|
||||
*/
|
||||
public function testCollectionFilteringLteOperator()
|
||||
{
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->productId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->lte('id', $this->secondCategoryId));
|
||||
|
||||
self::assertCount(2, $product->getCategories()->matching($criteria));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6740
|
||||
*/
|
||||
public function testCollectionFilteringLtOperator()
|
||||
{
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->productId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->lt('id', $this->secondCategoryId));
|
||||
|
||||
self::assertCount(1, $product->getCategories()->matching($criteria));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6740
|
||||
*/
|
||||
public function testCollectionFilteringGteOperator()
|
||||
{
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->productId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->gte('id', $this->firstCategoryId));
|
||||
|
||||
self::assertCount(2, $product->getCategories()->matching($criteria));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6740
|
||||
*/
|
||||
public function testCollectionFilteringGtOperator()
|
||||
{
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->productId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->gt('id', $this->firstCategoryId));
|
||||
|
||||
self::assertCount(1, $product->getCategories()->matching($criteria));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6740
|
||||
*/
|
||||
public function testCollectionFilteringEqualsOperator()
|
||||
{
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->productId);
|
||||
$criteria = Criteria::create()->where(Criteria::expr()->eq('id', $this->firstCategoryId));
|
||||
|
||||
self::assertCount(1, $product->getCategories()->matching($criteria));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\Events;
|
||||
use Doctrine\ORM\Internal\Hydration\AbstractHydrator;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
/**
|
||||
* @covers \Doctrine\ORM\Internal\Hydration\AbstractHydrator
|
||||
*/
|
||||
class AbstractHydratorTest extends OrmFunctionalTestCase
|
||||
{
|
||||
/**
|
||||
* @group DDC-3146
|
||||
* @group #1515
|
||||
*
|
||||
* Verify that the number of added events to the event listener from the abstract hydrator class is equal to the
|
||||
* number of removed events
|
||||
*/
|
||||
public function testOnClearEventListenerIsDetachedOnCleanup()
|
||||
{
|
||||
$mockConnection = $this->getMockBuilder('Doctrine\DBAL\Connection')->disableOriginalConstructor()->getMock();
|
||||
$mockEntityManagerInterface = $this->getMock('Doctrine\ORM\EntityManagerInterface');
|
||||
$mockEventManager = $this->getMock('Doctrine\Common\EventManager');
|
||||
$mockStatement = $this->getMock('Doctrine\DBAL\Driver\Statement');
|
||||
$mockResultMapping = $this->getMock('Doctrine\ORM\Query\ResultSetMapping');
|
||||
|
||||
$mockEntityManagerInterface->expects(self::any())->method('getEventManager')->willReturn($mockEventManager);
|
||||
$mockEntityManagerInterface->expects(self::any())->method('getConnection')->willReturn($mockConnection);
|
||||
$mockStatement->expects(self::once())->method('fetch')->willReturn(false);
|
||||
|
||||
/* @var $mockAbstractHydrator AbstractHydrator */
|
||||
$mockAbstractHydrator = $this
|
||||
->getMockBuilder('Doctrine\ORM\Internal\Hydration\AbstractHydrator')
|
||||
->setConstructorArgs([$mockEntityManagerInterface])
|
||||
->setMethods(['hydrateAllData'])
|
||||
->getMock();
|
||||
|
||||
$mockEventManager
|
||||
->expects(self::at(0))
|
||||
->method('addEventListener')
|
||||
->with([Events::onClear], $mockAbstractHydrator);
|
||||
|
||||
$mockEventManager
|
||||
->expects(self::at(1))
|
||||
->method('removeEventListener')
|
||||
->with([Events::onClear], $mockAbstractHydrator);
|
||||
|
||||
$mockEventManager
|
||||
->expects(self::at(2))
|
||||
->method('addEventListener')
|
||||
->with([Events::onClear], $mockAbstractHydrator);
|
||||
|
||||
$mockEventManager
|
||||
->expects(self::at(3))
|
||||
->method('removeEventListener')
|
||||
->with([Events::onClear], $mockAbstractHydrator);
|
||||
|
||||
iterator_to_array($mockAbstractHydrator->iterate($mockStatement, $mockResultMapping));
|
||||
$mockAbstractHydrator->hydrateAll($mockStatement, $mockResultMapping);
|
||||
}
|
||||
}
|
||||
@@ -2,37 +2,58 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Id;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\Id\SequenceGenerator;
|
||||
use Doctrine\Tests\Mocks\ConnectionMock;
|
||||
use Doctrine\Tests\Mocks\StatementArrayMock;
|
||||
use Doctrine\Tests\OrmTestCase;
|
||||
|
||||
/**
|
||||
* Description of SequenceGeneratorTest
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class SequenceGeneratorTest extends \Doctrine\Tests\OrmTestCase
|
||||
class SequenceGeneratorTest extends OrmTestCase
|
||||
{
|
||||
private $_em;
|
||||
private $_seqGen;
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
private $entityManager;
|
||||
|
||||
/**
|
||||
* @var SequenceGenerator
|
||||
*/
|
||||
private $sequenceGenerator;
|
||||
|
||||
/**
|
||||
* @var ConnectionMock
|
||||
*/
|
||||
private $connection;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->_em = $this->_getTestEntityManager();
|
||||
$this->_seqGen = new SequenceGenerator('seq', 10);
|
||||
parent::setUp();
|
||||
|
||||
$this->entityManager = $this->_getTestEntityManager();
|
||||
$this->sequenceGenerator = new SequenceGenerator('seq', 10);
|
||||
$this->connection = $this->entityManager->getConnection();
|
||||
|
||||
self::assertInstanceOf('Doctrine\Tests\Mocks\ConnectionMock', $this->connection);
|
||||
}
|
||||
|
||||
public function testGeneration()
|
||||
{
|
||||
for ($i=0; $i < 42; ++$i) {
|
||||
$this->connection->setFetchOneException(new \BadMethodCallException(
|
||||
'Fetch* method used. Query method should be used instead, '
|
||||
. 'as NEXTVAL should be run on a master server in master-slave setup.'
|
||||
));
|
||||
|
||||
for ($i = 0; $i < 42; ++$i) {
|
||||
if ($i % 10 == 0) {
|
||||
$this->_em->getConnection()->setFetchOneResult((int)($i / 10) * 10);
|
||||
$this->connection->setQueryResult(new StatementArrayMock([[(int)($i / 10) * 10]]));
|
||||
}
|
||||
$id = $this->_seqGen->generate($this->_em, null);
|
||||
$this->assertEquals($i, $id);
|
||||
$this->assertEquals((int)($i / 10) * 10 + 10, $this->_seqGen->getCurrentMaxValue());
|
||||
$this->assertEquals($i + 1, $this->_seqGen->getNextValue());
|
||||
|
||||
$id = $this->sequenceGenerator->generate($this->entityManager, null);
|
||||
|
||||
self::assertSame($i, $id);
|
||||
self::assertSame((int)($i / 10) * 10 + 10, $this->sequenceGenerator->getCurrentMaxValue());
|
||||
self::assertSame($i + 1, $this->sequenceGenerator->getNextValue());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1083,15 +1083,19 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
/**
|
||||
* @group DDC-2662
|
||||
* @group 6682
|
||||
*/
|
||||
public function testQuotedSequenceName()
|
||||
{
|
||||
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$cm->initializeReflection(new RuntimeReflectionService());
|
||||
|
||||
$cm->initializeReflection(new RuntimeReflectionService());
|
||||
$cm->setSequenceGeneratorDefinition(array('sequenceName' => '`foo`'));
|
||||
|
||||
$this->assertEquals(array('sequenceName' => 'foo', 'quoted' => true), $cm->sequenceGeneratorDefinition);
|
||||
self::assertSame(
|
||||
array('sequenceName' => 'foo', 'quoted' => true, 'allocationSize' => '1', 'initialValue' => '1'),
|
||||
$cm->sequenceGeneratorDefinition
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
use Doctrine\Tests\Mocks\ConnectionMock;
|
||||
use Doctrine\Tests\Mocks\DriverMock;
|
||||
use Doctrine\Tests\Mocks\EntityManagerMock;
|
||||
@@ -23,7 +24,7 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
protected $collection;
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\EntityManagerInterface
|
||||
* @var EntityManagerMock
|
||||
*/
|
||||
private $_emMock;
|
||||
|
||||
@@ -32,6 +33,8 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
parent::setUp();
|
||||
|
||||
$this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock()));
|
||||
|
||||
$this->setUpPersistentCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +61,6 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testCurrentInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->current();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
@@ -68,7 +70,6 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testKeyInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->key();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
@@ -78,7 +79,6 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testNextInitializesCollection()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$this->collection->next();
|
||||
$this->assertTrue($this->collection->isInitialized());
|
||||
}
|
||||
@@ -88,12 +88,12 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testRemovingElementsAlsoRemovesKeys()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$dummy = new \stdClass();
|
||||
|
||||
$this->collection->add('dummy');
|
||||
$this->collection->add($dummy);
|
||||
$this->assertEquals([0], array_keys($this->collection->toArray()));
|
||||
|
||||
$this->collection->removeElement('dummy');
|
||||
$this->collection->removeElement($dummy);
|
||||
$this->assertEquals([], array_keys($this->collection->toArray()));
|
||||
}
|
||||
|
||||
@@ -102,9 +102,7 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testClearWillAlsoClearKeys()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
|
||||
$this->collection->add('dummy');
|
||||
$this->collection->add(new \stdClass());
|
||||
$this->collection->clear();
|
||||
$this->assertEquals([], array_keys($this->collection->toArray()));
|
||||
}
|
||||
@@ -114,12 +112,142 @@ class PersistentCollectionTest extends OrmTestCase
|
||||
*/
|
||||
public function testClearWillAlsoResetKeyPositions()
|
||||
{
|
||||
$this->setUpPersistentCollection();
|
||||
$dummy = new \stdClass();
|
||||
|
||||
$this->collection->add('dummy');
|
||||
$this->collection->removeElement('dummy');
|
||||
$this->collection->add($dummy);
|
||||
$this->collection->removeElement($dummy);
|
||||
$this->collection->clear();
|
||||
$this->collection->add('dummy');
|
||||
$this->collection->add($dummy);
|
||||
$this->assertEquals([0], array_keys($this->collection->toArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6613
|
||||
* @group 6614
|
||||
* @group 6616
|
||||
*/
|
||||
public function testWillKeepNewItemsInDirtyCollectionAfterInitialization()
|
||||
{
|
||||
/* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
|
||||
$unitOfWork = $this
|
||||
->getMockBuilder('Doctrine\ORM\UnitOfWork')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_emMock->setUnitOfWork($unitOfWork);
|
||||
|
||||
$newElement = new \stdClass();
|
||||
$persistedElement = new \stdClass();
|
||||
|
||||
$this->collection->add($newElement);
|
||||
|
||||
self::assertFalse($this->collection->isInitialized());
|
||||
self::assertTrue($this->collection->isDirty());
|
||||
|
||||
$unitOfWork
|
||||
->expects(self::once())
|
||||
->method('loadCollection')
|
||||
->with($this->collection)
|
||||
->willReturnCallback(function (PersistentCollection $persistentCollection) use ($persistedElement) {
|
||||
$persistentCollection->unwrap()->add($persistedElement);
|
||||
});
|
||||
|
||||
$this->collection->initialize();
|
||||
|
||||
self::assertSame([$persistedElement, $newElement], $this->collection->toArray());
|
||||
self::assertTrue($this->collection->isInitialized());
|
||||
self::assertTrue($this->collection->isDirty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6613
|
||||
* @group 6614
|
||||
* @group 6616
|
||||
*/
|
||||
public function testWillDeDuplicateNewItemsThatWerePreviouslyPersistedInDirtyCollectionAfterInitialization()
|
||||
{
|
||||
/* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
|
||||
$unitOfWork = $this
|
||||
->getMockBuilder('Doctrine\ORM\UnitOfWork')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_emMock->setUnitOfWork($unitOfWork);
|
||||
|
||||
$newElement = new \stdClass();
|
||||
$newElementThatIsAlsoPersisted = new \stdClass();
|
||||
$persistedElement = new \stdClass();
|
||||
|
||||
$this->collection->add($newElementThatIsAlsoPersisted);
|
||||
$this->collection->add($newElement);
|
||||
|
||||
self::assertFalse($this->collection->isInitialized());
|
||||
self::assertTrue($this->collection->isDirty());
|
||||
|
||||
$unitOfWork
|
||||
->expects(self::once())
|
||||
->method('loadCollection')
|
||||
->with($this->collection)
|
||||
->willReturnCallback(function (PersistentCollection $persistentCollection) use (
|
||||
$persistedElement,
|
||||
$newElementThatIsAlsoPersisted
|
||||
) {
|
||||
$persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
|
||||
$persistentCollection->unwrap()->add($persistedElement);
|
||||
});
|
||||
|
||||
$this->collection->initialize();
|
||||
|
||||
self::assertSame(
|
||||
[$newElementThatIsAlsoPersisted, $persistedElement, $newElement],
|
||||
$this->collection->toArray()
|
||||
);
|
||||
self::assertTrue($this->collection->isInitialized());
|
||||
self::assertTrue($this->collection->isDirty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6613
|
||||
* @group 6614
|
||||
* @group 6616
|
||||
*/
|
||||
public function testWillNotMarkCollectionAsDirtyAfterInitializationIfNoElementsWereAdded()
|
||||
{
|
||||
/* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */
|
||||
$unitOfWork = $this
|
||||
->getMockBuilder('Doctrine\ORM\UnitOfWork')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$this->_emMock->setUnitOfWork($unitOfWork);
|
||||
|
||||
$newElementThatIsAlsoPersisted = new \stdClass();
|
||||
$persistedElement = new \stdClass();
|
||||
|
||||
$this->collection->add($newElementThatIsAlsoPersisted);
|
||||
|
||||
self::assertFalse($this->collection->isInitialized());
|
||||
self::assertTrue($this->collection->isDirty());
|
||||
|
||||
$unitOfWork
|
||||
->expects(self::once())
|
||||
->method('loadCollection')
|
||||
->with($this->collection)
|
||||
->willReturnCallback(function (PersistentCollection $persistentCollection) use (
|
||||
$persistedElement,
|
||||
$newElementThatIsAlsoPersisted
|
||||
) {
|
||||
$persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted);
|
||||
$persistentCollection->unwrap()->add($persistedElement);
|
||||
});
|
||||
|
||||
$this->collection->initialize();
|
||||
|
||||
self::assertSame(
|
||||
[$newElementThatIsAlsoPersisted, $persistedElement],
|
||||
$this->collection->toArray()
|
||||
);
|
||||
self::assertTrue($this->collection->isInitialized());
|
||||
self::assertFalse($this->collection->isDirty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,33 @@ class ProxyFactoryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$proxy->getDescription();
|
||||
}
|
||||
|
||||
public function testSkipMappedSuperClassesOnGeneration()
|
||||
{
|
||||
$cm = new ClassMetadata('stdClass');
|
||||
$cm->isMappedSuperclass = true;
|
||||
|
||||
self::assertSame(
|
||||
0,
|
||||
$this->proxyFactory->generateProxyClasses([$cm]),
|
||||
'No proxies generated.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6625
|
||||
*/
|
||||
public function testSkipEmbeddableClassesOnGeneration()
|
||||
{
|
||||
$cm = new ClassMetadata('stdClass');
|
||||
$cm->isEmbeddedClass = true;
|
||||
|
||||
self::assertSame(
|
||||
0,
|
||||
$this->proxyFactory->generateProxyClasses([$cm]),
|
||||
'No proxies generated.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1771
|
||||
*/
|
||||
|
||||
@@ -197,4 +197,66 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
|
||||
$q2 = clone $query;
|
||||
$this->assertSame($config->getDefaultQueryHints(), $q2->getHints());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testGetParameterTypeJuggling()
|
||||
{
|
||||
$query = $this->_em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id = ?0');
|
||||
|
||||
$query->setParameter(0, 0);
|
||||
|
||||
self::assertCount(1, $query->getParameters());
|
||||
self::assertSame(0, $query->getParameter(0)->getValue());
|
||||
self::assertSame(0, $query->getParameter('0')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithNameZeroIsNotOverridden()
|
||||
{
|
||||
$query = $this->_em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id != ?0 and u.username = :name');
|
||||
|
||||
$query->setParameter(0, 0);
|
||||
$query->setParameter('name', 'Doctrine');
|
||||
|
||||
self::assertCount(2, $query->getParameters());
|
||||
self::assertSame(0, $query->getParameter('0')->getValue());
|
||||
self::assertSame('Doctrine', $query->getParameter('name')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter()
|
||||
{
|
||||
$query = $this->_em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id != ?0 and u.username = :name');
|
||||
|
||||
$query->setParameter('name', 'Doctrine');
|
||||
$query->setParameter(0, 0);
|
||||
|
||||
self::assertCount(2, $query->getParameters());
|
||||
self::assertSame(0, $query->getParameter(0)->getValue());
|
||||
self::assertSame('Doctrine', $query->getParameter('name')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithTypeJugglingWorks()
|
||||
{
|
||||
$query = $this->_em->createQuery('select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id != ?0 and u.username = :name');
|
||||
|
||||
$query->setParameter('0', 1);
|
||||
$query->setParameter('name', 'Doctrine');
|
||||
$query->setParameter(0, 2);
|
||||
$query->setParameter('0', 3);
|
||||
|
||||
self::assertCount(2, $query->getParameters());
|
||||
self::assertSame(3, $query->getParameter(0)->getValue());
|
||||
self::assertSame(3, $query->getParameter('0')->getValue());
|
||||
self::assertSame('Doctrine', $query->getParameter('name')->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,12 +153,12 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
$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 id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id AND (c0_.id = c3_.id)'
|
||||
'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id INNER JOIN (company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id) ON (c0_.id = c3_.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 id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id ON (c0_.id = c3_.id)'
|
||||
'SELECT c0_.id AS id_0, c0_.name AS name_1, c1_.salary AS salary_2, c1_.department AS department_3, c1_.startDate AS startDate_4, c0_.discr AS discr_5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN (company_managers c2_ INNER JOIN company_employees c4_ ON c2_.id = c4_.id INNER JOIN company_persons c3_ ON c2_.id = c3_.id) ON (c0_.id = c3_.id)'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2165,7 +2165,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
// the where clause when not joining onto that table
|
||||
$this->assertSqlGeneration(
|
||||
'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c LEFT JOIN Doctrine\Tests\Models\Company\CompanyEmployee e WITH e.id = c.salesPerson WHERE c.completed = true',
|
||||
"SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_contracts c0_ LEFT JOIN company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id ON (c2_.id = c0_.salesPerson_id) WHERE (c0_.completed = 1) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
|
||||
"SELECT c0_.id AS id_0, c0_.completed AS completed_1, c0_.fixPrice AS fixPrice_2, c0_.hoursWorked AS hoursWorked_3, c0_.pricePerHour AS pricePerHour_4, c0_.maxPrice AS maxPrice_5, c0_.discr AS discr_6 FROM company_contracts c0_ LEFT JOIN (company_employees c1_ INNER JOIN company_persons c2_ ON c1_.id = c2_.id) ON (c2_.id = c0_.salesPerson_id) WHERE (c0_.completed = 1) AND c0_.discr IN ('fix', 'flexible', 'flexultra')"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1172,4 +1172,81 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals(['u', 'g'], $aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testGetParameterTypeJuggling()
|
||||
{
|
||||
$builder = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id = ?0');
|
||||
|
||||
$builder->setParameter(0, 0);
|
||||
|
||||
self::assertCount(1, $builder->getParameters());
|
||||
self::assertSame(0, $builder->getParameter(0)->getValue());
|
||||
self::assertSame(0, $builder->getParameter('0')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithNameZeroIsNotOverridden()
|
||||
{
|
||||
$builder = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id != ?0')
|
||||
->andWhere('u.username = :name');
|
||||
|
||||
$builder->setParameter(0, 0);
|
||||
$builder->setParameter('name', 'Doctrine');
|
||||
|
||||
self::assertCount(2, $builder->getParameters());
|
||||
self::assertSame(0, $builder->getParameter('0')->getValue());
|
||||
self::assertSame('Doctrine', $builder->getParameter('name')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter()
|
||||
{
|
||||
$builder = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id != ?0')
|
||||
->andWhere('u.username = :name');
|
||||
|
||||
$builder->setParameter('name', 'Doctrine');
|
||||
$builder->setParameter(0, 0);
|
||||
|
||||
self::assertCount(2, $builder->getParameters());
|
||||
self::assertSame(0, $builder->getParameter(0)->getValue());
|
||||
self::assertSame('Doctrine', $builder->getParameter('name')->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 6699
|
||||
*/
|
||||
public function testSetParameterWithTypeJugglingWorks()
|
||||
{
|
||||
$builder = $this->_em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
|
||||
->where('u.id != ?0')
|
||||
->andWhere('u.username = :name');
|
||||
|
||||
$builder->setParameter('0', 1);
|
||||
$builder->setParameter('name', 'Doctrine');
|
||||
$builder->setParameter(0, 2);
|
||||
$builder->setParameter('0', 3);
|
||||
|
||||
self::assertCount(2, $builder->getParameters());
|
||||
self::assertSame(3, $builder->getParameter(0)->getValue());
|
||||
self::assertSame(3, $builder->getParameter('0')->getValue());
|
||||
self::assertSame('Doctrine', $builder->getParameter('name')->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Tools\Console;
|
||||
|
||||
use Doctrine\ORM\Tools\Console\MetadataFilter;
|
||||
use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
|
||||
|
||||
/**
|
||||
* Tests for {@see \Doctrine\ORM\Tools\Console\MetadataFilter}
|
||||
*
|
||||
* @covers \Doctrine\ORM\Tools\Console\MetadataFilter
|
||||
*/
|
||||
class MetadataFilterTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
/**
|
||||
* @var DisconnectedClassMetadataFactory
|
||||
*/
|
||||
private $cmf;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$driver = $this->createAnnotationDriver();
|
||||
$em = $this->_getTestEntityManager();
|
||||
$em->getConfiguration()->setMetadataDriverImpl($driver);
|
||||
|
||||
$this->cmf = new DisconnectedClassMetadataFactory();
|
||||
$this->cmf->setEntityManager($em);
|
||||
}
|
||||
|
||||
public function testFilterWithEmptyArray()
|
||||
{
|
||||
$originalMetadatas = array(
|
||||
$metadataAaa = $this->cmf->getMetadataFor(MetadataFilterTestEntityAaa::CLASSNAME),
|
||||
$metadataBbb = $this->cmf->getMetadataFor(MetadataFilterTestEntityBbb::CLASSNAME),
|
||||
);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, array());
|
||||
|
||||
$this->assertContains($metadataAaa, $metadatas);
|
||||
$this->assertContains($metadataBbb, $metadatas);
|
||||
$this->assertCount(count($originalMetadatas), $metadatas);
|
||||
}
|
||||
|
||||
public function testFilterWithString()
|
||||
{
|
||||
$originalMetadatas = array(
|
||||
$metadataAaa = $this->cmf->getMetadataFor(MetadataFilterTestEntityAaa::CLASSNAME),
|
||||
$metadataBbb = $this->cmf->getMetadataFor(MetadataFilterTestEntityBbb::CLASSNAME),
|
||||
$metadataCcc = $this->cmf->getMetadataFor(MetadataFilterTestEntityCcc::CLASSNAME),
|
||||
);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'MetadataFilterTestEntityAaa');
|
||||
|
||||
$this->assertContains($metadataAaa, $metadatas);
|
||||
$this->assertNotContains($metadataBbb, $metadatas);
|
||||
$this->assertNotContains($metadataCcc, $metadatas);
|
||||
$this->assertCount(1, $metadatas);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'MetadataFilterTestEntityBbb');
|
||||
|
||||
$this->assertNotContains($metadataAaa, $metadatas);
|
||||
$this->assertContains($metadataBbb, $metadatas);
|
||||
$this->assertNotContains($metadataCcc, $metadatas);
|
||||
$this->assertCount(1, $metadatas);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'MetadataFilterTestEntityCcc');
|
||||
|
||||
$this->assertNotContains($metadataAaa, $metadatas);
|
||||
$this->assertNotContains($metadataBbb, $metadatas);
|
||||
$this->assertContains($metadataCcc, $metadatas);
|
||||
$this->assertCount(1, $metadatas);
|
||||
}
|
||||
|
||||
public function testFilterWithString2()
|
||||
{
|
||||
$originalMetadatas = array(
|
||||
$metadataFoo = $this->cmf->getMetadataFor(MetadataFilterTestEntityFoo::CLASSNAME),
|
||||
$metadataFooBar = $this->cmf->getMetadataFor(MetadataFilterTestEntityFooBar::CLASSNAME),
|
||||
$metadataBar = $this->cmf->getMetadataFor(MetadataFilterTestEntityBar::CLASSNAME),
|
||||
);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'MetadataFilterTestEntityFoo');
|
||||
|
||||
$this->assertContains($metadataFoo, $metadatas);
|
||||
$this->assertContains($metadataFooBar, $metadatas);
|
||||
$this->assertNotContains($metadataBar, $metadatas);
|
||||
$this->assertCount(2, $metadatas);
|
||||
}
|
||||
|
||||
public function testFilterWithArray()
|
||||
{
|
||||
$originalMetadatas = array(
|
||||
$metadataAaa = $this->cmf->getMetadataFor(MetadataFilterTestEntityAaa::CLASSNAME),
|
||||
$metadataBbb = $this->cmf->getMetadataFor(MetadataFilterTestEntityBbb::CLASSNAME),
|
||||
$metadataCcc = $this->cmf->getMetadataFor(MetadataFilterTestEntityCcc::CLASSNAME),
|
||||
);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, array(
|
||||
'MetadataFilterTestEntityAaa',
|
||||
'MetadataFilterTestEntityCcc',
|
||||
));
|
||||
|
||||
$this->assertContains($metadataAaa, $metadatas);
|
||||
$this->assertNotContains($metadataBbb, $metadatas);
|
||||
$this->assertContains($metadataCcc, $metadatas);
|
||||
$this->assertCount(2, $metadatas);
|
||||
}
|
||||
|
||||
public function testFilterWithRegex()
|
||||
{
|
||||
$originalMetadatas = array(
|
||||
$metadataFoo = $this->cmf->getMetadataFor(MetadataFilterTestEntityFoo::CLASSNAME),
|
||||
$metadataFooBar = $this->cmf->getMetadataFor(MetadataFilterTestEntityFooBar::CLASSNAME),
|
||||
$metadataBar = $this->cmf->getMetadataFor(MetadataFilterTestEntityBar::CLASSNAME),
|
||||
);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'Foo$');
|
||||
|
||||
$this->assertContains($metadataFoo, $metadatas);
|
||||
$this->assertNotContains($metadataFooBar, $metadatas);
|
||||
$this->assertNotContains($metadataBar, $metadatas);
|
||||
$this->assertCount(1, $metadatas);
|
||||
|
||||
$metadatas = $originalMetadatas;
|
||||
$metadatas = MetadataFilter::filter($metadatas, 'Bar$');
|
||||
|
||||
$this->assertNotContains($metadataFoo, $metadatas);
|
||||
$this->assertContains($metadataFooBar, $metadatas);
|
||||
$this->assertContains($metadataBar, $metadatas);
|
||||
$this->assertCount(2, $metadatas);
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityAaa
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityBbb
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityCcc
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityFoo
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityBar
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class MetadataFilterTestEntityFooBar
|
||||
{
|
||||
const CLASSNAME = __CLASS__;
|
||||
|
||||
/** @Id @Column(type="integer") */
|
||||
protected $id;
|
||||
}
|
||||
@@ -30,6 +30,18 @@ class CountOutputWalkerTest extends PaginationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountQuery_GroupBy()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p.name FROM Doctrine\Tests\ORM\Tools\Pagination\Person p GROUP BY p.name');
|
||||
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker');
|
||||
$query->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
$this->assertSame(
|
||||
"SELECT COUNT(*) AS dctrn_count FROM (SELECT p0_.name AS name_0 FROM Person p0_ GROUP BY p0_.name) dctrn_table", $query->getSQL()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountQuery_Having()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
@@ -37,8 +49,8 @@ class CountOutputWalkerTest extends PaginationTestCase
|
||||
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker');
|
||||
$query->setFirstResult(null)->setMaxResults(null);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT COUNT(*) AS dctrn_count FROM (SELECT DISTINCT id_1 FROM (SELECT count(u0_.id) AS sclr_0, g1_.id AS id_1, u0_.id AS id_2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr_0 > 0) dctrn_result) dctrn_table", $query->getSql()
|
||||
$this->assertSame(
|
||||
"SELECT COUNT(*) AS dctrn_count FROM (SELECT count(u0_.id) AS sclr_0, g1_.id AS id_1, u0_.id AS id_2 FROM groups g1_ LEFT JOIN user_group u2_ ON g1_.id = u2_.group_id LEFT JOIN User u0_ ON u0_.id = u2_.user_id GROUP BY g1_.id HAVING sclr_0 > 0) dctrn_table", $query->getSQL()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
namespace Doctrine\Tests\ORM\Tools;
|
||||
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
|
||||
use Doctrine\ORM\Tools\SchemaTool;
|
||||
use Doctrine\ORM\Tools\ToolEvents;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs;
|
||||
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs;
|
||||
|
||||
class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
|
||||
{
|
||||
@@ -138,6 +139,26 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertTrue($table->hasIndex('primary'));
|
||||
$this->assertTrue($table->hasIndex('uniq_hash'));
|
||||
}
|
||||
|
||||
public function testSetDiscriminatorColumnWithoutLength()
|
||||
{
|
||||
$em = $this->_getTestEntityManager();
|
||||
$schemaTool = new SchemaTool($em);
|
||||
$metadata = $em->getClassMetadata(__NAMESPACE__ . '\\FirstEntity');
|
||||
|
||||
$metadata->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE);
|
||||
$metadata->setDiscriminatorColumn(['name' => 'discriminator', 'type' => 'string']);
|
||||
|
||||
$schema = $schemaTool->getSchemaFromMetadata([$metadata]);
|
||||
|
||||
$this->assertTrue($schema->hasTable('first_entity'));
|
||||
$table = $schema->getTable('first_entity');
|
||||
|
||||
$this->assertTrue($table->hasColumn('discriminator'));
|
||||
$column = $table->getColumn('discriminator');
|
||||
|
||||
$this->assertEquals(255, $column->getLength());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,3 +208,45 @@ class UniqueConstraintAnnotationModel
|
||||
*/
|
||||
private $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="first_entity")
|
||||
*/
|
||||
class FirstEntity
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(name="id")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @OneToOne(targetEntity="SecondEntity")
|
||||
* @JoinColumn(name="id", referencedColumnName="fist_entity_id")
|
||||
*/
|
||||
public $secondEntity;
|
||||
|
||||
/**
|
||||
* @Column(name="name")
|
||||
*/
|
||||
public $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="second_entity")
|
||||
*/
|
||||
class SecondEntity
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(name="fist_entity_id")
|
||||
*/
|
||||
public $fist_entity_id;
|
||||
|
||||
/**
|
||||
* @Column(name="name")
|
||||
*/
|
||||
public $name;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,43 @@ class SetupTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\YamlDriver', $config->getMetadataDriverImpl());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 5904
|
||||
*/
|
||||
public function testCacheNamespaceShouldBeGeneratedWhenCacheIsNotGiven()
|
||||
{
|
||||
$config = Setup::createConfiguration(false, '/foo');
|
||||
$cache = $config->getMetadataCacheImpl();
|
||||
|
||||
self::assertSame('dc2_1effb2475fcfba4f9e8b8a1dbc8f3caf_', $cache->getNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 5904
|
||||
*/
|
||||
public function testCacheNamespaceShouldBeGeneratedWhenCacheIsGivenButHasNoNamespace()
|
||||
{
|
||||
$config = Setup::createConfiguration(false, '/foo', new ArrayCache());
|
||||
$cache = $config->getMetadataCacheImpl();
|
||||
|
||||
self::assertSame('dc2_1effb2475fcfba4f9e8b8a1dbc8f3caf_', $cache->getNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group 5904
|
||||
*/
|
||||
public function testConfiguredCacheNamespaceShouldBeUsedAsPrefixOfGeneratedNamespace()
|
||||
{
|
||||
$originalCache = new ArrayCache();
|
||||
$originalCache->setNamespace('foo');
|
||||
|
||||
$config = Setup::createConfiguration(false, '/foo', $originalCache);
|
||||
$cache = $config->getMetadataCacheImpl();
|
||||
|
||||
self::assertSame($originalCache, $cache);
|
||||
self::assertSame('foo:dc2_1effb2475fcfba4f9e8b8a1dbc8f3caf_', $cache->getNamespace());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1350
|
||||
*/
|
||||
@@ -98,7 +135,7 @@ class SetupTest extends \Doctrine\Tests\OrmTestCase
|
||||
$cache = $this->getMock('Doctrine\Common\Cache\Cache');
|
||||
$cache->expects($this->never())->method('setNamespace');
|
||||
|
||||
$config = Setup::createConfiguration(array(), true, $cache);
|
||||
$config = Setup::createConfiguration(true, null, $cache);
|
||||
|
||||
$this->assertSame($cache, $config->getResultCacheImpl());
|
||||
$this->assertSame($cache, $config->getMetadataCacheImpl());
|
||||
|
||||
@@ -309,6 +309,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
|
||||
protected function tearDown()
|
||||
{
|
||||
$conn = static::$_sharedConn;
|
||||
|
||||
// In case test is skipped, tearDown is called, but no setup may have run
|
||||
if ( ! $conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
$platform = $conn->getDatabasePlatform();
|
||||
|
||||
$this->_sqlLoggerStack->enabled = false;
|
||||
|
||||
Reference in New Issue
Block a user