Compare commits

..

91 Commits
2.3.0 ... 2.3.2

Author SHA1 Message Date
Benjamin Eberlei
c5725dd6bb Release 2.3.2 2013-01-07 21:05:04 +01:00
Benjamin Eberlei
b59cd047ff Bump submodule of DBAL to 2.3.2 2013-01-07 21:04:49 +01:00
Benjamin Eberlei
019094655b Merge branch 'DDC-2175' into 2.3 2012-12-24 11:18:12 +01:00
Benjamin Eberlei
88e817660c [DDC-2175] Fix bug in JoinedSubclassPersister 2012-12-24 11:14:18 +01:00
Benjamin Eberlei
aee75d8f25 Merge branch '2.3' of github.com:doctrine/doctrine2 into 2.3 2012-12-23 20:34:54 +01:00
Benjamin Eberlei
50132ddc18 Merge branch 'DDC-2206' into 2.3 2012-12-23 20:34:14 +01:00
Benjamin Eberlei
f05bcbc17c [DDC-2206] Fix Setup::registerAutoloadPEAR() to work with Symfony namespaces from top PEAR directory 2012-12-23 20:33:21 +01:00
Benjamin Eberlei
f94b6c07c7 Fix MySQL test 2012-12-22 21:50:42 +01:00
Benjamin Eberlei
b68c6b3d2d Merge branch 'DDC-1690' into 2.3 2012-12-22 12:46:06 +01:00
Patrick Schwisow
0425e8452d [DDC-1690] Added an empty line as requested. 2012-12-22 12:37:03 +01:00
Patrick Schwisow
c120700d89 [DDC-1690] Created unit test 2012-12-22 12:37:02 +01:00
Patrick Schwisow
22dc20c320 Fix DDC-1690
Added the lines suggested by the original reporter.
2012-12-22 12:37:02 +01:00
Benjamin Eberlei
6d89875306 Merge remote-tracking branch 'origin/2.3' into 2.3 2012-12-16 13:00:27 +01:00
Benjamin Eberlei
b666a62979 Merge branch 'DDC-2199' into 2.3 2012-12-16 12:58:46 +01:00
Benjamin Eberlei
f2f8c4f2dd DDC-2199 / DDC-2192 - Versioned fields didnt work in XML/YAML mapping 2012-12-16 12:58:17 +01:00
Benjamin Eberlei
59aef2ca95 Bump dev version to 2.3.2 2012-12-04 23:04:25 +01:00
Benjamin Eberlei
173b398b34 Release 2.3.1 2012-12-04 23:04:25 +01:00
Benjamin Eberlei
de22e726a4 Update DBAL dependency 2012-12-04 22:10:45 +01:00
Benjamin Eberlei
dab2b505a4 Merge branch 'DDC-2182' into 2.3 2012-12-04 21:59:56 +01:00
Francis Besset
0672688088 Passed column options to the join column 2012-12-04 21:58:58 +01:00
Francis Besset
660f89f745 Fixed trailing spaces on SchemaTool 2012-12-04 21:57:41 +01:00
Francis Besset
e0aa01ddb6 Fixed typo 2012-12-04 21:55:47 +01:00
Benjamin Eberlei
287b29aeaa Merge branch 'DDC-2156' into 2.3 2012-11-27 22:26:17 +01:00
Benjamin Eberlei
86132283f1 Clarify BC break in DDC-2156 2012-11-27 22:26:09 +01:00
Benjamin Eberlei
f75c3b517d Merge branch 'DDC-2172' into 2.3 2012-11-27 21:57:14 +01:00
Fabio B. Silva
6e7e4dd35a Fix CS 2012-11-27 21:56:32 +01:00
Fabio B. Silva
faedbfc09a refactoring tests 2012-11-27 21:56:32 +01:00
Fabio B. Silva
45269fe4f2 Fix DDC-2172 2012-11-27 21:56:32 +01:00
Benjamin Eberlei
a3fea32e0e Merge branch 'DDC-2074' into 2.3 2012-11-25 20:16:21 +01:00
Jan Kramer
c90ed73b33 [DDC-2074] Fixed bug regarding clearing PC's without owner
When calling clear on a PC that has no owner (e.g. because it was
cloned), it can't be deleted as there is no metadata available.
In these cases, it shouldn't be scheduled for deletion.
2012-11-25 20:15:57 +01:00
Jan Kramer
83943e86a2 [DDC-2074] Added test for PersistentCollection#clear. 2012-11-25 20:15:57 +01:00
Benjamin Eberlei
1aab5feb4a Merge branch 'DDC-2158' into 2.3 2012-11-25 12:34:47 +01:00
Francisco Facioni
469bd02b41 added outer left join 2012-11-25 12:28:38 +01:00
Francisco Facioni
24f74bc935 regression fix for left joins (double ON) 2012-11-25 12:28:38 +01:00
Benjamin Eberlei
77d060ab74 Merge branch 'DDC-2109' into 2.3 2012-11-12 15:49:41 +01:00
Benjamin Eberlei
01148e52f3 [DDC-2109] Fix bug with ResolveTargetEntityListener and ManyToMany associations. 2012-11-12 15:49:31 +01:00
Benjamin Eberlei
5756021571 Merge branch 'DDC-1958' into 2.3 2012-11-12 15:42:38 +01:00
Miha Vrhovnik
006d3833f6 extracted pgsql sql generation into a helper method 2012-11-12 15:04:15 +01:00
Miha Vrhovnik
8865a5b90d The distinct query should replicate the fields in order by clause and the order by clause itself from inner query
This fixes DDC-1958
2012-11-12 15:04:15 +01:00
Benjamin Eberlei
d0698754b2 Merge branch 'DDC-2071' into 2.3 2012-11-12 12:32:57 +01:00
HarmenM
4ea7a5dde4 Modified the WhereInWalkerTest to be compatible with a single InputParameter. 2012-11-12 12:30:48 +01:00
HarmenM
ed11e61812 Update lib/Doctrine/ORM/Tools/Pagination/Paginator.php
Replaced the foreach loop adding all IDs as single parameters with a single parameter which injects the IDs as an array.
2012-11-12 12:30:48 +01:00
HarmenM
e7e69daabe Update lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php
replaced the for-loop which adds the InputParameters for a single InputParameter for use with an array instead of a set of scalars.
2012-11-12 12:30:47 +01:00
Benjamin Eberlei
c6eb04de14 Merge branch 'DDC-2079' into 2.3 2012-11-09 22:16:44 +01:00
Fabio B. Silva
8c2009c67e Fix typo 2012-11-09 22:15:41 +01:00
Fabio B. Silva
a7ed9e638b Fix DDC-2079 2012-11-09 22:15:41 +01:00
Benjamin Eberlei
643ed0b8f5 Merge branch 'DDC-2069' into 2.3 2012-11-09 22:12:08 +01:00
Fabio B. Silva
57db88b62a Fix DDC-2069 2012-11-09 22:11:27 +01:00
Benjamin Eberlei
3c944b34ca Merge branch 'DDC-2086' into 2.3 2012-11-09 22:09:53 +01:00
Jasper N. Brouwer
1618a3e393 Added testcase for DDC-2086 2012-11-09 22:09:10 +01:00
Jasper N. Brouwer
a1094d352c Prevented "Undefined index" notice when updating
While executing updates on an entity scheduled for update without
a change-set, an "Undefined index" notice is raised.
2012-11-09 22:09:10 +01:00
Benjamin Eberlei
e4ef9e03ae Merge branch 'DDC-2082' into 2.3 2012-11-09 22:02:00 +01:00
justin.randell
a3c98b1087 check for false as a return value from get_parent_class(), not null 2012-11-09 22:01:00 +01:00
Benjamin Eberlei
2ce877bf8a Merge branch 'DDC-2113' into 2.3 2012-11-09 21:56:56 +01:00
Vaughn Clayton
6d35fad70f [DDC-2113] Surround WHERE clause with parens if using SQLFilter 2012-11-09 21:56:12 +01:00
Benjamin Eberlei
612ed2b3a2 Merge branch 'DDC-2116' into 2.3 2012-11-09 21:54:19 +01:00
Markus Lanthaler
95a85d67ea Improve DocBlock annotations of generated entities
Currently, the DocBlock annotations for member variables contain the variable name as description which is redundant and should be removed. Furthermore the class is annotated with the FQN instead of just the name. This makes automatically generated documentation quite ugly.
2012-11-09 21:53:34 +01:00
Benjamin Eberlei
edaab11a86 Merge branch 'DDC-2115' into 2.3 2012-11-09 21:47:42 +01:00
TR
1627c974b9 Update lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
coding standards change
2012-11-09 21:47:01 +01:00
TR
c6118cb045 refactoring getIndividualValue for valid key value
refactoring getIndividualValue
2012-11-09 21:47:01 +01:00
TR
461d201e40 notice is thrown up if no identifier values found
wrapping the setting of value with an array_key_exists to prevent a notice from being thrown
2012-11-09 21:47:00 +01:00
Benjamin Eberlei
653aef2c83 Merge branch 'DDC-2122' into 2.3 2012-11-09 21:41:49 +01:00
Jeremy Marc
045d058cec Compare to null instead of using isset 2012-11-09 21:41:02 +01:00
Jeremy Marc
9dbf4d8480 Allow 0 id for Entity
When using a 0 id, it's throwing InvalidArgumentException (Binding entities to query parameters only allowed for entities that have an identifier.)
2012-11-09 21:41:02 +01:00
Benjamin Eberlei
2229a5e4c6 Merge branch 'DDC-2123' into 2.3 2012-11-09 21:33:51 +01:00
Gordon Stratton
bbf092c6fd Fix for invalid 'double-ON' SQL generation with entity inheritance type JOINED.
In SqlWalker::walkJoin(), SqlWalker::walkRangeVariableDeclaration() can be
called which may produce an 'ON' clause if the entity inheritance type is
JOINED. As walkJoin() may then produce another ON clause, this results in
invalid SQL (e.g. '... ON foo = bar ON (baz = quux) ...' when the inheritance
type is JOINED.

This adds a test and a fix for the problem, by checking for an inheritance type
of JOINED in walkJoin() and using AND instead of ON in the appropriate place.

It seems like this part of the code is begging to be refactored. This is my
first foray into Doctrine internals and can't see a way to do this without
stomping all over the rest of the code, but this section seems ripe for cleanup
by somebody who is familiar.
2012-11-09 21:32:52 +01:00
Benjamin Eberlei
6fee945fda Merge branch 'DDC-1241' into 2.3 2012-11-09 21:30:17 +01:00
nemekzg
974f18da0c Proposed fix for DDC-1241 2012-11-09 21:29:37 +01:00
Benjamin Eberlei
9b198be070 Merge branch 'DDC-2126' into 2.3 2012-11-09 21:03:42 +01:00
Benjamin Morel
b610855248 Fixed errors:
- Typo in variable name in JoinClassPathExpression;
 - Undefined class AST\ArithmeticPrimary (x2);
 - QueryException::invalidPathExpression() expects a PathExpression, not a string.
2012-11-09 21:02:55 +01:00
Benjamin Eberlei
994917aa23 Merge branch 'DDC-2121' into 2.3 2012-11-09 20:56:07 +01:00
Fabio B. Silva
d64be2888e Fix DDC-2121 2012-11-09 20:55:15 +01:00
Benjamin Eberlei
737e47e155 Merge branch 'DDC-2073' into 2.3 2012-11-09 20:45:35 +01:00
Matthieu Napoli
ef4ff8be81 Fix and test for DDC-2073 2012-11-09 20:44:12 +01:00
Matthieu Napoli
b53c81ae8d Fix and test for DDC-2073 2012-11-09 20:44:12 +01:00
Benjamin Eberlei
6bad010959 Merge branch 'DDC-2067' into 2.3 2012-10-12 21:49:45 +02:00
Benjamin Eberlei
26cfbdd08b [DDC-2067] Refactor and fix bug in boolean evaluation inside XML Driver. 2012-10-12 21:49:35 +02:00
Benjamin Eberlei
e8412b85df Merge branch 'DDC-2068' into 2.3 2012-10-12 20:36:29 +02:00
Oleksandr Kovalov
2e5d7416d8 Fixed bug with comment option not being added to column. 2012-10-12 20:36:18 +02:00
jakoch
1988944e7e fix typo 2012-10-12 20:31:16 +02:00
Benjamin Eberlei
564ec1ee2a Merge branch 'DDC-2028' into 2.3 2012-10-05 23:20:05 +02:00
Asmir Mustafic
cb0cddef83 spaces 2012-10-05 23:19:55 +02:00
Asmir Mustafic
8b2c92a6bd typo fix 2012-10-05 23:19:55 +02:00
Benjamin Eberlei
825a68bcba Merge branch 'DDC-2044' into 2.3 2012-10-05 20:25:31 +02:00
Marcin Radziwoński
abd11374ee Fixed unique-constraint name in XML Exporter 2012-10-05 20:24:46 +02:00
Benjamin Eberlei
518357d987 Merge branch 'DDC-2059' into 2.3 2012-10-05 20:06:06 +02:00
Benjamin Eberlei
4109f22000 [DDC-2059] Fix column and foreign key interfering with each other during reverse engineering. 2012-10-05 20:04:42 +02:00
Fabio B. Silva
c60e6523e9 Fix test case 2012-10-04 19:58:30 +02:00
Benjamin Eberlei
04262e2b73 Merge branch 'DDC-2012' into 2.3 2012-10-03 12:48:22 +02:00
Fabio B. Silva
084101e287 Fix DDC-2012 2012-10-03 12:47:38 +02:00
Benjamin Eberlei
ea2b288578 Bump dev version to 2.3.1 2012-09-20 08:03:35 +02:00
49 changed files with 1137 additions and 138 deletions

View File

@@ -1,5 +1,13 @@
# Upgrade to 2.3
## EntityManager#find() not calls EntityRepository#find() anymore
Previous to 2.3, calling ``EntityManager#find()`` would be delegated to
``EntityRepository#find()``. This has lead to some unexpected behavior in the
core of Doctrine when people have overwritten the find method in their
repositories. That is why this behavior has been reversed in 2.3, and
``EntityRepository#find()`` calls ``EntityManager#find()`` instead.
## EntityGenerator add*() method generation
When generating an add*() method for a collection the EntityGenerator will now not

View File

@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
"type": "library","version":"2.3.0",
"type": "library","version":"2.3.2",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",

View File

@@ -281,7 +281,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."
);

View File

@@ -161,13 +161,14 @@ class EntityRepository implements ObjectRepository, Selectable
* Finds a single entity by a set of criteria.
*
* @param array $criteria
* @param array|null $orderBy
* @return object
*/
public function findOneBy(array $criteria)
public function findOneBy(array $criteria, array $orderBy = null)
{
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->load($criteria, null, null, array(), 0, 1);
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
}
/**
@@ -215,7 +216,7 @@ class EntityRepository implements ObjectRepository, Selectable
case 3:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
case 4;
case 4:
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
default:

View File

@@ -1478,6 +1478,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']);

View File

@@ -297,6 +297,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;
}

View File

@@ -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,27 @@ class XmlDriver extends FileDriver
if (isset($xmlRoot->field)) {
foreach ($xmlRoot->field as $fieldMapping) {
$mapping = $this->columnToArray($fieldMapping);
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$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 +343,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 +368,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 +442,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 +603,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,11 +654,11 @@ 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']) {
@@ -710,4 +719,12 @@ class XmlDriver extends FileDriver
return $result;
}
protected function evaluateBoolean($element)
{
$flag = (string)$element;
return ($flag === true || $flag == "true" || $flag == "1");
}
}

View File

@@ -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,10 @@ class YamlDriver extends FileDriver
}
}
if (isset($mapping['version'])) {
$metadata->setVersionMapping($mapping);
}
$metadata->mapField($mapping);
}
}
@@ -628,7 +634,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);
}
}

View File

@@ -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

View File

@@ -655,7 +655,7 @@ final class PersistentCollection implements Collection, Selectable
$this->initialized = true; // direct call, {@link initialize()} is too expensive
if ($this->association['isOwningSide']) {
if ($this->association['isOwningSide'] && $this->owner) {
$this->changed();
$uow->scheduleCollectionDeletion($this);

View File

@@ -88,7 +88,7 @@ class BasicEntityPersister
*/
static private $comparisonMap = array(
Comparison::EQ => '= %s',
Comparison::IS => '= %s',
Comparison::IS => 'IS %s',
Comparison::NEQ => '!= %s',
Comparison::GT => '> %s',
Comparison::GTE => '>= %s',
@@ -659,12 +659,13 @@ class BasicEntityPersister
* @param array $hints Hints for entity creation.
* @param int $lockMode
* @param int $limit Limit number of results
* @param array $orderBy Criteria to order by
* @return object The loaded and managed entity instance or NULL if the entity can not be found.
* @todo Check identity map? loadById method? Try to guess whether $criteria is the id?
*/
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null)
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0, $limit = null, array $orderBy = null)
{
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit);
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode, $limit, null, $orderBy);
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
@@ -1699,7 +1700,11 @@ class BasicEntityPersister
$idValues = $class->getIdentifierValues($value);
}
$value = $idValues[key($idValues)];
$key = key($idValues);
if (null !== $key){
$value = $idValues[$key];
}
}
return $value;

View File

@@ -227,8 +227,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// Make sure the table with the version column is updated even if no columns on that
// table were affected.
if ($isVersioned && ! isset($updateData[$versionedTable])) {
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
if ($isVersioned) {
if ( ! isset($updateData[$versionedTable])) {
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
}
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->assignDefaultVersionValue($entity, $id);
@@ -468,7 +470,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
} else if ($this->_class->name != $this->_class->rootEntityName ||
! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
}
}

View File

@@ -40,6 +40,6 @@ class JoinClassPathExpression extends Node
public function dispatch($walker)
{
return $sqlWalker->walkJoinPathExpression($this);
return $walker->walkJoinPathExpression($this);
}
}

View File

@@ -1007,8 +1007,13 @@ class SqlWalker implements TreeWalker
switch (true) {
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\RangeVariableDeclaration):
$class = $this->em->getClassMetadata($joinDeclaration->abstractSchemaName);
$condExprConjunction = $class->isInheritanceTypeJoined() && $joinType != AST\Join::JOIN_TYPE_LEFT && $joinType != AST\Join::JOIN_TYPE_LEFTOUTER
? ' AND '
: ' ON ';
$sql .= $this->walkRangeVariableDeclaration($joinDeclaration)
. ' ON (' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
. $condExprConjunction . '(' . $this->walkConditionalExpression($join->conditionalExpression) . ')';
break;
case ($joinDeclaration instanceof \Doctrine\ORM\Query\AST\JoinAssociationDeclaration):
@@ -1147,7 +1152,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 +1193,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):
@@ -1422,7 +1426,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 +1612,7 @@ class SqlWalker implements TreeWalker
if (count($filterClauses)) {
if ($condSql) {
$condSql .= ' AND ';
$condSql = '(' . $condSql . ') AND ';
}
$condSql .= implode(' AND ', $filterClauses);

View File

@@ -157,6 +157,38 @@ class EntityGenerator
Type::SIMPLE_ARRAY => 'array',
);
/**
* @var array Hash-map to handle generator types string.
*/
protected static $generatorStrategyMap = array(
ClassMetadataInfo::GENERATOR_TYPE_AUTO => 'AUTO',
ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE => 'SEQUENCE',
ClassMetadataInfo::GENERATOR_TYPE_TABLE => 'TABLE',
ClassMetadataInfo::GENERATOR_TYPE_IDENTITY => 'IDENTITY',
ClassMetadataInfo::GENERATOR_TYPE_NONE => 'NONE',
ClassMetadataInfo::GENERATOR_TYPE_UUID => 'UUID',
ClassMetadataInfo::GENERATOR_TYPE_CUSTOM => 'CUSTOM'
);
/**
* @var array Hash-map to handle the change tracking policy string.
*/
protected static $changeTrackingPolicyMap = array(
ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT => 'DEFERRED_IMPLICIT',
ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT => 'DEFERRED_EXPLICIT',
ClassMetadataInfo::CHANGETRACKING_NOTIFY => 'NOTIFY',
);
/**
* @var array Hash-map to handle the inheritance type string.
*/
protected static $inheritanceTypeMap = array(
ClassMetadataInfo::INHERITANCE_TYPE_NONE => 'NONE',
ClassMetadataInfo::INHERITANCE_TYPE_JOINED => 'JOINED',
ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_TABLE => 'SINGLE_TABLE',
ClassMetadataInfo::INHERITANCE_TYPE_TABLE_PER_CLASS => 'TABLE_PER_CLASS',
);
/**
* @var string
*/
@@ -672,7 +704,7 @@ public function __construct()
{
$lines = array();
$lines[] = '/**';
$lines[] = ' * '.$metadata->name;
$lines[] = ' * ' . $this->getClassName($metadata);
if ($this->generateAnnotations) {
$lines[] = ' *';
@@ -909,9 +941,14 @@ public function __construct()
$var = sprintf('%sMethodTemplate', $type);
$template = self::$$var;
$methodTypeHint = null;
$types = Type::getTypesMap();
$variableType = $typeHint ? $this->getType($typeHint) . ' ' : null;
$methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
if ($typeHint && ! isset($types[$typeHint])) {
$variableType = '\\' . ltrim($variableType, '\\');
$methodTypeHint = '\\' . $typeHint . ' ';
}
$replacements = array(
'<description>' => ucfirst($type) . ' ' . $fieldName,
@@ -991,9 +1028,9 @@ public function __construct()
$lines[] = $this->spaces . '/**';
if ($associationMapping['type'] & ClassMetadataInfo::TO_MANY) {
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\ArrayCollection';
$lines[] = $this->spaces . ' * @var \Doctrine\Common\Collections\Collection';
} else {
$lines[] = $this->spaces . ' * @var ' . $associationMapping['targetEntity'];
$lines[] = $this->spaces . ' * @var \\' . ltrim($associationMapping['targetEntity'], '\\');
}
if ($this->generateAnnotations) {
@@ -1080,17 +1117,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 +1159,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 +1246,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];
}
}

View File

@@ -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']));
}
}

View File

@@ -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)
);
}
}
}

View File

@@ -178,15 +178,10 @@ class Paginator implements \Countable, \IteratorAggregate
return new \ArrayIterator(array());
}
$namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
$whereInQuery->setFirstResult(null)->setMaxResults(null);
foreach ($ids as $i => $id) {
$i++;
$whereInQuery->setParameter("{$namespace}_{$i}", $id);
}
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
$result = $whereInQuery->getResult($this->query->getHydrationMode());
} else {

View File

@@ -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;

View File

@@ -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']) {

View File

@@ -385,6 +385,24 @@ class SchemaTool
}
if (isset($mapping['options'])) {
if (isset($mapping['options']['comment'])) {
$options['comment'] = $mapping['options']['comment'];
unset($mapping['options']['comment']);
}
if (isset($mapping['options']['unsigned'])) {
$options['unsigned'] = $mapping['options']['unsigned'];
unset($mapping['options']['unsigned']);
}
if (isset($mapping['options']['fixed'])) {
$options['fixed'] = $mapping['options']['fixed'];
unset($mapping['options']['fixed']);
}
$options['customSchemaOptions'] = $mapping['options'];
}
@@ -546,6 +564,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") {

View File

@@ -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();
}
/**

View File

@@ -980,7 +980,7 @@ class UnitOfWork implements PropertyChangedListener
);
}
if ($this->entityChangeSets[$oid]) {
if (!empty($this->entityChangeSets[$oid])) {
$persister->update($entity);
}
@@ -2571,6 +2571,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;

View File

@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
const VERSION = '2.3.0';
const VERSION = '2.3.2';
/**
* Compares a Doctrine version with the current one.

View File

@@ -22,6 +22,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()) {

View File

@@ -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
*/

View File

@@ -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()
{

View 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;
}
}

View 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;
}
}

View 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()));
}
}

View 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;
}

View 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;
}

View File

@@ -139,14 +139,25 @@ 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);
}
/**
* @depends testEntityTableNameAndInheritance
* @param ClassMetadata $class
@@ -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',

View File

@@ -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;
}

View File

@@ -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,
));
));

View File

@@ -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>

View File

@@ -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

View File

@@ -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

View File

@@ -7,6 +7,7 @@ use Doctrine\ORM\Persisters\BasicEntityPersister;
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
use Doctrine\Tests\Models\CustomType\CustomTypeFriend;
use Doctrine\Common\Collections\Expr\Comparison;
require_once __DIR__ . '/../../TestInit.php';
@@ -88,4 +89,13 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('t0."simple-entity-id" AS simpleentityid1, t0."simple-entity-value" AS simpleentityvalue2', $method->invoke($persister));
}
/**
* @group DDC-2073
*/
public function testSelectConditionStatementIsNull()
{
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS);
$this->assertEquals('test IS ?', $statement);
}
}

View File

@@ -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(

View File

@@ -167,6 +167,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');
@@ -278,6 +296,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
*

View File

@@ -10,14 +10,42 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
{
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a');
$query->expireQueryCache(true);
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
);
}
public function testLimitSubqueryWithSortPg()
{
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
$this->assertEquals(
"SELECT DISTINCT id0, title1 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC) dctrn_result ORDER BY title1 ASC", $limitQuery->getSql()
);
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
public function testLimitSubqueryPg()
{
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$this->testLimitSubquery();
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
public function testCountQuery_MixedResultsWithName()
{
$query = $this->entityManager->createQuery(

View File

@@ -21,6 +21,18 @@ class LimitSubqueryWalkerTest extends PaginationTestCase
);
}
public function testLimitSubqueryWithSort()
{
$query = $this->entityManager->createQuery(
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
$limitQuery = clone $query;
$limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'));
$this->assertEquals(
"SELECT DISTINCT m0_.id AS id0, m0_.title AS title1 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC", $limitQuery->getSql()
);
}
public function testCountQuery_MixedResultsWithName()
{
$query = $this->entityManager->createQuery(

View File

@@ -31,6 +31,8 @@ class MyBlogPost
* @ManyToOne(targetEntity="Category")
*/
public $category;
/** @column(type="string") */
public $title;
}
/**

View File

@@ -20,7 +20,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -34,7 +34,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -48,7 +48,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -62,7 +62,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -76,7 +76,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -90,7 +90,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -104,7 +104,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
@@ -118,7 +118,7 @@ class WhereInWalkerTest extends PaginationTestCase
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
$this->assertEquals(
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
);
}
}

View File

@@ -60,6 +60,31 @@ class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame('Doctrine\Tests\ORM\Tools\ResolveTargetEntity', $meta['oneToMany']['targetEntity']);
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['oneToOne']['targetEntity']);
}
/**
* @group DDC-2109
*/
public function testAssertTableColumnsAreNotAddedInManyToMany()
{
$evm = $this->em->getEventManager();
$this->listener->addResolveTargetEntity(
'Doctrine\Tests\ORM\Tools\ResolveTargetInterface',
'Doctrine\Tests\ORM\Tools\ResolveTargetEntity',
array()
);
$this->listener->addResolveTargetEntity(
'Doctrine\Tests\ORM\Tools\TargetInterface',
'Doctrine\Tests\ORM\Tools\TargetEntity',
array()
);
$evm->addEventListener(Events::loadClassMetadata, $this->listener);
$cm = $this->factory->getMetadataFor('Doctrine\Tests\ORM\Tools\ResolveTargetEntity');
$meta = $cm->associationMappings['manyToMany'];
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['targetEntity']);
$this->assertEquals(array('resolvetargetentity_id', 'targetinterface_id'), $meta['joinTableColumns']);
}
}
interface ResolveTargetInterface

View File

@@ -44,8 +44,8 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
$schema = $schemaTool->getSchemaFromMetadata($classes);
$expected = array('foo' => 'bar', 'baz' => array('key' => 'val'));
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables optionss");
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
}

View File

@@ -204,6 +204,29 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(UnitOfWork::STATE_DETACHED, $this->_unitOfWork->getEntityState($ph2));
$this->assertFalse($persister->isExistsCalled());
}
/**
* DDC-2086 [GH-484] Prevented "Undefined index" notice when updating.
*/
public function testNoUndefinedIndexNoticeOnScheduleForUpdateWithoutChanges()
{
// Setup fake persister and id generator
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
// Create a test user
$user = new ForumUser();
$user->name = 'Jasper';
$this->_unitOfWork->persist($user);
$this->_unitOfWork->commit();
// Schedule user for update without changes
$this->_unitOfWork->scheduleForUpdate($user);
// This commit should not raise an E_NOTICE
$this->_unitOfWork->commit();
}
}
/**
@@ -309,4 +332,4 @@ class VersionedAssignedIdentifierEntity
* @Version @Column(type="integer")
*/
public $version;
}
}