mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
158 Commits
old-protot
...
2.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5725dd6bb | ||
|
|
b59cd047ff | ||
|
|
019094655b | ||
|
|
88e817660c | ||
|
|
aee75d8f25 | ||
|
|
50132ddc18 | ||
|
|
f05bcbc17c | ||
|
|
f94b6c07c7 | ||
|
|
b68c6b3d2d | ||
|
|
0425e8452d | ||
|
|
c120700d89 | ||
|
|
22dc20c320 | ||
|
|
6d89875306 | ||
|
|
b666a62979 | ||
|
|
f2f8c4f2dd | ||
|
|
59aef2ca95 | ||
|
|
173b398b34 | ||
|
|
de22e726a4 | ||
|
|
dab2b505a4 | ||
|
|
0672688088 | ||
|
|
660f89f745 | ||
|
|
e0aa01ddb6 | ||
|
|
287b29aeaa | ||
|
|
86132283f1 | ||
|
|
f75c3b517d | ||
|
|
6e7e4dd35a | ||
|
|
faedbfc09a | ||
|
|
45269fe4f2 | ||
|
|
a3fea32e0e | ||
|
|
c90ed73b33 | ||
|
|
83943e86a2 | ||
|
|
1aab5feb4a | ||
|
|
469bd02b41 | ||
|
|
24f74bc935 | ||
|
|
77d060ab74 | ||
|
|
01148e52f3 | ||
|
|
5756021571 | ||
|
|
006d3833f6 | ||
|
|
8865a5b90d | ||
|
|
d0698754b2 | ||
|
|
4ea7a5dde4 | ||
|
|
ed11e61812 | ||
|
|
e7e69daabe | ||
|
|
c6eb04de14 | ||
|
|
8c2009c67e | ||
|
|
a7ed9e638b | ||
|
|
643ed0b8f5 | ||
|
|
57db88b62a | ||
|
|
3c944b34ca | ||
|
|
1618a3e393 | ||
|
|
a1094d352c | ||
|
|
e4ef9e03ae | ||
|
|
a3c98b1087 | ||
|
|
2ce877bf8a | ||
|
|
6d35fad70f | ||
|
|
612ed2b3a2 | ||
|
|
95a85d67ea | ||
|
|
edaab11a86 | ||
|
|
1627c974b9 | ||
|
|
c6118cb045 | ||
|
|
461d201e40 | ||
|
|
653aef2c83 | ||
|
|
045d058cec | ||
|
|
9dbf4d8480 | ||
|
|
2229a5e4c6 | ||
|
|
bbf092c6fd | ||
|
|
6fee945fda | ||
|
|
974f18da0c | ||
|
|
9b198be070 | ||
|
|
b610855248 | ||
|
|
994917aa23 | ||
|
|
d64be2888e | ||
|
|
737e47e155 | ||
|
|
ef4ff8be81 | ||
|
|
b53c81ae8d | ||
|
|
6bad010959 | ||
|
|
26cfbdd08b | ||
|
|
e8412b85df | ||
|
|
2e5d7416d8 | ||
|
|
1988944e7e | ||
|
|
564ec1ee2a | ||
|
|
cb0cddef83 | ||
|
|
8b2c92a6bd | ||
|
|
825a68bcba | ||
|
|
abd11374ee | ||
|
|
518357d987 | ||
|
|
4109f22000 | ||
|
|
c60e6523e9 | ||
|
|
04262e2b73 | ||
|
|
084101e287 | ||
|
|
ea2b288578 | ||
|
|
b5e19dca18 | ||
|
|
585c9fd208 | ||
|
|
c6101317cd | ||
|
|
477642a171 | ||
|
|
75e968b250 | ||
|
|
3294900faa | ||
|
|
2353736e8f | ||
|
|
586aea0236 | ||
|
|
18a7fc5726 | ||
|
|
44a56e8e49 | ||
|
|
c2b82fa529 | ||
|
|
d7da012918 | ||
|
|
85e5398354 | ||
|
|
3fd8392ccf | ||
|
|
0da0d02dec | ||
|
|
387516f144 | ||
|
|
53e164ba5d | ||
|
|
4d9f24b2ee | ||
|
|
a96bbbbe0a | ||
|
|
8edecfdcad | ||
|
|
741080dc17 | ||
|
|
30ad1b0706 | ||
|
|
9cdee12ccf | ||
|
|
c76280be42 | ||
|
|
0dcfabbc4d | ||
|
|
366c6a7dd6 | ||
|
|
2597192f22 | ||
|
|
bbf527a273 | ||
|
|
9308afc9a5 | ||
|
|
1a81444b04 | ||
|
|
d181fbc98d | ||
|
|
114e233d87 | ||
|
|
bdb36a71c5 | ||
|
|
8c1d64372c | ||
|
|
f4ba58358c | ||
|
|
131d3003a0 | ||
|
|
48e94343fd | ||
|
|
9d909cd583 | ||
|
|
3aaa90e1a8 | ||
|
|
971865f271 | ||
|
|
af08f05164 | ||
|
|
2e6b50bb53 | ||
|
|
17862d9a2a | ||
|
|
c99c7b6694 | ||
|
|
3f2ddc60d4 | ||
|
|
3b3d762277 | ||
|
|
992b51eba7 | ||
|
|
5527e121ec | ||
|
|
c55394c616 | ||
|
|
1676cf23c0 | ||
|
|
6dd3078153 | ||
|
|
1e2eca1a7e | ||
|
|
7029d3738d | ||
|
|
7f68347c1f | ||
|
|
e63575ea18 | ||
|
|
d7bdae3bbb | ||
|
|
e2c40dc365 | ||
|
|
dfa6ff64c4 | ||
|
|
ef27721db2 | ||
|
|
13d32e6de5 | ||
|
|
bd1e6ac309 | ||
|
|
369a30ad3d | ||
|
|
ac9df05c92 | ||
|
|
2158a0788e | ||
|
|
2389f77d91 | ||
|
|
5b55739990 | ||
|
|
3e53d9d79c |
@@ -1,5 +1,13 @@
|
||||
# Upgrade to 2.3
|
||||
|
||||
## EntityManager#find() not calls EntityRepository#find() anymore
|
||||
|
||||
Previous to 2.3, calling ``EntityManager#find()`` would be delegated to
|
||||
``EntityRepository#find()``. This has lead to some unexpected behavior in the
|
||||
core of Doctrine when people have overwritten the find method in their
|
||||
repositories. That is why this behavior has been reversed in 2.3, and
|
||||
``EntityRepository#find()`` calls ``EntityManager#find()`` instead.
|
||||
|
||||
## EntityGenerator add*() method generation
|
||||
|
||||
When generating an add*() method for a collection the EntityGenerator will now not
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"type": "library",
|
||||
"type": "library","version":"2.3.2",
|
||||
"description": "Object-Relational-Mapper for PHP",
|
||||
"keywords": ["orm", "database"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
@@ -14,7 +14,7 @@
|
||||
"require": {
|
||||
"php": ">=5.3.2",
|
||||
"ext-pdo": "*",
|
||||
"doctrine/dbal": ">=2.3-dev,<2.5-dev",
|
||||
"doctrine/dbal": "2.3.*",
|
||||
"symfony/console": "2.*"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -26,7 +26,7 @@
|
||||
"bin": ["bin/doctrine", "bin/doctrine.php"],
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.4.x-dev"
|
||||
"dev-master": "2.3.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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."
|
||||
);
|
||||
|
||||
@@ -25,6 +25,7 @@ use Doctrine\Common\Persistence\ObjectRepository;
|
||||
use Doctrine\Common\Collections\Selectable;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\ExpressionBuilder;
|
||||
|
||||
/**
|
||||
* An EntityRepository serves as a repository for entities with generic as well as
|
||||
@@ -160,13 +161,14 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
* Finds a single entity by a set of criteria.
|
||||
*
|
||||
* @param array $criteria
|
||||
* @param array|null $orderBy
|
||||
* @return object
|
||||
*/
|
||||
public function findOneBy(array $criteria)
|
||||
public function findOneBy(array $criteria, array $orderBy = null)
|
||||
{
|
||||
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
|
||||
|
||||
return $persister->load($criteria, null, null, array(), 0, 1);
|
||||
return $persister->load($criteria, null, null, array(), 0, 1, $orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,7 +216,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
case 3:
|
||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2]);
|
||||
|
||||
case 4;
|
||||
case 4:
|
||||
return $this->$method(array($fieldName => $arguments[0]), $arguments[1], $arguments[2], $arguments[3]);
|
||||
|
||||
default:
|
||||
|
||||
@@ -1188,7 +1188,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
// Complete fieldName and columnName mapping
|
||||
if ( ! isset($mapping['columnName'])) {
|
||||
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName'], $this->name);
|
||||
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']);
|
||||
}
|
||||
|
||||
if ($mapping['columnName'][0] === '`') {
|
||||
@@ -1465,7 +1465,6 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
if ( ! isset($mapping['joinTable']['name'])) {
|
||||
$mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
|
||||
}
|
||||
|
||||
if ( ! isset($mapping['joinTable']['joinColumns'])) {
|
||||
$mapping['joinTable']['joinColumns'] = array(array(
|
||||
'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']),
|
||||
@@ -1479,6 +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']);
|
||||
@@ -2725,7 +2726,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
// Association defined as Id field
|
||||
$joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
|
||||
$assocQuotedColumnNames = array_map(
|
||||
function ($joinColumn) {
|
||||
function ($joinColumn) use ($platform) {
|
||||
return isset($joinColumn['quoted'])
|
||||
? $platform->quoteIdentifier($joinColumn['name'])
|
||||
: $joinColumn['name'];
|
||||
|
||||
@@ -45,7 +45,7 @@ class DefaultNamingStrategy implements NamingStrategy
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $propertyName;
|
||||
}
|
||||
|
||||
@@ -197,43 +197,6 @@ class AnnotationDriver extends AbstractAnnotationDriver
|
||||
}
|
||||
}
|
||||
|
||||
$associationOverrides = array();
|
||||
// Evaluate AssociationOverrides annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'])) {
|
||||
$associationOverridesAnnot = $classAnnotations['Doctrine\ORM\Mapping\AssociationOverrides'];
|
||||
|
||||
foreach ($associationOverridesAnnot->value as $associationOverride) {
|
||||
// Check for JoinColummn/JoinColumns annotations
|
||||
if ($associationOverride->joinColumns) {
|
||||
$joinColumns = array();
|
||||
foreach ($associationOverride->joinColumns as $joinColumn) {
|
||||
$joinColumns[] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
$associationOverrides[$associationOverride->name]['joinColumns'] = $joinColumns;
|
||||
}
|
||||
|
||||
// Check for JoinTable annotations
|
||||
if ($associationOverride->joinTable) {
|
||||
$joinTable = null;
|
||||
$joinTableAnnot = $associationOverride->joinTable;
|
||||
$joinTable = array(
|
||||
'name' => $joinTableAnnot->name,
|
||||
'schema' => $joinTableAnnot->schema
|
||||
);
|
||||
|
||||
foreach ($joinTableAnnot->joinColumns as $joinColumn) {
|
||||
$joinTable['joinColumns'][] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
|
||||
foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) {
|
||||
$joinTable['inverseJoinColumns'][] = $this->joinColumnToArray($joinColumn);
|
||||
}
|
||||
|
||||
$associationOverrides[$associationOverride->name]['joinTable'] = $joinTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate InheritanceType annotation
|
||||
if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) {
|
||||
$inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType'];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -42,10 +42,9 @@ interface NamingStrategy
|
||||
* Return a column name for a property
|
||||
*
|
||||
* @param string $propertyName A property
|
||||
* @param string $className The fully-qualified class name
|
||||
* @return string A column name
|
||||
*/
|
||||
function propertyToColumnName($propertyName, $className = null);
|
||||
function propertyToColumnName($propertyName);
|
||||
|
||||
/**
|
||||
* Return the default reference column name
|
||||
|
||||
@@ -80,7 +80,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
public function propertyToColumnName($propertyName)
|
||||
{
|
||||
return $this->underscore($propertyName);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
|
||||
static public function entityWithoutIdentity($className, $entity)
|
||||
{
|
||||
throw new self(
|
||||
return new self(
|
||||
"The given entity of type '" . $className . "' (".self::objToStr($entity).") has no identity/no " .
|
||||
"id values set. It cannot be added to the identity map."
|
||||
);
|
||||
@@ -70,30 +70,30 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
|
||||
|
||||
static public function detachedEntityFoundThroughRelationship(array $assoc, $entry)
|
||||
{
|
||||
throw new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
|
||||
return new self("A detached entity of type " . $assoc['targetEntity'] . " (" . self::objToStr($entry) . ") "
|
||||
. " was found through the relationship '" . $assoc['sourceEntity'] . "#" . $assoc['fieldName'] . "' "
|
||||
. "during cascading a persist operation.");
|
||||
}
|
||||
|
||||
static public function entityNotManaged($entity)
|
||||
{
|
||||
throw new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
|
||||
return new self("Entity " . self::objToStr($entity) . " is not managed. An entity is managed if its fetched " .
|
||||
"from the database or registered as new through EntityManager#persist");
|
||||
}
|
||||
|
||||
static public function entityHasNoIdentity($entity, $operation)
|
||||
{
|
||||
throw new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
return new self("Entity has no identity, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function entityIsRemoved($entity, $operation)
|
||||
{
|
||||
throw new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
return new self("Entity is removed, therefore " . $operation ." cannot be performed. " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
static public function detachedEntityCannot($entity, $operation)
|
||||
{
|
||||
throw new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
return new self("A detached entity was found during " . $operation . " " . self::objToStr($entity));
|
||||
}
|
||||
|
||||
public static function invalidObject($context, $given, $parameterIndex = 1)
|
||||
|
||||
@@ -42,6 +42,7 @@ use Closure;
|
||||
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @author Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
|
||||
* @author Stefano Rodriguez <stefano.rodriguez@fubles.com>
|
||||
* @todo Design for inheritance to allow custom implementations?
|
||||
*/
|
||||
final class PersistentCollection implements Collection, Selectable
|
||||
@@ -654,7 +655,7 @@ final class PersistentCollection implements Collection, Selectable
|
||||
|
||||
$this->initialized = true; // direct call, {@link initialize()} is too expensive
|
||||
|
||||
if ($this->association['isOwningSide']) {
|
||||
if ($this->association['isOwningSide'] && $this->owner) {
|
||||
$this->changed();
|
||||
|
||||
$uow->scheduleCollectionDeletion($this);
|
||||
@@ -812,6 +813,13 @@ final class PersistentCollection implements Collection, Selectable
|
||||
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany assocations at the moment.");
|
||||
}
|
||||
|
||||
// If there are NEW objects we have to check if any of them matches the criteria
|
||||
$newObjects = array();
|
||||
|
||||
if ($this->isDirty) {
|
||||
$newObjects = $this->coll->matching($criteria)->toArray();
|
||||
}
|
||||
|
||||
$targetClass = $this->em->getClassMetadata(get_class($this->owner));
|
||||
|
||||
$id = $targetClass->getSingleIdReflectionProperty()->getValue($this->owner);
|
||||
@@ -824,7 +832,7 @@ final class PersistentCollection implements Collection, Selectable
|
||||
|
||||
$persister = $this->em->getUnitOfWork()->getEntityPersister($this->association['targetEntity']);
|
||||
|
||||
return new ArrayCollection($persister->loadCriteria($criteria));
|
||||
return new ArrayCollection(array_merge($persister->loadCriteria($criteria), $newObjects));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -808,10 +809,23 @@ class BasicEntityPersister
|
||||
return array(array(), array());
|
||||
}
|
||||
|
||||
$valueVisitor = new SqlValueVisitor($this->_class);
|
||||
$valueVisitor = new SqlValueVisitor();
|
||||
$valueVisitor->dispatch($expression);
|
||||
|
||||
return $valueVisitor->getParamsAndTypes();
|
||||
list($values, $types) = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
$sqlValues = array();
|
||||
foreach ($values as $value) {
|
||||
$sqlValues[] = $this->getValue($value);
|
||||
}
|
||||
|
||||
$sqlTypes = array();
|
||||
foreach ($types as $type) {
|
||||
list($field, $value) = $type;
|
||||
$sqlTypes[] = $this->getType($field, $value);
|
||||
}
|
||||
|
||||
return array($sqlValues, $sqlTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1686,7 +1700,11 @@ class BasicEntityPersister
|
||||
$idValues = $class->getIdentifierValues($value);
|
||||
}
|
||||
|
||||
$value = $idValues[key($idValues)];
|
||||
$key = key($idValues);
|
||||
|
||||
if (null !== $key){
|
||||
$value = $idValues[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -227,8 +227,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
|
||||
// Make sure the table with the version column is updated even if no columns on that
|
||||
// table were affected.
|
||||
if ($isVersioned && ! isset($updateData[$versionedTable])) {
|
||||
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
|
||||
if ($isVersioned) {
|
||||
if ( ! isset($updateData[$versionedTable])) {
|
||||
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
|
||||
}
|
||||
|
||||
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
|
||||
$this->assignDefaultVersionValue($entity, $id);
|
||||
@@ -468,7 +470,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
|
||||
}
|
||||
} else if ($this->_class->name != $this->_class->rootEntityName ||
|
||||
! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
|
||||
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
|
||||
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
|
||||
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,19 +46,6 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
*/
|
||||
private $types = array();
|
||||
|
||||
/**
|
||||
* @var \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
private $class;
|
||||
|
||||
/**
|
||||
* @param \Doctrine\ORM\Mapping\ClassMetadata
|
||||
*/
|
||||
public function __construct(ClassMetadata $class)
|
||||
{
|
||||
$this->class = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a comparison expression into the target query language output
|
||||
*
|
||||
@@ -70,9 +57,9 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
{
|
||||
$value = $comparison->getValue()->getValue();
|
||||
$field = $comparison->getField();
|
||||
|
||||
|
||||
$this->values[] = $value;
|
||||
$this->types[] = $this->getType($field, $value);
|
||||
$this->types[] = array($field, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,17 +97,4 @@ class SqlValueVisitor extends ExpressionVisitor
|
||||
{
|
||||
return array($this->values, $this->types);
|
||||
}
|
||||
|
||||
private function getType($field, $value)
|
||||
{
|
||||
$type = isset($this->class->fieldMappings[$field])
|
||||
? Type::getType($this->class->fieldMappings[$field]['type'])->getBindingType()
|
||||
: \PDO::PARAM_STR;
|
||||
|
||||
if (is_array($value)) {
|
||||
$type += Connection::ARRAY_PARAM_OFFSET;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,6 @@ class JoinClassPathExpression extends Node
|
||||
|
||||
public function dispatch($walker)
|
||||
{
|
||||
return $sqlWalker->walkJoinPathExpression($this);
|
||||
return $walker->walkJoinPathExpression($this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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']));
|
||||
}
|
||||
}
|
||||
@@ -180,6 +182,9 @@ class XmlExporter extends AbstractExporter
|
||||
if (isset($field['columnDefinition'])) {
|
||||
$fieldXml->addAttribute('column-definition', $field['columnDefinition']);
|
||||
}
|
||||
if (isset($field['nullable'])) {
|
||||
$fieldXml->addAttribute('nullable', $field['nullable'] ? 'true' : 'false');
|
||||
}
|
||||
}
|
||||
}
|
||||
$orderMap = array(
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,18 +174,15 @@ class Paginator implements \Countable, \IteratorAggregate
|
||||
|
||||
$whereInQuery = $this->cloneQuery($this->query);
|
||||
// don't do this for an empty id array
|
||||
if (count($ids) > 0) {
|
||||
$namespace = WhereInWalker::PAGINATOR_ID_ALIAS;
|
||||
|
||||
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
|
||||
$whereInQuery->setFirstResult(null)->setMaxResults(null);
|
||||
foreach ($ids as $i => $id) {
|
||||
$i++;
|
||||
$whereInQuery->setParameter("{$namespace}_{$i}", $id);
|
||||
}
|
||||
if (count($ids) == 0) {
|
||||
return new \ArrayIterator(array());
|
||||
}
|
||||
|
||||
$whereInQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\WhereInWalker'));
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, count($ids));
|
||||
$whereInQuery->setFirstResult(null)->setMaxResults(null);
|
||||
$whereInQuery->setParameter(WhereInWalker::PAGINATOR_ID_ALIAS, $ids);
|
||||
|
||||
$result = $whereInQuery->getResult($this->query->getHydrationMode());
|
||||
} else {
|
||||
$result = $this->cloneQuery($this->query)
|
||||
|
||||
@@ -102,11 +102,8 @@ class WhereInWalker extends TreeWalkerAdapter
|
||||
array($pathExpression)
|
||||
);
|
||||
$expression = new InExpression($arithmeticExpression);
|
||||
$ns = self::PAGINATOR_ID_ALIAS;
|
||||
$expression->literals[] = new InputParameter(":" . self::PAGINATOR_ID_ALIAS);
|
||||
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$expression->literals[] = new InputParameter(":{$ns}_$i");
|
||||
}
|
||||
} else {
|
||||
$expression = new NullComparisonExpression($pathExpression);
|
||||
$expression->not = false;
|
||||
|
||||
@@ -73,6 +73,7 @@ class ResolveTargetEntityListener
|
||||
$newMapping = $this->resolveTargetEntities[$mapping['targetEntity']];
|
||||
$newMapping = array_replace_recursive($mapping, $newMapping);
|
||||
$newMapping['fieldName'] = $mapping['fieldName'];
|
||||
|
||||
unset($classMetadata->associationMappings[$mapping['fieldName']]);
|
||||
|
||||
switch ($mapping['type']) {
|
||||
|
||||
@@ -385,6 +385,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") {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -206,7 +206,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* The EventManager used for dispatching events.
|
||||
*
|
||||
* @var EventManager
|
||||
* @var \Doctrine\Common\EventManager
|
||||
*/
|
||||
private $evm;
|
||||
|
||||
@@ -256,6 +256,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* 5) All entity deletions
|
||||
*
|
||||
* @param null|object|array $entity
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function commit($entity = null)
|
||||
@@ -390,6 +393,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* 4. Only if entity is properly managed.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function computeSingleEntityChangeSet($entity)
|
||||
@@ -440,6 +446,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets the changeset for an entity.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getEntityChangeSet($entity)
|
||||
@@ -708,8 +716,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Computes the changes of an association.
|
||||
*
|
||||
* @param AssociationMapping $assoc
|
||||
* @param array $assoc
|
||||
* @param mixed $value The value of the association.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws ORMException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function computeAssociationChanges($assoc, $value)
|
||||
{
|
||||
@@ -779,6 +792,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadata $class
|
||||
* @param object $entity
|
||||
*/
|
||||
private function persistNew($class, $entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
@@ -822,7 +839,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param ClassMetadata $class The class descriptor of the entity.
|
||||
* @param object $entity The entity for which to (re)calculate the change set.
|
||||
* @throws InvalidArgumentException If the passed entity is not MANAGED.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the passed entity is not MANAGED.
|
||||
*/
|
||||
public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity)
|
||||
{
|
||||
@@ -962,7 +980,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->entityChangeSets[$oid]) {
|
||||
if (!empty($this->entityChangeSets[$oid])) {
|
||||
$persister->update($entity);
|
||||
}
|
||||
|
||||
@@ -1025,6 +1043,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets the commit order.
|
||||
*
|
||||
* @param array $entityChangeSet
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getCommitOrder(array $entityChangeSet = null)
|
||||
@@ -1099,6 +1119,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* If the entity already has an identifier, it will be added to the identity map.
|
||||
*
|
||||
* @param object $entity The entity to schedule for insertion.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function scheduleForInsert($entity)
|
||||
{
|
||||
@@ -1134,6 +1157,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is scheduled for insertion.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForInsert($entity)
|
||||
@@ -1145,6 +1169,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Schedules an entity for being updated.
|
||||
*
|
||||
* @param object $entity The entity to schedule for being updated.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*/
|
||||
public function scheduleForUpdate($entity)
|
||||
{
|
||||
@@ -1194,6 +1220,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* at commit time.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForUpdate($entity)
|
||||
@@ -1206,6 +1233,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is registered to be checked in the unit of work.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForDirtyCheck($entity)
|
||||
@@ -1256,6 +1284,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* of work.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isScheduledForDelete($entity)
|
||||
@@ -1267,6 +1296,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is scheduled for insertion, update or deletion.
|
||||
*
|
||||
* @param $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEntityScheduled($entity)
|
||||
@@ -1286,6 +1316,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @ignore
|
||||
* @param object $entity The entity to register.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return boolean TRUE if the registration was successful, FALSE if the identity of
|
||||
* the entity in question is already managed.
|
||||
*/
|
||||
@@ -1317,6 +1350,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* This parameter can be set to improve performance of entity state detection
|
||||
* by potentially avoiding a database lookup if the distinction between NEW and DETACHED
|
||||
* is either known or does not matter for the caller of the method.
|
||||
*
|
||||
* @return int The entity state.
|
||||
*/
|
||||
public function getEntityState($entity, $assume = null)
|
||||
@@ -1392,6 +1426,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @ignore
|
||||
* @param object $entity
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function removeFromIdentityMap($entity)
|
||||
@@ -1425,6 +1462,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getByIdHash($idHash, $rootClassName)
|
||||
@@ -1440,6 +1478,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return mixed The found entity or FALSE.
|
||||
*/
|
||||
public function tryGetByIdHash($idHash, $rootClassName)
|
||||
@@ -1455,6 +1494,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Checks whether an entity is registered in the identity map of this UnitOfWork.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isInIdentityMap($entity)
|
||||
@@ -1482,6 +1522,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @ignore
|
||||
* @param string $idHash
|
||||
* @param string $rootClassName
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function containsIdHash($idHash, $rootClassName)
|
||||
@@ -1509,6 +1550,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to persist.
|
||||
* @param array $visited The already visited entities.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
private function doPersist($entity, array &$visited)
|
||||
{
|
||||
@@ -1578,7 +1622,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to delete.
|
||||
* @param array $visited The map of the already visited entities.
|
||||
* @throws InvalidArgumentException If the instance is a detached entity.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the instance is a detached entity.
|
||||
* @throws UnexpectedValueException
|
||||
*/
|
||||
private function doRemove($entity, array &$visited)
|
||||
{
|
||||
@@ -1627,10 +1673,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Merges the state of the given detached entity into this UnitOfWork.
|
||||
*
|
||||
* @param object $entity
|
||||
* @return object The managed copy of the entity.
|
||||
*
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
*
|
||||
* @return object The managed copy of the entity.
|
||||
*
|
||||
* @todo Require active transaction!? OptimisticLockException may result in undefined state!?
|
||||
*/
|
||||
public function merge($entity)
|
||||
@@ -1645,10 +1693,15 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $visited
|
||||
* @return object The managed copy of the entity.
|
||||
* @param object $prevManagedCopy
|
||||
* @param array $assoc
|
||||
*
|
||||
* @throws OptimisticLockException If the entity uses optimistic locking through a version
|
||||
* attribute and the version check against the managed copy fails.
|
||||
* @throws InvalidArgumentException If the entity instance is NEW.
|
||||
* @throws ORMInvalidArgumentException If the entity instance is NEW.
|
||||
* @throws EntityNotFoundException
|
||||
*
|
||||
* @return object The managed copy of the entity.
|
||||
*/
|
||||
private function doMerge($entity, array &$visited, $prevManagedCopy = null, $assoc = null)
|
||||
{
|
||||
@@ -1895,6 +1948,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* any local, unpersisted changes.
|
||||
*
|
||||
* @param object $entity The entity to refresh.
|
||||
*
|
||||
* @throws InvalidArgumentException If the entity is not MANAGED.
|
||||
*/
|
||||
public function refresh($entity)
|
||||
@@ -1909,7 +1963,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity The entity to refresh.
|
||||
* @param array $visited The already visited entities during cascades.
|
||||
* @throws InvalidArgumentException If the entity is not MANAGED.
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the entity is not MANAGED.
|
||||
*/
|
||||
private function doRefresh($entity, array &$visited)
|
||||
{
|
||||
@@ -2060,7 +2115,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param object $entity
|
||||
* @param array $visited
|
||||
* @param array $insertNow
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cascadePersist($entity, array &$visited)
|
||||
{
|
||||
@@ -2144,6 +2200,12 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @param object $entity
|
||||
* @param int $lockMode
|
||||
* @param int $lockVersion
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws TransactionRequiredException
|
||||
* @throws OptimisticLockException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function lock($entity, $lockMode, $lockVersion = null)
|
||||
{
|
||||
@@ -2279,13 +2341,20 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->collectionDeletions[$coid] = $coll;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PersistentCollection $coll
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCollectionScheduledForDeletion(PersistentCollection $coll)
|
||||
{
|
||||
return isset($this->collectionsDeletions[spl_object_hash($coll)]);
|
||||
return isset($this->collectionDeletions[spl_object_hash($coll)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMetadata $class
|
||||
*
|
||||
* @return \Doctrine\Common\Persistence\ObjectManagerAware|object
|
||||
*/
|
||||
private function newInstance($class)
|
||||
{
|
||||
@@ -2306,6 +2375,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @param string $className The name of the entity class.
|
||||
* @param array $data The data for the entity.
|
||||
* @param array $hints Any hints to account for during reconstitution/lookup of the entity.
|
||||
*
|
||||
* @return object The managed entity instance.
|
||||
* @internal Highly performance-sensitive method.
|
||||
*
|
||||
@@ -2501,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;
|
||||
@@ -2578,7 +2652,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Initializes (loads) an uninitialized persistent collection of an entity.
|
||||
*
|
||||
* @param PeristentCollection $collection The collection to initialize.
|
||||
* @param \Doctrine\ORM\PersistentCollection $collection The collection to initialize.
|
||||
*
|
||||
* @return void
|
||||
* @todo Maybe later move to EntityManager#initialize($proxyOrCollection). See DDC-733.
|
||||
*/
|
||||
public function loadCollection(PersistentCollection $collection)
|
||||
@@ -2612,6 +2688,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* present at the time the entity was reconstituted from the database.
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getOriginalEntityData($entity)
|
||||
@@ -2654,6 +2731,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* order as the identifier field names as returned by ClassMetadata#getIdentifierFieldNames().
|
||||
*
|
||||
* @param object $entity
|
||||
*
|
||||
* @return array The identifier values.
|
||||
*/
|
||||
public function getEntityIdentifier($entity)
|
||||
@@ -2667,6 +2745,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param mixed $id The entity identifier to look for.
|
||||
* @param string $rootClassName The name of the root class of the mapped entity hierarchy.
|
||||
*
|
||||
* @return mixed Returns the entity with the specified identifier if it exists in
|
||||
* this UnitOfWork, FALSE otherwise.
|
||||
*/
|
||||
@@ -2757,9 +2836,9 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Gets a collection persister for a collection-valued association.
|
||||
*
|
||||
* @param AssociationMapping $association
|
||||
* @param array $association
|
||||
*
|
||||
* @return AbstractCollectionPersister
|
||||
* @return \Doctrine\ORM\Persisters\AbstractCollectionPersister
|
||||
*/
|
||||
public function getCollectionPersister(array $association)
|
||||
{
|
||||
@@ -2901,6 +2980,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Helper method to initialize a lazy loading proxy or persistent collection.
|
||||
*
|
||||
* @param object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeObject($obj)
|
||||
@@ -2920,6 +3000,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Helper method to show an object as string.
|
||||
*
|
||||
* @param object $obj
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function objToStr($obj)
|
||||
@@ -2931,10 +3012,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* Marks an entity as read-only so that it will not be considered for updates during UnitOfWork#commit().
|
||||
*
|
||||
* This operation cannot be undone as some parts of the UnitOfWork now keep gathering information
|
||||
* on this object that might be necessary to perform a correct udpate.
|
||||
* on this object that might be necessary to perform a correct update.
|
||||
*
|
||||
*
|
||||
* @param object $object
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @param $object
|
||||
* @return void
|
||||
*/
|
||||
public function markReadOnly($object)
|
||||
@@ -2949,9 +3033,11 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* Is this entity read only?
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @param $object
|
||||
* @return void
|
||||
* @param object $object
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadOnly($object)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ class Version
|
||||
/**
|
||||
* Current Doctrine Version
|
||||
*/
|
||||
const VERSION = '2.4.0-DEV';
|
||||
const VERSION = '2.3.2';
|
||||
|
||||
/**
|
||||
* Compares a Doctrine version with the current one.
|
||||
|
||||
2
lib/vendor/doctrine-common
vendored
2
lib/vendor/doctrine-common
vendored
Submodule lib/vendor/doctrine-common updated: 0f7ba7fa71...d1c7d4334e
2
lib/vendor/doctrine-dbal
vendored
2
lib/vendor/doctrine-dbal
vendored
Submodule lib/vendor/doctrine-dbal updated: 659de9a189...e59abccfe8
@@ -10,7 +10,7 @@ namespace Doctrine\Tests\Mocks;
|
||||
class StatementMock implements \IteratorAggregate, \Doctrine\DBAL\Driver\Statement
|
||||
{
|
||||
public function bindValue($param, $value, $type = null){}
|
||||
public function bindParam($column, &$variable, $type = null){}
|
||||
public function bindParam($column, &$variable, $type = null, $length = null){}
|
||||
public function errorCode(){}
|
||||
public function errorInfo(){}
|
||||
public function execute($params = null){}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\Generic\DateTimeModel;
|
||||
use Doctrine\Common\Collections\Criteria;
|
||||
|
||||
/**
|
||||
* @author Josiah <josiah@jjs.id.au>
|
||||
*/
|
||||
class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('generic');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
if ($this->_em) {
|
||||
$this->_em->getConfiguration()->setEntityNamespaces(array());
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function loadFixture()
|
||||
{
|
||||
$today = new DateTimeModel();
|
||||
$today->datetime =
|
||||
$today->date =
|
||||
$today->time =
|
||||
new \DateTime('today');
|
||||
$this->_em->persist($today);
|
||||
|
||||
$tomorrow = new DateTimeModel();
|
||||
$tomorrow->datetime =
|
||||
$tomorrow->date =
|
||||
$tomorrow->time =
|
||||
new \DateTime('tomorrow');
|
||||
$this->_em->persist($tomorrow);
|
||||
|
||||
$yesterday = new DateTimeModel();
|
||||
$yesterday->datetime =
|
||||
$yesterday->date =
|
||||
$yesterday->time =
|
||||
new \DateTime('yesterday');
|
||||
$this->_em->persist($yesterday);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
unset($today);
|
||||
unset($tomorrow);
|
||||
unset($yesterday);
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testLteDateComparison()
|
||||
{
|
||||
$this->loadFixture();
|
||||
|
||||
$repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
|
||||
$dates = $repository->matching(new Criteria(
|
||||
Criteria::expr()->lte('datetime', new \DateTime('today'))
|
||||
));
|
||||
|
||||
$this->assertEquals(2, count($dates));
|
||||
}
|
||||
}
|
||||
@@ -344,6 +344,20 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertEquals($addressId, $address->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1241
|
||||
*/
|
||||
public function testFindOneByOrderBy()
|
||||
{
|
||||
$this->loadFixture();
|
||||
|
||||
$repos = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
|
||||
$userAsc = $repos->findOneBy(array(), array("username" => "ASC"));
|
||||
$userDesc = $repos->findOneBy(array(), array("username" => "DESC"));
|
||||
|
||||
$this->assertNotSame($userAsc, $userDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-817
|
||||
*/
|
||||
|
||||
@@ -173,6 +173,30 @@ class OneToManyBidirectionalAssociationTest extends \Doctrine\Tests\OrmFunctiona
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertEquals(2, count($results));
|
||||
}
|
||||
|
||||
public function testMatchingBis()
|
||||
{
|
||||
$this->_createFixture();
|
||||
|
||||
$product = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $this->product->getId());
|
||||
$features = $product->getFeatures();
|
||||
|
||||
$thirdFeature = new ECommerceFeature();
|
||||
$thirdFeature->setDescription('Third feature');
|
||||
$product->addFeature($thirdFeature);
|
||||
|
||||
$results = $features->matching(new Criteria(
|
||||
Criteria::expr()->eq('description', 'Third feature')
|
||||
));
|
||||
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertCount(1, $results);
|
||||
|
||||
$results = $features->matching(new Criteria());
|
||||
|
||||
$this->assertInstanceOf('Doctrine\Common\Collections\Collection', $results);
|
||||
$this->assertCount(3, $results);
|
||||
}
|
||||
|
||||
private function _createFixture()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -29,12 +29,12 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$tool = new SchemaTool($this->_em);
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[2]);
|
||||
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[3]);
|
||||
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[4]);
|
||||
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[5]);
|
||||
$this->assertEquals("CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[2]);
|
||||
$this->assertEquals("CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[3]);
|
||||
$this->assertEquals("CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[4]);
|
||||
$this->assertEquals("CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[5]);
|
||||
$this->assertEquals("ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id)", $sql[6]);
|
||||
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AA76ED395 FOREIGN KEY (user_id) REFERENCES cms_users (id)", $sql[7]);
|
||||
$this->assertEquals("ALTER TABLE cms_users_groups ADD CONSTRAINT FK_7EA9409AFE54D947 FOREIGN KEY (group_id) REFERENCES cms_groups (id)", $sql[8]);
|
||||
@@ -54,7 +54,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals(1, count($sql));
|
||||
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE decimal_model (id INT AUTO_INCREMENT NOT NULL, `decimal` NUMERIC(5, 2) NOT NULL, `high_scale` NUMERIC(14, 4) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
}
|
||||
|
||||
public function testGetCreateSchemaSql3()
|
||||
@@ -67,7 +67,7 @@ class MySqlSchemaToolTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$sql = $tool->getCreateSchemaSql($classes);
|
||||
|
||||
$this->assertEquals(1, count($sql));
|
||||
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
153
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php
Normal file
153
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php
Normal file
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\NotifyPropertyChanged,
|
||||
Doctrine\Common\PropertyChangedListener;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC1690Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
try {
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Parent'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Child')
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
// Swallow all exceptions. We do not test the schema tool here.
|
||||
}
|
||||
}
|
||||
|
||||
public function testChangeTracking()
|
||||
{
|
||||
$parent = new DDC1690Parent();
|
||||
$child = new DDC1690Child();
|
||||
$parent->setName('parent');
|
||||
$child->setName('child');
|
||||
|
||||
$parent->setChild($child);
|
||||
$child->setParent($parent);
|
||||
|
||||
$this->_em->persist($parent);
|
||||
$this->_em->persist($child);
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
|
||||
$parentId = $parent->getId();
|
||||
$childId = $child->getId();
|
||||
unset($parent, $child);
|
||||
|
||||
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
|
||||
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
unset($parent, $child);
|
||||
|
||||
$parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);
|
||||
$child = $parent->getChild();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
unset($parent, $child);
|
||||
|
||||
$child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId);
|
||||
$parent = $child->getParent();
|
||||
|
||||
$this->assertEquals(1, count($parent->listeners));
|
||||
$this->assertEquals(1, count($child->listeners));
|
||||
}
|
||||
}
|
||||
|
||||
class NotifyBaseEntity implements NotifyPropertyChanged {
|
||||
public $listeners = array();
|
||||
|
||||
public function addPropertyChangedListener(PropertyChangedListener $listener) {
|
||||
if (!in_array($listener, $this->listeners)) {
|
||||
$this->listeners[] = $listener;
|
||||
}
|
||||
}
|
||||
|
||||
protected function onPropertyChanged($propName, $oldValue, $newValue) {
|
||||
if ($this->listeners) {
|
||||
foreach ($this->listeners as $listener) {
|
||||
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity @ChangeTrackingPolicy("NOTIFY") */
|
||||
class DDC1690Parent extends NotifyBaseEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
|
||||
/** @Column */
|
||||
private $name;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC1690Child") */
|
||||
private $child;
|
||||
|
||||
function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name) {
|
||||
$this->onPropertyChanged('name', $this->name, $name);
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function setChild($child) {
|
||||
$this->child = $child;
|
||||
}
|
||||
|
||||
function getChild() {
|
||||
return $this->child;
|
||||
}
|
||||
}
|
||||
|
||||
/** @Entity */
|
||||
class DDC1690Child extends NotifyBaseEntity {
|
||||
/** @Id @Column(type="integer") @GeneratedValue */
|
||||
private $id;
|
||||
|
||||
/** @Column */
|
||||
private $name;
|
||||
|
||||
/** @OneToOne(targetEntity="DDC1690Parent", mappedBy="child") */
|
||||
private $parent;
|
||||
|
||||
function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
function setName($name) {
|
||||
$this->onPropertyChanged('name', $this->name, $name);
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
function setParent($parent) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
function getParent() {
|
||||
return $this->parent;
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
use Doctrine\Tests\Models\Quote\Group;
|
||||
use Doctrine\Tests\Models\Quote\User;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-1845
|
||||
* @group DDC-1885
|
||||
@@ -170,4 +168,4 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0));
|
||||
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php
Normal file
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1918Test.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||
|
||||
/**
|
||||
* @group DDC-1918
|
||||
*/
|
||||
class DDC1918Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testLastPageCorrect()
|
||||
{
|
||||
$groups = array();
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$group = new CmsGroup();
|
||||
$group->name = "test";
|
||||
$this->_em->persist($group);
|
||||
|
||||
$groups[] = $group;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$user = new CmsUser();
|
||||
$user->username = "user$i";
|
||||
$user->name = "user$i";
|
||||
$user->status = "active";
|
||||
$user->groups = $groups;
|
||||
|
||||
$this->_em->persist($user);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$query = $this->_em->createQuery('SELECT u, g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
|
||||
$query->setFirstResult(6);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(3, count(iterator_to_array($paginator)));
|
||||
|
||||
$query->setFirstResult(8);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(2, count(iterator_to_array($paginator)));
|
||||
|
||||
$query->setFirstResult(10);
|
||||
$query->setMaxResults(3);
|
||||
|
||||
$paginator = new Paginator($query, true);
|
||||
$this->assertEquals(0, count(iterator_to_array($paginator)));
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
/**
|
||||
* @group DDC-1925
|
||||
* @group DDC-1210
|
||||
*/
|
||||
class DDC1925Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testIssue()
|
||||
{
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925User'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1925Product'),
|
||||
));
|
||||
|
||||
$user = new DDC1925User();
|
||||
$user->setTitle("Test User");
|
||||
$this->_em->persist($user);
|
||||
|
||||
$product = new DDC1925Product();
|
||||
$product->setTitle("Test product");
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
|
||||
$product->addBuyer($user);
|
||||
|
||||
$this->_em->getUnitOfWork()->computeChangeSets();
|
||||
|
||||
$this->_em->persist($product);
|
||||
$this->_em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table
|
||||
* @Entity
|
||||
*/
|
||||
class DDC1925Product
|
||||
{
|
||||
/**
|
||||
* @var integer $id
|
||||
*
|
||||
* @Column(name="id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string $title
|
||||
*
|
||||
* @Column(name="title", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="DDC1925User")
|
||||
* @JoinTable(
|
||||
* name="user_purchases",
|
||||
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
|
||||
* inverseJoinColumns={@JoinColumn(name="user_id", referencedColumnName="id")}
|
||||
* )
|
||||
*/
|
||||
private $buyers;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->buyers = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $buyers
|
||||
*/
|
||||
public function setBuyers($buyers)
|
||||
{
|
||||
$this->buyers = $buyers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBuyers()
|
||||
{
|
||||
return $this->buyers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DDC1925User $buyer
|
||||
*/
|
||||
public function addBuyer(DDC1925User $buyer)
|
||||
{
|
||||
$this->buyers[] = $buyer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table
|
||||
* @Entity
|
||||
*/
|
||||
class DDC1925User
|
||||
{
|
||||
/**
|
||||
* @var integer
|
||||
*
|
||||
* @Column(name="id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @Column(name="title", type="string", length=255)
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* Get id
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTitle()
|
||||
{
|
||||
return $this->title;
|
||||
}
|
||||
}
|
||||
177
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php
Executable file
177
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2012Test.php
Executable file
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
|
||||
/**
|
||||
* @group DDC-2012
|
||||
*/
|
||||
class DDC2012Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Type::addType(DDC2012TsVectorType::MYTYPE, __NAMESPACE__ . '\DDC2012TsVectorType');
|
||||
|
||||
DDC2012TsVectorType::$calls = array();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012Item'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2012ItemPerson'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$item = new DDC2012ItemPerson();
|
||||
$item->tsv = array('word1', 'word2', 'word3');
|
||||
|
||||
$this->_em->persist($item);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$item = $this->_em->find(get_class($item), $item->id);
|
||||
|
||||
$this->assertArrayHasKey('convertToDatabaseValueSQL', DDC2012TsVectorType::$calls);
|
||||
$this->assertArrayHasKey('convertToDatabaseValue', DDC2012TsVectorType::$calls);
|
||||
$this->assertArrayHasKey('convertToPHPValue', DDC2012TsVectorType::$calls);
|
||||
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
|
||||
$this->assertCount(1, DDC2012TsVectorType::$calls['convertToPHPValue']);
|
||||
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
|
||||
$this->assertEquals(array('word1', 'word2', 'word3'), $item->tsv);
|
||||
|
||||
|
||||
$item->tsv = array('word1', 'word2');
|
||||
|
||||
$this->_em->persist($item);
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$item = $this->_em->find(get_class($item), $item->id);
|
||||
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValueSQL']);
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToDatabaseValue']);
|
||||
$this->assertCount(2, DDC2012TsVectorType::$calls['convertToPHPValue']);
|
||||
|
||||
$this->assertInstanceOf(__NAMESPACE__ . '\DDC2012Item', $item);
|
||||
$this->assertEquals(array('word1', 'word2'), $item->tsv);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2010_item")
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="type_id", type="smallint")
|
||||
* @DiscriminatorMap({
|
||||
* 1 = "DDC2012ItemPerson"
|
||||
* })
|
||||
*/
|
||||
class DDC2012Item
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @GeneratedValue
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(name="tsv", type="tsvector", nullable=true)
|
||||
*/
|
||||
public $tsv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="ddc2010_item_person")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2012ItemPerson extends DDC2012Item
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
class DDC2012TsVectorType extends Type
|
||||
{
|
||||
const MYTYPE = 'tsvector';
|
||||
|
||||
public static $calls = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getVarcharTypeDeclarationSQL($fieldDeclaration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = implode(" ", $value);
|
||||
}
|
||||
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform)
|
||||
{
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'value' => $value,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
return explode(" ", strtolower($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
|
||||
{
|
||||
self::$calls[__FUNCTION__][] = array(
|
||||
'sqlExpr' => $sqlExpr,
|
||||
'platform' => $platform,
|
||||
);
|
||||
|
||||
// changed to upper expression to keep the test compatible with other Databases
|
||||
//sprintf('to_tsvector(%s)', $sqlExpr);
|
||||
|
||||
return $platform->getUpperExpression($sqlExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function canRequireSQLConversion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return self::MYTYPE;
|
||||
}
|
||||
}
|
||||
29
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php
Normal file
29
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2074Test.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceCategory;
|
||||
use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
|
||||
|
||||
/**
|
||||
* @group DDC-2074
|
||||
*/
|
||||
class DDC2074Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testShouldNotScheduleDeletionOnClonedInstances()
|
||||
{
|
||||
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
|
||||
$product = new ECommerceProduct();
|
||||
$category = new ECommerceCategory();
|
||||
$collection = new PersistentCollection($this->_em, $class, new ArrayCollection(array($category)));
|
||||
$collection->setOwner($product, $class->associationMappings['categories']);
|
||||
|
||||
$uow = $this->_em->getUnitOfWork();
|
||||
$clonedCollection = clone $collection;
|
||||
$clonedCollection->clear();
|
||||
|
||||
$this->assertEquals(0, count($uow->getScheduledCollectionDeletions()));
|
||||
}
|
||||
}
|
||||
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php
Normal file
62
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2175Test.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
/**
|
||||
* @group DDC-2175
|
||||
*/
|
||||
class DDC2175Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2175Entity'),
|
||||
));
|
||||
}
|
||||
|
||||
public function testIssue()
|
||||
{
|
||||
$entity = new DDC2175Entity();
|
||||
$entity->field = "foo";
|
||||
|
||||
$this->_em->persist($entity);
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $entity->version);
|
||||
|
||||
$entity->field = "bar";
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(2, $entity->version);
|
||||
|
||||
$entity->field = "baz";
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(3, $entity->version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorMap({"entity": "DDC2175Entity"})
|
||||
*/
|
||||
class DDC2175Entity
|
||||
{
|
||||
/**
|
||||
* @Id @GeneratedValue @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string")
|
||||
*/
|
||||
public $field;
|
||||
|
||||
/**
|
||||
* @Version
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $version;
|
||||
}
|
||||
52
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php
Normal file
52
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2182Test.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC2182Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function testPassColumnOptionsToJoinColumns()
|
||||
{
|
||||
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'mysql') {
|
||||
$this->markTestSkipped("This test is useful for all databases, but designed only for mysql.");
|
||||
}
|
||||
|
||||
$sql = $this->_schemaTool->getCreateSchemaSql(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionParent'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2182OptionChild'),
|
||||
));
|
||||
|
||||
$this->assertEquals("CREATE TABLE DDC2182OptionParent (id INT UNSIGNED NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[0]);
|
||||
$this->assertEquals("CREATE TABLE DDC2182OptionChild (id VARCHAR(255) NOT NULL, parent_id INT UNSIGNED DEFAULT NULL, INDEX IDX_B314D4AD727ACA70 (parent_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB", $sql[1]);
|
||||
$this->assertEquals("ALTER TABLE DDC2182OptionChild ADD CONSTRAINT FK_B314D4AD727ACA70 FOREIGN KEY (parent_id) REFERENCES DDC2182OptionParent (id)", $sql[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table
|
||||
*/
|
||||
class DDC2182OptionParent
|
||||
{
|
||||
/** @Id @Column(type="integer", options={"unsigned": true}) */
|
||||
private $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @Table
|
||||
*/
|
||||
class DDC2182OptionChild
|
||||
{
|
||||
/** @Id @Column */
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="DDC2182OptionParent")
|
||||
* @JoinColumn(referencedColumnName="id")
|
||||
*/
|
||||
private $parent;
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
@@ -922,26 +922,6 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertEquals('doctrineglobal_article_cms_cmsuser', $articleMetadata->associationMappings['author']['joinTable']['name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-984
|
||||
* @group DDC-559
|
||||
*/
|
||||
public function testFullyQualifiedClassNameShouldBeGivenToNamingStrategyPropertyToColumnName()
|
||||
{
|
||||
$namingStrategy = new MyPrefixNamingStrategy();
|
||||
$metadata = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress', $namingStrategy);
|
||||
|
||||
$metadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
|
||||
|
||||
$metadata->mapField(array('fieldName'=>'country'));
|
||||
$metadata->mapField(array('fieldName'=>'city'));
|
||||
|
||||
$this->assertEquals($metadata->fieldNames, array(
|
||||
'cmsaddress_country' => 'country',
|
||||
'cmsaddress_city' => 'city'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-1746
|
||||
*/
|
||||
@@ -1013,14 +993,3 @@ class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStra
|
||||
return strtolower($className);
|
||||
}
|
||||
}
|
||||
|
||||
class MyPrefixNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function propertyToColumnName($propertyName, $className = null)
|
||||
{
|
||||
return strtolower($this->classToTableName($className)) . '_' . $propertyName;
|
||||
}
|
||||
}
|
||||
@@ -54,4 +54,35 @@ class YamlMappingDriverTest extends AbstractMappingDriverTest
|
||||
$this->createClassMetadata('Doctrine\Tests\Models\Generic\SerializationModel');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2069
|
||||
*/
|
||||
public function testSpacesShouldBeIgnoredWhenUseExplode()
|
||||
{
|
||||
$metadata = $this->createClassMetadata(__NAMESPACE__.'\DDC2069Entity');
|
||||
$unique = $metadata->table['uniqueConstraints'][0]['columns'];
|
||||
$indexes = $metadata->table['indexes'][0]['columns'];
|
||||
|
||||
$nameField = $metadata->fieldMappings['name'];
|
||||
$valueField = $metadata->fieldMappings['value'];
|
||||
|
||||
$this->assertEquals('name', $unique[0]);
|
||||
$this->assertEquals('value', $unique[1]);
|
||||
|
||||
$this->assertEquals('value', $indexes[0]);
|
||||
$this->assertEquals('name', $indexes[1]);
|
||||
|
||||
$this->assertEquals(255, $nameField['length']);
|
||||
$this->assertEquals(255, $valueField['length']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DDC2069Entity
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $name;
|
||||
|
||||
public $value;
|
||||
}
|
||||
@@ -35,6 +35,9 @@ $metadata->mapField(array(
|
||||
'columnName' => 'user_email',
|
||||
'columnDefinition' => 'CHAR(32) NOT NULL',
|
||||
));
|
||||
$mapping = array('fieldName' => 'version', 'type' => 'integer');
|
||||
$metadata->setVersionMapping($mapping);
|
||||
$metadata->mapField($mapping);
|
||||
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
|
||||
$metadata->mapOneToOne(array(
|
||||
'fieldName' => 'address',
|
||||
@@ -121,4 +124,4 @@ $metadata->setSequenceGeneratorDefinition(array(
|
||||
'sequenceName' => 'tablename_seq',
|
||||
'allocationSize' => 100,
|
||||
'initialValue' => 1,
|
||||
));
|
||||
));
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
|
||||
<entity name="Doctrine\Tests\ORM\Mapping\User" table="cms_users">
|
||||
<options>
|
||||
<option name="foo">bar</option>
|
||||
@@ -36,7 +36,7 @@
|
||||
<generator strategy="AUTO"/>
|
||||
<sequence-generator sequence-name="tablename_seq" allocation-size="100" initial-value="1" />
|
||||
</id>
|
||||
|
||||
|
||||
<field name="name" column="name" type="string" length="50" nullable="true" unique="true">
|
||||
<options>
|
||||
<option name="foo">bar</option>
|
||||
@@ -46,12 +46,14 @@
|
||||
</options>
|
||||
</field>
|
||||
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
|
||||
|
||||
|
||||
<field name="version" type="integer" version="true" />
|
||||
|
||||
<one-to-one field="address" target-entity="Address" inversed-by="user">
|
||||
<cascade><cascade-remove /></cascade>
|
||||
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
|
||||
</one-to-one>
|
||||
|
||||
|
||||
<one-to-many field="phonenumbers" target-entity="Phonenumber" mapped-by="user" index-by="number" orphan-removal="true">
|
||||
<cascade>
|
||||
<cascade-persist/>
|
||||
@@ -60,7 +62,7 @@
|
||||
<order-by-field name="number" direction="ASC" />
|
||||
</order-by>
|
||||
</one-to-many>
|
||||
|
||||
|
||||
<many-to-many field="groups" target-entity="Group">
|
||||
<cascade>
|
||||
<cascade-all/>
|
||||
@@ -74,7 +76,7 @@
|
||||
</inverse-join-columns>
|
||||
</join-table>
|
||||
</many-to-many>
|
||||
|
||||
|
||||
</entity>
|
||||
|
||||
</doctrine-mapping>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
Doctrine\Tests\ORM\Mapping\DDC2069Entity:
|
||||
type: entity
|
||||
id:
|
||||
id:
|
||||
fields:
|
||||
name:
|
||||
type: string ( 255 )
|
||||
value:
|
||||
type: string ( 255 )
|
||||
uniqueConstraints:
|
||||
0:
|
||||
columns: name, value
|
||||
indexes:
|
||||
0:
|
||||
columns: value, name
|
||||
@@ -30,6 +30,9 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||
type: string
|
||||
column: user_email
|
||||
columnDefinition: CHAR(32) NOT NULL
|
||||
version:
|
||||
type: integer
|
||||
version: true
|
||||
oneToOne:
|
||||
address:
|
||||
targetEntity: Address
|
||||
@@ -73,4 +76,4 @@ Doctrine\Tests\ORM\Mapping\User:
|
||||
name_idx:
|
||||
columns: name
|
||||
0:
|
||||
columns: user_email
|
||||
columns: user_email
|
||||
|
||||
@@ -7,6 +7,7 @@ use Doctrine\ORM\Persisters\BasicEntityPersister;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeParent;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeChild;
|
||||
use Doctrine\Tests\Models\CustomType\CustomTypeFriend;
|
||||
use Doctrine\Common\Collections\Expr\Comparison;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
@@ -88,4 +89,13 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
|
||||
|
||||
$this->assertEquals('t0."simple-entity-id" AS simpleentityid1, t0."simple-entity-value" AS simpleentityvalue2', $method->invoke($persister));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2073
|
||||
*/
|
||||
public function testSelectConditionStatementIsNull()
|
||||
{
|
||||
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS);
|
||||
$this->assertEquals('test IS ?', $statement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -10,14 +10,42 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a');
|
||||
$query->expireQueryCache(true);
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, c1_.id AS id1, a2_.id AS id2, a2_.name AS name3, m0_.author_id AS author_id4, m0_.category_id AS category_id5 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
|
||||
"SELECT DISTINCT id0 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id) dctrn_result", $limitQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryWithSortPg()
|
||||
{
|
||||
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
|
||||
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
|
||||
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT id0, title1 FROM (SELECT m0_.id AS id0, m0_.title AS title1, c1_.id AS id2, a2_.id AS id3, a2_.name AS name4, m0_.author_id AS author_id5, m0_.category_id AS category_id6 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC) dctrn_result ORDER BY title1 ASC", $limitQuery->getSql()
|
||||
);
|
||||
|
||||
$this->entityManager->getConnection()->setDatabasePlatform($odp);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryPg()
|
||||
{
|
||||
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
|
||||
$this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
|
||||
|
||||
$this->testLimitSubquery();
|
||||
|
||||
$this->entityManager->getConnection()->setDatabasePlatform($odp);
|
||||
}
|
||||
|
||||
public function testCountQuery_MixedResultsWithName()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
|
||||
@@ -21,6 +21,18 @@ class LimitSubqueryWalkerTest extends PaginationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLimitSubqueryWithSort()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
'SELECT p, c, a FROM Doctrine\Tests\ORM\Tools\Pagination\MyBlogPost p JOIN p.category c JOIN p.author a ORDER BY p.title');
|
||||
$limitQuery = clone $query;
|
||||
$limitQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'));
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT DISTINCT m0_.id AS id0, m0_.title AS title1 FROM MyBlogPost m0_ INNER JOIN Category c1_ ON m0_.category_id = c1_.id INNER JOIN Author a2_ ON m0_.author_id = a2_.id ORDER BY m0_.title ASC", $limitQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountQuery_MixedResultsWithName()
|
||||
{
|
||||
$query = $this->entityManager->createQuery(
|
||||
|
||||
@@ -31,6 +31,8 @@ class MyBlogPost
|
||||
* @ManyToOne(targetEntity="Category")
|
||||
*/
|
||||
public $category;
|
||||
/** @column(type="string") */
|
||||
public $title;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT a0_.id AS id0, a0_.name AS name1, sum(a0_.name) AS sclr2 FROM Author a0_ WHERE a0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE 1 = 1 AND 2 = 2 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 OR 2 = 2) AND 3 = 3 AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (1 = 1 AND 2 = 2 OR 3 = 3) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ class WhereInWalkerTest extends PaginationTestCase
|
||||
$whereInQuery->setHint(WhereInWalker::HINT_PAGINATOR_ID_COUNT, 10);
|
||||
|
||||
$this->assertEquals(
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", $whereInQuery->getSql()
|
||||
"SELECT u0_.id AS id0, g1_.id AS id1 FROM User u0_ INNER JOIN user_group u2_ ON u0_.id = u2_.user_id INNER JOIN groups g1_ ON g1_.id = u2_.group_id WHERE (NOT 1 = 2) AND u0_.id IN (?)", $whereInQuery->getSql()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,31 @@ class ResolveTargetEntityListenerTest extends \Doctrine\Tests\OrmTestCase
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\ResolveTargetEntity', $meta['oneToMany']['targetEntity']);
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['oneToOne']['targetEntity']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-2109
|
||||
*/
|
||||
public function testAssertTableColumnsAreNotAddedInManyToMany()
|
||||
{
|
||||
$evm = $this->em->getEventManager();
|
||||
$this->listener->addResolveTargetEntity(
|
||||
'Doctrine\Tests\ORM\Tools\ResolveTargetInterface',
|
||||
'Doctrine\Tests\ORM\Tools\ResolveTargetEntity',
|
||||
array()
|
||||
);
|
||||
$this->listener->addResolveTargetEntity(
|
||||
'Doctrine\Tests\ORM\Tools\TargetInterface',
|
||||
'Doctrine\Tests\ORM\Tools\TargetEntity',
|
||||
array()
|
||||
);
|
||||
|
||||
$evm->addEventListener(Events::loadClassMetadata, $this->listener);
|
||||
$cm = $this->factory->getMetadataFor('Doctrine\Tests\ORM\Tools\ResolveTargetEntity');
|
||||
$meta = $cm->associationMappings['manyToMany'];
|
||||
|
||||
$this->assertSame('Doctrine\Tests\ORM\Tools\TargetEntity', $meta['targetEntity']);
|
||||
$this->assertEquals(array('resolvetargetentity_id', 'targetinterface_id'), $meta['joinTableColumns']);
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolveTargetInterface
|
||||
|
||||
@@ -44,8 +44,8 @@ class SchemaToolTest extends \Doctrine\Tests\OrmTestCase
|
||||
$schema = $schemaTool->getSchemaFromMetadata($classes);
|
||||
|
||||
$expected = array('foo' => 'bar', 'baz' => array('key' => 'val'));
|
||||
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables optionss");
|
||||
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getOptions(), "options annotation are passed to the tables options");
|
||||
$this->assertEquals($expected, $schema->getTable('TestEntityWithAnnotationOptionsAttribute')->getColumn('test')->getCustomSchemaOptions(), "options annotation are passed to the columns customSchemaOptions");
|
||||
}
|
||||
|
||||
|
||||
@@ -204,6 +204,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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user