From fb055ca75d3ee4f126f17869cc6cb645d3bb5cd2 Mon Sep 17 00:00:00 2001
From: Thomas Rothe
Date: Sun, 16 Dec 2012 18:20:10 +0100
Subject: [PATCH 001/332] fixed problems with joined inheritance and composite
keys
SchemaTool now creates all Id columns not just only the first one.
Insert statement for child entity now contains parameter for additional key columns only once.
---
.../Persisters/JoinedSubclassPersister.php | 5 +-
lib/Doctrine/ORM/Tools/SchemaTool.php | 141 ++++++++++++++----
.../JoinedChildClass.php | 21 +++
.../JoinedRootClass.php | 25 ++++
.../JoinedTableCompositeKeyTest.php | 64 ++++++++
.../Doctrine/Tests/OrmFunctionalTestCase.php | 10 ++
6 files changed, 233 insertions(+), 33 deletions(-)
create mode 100644 tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php
create mode 100644 tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedRootClass.php
create mode 100644 tests/Doctrine/Tests/ORM/Functional/JoinedTableCompositeKeyTest.php
diff --git a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
index 58aa7df17..8ad88c1d8 100644
--- a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
+++ b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
@@ -182,6 +182,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// Execute inserts on subtables.
// The order doesn't matter because all child tables link to the root table via FK.
foreach ($subTableStmts as $tableName => $stmt) {
+ /** @var \Doctrine\DBAL\Statement $stmt */
$paramIndex = 1;
$data = isset($insertData[$tableName])
? $insertData[$tableName]
@@ -194,7 +195,9 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
foreach ($data as $columnName => $value) {
- $stmt->bindValue($paramIndex++, $value, $this->columnTypes[$columnName]);
+ if (!isset($id[$columnName])) {
+ $stmt->bindValue($paramIndex++, $value, $this->columnTypes[$columnName]);
+ }
}
$stmt->execute();
diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php
index 6a5319b1c..f917b9d06 100644
--- a/lib/Doctrine/ORM/Tools/SchemaTool.php
+++ b/lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -91,7 +91,7 @@ class SchemaTool
foreach ($createSchemaSql as $sql) {
try {
$conn->executeQuery($sql);
- } catch(\Exception $e) {
+ } catch (\Exception $e) {
throw ToolsException::schemaToolFailure($sql, $e);
}
}
@@ -147,6 +147,7 @@ class SchemaTool
$blacklistedFks = array();
foreach ($classes as $class) {
+ /** @var \Doctrine\ORM\Mapping\ClassMetadata $class */
if ($this->processingNotRequired($class, $processedClasses)) {
continue;
}
@@ -154,7 +155,7 @@ class SchemaTool
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
if ($class->isInheritanceTypeSingleTable()) {
- $columns = $this->gatherColumns($class, $table);
+ $this->gatherColumns($class, $table);
$this->gatherRelationsSql($class, $table, $schema, $addedFks, $blacklistedFks);
// Add the discriminator column
@@ -177,7 +178,11 @@ class SchemaTool
$pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) {
- $columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
+ $columnName = $this->quoteStrategy->getColumnName(
+ $mapping['fieldName'],
+ $class,
+ $this->platform
+ );
$this->gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($fieldName)) {
@@ -193,20 +198,36 @@ class SchemaTool
$this->addDiscriminatorColumnDefinition($class, $table);
} else {
// Add an ID FK column to child tables
- /* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
- $idMapping = $class->fieldMappings[$class->identifier[0]];
- $this->gatherColumn($class, $idMapping, $table);
- $columnName = $this->quoteStrategy->getColumnName($class->identifier[0], $class, $this->platform);
- // TODO: This seems rather hackish, can we optimize it?
- $table->getColumn($columnName)->setAutoincrement(false);
+ $inheritedKeyColumns = array();
+ foreach ($class->identifier as $identifierField) {
+ $idMapping = $class->fieldMappings[$identifierField];
+ if (isset($idMapping['inherited'])) {
+ $this->gatherColumn($class, $idMapping, $table);
+ $columnName = $this->quoteStrategy->getColumnName(
+ $identifierField,
+ $class,
+ $this->platform
+ );
+ // TODO: This seems rather hackish, can we optimize it?
+ $table->getColumn($columnName)->setAutoincrement(false);
- $pkColumns[] = $columnName;
+ $pkColumns[] = $columnName;
+ $inheritedKeyColumns[] = $columnName;
+ }
+ }
+ if (!empty($inheritedKeyColumns)) {
+ // Add a FK constraint on the ID column
+ $table->addForeignKeyConstraint(
+ $this->quoteStrategy->getTableName(
+ $this->em->getClassMetadata($class->rootEntityName),
+ $this->platform
+ ),
+ $inheritedKeyColumns,
+ $inheritedKeyColumns,
+ array('onDelete' => 'CASCADE')
+ );
+ }
- // Add a FK constraint on the ID column
- $table->addForeignKeyConstraint(
- $this->quoteStrategy->getTableName($this->em->getClassMetadata($class->rootEntityName), $this->platform),
- array($columnName), array($columnName), array('onDelete' => 'CASCADE')
- );
}
$table->setPrimaryKey($pkColumns);
@@ -268,7 +289,10 @@ class SchemaTool
}
if ($eventManager->hasListeners(ToolEvents::postGenerateSchemaTable)) {
- $eventManager->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
+ $eventManager->dispatchEvent(
+ ToolEvents::postGenerateSchemaTable,
+ new GenerateSchemaTableEventArgs($class, $schema, $table)
+ );
}
}
@@ -277,7 +301,10 @@ class SchemaTool
}
if ($eventManager->hasListeners(ToolEvents::postGenerateSchema)) {
- $eventManager->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->em, $schema));
+ $eventManager->dispatchEvent(
+ ToolEvents::postGenerateSchema,
+ new GenerateSchemaEventArgs($this->em, $schema)
+ );
}
return $schema;
@@ -296,7 +323,9 @@ class SchemaTool
{
$discrColumn = $class->discriminatorColumn;
- if ( ! isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) {
+ if ( ! isset($discrColumn['type']) ||
+ (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)
+ ) {
$discrColumn['type'] = 'string';
$discrColumn['length'] = 255;
}
@@ -339,7 +368,7 @@ class SchemaTool
// For now, this is a hack required for single table inheritence, since this method is called
// twice by single table inheritence relations
- if(!$table->hasIndex('primary')) {
+ if (!$table->hasIndex('primary')) {
//$table->setPrimaryKey($pkColumns);
}
}
@@ -367,7 +396,7 @@ class SchemaTool
$options['platformOptions'] = array();
$options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false;
- if(strtolower($columnType) == 'string' && $options['length'] === null) {
+ if (strtolower($columnType) == 'string' && $options['length'] === null) {
$options['length'] = 255;
}
@@ -452,9 +481,18 @@ class SchemaTool
if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
$primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type
- $this->_gatherRelationJoinColumns($mapping['joinColumns'], $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints, $addedFks, $blacklistedFks);
+ $this->gatherRelationJoinColumns(
+ $mapping['joinColumns'],
+ $table,
+ $foreignClass,
+ $mapping,
+ $primaryKeyColumns,
+ $uniqueConstraints,
+ $addedFks,
+ $blacklistedFks
+ );
- foreach($uniqueConstraints as $indexName => $unique) {
+ foreach ($uniqueConstraints as $indexName => $unique) {
$table->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
}
} elseif ($mapping['type'] == ClassMetadata::ONE_TO_MANY && $mapping['isOwningSide']) {
@@ -464,19 +502,39 @@ class SchemaTool
// create join table
$joinTable = $mapping['joinTable'];
- $theJoinTable = $schema->createTable($this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform));
+ $theJoinTable = $schema->createTable(
+ $this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform)
+ );
$primaryKeyColumns = $uniqueConstraints = array();
// Build first FK constraint (relation table => source table)
- $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints, $addedFks, $blacklistedFks);
+ $this->gatherRelationJoinColumns(
+ $joinTable['joinColumns'],
+ $theJoinTable,
+ $class,
+ $mapping,
+ $primaryKeyColumns,
+ $uniqueConstraints,
+ $addedFks,
+ $blacklistedFks
+ );
// Build second FK constraint (relation table => target table)
- $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints, $addedFks, $blacklistedFks);
+ $this->gatherRelationJoinColumns(
+ $joinTable['inverseJoinColumns'],
+ $theJoinTable,
+ $foreignClass,
+ $mapping,
+ $primaryKeyColumns,
+ $uniqueConstraints,
+ $addedFks,
+ $blacklistedFks
+ );
$theJoinTable->setPrimaryKey($primaryKeyColumns);
- foreach($uniqueConstraints as $indexName => $unique) {
+ foreach ($uniqueConstraints as $indexName => $unique) {
$theJoinTable->addUniqueIndex($unique['columns'], is_numeric($indexName) ? null : $indexName);
}
}
@@ -507,7 +565,8 @@ class SchemaTool
if (in_array($referencedColumnName, $class->getIdentifierColumnNames())) {
// it seems to be an entity as foreign key
foreach ($class->getIdentifierFieldNames() as $fieldName) {
- if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
+ if ($class->hasAssociation($fieldName)
+ && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
return $this->getDefiningClass(
$this->em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
$class->getSingleAssociationReferencedJoinColumnName($fieldName)
@@ -531,8 +590,16 @@ class SchemaTool
* @param array $addedFks
* @param array $blacklistedFks
*/
- private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints, &$addedFks, &$blacklistedFks)
- {
+ private function gatherRelationJoinColumns(
+ $joinColumns,
+ $theJoinTable,
+ $class,
+ $mapping,
+ &$primaryKeyColumns,
+ &$uniqueConstraints,
+ &$addedFks,
+ &$blacklistedFks
+ ) {
$localColumns = array();
$foreignColumns = array();
$fkOptions = array();
@@ -540,7 +607,10 @@ class SchemaTool
foreach ($joinColumns as $joinColumn) {
- list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']);
+ list($definingClass, $referencedFieldName) = $this->getDefiningClass(
+ $class,
+ $joinColumn['referencedColumnName']
+ );
if ( ! $definingClass) {
throw new \Doctrine\ORM\ORMException(
@@ -550,7 +620,11 @@ class SchemaTool
}
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
- $quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $class, $this->platform);
+ $quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName(
+ $joinColumn,
+ $class,
+ $this->platform
+ );
$primaryKeyColumns[] = $quotedColumnName;
$localColumns[] = $quotedColumnName;
@@ -617,7 +691,10 @@ class SchemaTool
} elseif (!isset($blacklistedFks[$compositeName])) {
$addedFks[$compositeName] = array('foreignTableName' => $foreignTableName, 'foreignColumns' => $foreignColumns);
$theJoinTable->addUnnamedForeignKeyConstraint(
- $foreignTableName, $localColumns, $foreignColumns, $fkOptions
+ $foreignTableName,
+ $localColumns,
+ $foreignColumns,
+ $fkOptions
);
}
}
diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php b/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php
new file mode 100644
index 000000000..ba5973647
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/CompositeKeyInheritance/JoinedChildClass.php
@@ -0,0 +1,21 @@
+useModelSet('compositekeyinheritance');
+ parent::setUp();
+
+ }
+
+ /**
+ *
+ */
+ public function testInsertWithCompositeKey()
+ {
+ $childEntity = new JoinedChildClass();
+ $this->_em->persist($childEntity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $entity = $this->findEntity();
+ $this->assertEquals($childEntity, $entity);
+ }
+
+ /**
+ *
+ */
+ public function testUpdateWithCompositeKey()
+ {
+ $childEntity = new JoinedChildClass();
+ $this->_em->persist($childEntity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $entity = $this->findEntity();
+ $entity->extension = 'ext-new';
+ $this->_em->persist($entity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $persistedEntity = $this->findEntity();
+ $this->assertEquals($entity, $persistedEntity);
+ }
+
+ /**
+ * @return \Doctrine\Tests\Models\CompositeKeyInheritance\JoinedChildClass
+ */
+ private function findEntity()
+ {
+ return $this->_em->find(
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\JoinedRootClass',
+ array('keyPart1' => 'part-1', 'keyPart2' => 'part-2')
+ );
+ }
+}
diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php
index 4b72a9a27..872f86c81 100644
--- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php
+++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php
@@ -124,6 +124,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\CustomType\CustomTypeParent',
'Doctrine\Tests\Models\CustomType\CustomTypeUpperCase',
),
+ 'compositekeyinheritance' => array(
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\JoinedRootClass',
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\JoinedChildClass',
+ )
);
protected function useModelSet($setName)
@@ -239,6 +243,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
$conn->executeUpdate('DELETE FROM customtype_uppercases');
}
+ if (isset($this->_usedModelSets['compositekeyinheritance'])) {
+ $conn->executeUpdate('DELETE FROM JoinedChildClass');
+ $conn->executeUpdate('DELETE FROM JoinedRootClass');
+ }
+
+
$this->_em->clear();
}
From 86c33d78d08afa3ed0b759884e09d497878094e5 Mon Sep 17 00:00:00 2001
From: Thomas Rothe
Date: Mon, 17 Dec 2012 11:01:20 +0100
Subject: [PATCH 002/332] inheritance with composite keys
added tests for single table inheritance
---
.../SingleChildClass.php | 21 ++++++
.../SingleRootClass.php | 25 ++++++++
.../SingleTableCompositeKeyTest.php | 64 +++++++++++++++++++
.../Doctrine/Tests/OrmFunctionalTestCase.php | 3 +
4 files changed, 113 insertions(+)
create mode 100644 tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php
create mode 100644 tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleRootClass.php
create mode 100644 tests/Doctrine/Tests/ORM/Functional/SingleTableCompositeKeyTest.php
diff --git a/tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php b/tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php
new file mode 100644
index 000000000..05579bce4
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/CompositeKeyInheritance/SingleChildClass.php
@@ -0,0 +1,21 @@
+useModelSet('compositekeyinheritance');
+ parent::setUp();
+
+ }
+
+ /**
+ *
+ */
+ public function testInsertWithCompositeKey()
+ {
+ $childEntity = new SingleChildClass();
+ $this->_em->persist($childEntity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $entity = $this->findEntity();
+ $this->assertEquals($childEntity, $entity);
+ }
+
+ /**
+ *
+ */
+ public function testUpdateWithCompositeKey()
+ {
+ $childEntity = new SingleChildClass();
+ $this->_em->persist($childEntity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $entity = $this->findEntity();
+ $entity->extension = 'ext-new';
+ $this->_em->persist($entity);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $persistedEntity = $this->findEntity();
+ $this->assertEquals($entity, $persistedEntity);
+ }
+
+ /**
+ * @return \Doctrine\Tests\Models\CompositeKeyInheritance\JoinedChildClass
+ */
+ private function findEntity()
+ {
+ return $this->_em->find(
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\SingleRootClass',
+ array('keyPart1' => 'part-1', 'keyPart2' => 'part-2')
+ );
+ }
+}
diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php
index 872f86c81..18fd19297 100644
--- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php
+++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php
@@ -127,6 +127,8 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
'compositekeyinheritance' => array(
'Doctrine\Tests\Models\CompositeKeyInheritance\JoinedRootClass',
'Doctrine\Tests\Models\CompositeKeyInheritance\JoinedChildClass',
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\SingleRootClass',
+ 'Doctrine\Tests\Models\CompositeKeyInheritance\SingleChildClass',
)
);
@@ -246,6 +248,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase
if (isset($this->_usedModelSets['compositekeyinheritance'])) {
$conn->executeUpdate('DELETE FROM JoinedChildClass');
$conn->executeUpdate('DELETE FROM JoinedRootClass');
+ $conn->executeUpdate('DELETE FROM SingleRootClass');
}
From 35562d3a4d70a2bc0f215ed8fcccfa76b1c66064 Mon Sep 17 00:00:00 2001
From: Benjamin Morel
Date: Tue, 12 Feb 2013 15:51:24 +0000
Subject: [PATCH 003/332] Unit tests: cleaned up outdated / unused / commented
out code.
---
tests/Doctrine/Tests/Mocks/DriverMock.php | 14 --------
.../Tests/Mocks/EntityManagerMock.php | 22 -------------
.../Tests/Mocks/EntityPersisterMock.php | 19 -----------
.../Tests/Mocks/HydratorMockStatement.php | 17 +---------
.../Tests/Mocks/IdentityIdGeneratorMock.php | 16 ----------
tests/Doctrine/Tests/Mocks/SequenceMock.php | 32 -------------------
tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php | 22 -------------
tests/Doctrine/Tests/ORM/UnitOfWorkTest.php | 7 ----
8 files changed, 1 insertion(+), 148 deletions(-)
delete mode 100644 tests/Doctrine/Tests/Mocks/IdentityIdGeneratorMock.php
diff --git a/tests/Doctrine/Tests/Mocks/DriverMock.php b/tests/Doctrine/Tests/Mocks/DriverMock.php
index c7a101094..af9f869ce 100644
--- a/tests/Doctrine/Tests/Mocks/DriverMock.php
+++ b/tests/Doctrine/Tests/Mocks/DriverMock.php
@@ -25,20 +25,6 @@ class DriverMock implements \Doctrine\DBAL\Driver
return new DriverConnectionMock();
}
- /**
- * Constructs the Sqlite PDO DSN.
- *
- * @param array $params
- *
- * @return string The DSN.
- *
- * @override
- */
- protected function _constructPdoDsn(array $params)
- {
- return "";
- }
-
/**
* {@inheritdoc}
*/
diff --git a/tests/Doctrine/Tests/Mocks/EntityManagerMock.php b/tests/Doctrine/Tests/Mocks/EntityManagerMock.php
index 91f1c9daa..b27e96c4b 100644
--- a/tests/Doctrine/Tests/Mocks/EntityManagerMock.php
+++ b/tests/Doctrine/Tests/Mocks/EntityManagerMock.php
@@ -38,11 +38,6 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
*/
private $_proxyFactoryMock;
- /**
- * @var array
- */
- private $_idGenerators = array();
-
/**
* {@inheritdoc}
*/
@@ -103,21 +98,4 @@ class EntityManagerMock extends \Doctrine\ORM\EntityManager
return new EntityManagerMock($conn, $config, $eventManager);
}
-/*
- public function setIdGenerator($className, $generator)
- {
- $this->_idGenerators[$className] = $generator;
- }
-*/
- /** @override */
-/* public function getIdGenerator($className)
- {
-
- if (isset($this->_idGenerators[$className])) {
- return $this->_idGenerators[$className];
- }
-
- return parent::getIdGenerator($className);
- }
- */
}
diff --git a/tests/Doctrine/Tests/Mocks/EntityPersisterMock.php b/tests/Doctrine/Tests/Mocks/EntityPersisterMock.php
index 862000eb5..41b74607d 100644
--- a/tests/Doctrine/Tests/Mocks/EntityPersisterMock.php
+++ b/tests/Doctrine/Tests/Mocks/EntityPersisterMock.php
@@ -42,25 +42,6 @@ class EntityPersisterMock extends \Doctrine\ORM\Persisters\BasicEntityPersister
*/
private $existsCalled = false;
- /**
- * @param object $entity
- *
- * @return mixed
- *
- * @override
- */
- public function insert($entity)
- {
- $this->inserts[] = $entity;
- if ( ! is_null($this->mockIdGeneratorType) && $this->mockIdGeneratorType == \Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY
- || $this->class->isIdGeneratorIdentity()) {
- $id = $this->identityColumnValueCounter++;
- $this->postInsertIds[$id] = $entity;
- return $id;
- }
- return null;
- }
-
/**
* @param object $entity
*
diff --git a/tests/Doctrine/Tests/Mocks/HydratorMockStatement.php b/tests/Doctrine/Tests/Mocks/HydratorMockStatement.php
index 6c9ff6b8b..9d06ba6b8 100644
--- a/tests/Doctrine/Tests/Mocks/HydratorMockStatement.php
+++ b/tests/Doctrine/Tests/Mocks/HydratorMockStatement.php
@@ -68,21 +68,6 @@ class HydratorMockStatement implements \IteratorAggregate, \Doctrine\DBAL\Driver
return true;
}
- /**
- * @param array $resultSet
- *
- * @return void
- */
- public function setResultSet(array $resultSet)
- {
- reset($resultSet);
- $this->_resultSet = $resultSet;
- }
-
- public function bindColumn($column, &$param, $type = null)
- {
- }
-
/**
* {@inheritdoc}
*/
@@ -93,7 +78,7 @@ class HydratorMockStatement implements \IteratorAggregate, \Doctrine\DBAL\Driver
/**
* {@inheritdoc}
*/
- public function bindParam($column, &$variable, $type = null, $length = null, $driverOptions = array())
+ public function bindParam($column, &$variable, $type = null)
{
}
diff --git a/tests/Doctrine/Tests/Mocks/IdentityIdGeneratorMock.php b/tests/Doctrine/Tests/Mocks/IdentityIdGeneratorMock.php
deleted file mode 100644
index 868b7fe44..000000000
--- a/tests/Doctrine/Tests/Mocks/IdentityIdGeneratorMock.php
+++ /dev/null
@@ -1,16 +0,0 @@
-_mockPostInsertId = $id;
- }
-}
diff --git a/tests/Doctrine/Tests/Mocks/SequenceMock.php b/tests/Doctrine/Tests/Mocks/SequenceMock.php
index 8612e0d27..4f5123004 100644
--- a/tests/Doctrine/Tests/Mocks/SequenceMock.php
+++ b/tests/Doctrine/Tests/Mocks/SequenceMock.php
@@ -22,30 +22,6 @@ class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator
return $this->_sequenceNumber++;
}
- /**
- * @override
- */
- public function nextId($seqName, $ondemand = true)
- {
- return $this->_sequenceNumber++;
- }
-
- /**
- * @override
- */
- public function lastInsertId($table = null, $field = null)
- {
- return $this->_sequenceNumber - 1;
- }
-
- /**
- * @override
- */
- public function currId($seqName)
- {
- return $this->_sequenceNumber;
- }
-
/* Mock API */
/**
@@ -55,12 +31,4 @@ class SequenceMock extends \Doctrine\ORM\Id\SequenceGenerator
{
$this->_sequenceNumber = 0;
}
-
- /**
- * @return void
- */
- public function autoinc()
- {
- $this->_sequenceNumber++;
- }
}
diff --git a/tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php b/tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php
index 95c511c70..0dd0671d0 100644
--- a/tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php
+++ b/tests/Doctrine/Tests/Mocks/UnitOfWorkMock.php
@@ -52,28 +52,6 @@ class UnitOfWorkMock extends \Doctrine\ORM\UnitOfWork
$this->_persisterMock[$entityName] = $persister;
}
- /**
- * @param object $entity
- * @param array $mockChangeSet
- *
- * @return void
- */
- public function setDataChangeSet($entity, array $mockChangeSet)
- {
- $this->_mockDataChangeSets[spl_object_hash($entity)] = $mockChangeSet;
- }
-
- /**
- * @param object $entity
- * @param mixed $state
- *
- * @return void
- */
- public function setEntityState($entity, $state)
- {
- $this->_entityStates[spl_object_hash($entity)] = $state;
- }
-
/**
* {@inheritdoc}
*/
diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
index e091483e3..9a645d52e 100644
--- a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
+++ b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
@@ -7,7 +7,6 @@ use Doctrine\Tests\Mocks\ConnectionMock;
use Doctrine\Tests\Mocks\EntityManagerMock;
use Doctrine\Tests\Mocks\UnitOfWorkMock;
use Doctrine\Tests\Mocks\EntityPersisterMock;
-use Doctrine\Tests\Mocks\IdentityIdGeneratorMock;
use Doctrine\Tests\Models\Forum\ForumUser;
use Doctrine\Tests\Models\Forum\ForumAvatar;
@@ -54,8 +53,6 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
// Setup fake persister and id generator for identity generation
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
- //$idGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
- //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $idGeneratorMock);
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
// Test
@@ -96,14 +93,10 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
//ForumUser
$userPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumUser"));
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumUser', $userPersister);
- //$userIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
- //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumUser', $userIdGeneratorMock);
$userPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
// ForumAvatar
$avatarPersister = new EntityPersisterMock($this->_emMock, $this->_emMock->getClassMetadata("Doctrine\Tests\Models\Forum\ForumAvatar"));
$this->_unitOfWork->setEntityPersister('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarPersister);
- //$avatarIdGeneratorMock = new IdentityIdGeneratorMock($this->_emMock);
- //$this->_emMock->setIdGenerator('Doctrine\Tests\Models\Forum\ForumAvatar', $avatarIdGeneratorMock);
$avatarPersister->setMockIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_IDENTITY);
// Test
From 5206566707971db0b68d5256958e68b820dbab78 Mon Sep 17 00:00:00 2001
From: Abdellatif Ait boudad
Date: Tue, 26 Feb 2013 00:02:34 +0000
Subject: [PATCH 004/332] Remove dead code
---
lib/Doctrine/ORM/Event/OnFlushEventArgs.php | 24 ---------------------
1 file changed, 24 deletions(-)
diff --git a/lib/Doctrine/ORM/Event/OnFlushEventArgs.php b/lib/Doctrine/ORM/Event/OnFlushEventArgs.php
index ea5d0566e..2dd05a5fa 100644
--- a/lib/Doctrine/ORM/Event/OnFlushEventArgs.php
+++ b/lib/Doctrine/ORM/Event/OnFlushEventArgs.php
@@ -38,9 +38,6 @@ class OnFlushEventArgs extends EventArgs
*/
private $em;
- //private $entitiesToPersist = array();
- //private $entitiesToRemove = array();
-
/**
* Constructor.
*
@@ -61,25 +58,4 @@ class OnFlushEventArgs extends EventArgs
return $this->em;
}
- /*
- public function addEntityToPersist($entity)
- {
-
- }
-
- public function addEntityToRemove($entity)
- {
-
- }
-
- public function addEntityToUpdate($entity)
- {
-
- }
-
- public function getEntitiesToPersist()
- {
- return $this->_entitiesToPersist;
- }
- */
}
From f9519479fcbad6cd8c7fd5e16e9f3141c4b5be82 Mon Sep 17 00:00:00 2001
From: Norbert Orzechowicz
Date: Thu, 28 Feb 2013 10:10:28 +0100
Subject: [PATCH 005/332] Fix SimpleObjectHydrator behavior when column not
exists in fieldMappings, relationMappings and metaMappings
---
.../Hydration/SimpleObjectHydrator.php | 5 +++-
.../Hydration/SimpleObjectHydratorTest.php | 24 +++++++++++++++++++
2 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
index abd29e76f..249b60462 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
@@ -176,10 +176,13 @@ class SimpleObjectHydrator extends AbstractHydrator
// One solution is to load the association, but it might require extra efforts.
return array('name' => $column);
- default:
+ case (isset($this->_rsm->metaMappings[$column])):
return array(
'name' => $this->_rsm->metaMappings[$column]
);
+
+ default:
+ return null;
}
}
}
diff --git a/tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php b/tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php
index 80f90e7ff..400b5829f 100644
--- a/tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php
+++ b/tests/Doctrine/Tests/ORM/Hydration/SimpleObjectHydratorTest.php
@@ -34,4 +34,28 @@ class SimpleObjectHydratorTest extends HydrationTestCase
$hydrator = new \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator($this->_em);
$hydrator->hydrateAll($stmt, $rsm);
}
+
+ public function testExtraFieldInResultSetShouldBeIgnore()
+ {
+ $rsm = new ResultSetMapping;
+ $rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsAddress', 'a');
+ $rsm->addFieldResult('a', 'a__id', 'id');
+ $rsm->addFieldResult('a', 'a__city', 'city');
+ $resultSet = array(
+ array(
+ 'a__id' => '1',
+ 'a__city' => 'Cracow',
+ 'doctrine_rownum' => '1'
+ ),
+ );
+
+ $expectedEntity = new \Doctrine\Tests\Models\CMS\CmsAddress();
+ $expectedEntity->id = 1;
+ $expectedEntity->city = 'Cracow';
+
+ $stmt = new HydratorMockStatement($resultSet);
+ $hydrator = new \Doctrine\ORM\Internal\Hydration\SimpleObjectHydrator($this->_em);
+ $result = $hydrator->hydrateAll($stmt, $rsm);
+ $this->assertEquals($result[0], $expectedEntity);
+ }
}
From 20b46fe17f785cee164e9cb55f7f1bc7401616fc Mon Sep 17 00:00:00 2001
From: Matthieu Napoli
Date: Fri, 1 Mar 2013 15:11:21 +0100
Subject: [PATCH 006/332] Fixed broken code block in documentation
---
docs/en/cookbook/resolve-target-entity-listener.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/en/cookbook/resolve-target-entity-listener.rst b/docs/en/cookbook/resolve-target-entity-listener.rst
index c3f866532..c77459183 100644
--- a/docs/en/cookbook/resolve-target-entity-listener.rst
+++ b/docs/en/cookbook/resolve-target-entity-listener.rst
@@ -1,4 +1,4 @@
-Keeping your Modules independent
+Keeping your Modules independents
=================================
.. versionadded:: 2.2
@@ -112,7 +112,7 @@ An InvoiceSubjectInterface
Next, we need to configure the listener. Add this to the area you set up Doctrine. You
must set this up in the way outlined below, otherwise you can not be guaranteed that
-the targetEntity resolution will occur reliably::
+the targetEntity resolution will occur reliably:
.. code-block:: php
From 32dd7f1a0eb4455596ad099b4167cd33b487da04 Mon Sep 17 00:00:00 2001
From: Matthieu Napoli
Date: Fri, 1 Mar 2013 15:16:59 +0100
Subject: [PATCH 007/332] Missing link to a cookbook in the docs
The cookbook existed in the docs but there was no link to it in the docs.
---
docs/en/index.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/en/index.rst b/docs/en/index.rst
index 9536ee56d..69a3cacf8 100644
--- a/docs/en/index.rst
+++ b/docs/en/index.rst
@@ -113,7 +113,8 @@ Cookbook
:doc:`Using Wakeup Or Clone ` |
:doc:`Working with DateTime ` |
:doc:`Validation ` |
- :doc:`Entities in the Session `
+ :doc:`Entities in the Session ` |
+ :doc:`Keeping your Modules independents `
* **Integration into Frameworks/Libraries**
:doc:`CodeIgniter `
From 1846f5845cc803f6ecda8e0ddad02d73951be3f8 Mon Sep 17 00:00:00 2001
From: MDrollette
Date: Fri, 1 Mar 2013 11:58:51 -0600
Subject: [PATCH 008/332] alias the proxy class on import to avoid "already
exists" error
---
lib/Doctrine/ORM/Proxy/ProxyFactory.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
index f23b1063f..c8964804e 100644
--- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php
+++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
@@ -23,7 +23,7 @@ use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Proxy\AbstractProxyFactory;
use Doctrine\Common\Proxy\ProxyDefinition;
use Doctrine\Common\Util\ClassUtils;
-use Doctrine\Common\Proxy\Proxy;
+use Doctrine\Common\Proxy\Proxy as BaseProxy;
use Doctrine\Common\Proxy\ProxyGenerator;
use Doctrine\ORM\ORMInvalidArgumentException;
use Doctrine\ORM\Persisters\BasicEntityPersister;
@@ -116,7 +116,7 @@ class ProxyFactory extends AbstractProxyFactory
private function createInitializer(ClassMetadata $classMetadata, BasicEntityPersister $entityPersister)
{
if ($classMetadata->getReflectionClass()->hasMethod('__wakeup')) {
- return function (Proxy $proxy) use ($entityPersister, $classMetadata) {
+ return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) {
$proxy->__setInitializer(null);
$proxy->__setCloner(null);
@@ -141,7 +141,7 @@ class ProxyFactory extends AbstractProxyFactory
};
}
- return function (Proxy $proxy) use ($entityPersister, $classMetadata) {
+ return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) {
$proxy->__setInitializer(null);
$proxy->__setCloner(null);
@@ -177,7 +177,7 @@ class ProxyFactory extends AbstractProxyFactory
*/
private function createCloner(ClassMetadata $classMetadata, BasicEntityPersister $entityPersister)
{
- return function (Proxy $proxy) use ($entityPersister, $classMetadata) {
+ return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) {
if ($proxy->__isInitialized()) {
return;
}
From 159daa9985edfdecd73d490f79a614baba103de2 Mon Sep 17 00:00:00 2001
From: Matthieu Napoli
Date: Sat, 2 Mar 2013 18:40:58 +0100
Subject: [PATCH 009/332] Reverted incorrect typo fix -_-
---
docs/en/cookbook/resolve-target-entity-listener.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/cookbook/resolve-target-entity-listener.rst b/docs/en/cookbook/resolve-target-entity-listener.rst
index c77459183..71b746602 100644
--- a/docs/en/cookbook/resolve-target-entity-listener.rst
+++ b/docs/en/cookbook/resolve-target-entity-listener.rst
@@ -1,4 +1,4 @@
-Keeping your Modules independents
+Keeping your Modules independent
=================================
.. versionadded:: 2.2
From 2eff096dddf8d56469e6877fcd40b9d06ae98e61 Mon Sep 17 00:00:00 2001
From: Matthieu Napoli
Date: Sat, 2 Mar 2013 18:42:38 +0100
Subject: [PATCH 010/332] Typo
---
docs/en/index.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/index.rst b/docs/en/index.rst
index 69a3cacf8..f0f94c3c1 100644
--- a/docs/en/index.rst
+++ b/docs/en/index.rst
@@ -114,7 +114,7 @@ Cookbook
:doc:`Working with DateTime ` |
:doc:`Validation ` |
:doc:`Entities in the Session ` |
- :doc:`Keeping your Modules independents `
+ :doc:`Keeping your Modules independent `
* **Integration into Frameworks/Libraries**
:doc:`CodeIgniter `
From e809f9c26666e675fea1ab350296573c8963d815 Mon Sep 17 00:00:00 2001
From: Alex Carol
Date: Sun, 3 Mar 2013 23:14:58 +0100
Subject: [PATCH 011/332] Removed unnecessary
Date: Wed, 6 Mar 2013 10:48:47 +0100
Subject: [PATCH 012/332] Added $isIdentifierColumn documentation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
I've added the documentation of the argument $isIdentifierColumn since in case of foreign composite keys it doesn't
---
docs/en/reference/native-sql.rst | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/docs/en/reference/native-sql.rst b/docs/en/reference/native-sql.rst
index 6bf8b9dee..b8a91000e 100644
--- a/docs/en/reference/native-sql.rst
+++ b/docs/en/reference/native-sql.rst
@@ -203,11 +203,12 @@ detail:
/**
* Adds a meta column (foreign key or discriminator column) to the result set.
*
- * @param string $alias
- * @param string $columnAlias
- * @param string $columnName
+ * @param string $alias
+ * @param string $columnAlias
+ * @param string $columnName
+ * @param boolean $isIdentifierColumn
*/
- public function addMetaResult($alias, $columnAlias, $columnName)
+ public function addMetaResult($alias, $columnAlias, $columnName, $isIdentifierColumn = false)
The first parameter is the alias of the entity result to which the
meta column belongs. A meta result column (foreign key or
@@ -215,6 +216,8 @@ discriminator column) always belongs to to an entity result. The
second parameter is the column alias/name of the column in the SQL
result set and the third parameter is the column name used in the
mapping.
+The fourth parameter should be set to true in case the primary key
+of the entity is the foreign key you're adding.
Discriminator Column
~~~~~~~~~~~~~~~~~~~~
From acc8b61cd151382ddf23967abc93b68d3f5816ac Mon Sep 17 00:00:00 2001
From: Lars Strojny
Date: Mon, 26 Nov 2012 01:03:46 +0100
Subject: [PATCH 013/332] Adding EntityManagerDecorator base class as an
extension point for EntityManager
---
.../ORM/Decorator/EntityManagerDecorator.php | 271 ++++++++++++++++++
lib/Doctrine/ORM/EntityManager.php | 4 +-
lib/Doctrine/ORM/EntityManagerInterface.php | 60 ++++
.../Decorator/EntityManagerDecoratorTest.php | 66 +++++
4 files changed, 399 insertions(+), 2 deletions(-)
create mode 100644 lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
create mode 100644 lib/Doctrine/ORM/EntityManagerInterface.php
create mode 100644 tests/Doctrine/Tests/ORM/Decorator/EntityManagerDecoratorTest.php
diff --git a/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
new file mode 100644
index 000000000..dc123118f
--- /dev/null
+++ b/lib/Doctrine/ORM/Decorator/EntityManagerDecorator.php
@@ -0,0 +1,271 @@
+.
+ */
+
+namespace Doctrine\ORM\Decorator;
+
+use Doctrine\DBAL\LockMode;
+use Doctrine\ORM\Query\ResultSetMapping;
+use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\Common\Persistence\ObjectManagerDecorator;
+
+/**
+ * Base class for EntityManager decorators
+ *
+ * @since 2.4
+ * @author Lars Strojny wrapped = $wrapped;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConnection()
+ {
+ return $this->wrapped->getConnection();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getExpressionBuilder()
+ {
+ return $this->wrapped->getExpressionBuilder();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function beginTransaction()
+ {
+ return $this->wrapped->beginTransaction();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transactional($func)
+ {
+ return $this->wrapped->transactional($func);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function commit()
+ {
+ return $this->wrapped->commit();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rollback()
+ {
+ return $this->wrapped->rollback();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createQuery($dql = '')
+ {
+ return $this->wrapped->createQuery($dql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createNamedQuery($name)
+ {
+ return $this->wrapped->createNamedQuery($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createNativeQuery($sql, ResultSetMapping $rsm)
+ {
+ return $this->wrapped->createNativeQuery($sql, $rsm);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createNamedNativeQuery($name)
+ {
+ return $this->wrapped->createNamedNativeQuery($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function createQueryBuilder()
+ {
+ return $this->wrapped->createQueryBuilder();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getReference($entityName, $id)
+ {
+ return $this->wrapped->getReference($entityName, $id);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getPartialReference($entityName, $identifier)
+ {
+ return $this->wrapped->getPartialReference($entityName, $identifier);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function close()
+ {
+ return $this->wrapped->close();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function copy($entity, $deep = false)
+ {
+ return $this->wrapped->copy($entity, $deep);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function lock($entity, $lockMode, $lockVersion = null)
+ {
+ return $this->wrapped->lock($entity, $lockMode, $lockVersion);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function find($entityName, $id, $lockMode = LockMode::NONE, $lockVersion = null)
+ {
+ return $this->wrapped->find($entityName, $id, $lockMode, $lockVersion);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function flush($entity = null)
+ {
+ return $this->wrapped->flush($entity);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getEventManager()
+ {
+ return $this->wrapped->getEventManager();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getConfiguration()
+ {
+ return $this->wrapped->getConfiguration();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isOpen()
+ {
+ return $this->wrapped->isOpen();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getUnitOfWork()
+ {
+ return $this->wrapped->getUnitOfWork();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getHydrator($hydrationMode)
+ {
+ return $this->wrapped->getHydrator($hydrationMode);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function newHydrator($hydrationMode)
+ {
+ return $this->wrapped->newHydrator($hydrationMode);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getProxyFactory()
+ {
+ return $this->wrapped->getProxyFactory();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFilters()
+ {
+ return $this->wrapped->getFilters();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFiltersStateClean()
+ {
+ return $this->wrapped->isFiltersStateClean();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasFilters()
+ {
+ return $this->wrapped->hasFilters();
+ }
+}
diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php
index 4da4abed4..53cbf1926 100644
--- a/lib/Doctrine/ORM/EntityManager.php
+++ b/lib/Doctrine/ORM/EntityManager.php
@@ -40,7 +40,7 @@ use Doctrine\Common\Util\ClassUtils;
* @author Jonathan Wage
* @author Roman Borschel
*/
-class EntityManager implements ObjectManager
+/* final */class EntityManager implements EntityManagerInterface
{
/**
* The used Configuration.
@@ -286,7 +286,7 @@ class EntityManager implements ObjectManager
*
* @return \Doctrine\ORM\Query
*/
- public function createQuery($dql = "")
+ public function createQuery($dql = '')
{
$query = new Query($this);
diff --git a/lib/Doctrine/ORM/EntityManagerInterface.php b/lib/Doctrine/ORM/EntityManagerInterface.php
new file mode 100644
index 000000000..d72f7cd0c
--- /dev/null
+++ b/lib/Doctrine/ORM/EntityManagerInterface.php
@@ -0,0 +1,60 @@
+.
+ */
+
+namespace Doctrine\ORM;
+
+use Doctrine\Common\Persistence\ObjectManager;
+use Doctrine\DBAL\LockMode;
+use Doctrine\ORM\Query\ResultSetMapping;
+
+/**
+ * EntityManager interface
+ *
+ * @since 2.4
+ * @author Lars Strojny wrapped = $this->getMock('Doctrine\ORM\EntityManagerInterface');
+ $this->decorator = $this->getMockBuilder('Doctrine\ORM\Decorator\EntityManagerDecorator')
+ ->setConstructorArgs(array($this->wrapped))
+ ->setMethods(null)
+ ->getMock();
+ }
+
+ public function getMethodParameters()
+ {
+ $class = new \ReflectionClass('Doctrine\ORM\EntityManager');
+
+ $methods = array();
+ foreach ($class->getMethods() as $method) {
+ if ($method->isConstructor() || $method->isStatic() || !$method->isPublic()) {
+ continue;
+ }
+
+ /** Special case EntityManager::createNativeQuery() */
+ if ($method->getName() === 'createNativeQuery') {
+ $methods[] = array($method->getName(), array('name', new ResultSetMapping()));
+ continue;
+ }
+
+ if ($method->getNumberOfRequiredParameters() === 0) {
+ $methods[] = array($method->getName(), array());
+ } elseif ($method->getNumberOfRequiredParameters() > 0) {
+ $methods[] = array($method->getName(), array_fill(0, $method->getNumberOfRequiredParameters(), 'req') ?: array());
+ }
+ if ($method->getNumberOfParameters() != $method->getNumberOfRequiredParameters()) {
+ $methods[] = array($method->getName(), array_fill(0, $method->getNumberOfParameters(), 'all') ?: array());
+ }
+ }
+
+ return $methods;
+ }
+
+ /**
+ * @dataProvider getMethodParameters
+ */
+ public function testAllMethodCallsAreDelegatedToTheWrappedInstance($method, array $parameters)
+ {
+ $stub = $this->wrapped
+ ->expects($this->once())
+ ->method($method)
+ ->will($this->returnValue('INNER VALUE FROM ' . $method));
+
+ call_user_func_array(array($stub, 'with'), $parameters);
+
+ $this->assertSame('INNER VALUE FROM ' . $method, call_user_func_array(array($this->decorator, $method), $parameters));
+ }
+}
From 760623346c9423dac76ff541d81066018ee28035 Mon Sep 17 00:00:00 2001
From: Jan Kramer
Date: Tue, 5 Mar 2013 15:02:20 +0100
Subject: [PATCH 014/332] Added 'contains' comparison
---
composer.json | 1 +
composer.lock | 58 ++++++++++++-------
.../ORM/Persisters/BasicEntityPersister.php | 19 +++---
.../ORM/Persisters/SqlValueVisitor.php | 18 +++++-
.../ORM/Functional/EntityRepositoryTest.php | 16 +++++
5 files changed, 80 insertions(+), 32 deletions(-)
diff --git a/composer.json b/composer.json
index 2c00492dd..89d62f2f6 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,7 @@
"require": {
"php": ">=5.3.2",
"ext-pdo": "*",
+ "doctrine/collections": "~1.1",
"doctrine/dbal": ">=2.4-dev,<2.5-dev",
"symfony/console": "2.*"
},
diff --git a/composer.lock b/composer.lock
index 6b3fcb3d0..23205bf9a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,5 +1,5 @@
{
- "hash": "eff8840dfb1a83e6e1aef32b8031ac7c",
+ "hash": "acae8c9f654bd03696631d5eac8d16ad",
"packages": [
{
"name": "doctrine/annotations",
@@ -22,7 +22,6 @@
"require-dev": {
"doctrine/cache": "1.*"
},
- "time": "2013-01-12 19:23:32",
"type": "library",
"autoload": {
"psr-0": {
@@ -65,7 +64,8 @@
"annotations",
"docblock",
"parser"
- ]
+ ],
+ "time": "2013-01-12 19:23:32"
},
{
"name": "doctrine/cache",
@@ -84,7 +84,6 @@
"require": {
"php": ">=5.3.2"
},
- "time": "2013-01-10 22:43:46",
"type": "library",
"autoload": {
"psr-0": {
@@ -126,27 +125,32 @@
"keywords": [
"cache",
"caching"
- ]
+ ],
+ "time": "2013-01-10 22:43:46"
},
{
"name": "doctrine/collections",
- "version": "v1.0",
+ "version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
- "reference": "v1.0"
+ "reference": "560f29c39cfcfbcd210e5d549d993a39d898b04b"
},
"dist": {
"type": "zip",
- "url": "https://github.com/doctrine/collections/archive/v1.0.zip",
- "reference": "v1.0",
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/560f29c39cfcfbcd210e5d549d993a39d898b04b",
+ "reference": "560f29c39cfcfbcd210e5d549d993a39d898b04b",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
- "time": "2013-01-12 16:36:50",
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
"autoload": {
"psr-0": {
"Doctrine\\Common\\Collections\\": "lib/"
@@ -188,7 +192,8 @@
"array",
"collections",
"iterator"
- ]
+ ],
+ "time": "2013-03-07 12:15:54"
},
{
"name": "doctrine/common",
@@ -212,7 +217,6 @@
"doctrine/lexer": "1.*",
"php": ">=5.3.2"
},
- "time": "2013-01-29 12:48:56",
"type": "library",
"extra": {
"branch-alias": {
@@ -262,7 +266,8 @@
"eventmanager",
"persistence",
"spl"
- ]
+ ],
+ "time": "2013-01-29 12:48:56"
},
{
"name": "doctrine/dbal",
@@ -288,7 +293,6 @@
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
},
- "time": "2013-02-09 23:28:29",
"type": "library",
"extra": {
"branch-alias": {
@@ -331,7 +335,8 @@
"dbal",
"persistence",
"queryobject"
- ]
+ ],
+ "time": "2013-02-09 23:28:29"
},
{
"name": "doctrine/inflector",
@@ -350,7 +355,6 @@
"require": {
"php": ">=5.3.2"
},
- "time": "2013-01-10 21:49:15",
"type": "library",
"autoload": {
"psr-0": {
@@ -394,7 +398,8 @@
"pluarlize",
"singuarlize",
"string"
- ]
+ ],
+ "time": "2013-01-10 21:49:15"
},
{
"name": "doctrine/lexer",
@@ -413,7 +418,6 @@
"require": {
"php": ">=5.3.2"
},
- "time": "2013-01-12 18:59:04",
"type": "library",
"autoload": {
"psr-0": {
@@ -446,7 +450,8 @@
"keywords": [
"lexer",
"parser"
- ]
+ ],
+ "time": "2013-01-12 18:59:04"
},
{
"name": "symfony/console",
@@ -466,7 +471,6 @@
"require": {
"php": ">=5.3.3"
},
- "time": "2013-01-31 21:39:01",
"type": "library",
"extra": {
"branch-alias": {
@@ -493,15 +497,25 @@
}
],
"description": "Symfony Console Component",
- "homepage": "http://symfony.com"
+ "homepage": "http://symfony.com",
+ "time": "2013-01-31 21:39:01"
}
],
- "packages-dev": null,
+ "packages-dev": [
+
+ ],
"aliases": [
],
"minimum-stability": "dev",
"stability-flags": [
+ ],
+ "platform": {
+ "php": ">=5.3.2",
+ "ext-pdo": "*"
+ },
+ "platform-dev": [
+
]
}
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index d5543dad4..649ad2e8e 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -84,15 +84,16 @@ class BasicEntityPersister
* @var array
*/
static private $comparisonMap = array(
- Comparison::EQ => '= %s',
- Comparison::IS => 'IS %s',
- Comparison::NEQ => '!= %s',
- Comparison::GT => '> %s',
- Comparison::GTE => '>= %s',
- Comparison::LT => '< %s',
- Comparison::LTE => '<= %s',
- Comparison::IN => 'IN (%s)',
- Comparison::NIN => 'NOT IN (%s)',
+ Comparison::EQ => '= %s',
+ Comparison::IS => 'IS %s',
+ Comparison::NEQ => '!= %s',
+ Comparison::GT => '> %s',
+ Comparison::GTE => '>= %s',
+ Comparison::LT => '< %s',
+ Comparison::LTE => '<= %s',
+ Comparison::IN => 'IN (%s)',
+ Comparison::NIN => 'NOT IN (%s)',
+ Comparison::CONTAINS => 'LIKE %s',
);
/**
diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
index 1d805c041..79e5150e5 100644
--- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
+++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
@@ -50,7 +50,7 @@ class SqlValueVisitor extends ExpressionVisitor
*/
public function walkComparison(Comparison $comparison)
{
- $value = $comparison->getValue()->getValue();
+ $value = $this->getValueFromComparison($comparison);
$field = $comparison->getField();
$this->values[] = $value;
@@ -92,4 +92,20 @@ class SqlValueVisitor extends ExpressionVisitor
{
return array($this->values, $this->types);
}
+
+ /**
+ * Returns the value from a Comparison. In case of a CONTAINS comparison,
+ * the value is wrapped in %-signs, because it will be used in a LIKE clause.
+ *
+ * @param \Doctrine\Common\Collections\Expr\Comparison $comparison
+ * @return mixed
+ */
+ protected function getValueFromComparison(Comparison $comparison)
+ {
+ $value = $comparison->getValue()->getValue();
+
+ return $comparison->getOperator() == Comparison::CONTAINS
+ ? "%{$value}%"
+ : $value;
+ }
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
index 5be4615fb..7874435bd 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
@@ -781,6 +781,22 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(4, count($users));
}
+ public function testMatchingCriteriaContainsComparison()
+ {
+ $this->loadFixture();
+
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
+
+ $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Foobar')));
+ $this->assertEquals(0, count($users));
+
+ $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Rom')));
+ $this->assertEquals(1, count($users));
+
+ $users = $repository->matching(new Criteria(Criteria::expr()->contains('status', 'dev')));
+ $this->assertEquals(2, count($users));
+ }
+
/**
* @group DDC-2055
*/
From 9d5e7eb6e9f8f422f3d7cb46d23f1ce50b0250d7 Mon Sep 17 00:00:00 2001
From: Jan Kramer
Date: Thu, 7 Mar 2013 14:12:10 +0100
Subject: [PATCH 015/332] Added composer.lock to .gitignore
---
.gitignore | 1 +
composer.lock | 521 --------------------------------------------------
2 files changed, 1 insertion(+), 521 deletions(-)
delete mode 100644 composer.lock
diff --git a/.gitignore b/.gitignore
index 240207aee..490413d15 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ lib/Doctrine/DBAL
.project
.idea
vendor/
+composer.lock
diff --git a/composer.lock b/composer.lock
deleted file mode 100644
index 23205bf9a..000000000
--- a/composer.lock
+++ /dev/null
@@ -1,521 +0,0 @@
-{
- "hash": "acae8c9f654bd03696631d5eac8d16ad",
- "packages": [
- {
- "name": "doctrine/annotations",
- "version": "v1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/annotations.git",
- "reference": "v1.0"
- },
- "dist": {
- "type": "zip",
- "url": "https://github.com/doctrine/annotations/archive/v1.0.zip",
- "reference": "v1.0",
- "shasum": ""
- },
- "require": {
- "doctrine/lexer": "1.*",
- "php": ">=5.3.2"
- },
- "require-dev": {
- "doctrine/cache": "1.*"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Annotations\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Docblock Annotations Parser",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "annotations",
- "docblock",
- "parser"
- ],
- "time": "2013-01-12 19:23:32"
- },
- {
- "name": "doctrine/cache",
- "version": "v1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/cache.git",
- "reference": "v1.0"
- },
- "dist": {
- "type": "zip",
- "url": "https://github.com/doctrine/cache/archive/v1.0.zip",
- "reference": "v1.0",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Cache\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Caching library offering an object-oriented API for many cache backends",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "cache",
- "caching"
- ],
- "time": "2013-01-10 22:43:46"
- },
- {
- "name": "doctrine/collections",
- "version": "dev-master",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/collections.git",
- "reference": "560f29c39cfcfbcd210e5d549d993a39d898b04b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/collections/zipball/560f29c39cfcfbcd210e5d549d993a39d898b04b",
- "reference": "560f29c39cfcfbcd210e5d549d993a39d898b04b",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Collections\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Collections Abstraction library",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "array",
- "collections",
- "iterator"
- ],
- "time": "2013-03-07 12:15:54"
- },
- {
- "name": "doctrine/common",
- "version": "dev-master",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/common",
- "reference": "53859ae1c84ccf1a5aa58c8379c69cd9adedf03a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/common/zipball/53859ae1c84ccf1a5aa58c8379c69cd9adedf03a",
- "reference": "53859ae1c84ccf1a5aa58c8379c69cd9adedf03a",
- "shasum": ""
- },
- "require": {
- "doctrine/annotations": "1.*",
- "doctrine/cache": "1.*",
- "doctrine/collections": "1.*",
- "doctrine/inflector": "1.*",
- "doctrine/lexer": "1.*",
- "php": ">=5.3.2"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.4.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Common Library for Doctrine projects",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "annotations",
- "collections",
- "eventmanager",
- "persistence",
- "spl"
- ],
- "time": "2013-01-29 12:48:56"
- },
- {
- "name": "doctrine/dbal",
- "version": "dev-master",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/dbal",
- "reference": "eb6ee9a86421ba534d7c5514b190d1d06b30d4b1"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/eb6ee9a86421ba534d7c5514b190d1d06b30d4b1",
- "reference": "eb6ee9a86421ba534d7c5514b190d1d06b30d4b1",
- "shasum": ""
- },
- "require": {
- "doctrine/common": "2.4.x-dev",
- "php": ">=5.3.2"
- },
- "require-dev": {
- "symfony/console": "2.*"
- },
- "suggest": {
- "symfony/console": "For helpful console commands such as SQL execution and import of files."
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.4.x-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Doctrine\\DBAL\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- }
- ],
- "description": "Database Abstraction Layer",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "database",
- "dbal",
- "persistence",
- "queryobject"
- ],
- "time": "2013-02-09 23:28:29"
- },
- {
- "name": "doctrine/inflector",
- "version": "v1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/inflector.git",
- "reference": "v1.0"
- },
- "dist": {
- "type": "zip",
- "url": "https://github.com/doctrine/inflector/archive/v1.0.zip",
- "reference": "v1.0",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Inflector\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com",
- "homepage": "http://www.jwage.com/"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Common String Manipulations with regard to casing and singular/plural rules.",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "inflection",
- "pluarlize",
- "singuarlize",
- "string"
- ],
- "time": "2013-01-10 21:49:15"
- },
- {
- "name": "doctrine/lexer",
- "version": "v1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/lexer.git",
- "reference": "v1.0"
- },
- "dist": {
- "type": "zip",
- "url": "https://github.com/doctrine/lexer/archive/v1.0.zip",
- "reference": "v1.0",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.2"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "Doctrine\\Common\\Lexer\\": "lib/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com",
- "homepage": "http://www.instaclick.com"
- },
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com",
- "homepage": "https://github.com/schmittjoh",
- "role": "Developer of wrapped JMSSerializerBundle"
- }
- ],
- "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
- "homepage": "http://www.doctrine-project.org",
- "keywords": [
- "lexer",
- "parser"
- ],
- "time": "2013-01-12 18:59:04"
- },
- {
- "name": "symfony/console",
- "version": "dev-master",
- "target-dir": "Symfony/Component/Console",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/Console",
- "reference": "f65e34d058f0990a724f78e8d091dc0a20e439ac"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/Console/zipball/f65e34d058f0990a724f78e8d091dc0a20e439ac",
- "reference": "f65e34d058f0990a724f78e8d091dc0a20e439ac",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.3-dev"
- }
- },
- "autoload": {
- "psr-0": {
- "Symfony\\Component\\Console\\": ""
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
- }
- ],
- "description": "Symfony Console Component",
- "homepage": "http://symfony.com",
- "time": "2013-01-31 21:39:01"
- }
- ],
- "packages-dev": [
-
- ],
- "aliases": [
-
- ],
- "minimum-stability": "dev",
- "stability-flags": [
-
- ],
- "platform": {
- "php": ">=5.3.2",
- "ext-pdo": "*"
- },
- "platform-dev": [
-
- ]
-}
From a2cd0f5804a6a76d6e9e39fc40084a286e5ccdfc Mon Sep 17 00:00:00 2001
From: Pascal Borreli
Date: Mon, 11 Mar 2013 00:08:58 +0000
Subject: [PATCH 016/332] Fixed typos
---
UPGRADE.md | 8 ++---
docs/en/cookbook/entities-in-session.rst | 2 +-
docs/en/reference/faq.rst | 2 +-
.../reference/working-with-associations.rst | 2 +-
docs/en/tutorials/composite-primary-keys.rst | 4 +--
lib/Doctrine/ORM/AbstractQuery.php | 2 +-
lib/Doctrine/ORM/Events.php | 2 +-
.../Internal/Hydration/AbstractHydrator.php | 8 ++---
.../Internal/Hydration/HydrationException.php | 2 +-
.../Mapping/Builder/AssociationBuilder.php | 2 +-
.../Mapping/Builder/ClassMetadataBuilder.php | 22 ++++++------
.../ORM/Mapping/ClassMetadataFactory.php | 4 +--
.../ORM/Mapping/ClassMetadataInfo.php | 20 +++++------
.../Mapping/DefaultEntityListenerResolver.php | 2 +-
.../ORM/Mapping/Driver/AnnotationDriver.php | 4 +--
.../ORM/Mapping/Driver/DatabaseDriver.php | 6 ++--
lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 2 +-
lib/Doctrine/ORM/Mapping/MappingException.php | 12 +++----
.../ORM/ORMInvalidArgumentException.php | 2 +-
lib/Doctrine/ORM/OptimisticLockException.php | 2 +-
lib/Doctrine/ORM/PersistentCollection.php | 2 +-
.../ORM/Persisters/BasicEntityPersister.php | 8 ++---
.../Persisters/JoinedSubclassPersister.php | 12 +++----
.../ORM/Persisters/SingleTablePersister.php | 2 +-
lib/Doctrine/ORM/Query.php | 2 +-
lib/Doctrine/ORM/Query/Expr.php | 4 +--
.../ORM/Query/ParameterTypeInferer.php | 2 +-
lib/Doctrine/ORM/Query/Parser.php | 16 ++++-----
lib/Doctrine/ORM/Query/QueryException.php | 10 +++---
lib/Doctrine/ORM/Query/SqlWalker.php | 12 +++----
lib/Doctrine/ORM/Query/TreeWalkerAdapter.php | 2 +-
.../Console/Command/ConvertMappingCommand.php | 4 +--
.../Command/GenerateEntitiesCommand.php | 2 +-
lib/Doctrine/ORM/Tools/SchemaTool.php | 4 +--
lib/Doctrine/ORM/Tools/ToolEvents.php | 2 +-
lib/Doctrine/ORM/UnitOfWork.php | 4 +--
phpunit.xml.dist | 2 +-
run-all.sh | 2 +-
.../Tests/Models/StockExchange/Bond.php | 4 +--
.../ORM/Functional/AdvancedDqlQueryTest.php | 2 +-
.../ORM/Functional/BasicFunctionalTest.php | 2 +-
.../Functional/ClassTableInheritanceTest.php | 2 +-
.../Functional/CompositePrimaryKeyTest.php | 2 +-
.../ORM/Functional/DefaultValuesTest.php | 2 +-
.../ORM/Functional/EntityRepositoryTest.php | 4 +--
.../Functional/ExtraLazyCollectionTest.php | 2 +-
.../ORM/Functional/IndexByAssociationTest.php | 20 +++++------
.../Tests/ORM/Functional/Locking/LockTest.php | 2 +-
...nyToManySelfReferentialAssociationTest.php | 2 +-
.../Tests/ORM/Functional/NewOperatorTest.php | 2 +-
...OneToManyUnidirectionalAssociationTest.php | 2 +-
.../Functional/OneToOneOrphanRemovalTest.php | 2 +-
.../Functional/SingleTableInheritanceTest.php | 6 ++--
.../ORM/Functional/Ticket/DDC117Test.php | 4 +--
.../ORM/Functional/Ticket/DDC142Test.php | 2 +-
.../ORM/Functional/Ticket/DDC1526Test.php | 2 +-
.../ORM/Functional/Ticket/DDC1719Test.php | 4 +--
.../ORM/Functional/Ticket/DDC1843Test.php | 6 ++--
.../ORM/Functional/Ticket/DDC1885Test.php | 4 +--
.../ORM/Functional/Ticket/DDC501Test.php | 2 +-
.../ORM/Functional/Ticket/DDC599Test.php | 2 +-
.../ORM/Functional/Ticket/DDC618Test.php | 6 ++--
.../ORM/Functional/Ticket/DDC758Test.php | 2 +-
.../ORM/Functional/Ticket/DDC933Test.php | 2 +-
.../ORM/Mapping/AbstractMappingDriverTest.php | 10 +++---
.../ORM/Mapping/AnnotationDriverTest.php | 2 +-
.../Mapping/BasicInheritanceMappingTest.php | 34 +++++++++----------
.../ORM/Mapping/ClassMetadataFactoryTest.php | 4 +--
.../Tests/ORM/Mapping/ClassMetadataTest.php | 14 ++++----
.../Performance/HydrationPerformanceTest.php | 2 +-
.../ORM/Query/SelectSqlGenerationTest.php | 2 +-
.../ORM/Query/UpdateSqlGenerationTest.php | 4 +--
.../AbstractClassMetadataExporterTest.php | 2 +-
.../Tests/ORM/Tools/SchemaToolTest.php | 2 +-
.../Doctrine/Tests/OrmFunctionalTestCase.php | 2 +-
tests/NativePhpunitTask.php | 2 +-
tests/dbproperties.xml.dev | 2 +-
77 files changed, 188 insertions(+), 188 deletions(-)
diff --git a/UPGRADE.md b/UPGRADE.md
index dacc3ffd6..e80aa55ad 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -126,7 +126,7 @@ from 2.0 have to configure the annotation driver if they don't use `Configuratio
$config->setMetadataDriverImpl($driver);
-## Scalar mappings can now be ommitted from DQL result
+## Scalar mappings can now be omitted from DQL result
You are now allowed to mark scalar SELECT expressions as HIDDEN an they are not hydrated anymore.
Example:
@@ -307,7 +307,7 @@ them for batch updates like SchemaTool and other commands. However the
annotations driver being a default driver does not really help that much
anyways.
-Therefore we decided to break backwards compability in this issue and drop
+Therefore we decided to break backwards compatibility in this issue and drop
the support for Annotations as Default Driver and require our users to
specify the driver explicitly (which allows us to ask for the path to all
entities).
@@ -366,7 +366,7 @@ apologize for the inconvenience.
## Default Property for Field Mappings
The "default" option for database column defaults has been removed. If desired, database column defaults can
-be implemented by using the columnDefinition attribute of the @Column annotation (or the approriate XML and YAML equivalents).
+be implemented by using the columnDefinition attribute of the @Column annotation (or the appropriate XML and YAML equivalents).
Prefer PHP default values, if possible.
## Selecting Partial Objects
@@ -451,7 +451,7 @@ With new required method AbstractTask::buildDocumentation, its implementation de
* "doctrine schema-tool --drop" now always drops the complete database instead of
only those tables defined by the current database model. The previous method had
- problems when foreign keys of orphaned tables pointed to tables that were schedulded
+ problems when foreign keys of orphaned tables pointed to tables that were scheduled
for deletion.
* Use "doctrine schema-tool --update" to get a save incremental update for your
database schema without deleting any unused tables, sequences or foreign keys.
diff --git a/docs/en/cookbook/entities-in-session.rst b/docs/en/cookbook/entities-in-session.rst
index 2fd771e5d..664cff53f 100644
--- a/docs/en/cookbook/entities-in-session.rst
+++ b/docs/en/cookbook/entities-in-session.rst
@@ -64,5 +64,5 @@ object or implement the __sleep() magic method on your entity.
When you called detach on your objects they get "unmanaged" with that
entity manager. This means you cannot use them as part of write operations
- during ``EntityManagr#flush()`` anymore in this request.
+ during ``EntityManager#flush()`` anymore in this request.
diff --git a/docs/en/reference/faq.rst b/docs/en/reference/faq.rst
index 5d57c24f7..800b168bd 100644
--- a/docs/en/reference/faq.rst
+++ b/docs/en/reference/faq.rst
@@ -162,7 +162,7 @@ is supposed to kick-start you, but not towards 100%.
Why does the EntityGenerator not generate inheritance correctly?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Just from the details of the discriminator map the EntityGenerator cannot guess the inheritance hierachy.
+Just from the details of the discriminator map the EntityGenerator cannot guess the inheritance hierarchy.
This is why the generation of inherited entities does not fully work. You have to adjust some additional
code to get this one working correctly.
diff --git a/docs/en/reference/working-with-associations.rst b/docs/en/reference/working-with-associations.rst
index 253edad7e..7f46eba6a 100644
--- a/docs/en/reference/working-with-associations.rst
+++ b/docs/en/reference/working-with-associations.rst
@@ -689,7 +689,7 @@ interchangeably, independent of in-memory or sql-backed collections.
*/
public function setMaxResults($maxResults);
public function getOrderings();
- public function getWhereExpresion();
+ public function getWhereExpression();
public function getFirstResult();
public function getMaxResults();
}
diff --git a/docs/en/tutorials/composite-primary-keys.rst b/docs/en/tutorials/composite-primary-keys.rst
index 82a5210cb..dd4e49e04 100644
--- a/docs/en/tutorials/composite-primary-keys.rst
+++ b/docs/en/tutorials/composite-primary-keys.rst
@@ -19,7 +19,7 @@ the ID fields have to have their values set before you call ``EntityManager#pers
Primitive Types only
~~~~~~~~~~~~~~~~~~~~
-Even in version 2.0 you can have composite keys as long as they only consist of the primative types
+Even in version 2.0 you can have composite keys as long as they only consist of the primitive types
``integer`` and ``string``. Suppose you want to create a database of cars and use the model-name
and year of production as primary keys:
@@ -129,7 +129,7 @@ of one or many parent entities.
- Dynamic Attributes of an Entity (for example Article). Each Article has many
attributes with primary key "article_id" and "attribute_name".
-- Address object of a Person, the primary key of the adress is "user_id". This is not a case of a composite primary
+- Address object of a Person, the primary key of the address is "user_id". This is not a case of a composite primary
key, but the identity is derived through a foreign entity and a foreign key.
- Join Tables with metadata can be modelled as Entity, for example connections between two articles
with a little description and a score.
diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php
index be1a0a1fb..52f6ef507 100644
--- a/lib/Doctrine/ORM/AbstractQuery.php
+++ b/lib/Doctrine/ORM/AbstractQuery.php
@@ -386,7 +386,7 @@ abstract class AbstractQuery
}
/**
- * Defines a cache driver to be used for caching result sets and implictly enables caching.
+ * Defines a cache driver to be used for caching result sets and implicitly enables caching.
*
* @param \Doctrine\Common\Cache\Cache|null $resultCacheDriver Cache driver
*
diff --git a/lib/Doctrine/ORM/Events.php b/lib/Doctrine/ORM/Events.php
index 28fdcd9a9..8c13fa2d5 100644
--- a/lib/Doctrine/ORM/Events.php
+++ b/lib/Doctrine/ORM/Events.php
@@ -122,7 +122,7 @@ final class Events
/**
* The preFlush event occurs when the EntityManager#flush() operation is invoked,
- * but before any changes to managed entites have been calculated. This event is
+ * but before any changes to managed entities have been calculated. This event is
* always raised right after EntityManager#flush() call.
*/
const preFlush = 'preFlush';
diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
index 1254bacb4..afd4b41a1 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
@@ -168,7 +168,7 @@ abstract class AbstractHydrator
}
/**
- * Excutes one-time preparation tasks, once each time hydration is started
+ * Executes one-time preparation tasks, once each time hydration is started
* through {@link hydrateAll} or {@link iterate()}.
*
* @return void
@@ -178,7 +178,7 @@ abstract class AbstractHydrator
}
/**
- * Excutes one-time cleanup tasks at the end of a hydration that was initiated
+ * Executes one-time cleanup tasks at the end of a hydration that was initiated
* through {@link hydrateAll} or {@link iterate()}.
*
* @return void
@@ -223,7 +223,7 @@ abstract class AbstractHydrator
* Puts the elements of a result row into a new array, grouped by the dql alias
* they belong to. The column names in the result set are mapped to their
* field names during this procedure as well as any necessary conversions on
- * the values applied. Scalar values are kept in a specfic key 'scalars'.
+ * the values applied. Scalar values are kept in a specific key 'scalars'.
*
* @param array $data SQL Result Row.
* @param array &$cache Cache for column to field result information.
@@ -321,7 +321,7 @@ abstract class AbstractHydrator
}
// in an inheritance hierarchy the same field could be defined several times.
- // We overwrite this value so long we dont have a non-null value, that value we keep.
+ // We overwrite this value so long we don't have a non-null value, that value we keep.
// Per definition it cannot be that a field is defined several times and has several values.
if (isset($rowData[$dqlAlias][$cache[$key]['fieldName']]) && $value === null) {
continue;
diff --git a/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php b/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php
index 496942e94..c1c13c1f7 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/HydrationException.php
@@ -49,7 +49,7 @@ class HydrationException extends \Doctrine\ORM\ORMException
public static function emptyDiscriminatorValue($dqlAlias)
{
return new self("The DQL alias '" . $dqlAlias . "' contains an entity ".
- "of an inheritance hierachy with an empty discriminator value. This means " .
+ "of an inheritance hierarchy with an empty discriminator value. This means " .
"that the database contains inconsistent data with an empty " .
"discriminator value in a table row."
);
diff --git a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php
index 93179a406..942a662e4 100644
--- a/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php
+++ b/lib/Doctrine/ORM/Mapping/Builder/AssociationBuilder.php
@@ -200,7 +200,7 @@ class AssociationBuilder
} else if ($this->type == ClassMetadata::ONE_TO_ONE) {
$cm->mapOneToOne($mapping);
} else {
- throw new \InvalidArgumentException("Type should be a ToOne Assocation here");
+ throw new \InvalidArgumentException("Type should be a ToOne Association here");
}
return $this->builder;
}
diff --git a/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php b/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
index a634f1678..774c9e06e 100644
--- a/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
+++ b/lib/Doctrine/ORM/Mapping/Builder/ClassMetadataBuilder.php
@@ -163,7 +163,7 @@ class ClassMetadataBuilder
}
/**
- * Sets class as root of a joined table inheritance hierachy.
+ * Sets class as root of a joined table inheritance hierarchy.
*
* @return ClassMetadataBuilder
*/
@@ -175,7 +175,7 @@ class ClassMetadataBuilder
}
/**
- * Sets class as root of a single table inheritance hierachy.
+ * Sets class as root of a single table inheritance hierarchy.
*
* @return ClassMetadataBuilder
*/
@@ -207,7 +207,7 @@ class ClassMetadataBuilder
}
/**
- * Adds a subclass to this inheritance hierachy.
+ * Adds a subclass to this inheritance hierarchy.
*
* @param string $name
* @param string $class
@@ -319,7 +319,7 @@ class ClassMetadataBuilder
}
/**
- * Creates a ManyToOne Assocation Builder.
+ * Creates a ManyToOne Association Builder.
*
* Note: This method does not add the association, you have to call build() on the AssociationBuilder.
*
@@ -361,7 +361,7 @@ class ClassMetadataBuilder
}
/**
- * Adds simple inverse one-to-one assocation.
+ * Adds simple inverse one-to-one association.
*
* @param string $name
* @param string $targetEntity
@@ -378,7 +378,7 @@ class ClassMetadataBuilder
}
/**
- * Adds simple owning one-to-one assocation.
+ * Adds simple owning one-to-one association.
*
* @param string $name
* @param string $targetEntity
@@ -398,7 +398,7 @@ class ClassMetadataBuilder
}
/**
- * Creates a ManyToMany Assocation Builder.
+ * Creates a ManyToMany Association Builder.
*
* @param string $name
* @param string $targetEntity
@@ -418,7 +418,7 @@ class ClassMetadataBuilder
}
/**
- * Adds a simple owning many to many assocation.
+ * Adds a simple owning many to many association.
*
* @param string $name
* @param string $targetEntity
@@ -438,7 +438,7 @@ class ClassMetadataBuilder
}
/**
- * Adds a simple inverse many to many assocation.
+ * Adds a simple inverse many to many association.
*
* @param string $name
* @param string $targetEntity
@@ -455,7 +455,7 @@ class ClassMetadataBuilder
}
/**
- * Creates a one to many assocation builder.
+ * Creates a one to many association builder.
*
* @param string $name
* @param string $targetEntity
@@ -475,7 +475,7 @@ class ClassMetadataBuilder
}
/**
- * Adds simple OneToMany assocation.
+ * Adds simple OneToMany association.
*
* @param string $name
* @param string $targetEntity
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index 4ea082d31..242a9099f 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -193,7 +193,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
}
$class->validateIdentifier();
- $class->validateAssocations();
+ $class->validateAssociations();
$class->validateLifecycleCallbacks($this->getReflectionService());
// verify inheritance
@@ -319,7 +319,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
foreach ($parentClass->associationMappings as $field => $mapping) {
if ($parentClass->isMappedSuperclass) {
if ($mapping['type'] & ClassMetadata::TO_MANY && !$mapping['isOwningSide']) {
- throw MappingException::illegalToManyAssocationOnMappedSuperclass($parentClass->name, $field);
+ throw MappingException::illegalToManyAssociationOnMappedSuperclass($parentClass->name, $field);
}
$mapping['sourceEntity'] = $subClass->name;
}
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index fc808d3e5..1396d2a11 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -509,7 +509,7 @@ class ClassMetadataInfo implements ClassMetadata
public $isIdentifierComposite = false;
/**
- * READ-ONLY: Flag indicating wheather the identifier/primary key contains at least one foreign key association.
+ * READ-ONLY: Flag indicating whether the identifier/primary key contains at least one foreign key association.
*
* This flag is necessary because some code blocks require special treatment of this cases.
*
@@ -631,7 +631,7 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
- * Gets the ReflectionPropertys of the mapped class.
+ * Gets the ReflectionProperties of the mapped class.
*
* @return array An array of ReflectionProperty instances.
*/
@@ -938,7 +938,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* @throws MappingException
*/
- public function validateAssocations()
+ public function validateAssociations()
{
foreach ($this->associationMappings as $mapping) {
if ( ! ClassLoader::classExists($mapping['targetEntity']) ) {
@@ -1437,7 +1437,7 @@ class ClassMetadataInfo implements ClassMetadata
));
}
- $uniqueContraintColumns = array();
+ $uniqueConstraintColumns = array();
foreach ($mapping['joinColumns'] as &$joinColumn) {
if ($mapping['type'] === self::ONE_TO_ONE && ! $this->isInheritanceTypeSingleTable()) {
if (count($mapping['joinColumns']) == 1) {
@@ -1445,7 +1445,7 @@ class ClassMetadataInfo implements ClassMetadata
$joinColumn['unique'] = true;
}
} else {
- $uniqueContraintColumns[] = $joinColumn['name'];
+ $uniqueConstraintColumns[] = $joinColumn['name'];
}
}
@@ -1472,12 +1472,12 @@ class ClassMetadataInfo implements ClassMetadata
? $joinColumn['fieldName'] : $joinColumn['name'];
}
- if ($uniqueContraintColumns) {
+ if ($uniqueConstraintColumns) {
if ( ! $this->table) {
throw new RuntimeException("ClassMetadataInfo::setTable() has to be called before defining a one to one relationship.");
}
$this->table['uniqueConstraints'][$mapping['fieldName']."_uniq"] = array(
- 'columns' => $uniqueContraintColumns
+ 'columns' => $uniqueConstraintColumns
);
}
@@ -1488,7 +1488,7 @@ class ClassMetadataInfo implements ClassMetadata
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) {
- throw MappingException::illegalInverseIdentifierAssocation($this->name, $mapping['fieldName']);
+ throw MappingException::illegalInverseIdentifierAssociation($this->name, $mapping['fieldName']);
}
return $mapping;
@@ -2051,7 +2051,7 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
- * Checks if this entity is the root in any entity-inheritance-hierachy.
+ * Checks if this entity is the root in any entity-inheritance-hierarchy.
*
* @return bool
*/
@@ -2427,7 +2427,7 @@ class ClassMetadataInfo implements ClassMetadata
* @deprecated Deprecated since version 2.4 in favor of \Doctrine\ORM\Event\ListenersInvoker
*
* @param string $lifecycleEvent The lifecycle event.
- * @param object $entity The Entity on which the event occured.
+ * @param object $entity The Entity on which the event occurred.
*
* @return void
*/
diff --git a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php
index 78c93791b..75658547e 100644
--- a/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php
+++ b/lib/Doctrine/ORM/Mapping/DefaultEntityListenerResolver.php
@@ -21,7 +21,7 @@
namespace Doctrine\ORM\Mapping;
/**
- * The default DefaultEntityListene
+ * The default DefaultEntityListener
*
* @since 2.4
* @author Fabio B. Silva
diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
index a4bea98ea..9e1c734cc 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -247,7 +247,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
$mapping = array();
$mapping['fieldName'] = $property->getName();
- // Check for JoinColummn/JoinColumns annotations
+ // Check for JoinColumn/JoinColumns annotations
$joinColumns = array();
if ($joinColumnAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) {
@@ -375,7 +375,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
$override = array();
$fieldName = $associationOverride->name;
- // Check for JoinColummn/JoinColumns annotations
+ // Check for JoinColumn/JoinColumns annotations
if ($associationOverride->joinColumns) {
$joinColumns = array();
foreach ($associationOverride->joinColumns as $joinColumn) {
diff --git a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
index e1f75da6d..15a4e0d2c 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
@@ -84,7 +84,7 @@ class DatabaseDriver implements MappingDriver
}
/**
- * Sets tables manually instead of relying on the reverse engeneering capabilities of SchemaManager.
+ * Sets tables manually instead of relying on the reverse engineering capabilities of SchemaManager.
*
* @param array $entityTables
* @param array $manyToManyTables
@@ -252,7 +252,7 @@ class DatabaseDriver implements MappingDriver
if (!$otherFk) {
// the definition of this many to many table does not contain
- // enough foreign key information to continue reverse engeneering.
+ // enough foreign key information to continue reverse engineering.
continue;
}
@@ -319,7 +319,7 @@ class DatabaseDriver implements MappingDriver
);
}
- //Here we need to check if $cols are the same as $primaryKeyColums
+ //Here we need to check if $cols are the same as $primaryKeyColumns
if (!array_diff($cols,$primaryKeyColumns)) {
$metadata->mapOneToOne($associationMapping);
} else {
diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
index 26d1becd0..461038932 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php
@@ -224,7 +224,7 @@ class XmlDriver extends FileDriver
$metadata->table['options'] = $this->_parseOptions($xmlRoot->options->children());
}
- // The mapping assignement is done in 2 times as a bug might occurs on some php/xml lib versions
+ // The mapping assignment is done in 2 times as a bug might occurs on some php/xml lib versions
// The internal SimpleXmlIterator get resetted, to this generate a duplicate field exception
$mappings = array();
// Evaluate mappings
diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php
index 61ecb4d11..a8345bbd6 100644
--- a/lib/Doctrine/ORM/Mapping/MappingException.php
+++ b/lib/Doctrine/ORM/Mapping/MappingException.php
@@ -529,7 +529,7 @@ class MappingException extends \Doctrine\ORM\ORMException
*/
public static function cannotVersionIdField($className, $fieldName)
{
- return new self("Setting Id field '$fieldName' as versionale in entity class '$className' is not supported.");
+ return new self("Setting Id field '$fieldName' as versionable in entity class '$className' is not supported.");
}
/**
@@ -561,7 +561,7 @@ class MappingException extends \Doctrine\ORM\ORMException
*
* @return MappingException
*/
- public static function illegalToManyAssocationOnMappedSuperclass($className, $field)
+ public static function illegalToManyAssociationOnMappedSuperclass($className, $field)
{
return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'.");
}
@@ -632,7 +632,7 @@ class MappingException extends \Doctrine\ORM\ORMException
*
* @return MappingException
*/
- public static function illegalInverseIdentifierAssocation($className, $field)
+ public static function illegalInverseIdentifierAssociation($className, $field)
{
return new self("An inverse association is not allowed to be identifier in '$className#$field'.");
}
@@ -643,7 +643,7 @@ class MappingException extends \Doctrine\ORM\ORMException
*
* @return MappingException
*/
- public static function illegalToManyIdentifierAssoaction($className, $field)
+ public static function illegalToManyIdentifierAssociation($className, $field)
{
return new self("Many-to-many or one-to-many associations are not allowed to be identifier in '$className#$field'.");
}
@@ -668,8 +668,8 @@ class MappingException extends \Doctrine\ORM\ORMException
{
return new self(
"Entity '" . $className . "' has to be part of the discriminator map of '" . $rootClassName . "' " .
- "to be properly mapped in the inheritance hierachy. Alternatively you can make '".$className."' an abstract class " .
- "to avoid this exception from occuring."
+ "to be properly mapped in the inheritance hierarchy. Alternatively you can make '".$className."' an abstract class " .
+ "to avoid this exception from occurring."
);
}
diff --git a/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/lib/Doctrine/ORM/ORMInvalidArgumentException.php
index 1773df291..cb5037679 100644
--- a/lib/Doctrine/ORM/ORMInvalidArgumentException.php
+++ b/lib/Doctrine/ORM/ORMInvalidArgumentException.php
@@ -176,7 +176,7 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
public static function invalidCompositeIdentifier()
{
return new self("Binding an entity with a composite primary key to a query is not supported. " .
- "You should split the parameter into the explicit fields and bind them seperately.");
+ "You should split the parameter into the explicit fields and bind them separately.");
}
/**
diff --git a/lib/Doctrine/ORM/OptimisticLockException.php b/lib/Doctrine/ORM/OptimisticLockException.php
index 6f1a57631..57ea66bde 100644
--- a/lib/Doctrine/ORM/OptimisticLockException.php
+++ b/lib/Doctrine/ORM/OptimisticLockException.php
@@ -71,7 +71,7 @@ class OptimisticLockException extends ORMException
*
* @return OptimisticLockException
*/
- public static function lockFailedVersionMissmatch($entity, $expectedLockVersion, $actualLockVersion)
+ public static function lockFailedVersionMismatch($entity, $expectedLockVersion, $actualLockVersion)
{
return new self("The optimistic lock failed, version " . $expectedLockVersion . " was expected, but is actually ".$actualLockVersion, $entity);
}
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index dbfac3716..33040d993 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -843,7 +843,7 @@ final class PersistentCollection implements Collection, Selectable
}
if ($this->association['type'] !== ClassMetadata::ONE_TO_MANY) {
- throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany assocations at the moment.");
+ throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
}
// If there are NEW objects we have to check if any of them matches the criteria
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index d5543dad4..c6bd8e847 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -37,7 +37,7 @@ use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\Comparison;
/**
- * A BasicEntityPersiter maps an entity to a single table in a relational database.
+ * A BasicEntityPersister maps an entity to a single table in a relational database.
*
* A persister is always responsible for a single entity type.
*
@@ -177,8 +177,8 @@ class BasicEntityPersister
protected $selectColumnListSql;
/**
- * The JOIN SQL fragement used to eagerly load all many-to-one and one-to-one
- * associations configured as FETCH_EAGER, aswell as all inverse one-to-one associations.
+ * The JOIN SQL fragment used to eagerly load all many-to-one and one-to-one
+ * associations configured as FETCH_EAGER, as well as all inverse one-to-one associations.
*
* @var string
*/
@@ -499,7 +499,7 @@ class BasicEntityPersister
}
// @Todo this only covers scenarios with no inheritance or of the same level. Is there something
- // like self-referential relationship between different levels of an inheritance hierachy? I hope not!
+ // like self-referential relationship between different levels of an inheritance hierarchy? I hope not!
$selfReferential = ($mapping['targetEntity'] == $mapping['sourceEntity']);
$class = $this->class;
$association = $mapping;
diff --git a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
index 4989c7919..7a2f16a1a 100644
--- a/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
+++ b/lib/Doctrine/ORM/Persisters/JoinedSubclassPersister.php
@@ -302,31 +302,31 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// INNER JOIN parent tables
foreach ($this->class->parentClasses as $parentClassName) {
- $contitions = array();
+ $conditions = array();
$parentClass = $this->em->getClassMetadata($parentClassName);
$tableAlias = $this->getSQLTableAlias($parentClassName);
$joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->platform) . ' ' . $tableAlias . ' ON ';
foreach ($identifierColumn as $idColumn) {
- $contitions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+ $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}
- $joinSql .= implode(' AND ', $contitions);
+ $joinSql .= implode(' AND ', $conditions);
}
// OUTER JOIN sub tables
foreach ($this->class->subClasses as $subClassName) {
- $contitions = array();
+ $conditions = array();
$subClass = $this->em->getClassMetadata($subClassName);
$tableAlias = $this->getSQLTableAlias($subClassName);
$joinSql .= ' LEFT JOIN ' . $this->quoteStrategy->getTableName($subClass, $this->platform) . ' ' . $tableAlias . ' ON ';
foreach ($identifierColumn as $idColumn) {
- $contitions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
+ $conditions[] = $baseTableAlias . '.' . $idColumn . ' = ' . $tableAlias . '.' . $idColumn;
}
- $joinSql .= implode(' AND ', $contitions);
+ $joinSql .= implode(' AND ', $conditions);
}
if ($assoc != null && $assoc['type'] == ClassMetadata::MANY_TO_MANY) {
diff --git a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php
index 0d7abc8d9..e157a90a2 100644
--- a/lib/Doctrine/ORM/Persisters/SingleTablePersister.php
+++ b/lib/Doctrine/ORM/Persisters/SingleTablePersister.php
@@ -178,7 +178,7 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
{
// Ensure that the filters are applied to the root entity of the inheritance tree
$targetEntity = $this->em->getClassMetadata($targetEntity->rootEntityName);
- // we dont care about the $targetTableAlias, in a STI there is only one table.
+ // we don't care about the $targetTableAlias, in a STI there is only one table.
return parent::generateFilterConditionSQL($targetEntity, $targetTableAlias);
}
diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php
index 8b8d40111..107055ed3 100644
--- a/lib/Doctrine/ORM/Query.php
+++ b/lib/Doctrine/ORM/Query.php
@@ -327,7 +327,7 @@ final class Query extends AbstractQuery
}
if (count($sqlParams) != count($types)) {
- throw QueryException::parameterTypeMissmatch();
+ throw QueryException::parameterTypeMismatch();
}
if ($sqlParams) {
diff --git a/lib/Doctrine/ORM/Query/Expr.php b/lib/Doctrine/ORM/Query/Expr.php
index 90c706137..48fb790b6 100644
--- a/lib/Doctrine/ORM/Query/Expr.php
+++ b/lib/Doctrine/ORM/Query/Expr.php
@@ -350,8 +350,8 @@ class Expr
* When converted to string, it will generated a * . Example:
*
* [php]
- * // u.salary * u.percentAnualSalaryIncrease
- * $q->expr()->prod('u.salary', 'u.percentAnualSalaryIncrease')
+ * // u.salary * u.percentAnnualSalaryIncrease
+ * $q->expr()->prod('u.salary', 'u.percentAnnualSalaryIncrease')
*
* @param mixed $x Left expression.
* @param mixed $y Right expression.
diff --git a/lib/Doctrine/ORM/Query/ParameterTypeInferer.php b/lib/Doctrine/ORM/Query/ParameterTypeInferer.php
index 602dde6d8..462f971ba 100644
--- a/lib/Doctrine/ORM/Query/ParameterTypeInferer.php
+++ b/lib/Doctrine/ORM/Query/ParameterTypeInferer.php
@@ -23,7 +23,7 @@ use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type;
/**
- * Provides an enclosed support for parameter infering.
+ * Provides an enclosed support for parameter inferring.
*
* @link www.doctrine-project.org
* @since 2.0
diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php
index 460ebea46..e7a0e3ed2 100644
--- a/lib/Doctrine/ORM/Query/Parser.php
+++ b/lib/Doctrine/ORM/Query/Parser.php
@@ -305,7 +305,7 @@ class Parser
*
* @return void
*
- * @throws QueryException If the tokens dont match.
+ * @throws QueryException If the tokens don't match.
*/
public function match($token)
{
@@ -644,7 +644,7 @@ class Parser
}
if ($class->getConstructor() === null) {
- $this->semanticalError(sprintf('Class "%s" has not a valid contructor.', $className), $token);
+ $this->semanticalError(sprintf('Class "%s" has not a valid constructor.', $className), $token);
}
if ($class->getConstructor()->getNumberOfRequiredParameters() > count($args)) {
@@ -2373,7 +2373,7 @@ class Parser
return $condPrimary;
}
- // Peek beyond the matching closing paranthesis ')'
+ // Peek beyond the matching closing parenthesis ')'
$peek = $this->peekBeyondClosingParenthesis();
if (in_array($peek['value'], array("=", "<", "<=", "<>", ">", ">=", "!=")) ||
@@ -2445,7 +2445,7 @@ class Parser
$token = $this->lexer->peek();
}
- // We need to go even further in case of IS (differenciate between NULL and EMPTY)
+ // We need to go even further in case of IS (differentiate between NULL and EMPTY)
$lookahead = $this->lexer->peek();
}
@@ -2495,19 +2495,19 @@ class Parser
*/
public function EmptyCollectionComparisonExpression()
{
- $emptyColletionCompExpr = new AST\EmptyCollectionComparisonExpression(
+ $emptyCollectionCompExpr = new AST\EmptyCollectionComparisonExpression(
$this->CollectionValuedPathExpression()
);
$this->match(Lexer::T_IS);
if ($this->lexer->isNextToken(Lexer::T_NOT)) {
$this->match(Lexer::T_NOT);
- $emptyColletionCompExpr->not = true;
+ $emptyCollectionCompExpr->not = true;
}
$this->match(Lexer::T_EMPTY);
- return $emptyColletionCompExpr;
+ return $emptyCollectionCompExpr;
}
/**
@@ -2800,7 +2800,7 @@ class Parser
}
if ($peek['value'] == '(') {
- // do NOT directly go to FunctionsReturningString() because it doesnt check for custom functions.
+ // do NOT directly go to FunctionsReturningString() because it doesn't check for custom functions.
return $this->FunctionDeclaration();
}
diff --git a/lib/Doctrine/ORM/Query/QueryException.php b/lib/Doctrine/ORM/Query/QueryException.php
index 06a622644..da0d2d50c 100644
--- a/lib/Doctrine/ORM/Query/QueryException.php
+++ b/lib/Doctrine/ORM/Query/QueryException.php
@@ -123,9 +123,9 @@ class QueryException extends \Doctrine\ORM\ORMException
/**
* @return QueryException
*/
- public static function parameterTypeMissmatch()
+ public static function parameterTypeMismatch()
{
- return new self("DQL Query parameter and type numbers missmatch, but have to be exactly equal.");
+ return new self("DQL Query parameter and type numbers mismatch, but have to be exactly equal.");
}
/**
@@ -159,7 +159,7 @@ class QueryException extends \Doctrine\ORM\ORMException
{
return new self(
"Invalid query operation: Not allowed to iterate over fetch join collections ".
- "in class ".$assoc['sourceEntity']." assocation ".$assoc['fieldName']
+ "in class ".$assoc['sourceEntity']." association ".$assoc['fieldName']
);
}
@@ -184,7 +184,7 @@ class QueryException extends \Doctrine\ORM\ORMException
{
return new self(
"Unsupported query operation: It is not yet possible to overwrite the join ".
- "conditions in class ".$assoc['sourceEntityName']." assocation ".$assoc['fieldName'].". ".
+ "conditions in class ".$assoc['sourceEntityName']." association ".$assoc['fieldName'].". ".
"Use WITH to append additional join conditions to the association."
);
}
@@ -234,7 +234,7 @@ class QueryException extends \Doctrine\ORM\ORMException
public static function instanceOfUnrelatedClass($className, $rootClass)
{
return new self("Cannot check if a child of '" . $rootClass . "' is instanceof '" . $className . "', " .
- "inheritance hierachy exists between these two classes.");
+ "inheritance hierarchy exists between these two classes.");
}
/**
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 81660fd83..30a39924e 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -1042,7 +1042,7 @@ class SqlWalker implements TreeWalker
// Handle WITH clause
if (($condExpr = $join->conditionalExpression) !== null) {
- // Phase 2 AST optimization: Skip processment of ConditionalExpression
+ // Phase 2 AST optimization: Skip processing of ConditionalExpression
// if only one ConditionalTerm is defined
$sql .= ' AND (' . $this->walkConditionalExpression($condExpr) . ')';
}
@@ -1691,7 +1691,7 @@ class SqlWalker implements TreeWalker
*/
public function walkConditionalExpression($condExpr)
{
- // Phase 2 AST optimization: Skip processment of ConditionalExpression
+ // Phase 2 AST optimization: Skip processing of ConditionalExpression
// if only one ConditionalTerm is defined
if ( ! ($condExpr instanceof AST\ConditionalExpression)) {
return $this->walkConditionalTerm($condExpr);
@@ -1705,7 +1705,7 @@ class SqlWalker implements TreeWalker
*/
public function walkConditionalTerm($condTerm)
{
- // Phase 2 AST optimization: Skip processment of ConditionalTerm
+ // Phase 2 AST optimization: Skip processing of ConditionalTerm
// if only one ConditionalFactor is defined
if ( ! ($condTerm instanceof AST\ConditionalTerm)) {
return $this->walkConditionalFactor($condTerm);
@@ -1719,7 +1719,7 @@ class SqlWalker implements TreeWalker
*/
public function walkConditionalFactor($factor)
{
- // Phase 2 AST optimization: Skip processment of ConditionalFactor
+ // Phase 2 AST optimization: Skip processing of ConditionalFactor
// if only one ConditionalPrimary is defined
return ( ! ($factor instanceof AST\ConditionalFactor))
? $this->walkConditionalPrimary($factor)
@@ -2114,7 +2114,7 @@ class SqlWalker implements TreeWalker
: $term;
}
- // Phase 2 AST optimization: Skip processment of ArithmeticTerm
+ // Phase 2 AST optimization: Skip processing of ArithmeticTerm
// if only one ArithmeticFactor is defined
if ( ! ($term instanceof AST\ArithmeticTerm)) {
return $this->walkArithmeticFactor($term);
@@ -2132,7 +2132,7 @@ class SqlWalker implements TreeWalker
return $factor;
}
- // Phase 2 AST optimization: Skip processment of ArithmeticFactor
+ // Phase 2 AST optimization: Skip processing of ArithmeticFactor
// if only one ArithmeticPrimary is defined
if ( ! ($factor instanceof AST\ArithmeticFactor)) {
return $this->walkArithmeticPrimary($factor);
diff --git a/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php b/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php
index c285739d8..e95155c13 100644
--- a/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php
+++ b/lib/Doctrine/ORM/Query/TreeWalkerAdapter.php
@@ -90,7 +90,7 @@ abstract class TreeWalkerAdapter implements TreeWalker
}
/**
- * Retrieves the Query Instance reponsible for the current walkers execution.
+ * Retrieves the Query Instance responsible for the current walkers execution.
*
* @return \Doctrine\ORM\AbstractQuery
*/
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
index df561d583..cec5d26a3 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
@@ -86,10 +86,10 @@ class ConvertMappingCommand extends Command
Convert mapping information between supported formats.
This is an execute one-time command. It should not be necessary for
-you to call this method multiple times, escpecially when using the --from-database
+you to call this method multiple times, especially when using the --from-database
flag.
-Converting an existing databsae schema into mapping files only solves about 70-80%
+Converting an existing database schema into mapping files only solves about 70-80%
of the necessary mapping information. Additionally the detection from an existing
database cannot detect inverse associations, inheritance types,
entities with foreign keys as primary keys and many of the
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
index 377841f1e..764e89500 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
@@ -91,7 +91,7 @@ to error and we suggest you use code repositories such as GIT or SVN to make
backups of your code.
It makes sense to generate the entity code if you are using entities as Data
-Access Objects only and dont put much additional logic on them. If you are
+Access Objects only and don't put much additional logic on them. If you are
however putting much more logic on the entities you should refrain from using
the entity-generator and code your entities manually.
diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php
index 02ef1e7c7..f66a49d15 100644
--- a/lib/Doctrine/ORM/Tools/SchemaTool.php
+++ b/lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -500,7 +500,7 @@ class SchemaTool
* Gets the class metadata that is responsible for the definition of the referenced column name.
*
* Previously this was a simple task, but with DDC-117 this problem is actually recursive. If its
- * not a simple field, go through all identifier field names that are associations recursivly and
+ * not a simple field, go through all identifier field names that are associations recursively and
* find that referenced column name.
*
* TODO: Is there any way to make this code more pleasing?
@@ -643,7 +643,7 @@ class SchemaTool
/**
* Drops the database schema for the given classes.
*
- * In any way when an exception is thrown it is supressed since drop was
+ * In any way when an exception is thrown it is suppressed since drop was
* issued for all classes of the schema and some probably just don't exist.
*
* @param array $classes
diff --git a/lib/Doctrine/ORM/Tools/ToolEvents.php b/lib/Doctrine/ORM/Tools/ToolEvents.php
index 7aa98d9a6..aebb5d8f3 100644
--- a/lib/Doctrine/ORM/Tools/ToolEvents.php
+++ b/lib/Doctrine/ORM/Tools/ToolEvents.php
@@ -23,7 +23,7 @@ class ToolEvents
{
/**
* The postGenerateSchemaTable event occurs in SchemaTool#getSchemaFromMetadata()
- * whenever an entity class is transformed into its table representation. It recieves
+ * whenever an entity class is transformed into its table representation. It receives
* the current non-complete Schema instance, the Entity Metadata Class instance and
* the Schema Table instance of this entity.
*
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 3a3f14e59..4c3f3720c 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -1822,7 +1822,7 @@ class UnitOfWork implements PropertyChangedListener
// Throw exception if versions dont match.
if ($managedCopyVersion != $entityVersion) {
- throw OptimisticLockException::lockFailedVersionMissmatch($entity, $entityVersion, $managedCopyVersion);
+ throw OptimisticLockException::lockFailedVersionMismatch($entity, $entityVersion, $managedCopyVersion);
}
}
@@ -2281,7 +2281,7 @@ class UnitOfWork implements PropertyChangedListener
$entityVersion = $class->reflFields[$class->versionField]->getValue($entity);
if ($entityVersion != $lockVersion) {
- throw OptimisticLockException::lockFailedVersionMissmatch($entity, $lockVersion, $entityVersion);
+ throw OptimisticLockException::lockFailedVersionMismatch($entity, $lockVersion, $entityVersion);
}
break;
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 3ab5edbae..e6fc54315 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -2,7 +2,7 @@
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: yaml
+
+ # config/yaml/Product.dcm.yml
+ Product:
+ type: entity
+ table: products
+ id:
+ id:
+ type: integer
+ generator:
+ strategy: AUTO
+ fields:
+ name:
+ type: string
+
+The top-level ``entity`` definition tag specifies information about
+the class and table-name. The primitive type ``Product::$name`` is
+defined as ``field`` attributes. The Id property is defined with
+the ``id`` tag. The id has a ``generator`` tag nested inside which
+defines that the primary key generation mechanism automatically
+uses the database platforms native id generation strategy, for
+example AUTO INCREMENT in the case of MySql or Sequences in the
+case of PostgreSql and Oracle.
+
+You have to update the database now, because we have a first Entity now:
+
+::
+
+ $ php vendor/bin/doctrine orm:schema-tool:update
+
+Now create a simple script to create a new product:
+
+.. code-block:: php
+
+ setName($newProductName);
+
+ $entityManager->persist($product);
+ $entityManager->flush();
+
+ echo "Created Product with ID " . $product->getId() . "\n";
+
+Call this script to see how new products are created:
+
+::
+
+ $ php create_product.php ORM
+ $ php create_product.php DBAL
+
+What is happening here? In the code using the Product is pretty standard OOP.
+The interesting bits are the communication with the ``EntityManager``. To
+notify the EntityManager that a new entity should be inserted into the database
+you have to call ``persist()``. However the EntityManager does not act on this
+command, its merely notified. You have to explicitly call ``flush()`` to have
+the EntityManager write those two entities to the database.
+
+You might wonder why does this distinction between persist notification and
+flush exist: Doctrine 2 uses the UnitOfWork pattern to aggregate all writes
+(INSERT, UPDATE, DELETE) into one single transaction, which is executed when
+flush is called. Using this approach the write-performance is significantly
+better than in a scenario where updates are done for each entity in isolation.
+In more complex scenarios than the previous two, you are free to request
+updates on many different entities and all flush them at once.
+
+Doctrine's UnitOfWork detects entities that have changed after retrieval from
+the database automatically when the flush operation is called, so that you only
+have to keep track of those entities that are new or to be removed and pass
+them to ``EntityManager#persist()`` and ``EntityManager#remove()``
+respectively.
+
+We want to see a list of all the products now, so lets create a new script for
+this:
+
+.. code-block:: php
+
+ getRepository('Product');
+ $products = $productRepository->findAll();
+
+ foreach ($products as $product) {
+ echo sprintf("-%s\n", $product->getName());
+ }
+
+The ``EntityRepository`` fetched through the ``EntityManager#getRepository()``
+method exists for every entity and is provided by Doctrine. It contains
+some finder methods such as ``findAll()`` we used here.
+
+Lets display the name of a product based on its ID:
+
+.. code-block:: php
+
+ find('Product', $id);
+
+ echo sprintf("-%s\n", $product->getName());
+
+Adding Bug and User Entities
+----------------------------
+
+We continue with the bug tracker domain, by creating the missing
+classes ``Bug`` and ``User`` and putting them into
+`src/Bug.php` and `src/User.php`
+respectively.
+
+.. code-block:: php
+
+ `.
-
- An entity contains persistable properties. A persistable property
- is an instance variable of the entity that is saved into and retrieved from the database
- by Doctrine's data mapping capabilities.
-
-Note how all properties have getter and setter methods defined except
-`$id`. To access data from entities Doctrine 2 uses the Reflection API, so it
-is possible for Doctrine to access the value of `$id`. You don't have to
-take Doctrine into account when designing access to the state of your objects.
-
All of the properties so far are scalar values, for example the 3 ID
fields of the entities, their names, description, status and change dates.
@@ -296,7 +556,6 @@ persistence.
Debug::dump() method just ignores any occurrences of it in Proxy
instances.
-
Because we only work with collections for the references we must be
careful to implement a bidirectional reference in the domain model.
The concept of owning or inverse side of a relation is central to
@@ -448,112 +707,8 @@ the database that points from Bugs to Products.
}
We are now finished with the domain model given the requirements.
-From the simple model with public properties only we had to do
-quite some work to get to a model where we encapsulated the
-references between the objects to make sure we don't break its
-consistent state when using Doctrine.
-
-However up to now the assumptions Doctrine imposed on our business
-objects have not restricting us much in our domain modelling
-capabilities. Actually we would have encapsulated access to all the
-properties anyways by using object-oriented best-practices.
-
-Metadata Mappings for our Entities
-----------------------------------
-
-Up to now we have only implemented our Entities as Data-Structures
-without actually telling Doctrine how to persist them in the
-database. If perfect in-memory databases would exist, we could now
-finish the application using these entities by implementing code to
-fulfil all the requirements. However the world isn't perfect and we
-have to persist our entities in some storage to make sure we don't
-loose their state. Doctrine currently serves Relational Database
-Management Systems. In the future we are thinking to support NoSQL
-vendors like CouchDb or MongoDb, however this is still far in the
-future.
-
-The next step for persistence with Doctrine is to describe the
-structure of our domain model entities to Doctrine using a metadata
-language. The metadata language describes how entities, their
-properties and references should be persisted and what constraints
-should be applied to them.
-
-Metadata for entities are loaded using a
-``Doctrine\ORM\Mapping\Driver\Driver`` implementation and Doctrine
-2 already comes with XML, YAML and Annotations Drivers. This
-Getting Started Guide will show the mappings for all Mapping Drivers.
-References in the text will be made to the XML mapping.
-
-Since we haven't namespaced our three entities, we have to
-implement three mapping files called Bug.dcm.xml, Product.dcm.xml
-and User.dcm.xml (or .yml) and put them into a distinct folder for mapping
-configurations. For the annotations driver we need to use
-doc-block comments on the entity classes themselves.
-
-The first discussed definition will be for the Product, since it is
-the most simple one:
-
-.. configuration-block::
-
- .. code-block:: php
-
-
-
-
-
-
-
-
-
-
-
-
-
- .. code-block:: yaml
-
- # config/yaml/Product.dcm.yml
- Product:
- type: entity
- table: products
- id:
- id:
- type: integer
- generator:
- strategy: AUTO
- fields:
- name:
- type: string
-
-The top-level ``entity`` definition tag specifies information about
-the class and table-name. The primitive type ``Product::$name`` is
-defined as ``field`` attributes. The Id property is defined with
-the ``id`` tag. The id has a ``generator`` tag nested inside which
-defines that the primary key generation mechanism automatically
-uses the database platforms native id generation strategy, for
-example AUTO INCREMENT in the case of MySql or Sequences in the
-case of PostgreSql and Oracle.
-
-We then go on specifying the definition of a Bug:
+Now we continue adding metadata mappings for the ``User`` and ``Bug``
+as we did for the ``Product`` before:
.. configuration-block::
.. code-block:: php
@@ -654,7 +809,7 @@ We then go on specifying the definition of a Bug:
targetEntity: Product
-Here again we have the entity, id and primitive type definitions.
+Here we have the entity, id and primitive type definitions.
The column names are used from the Zend\_Db\_Table examples and
have different names than the properties on the Bug class.
Additionally for the "created" field it is specified that it is of
@@ -774,118 +929,10 @@ class that holds the owning sides.
This example has a fair overview of the most basic features of the
metadata definition language.
-Obtaining the EntityManager
----------------------------
-
-Doctrine's public interface is the EntityManager, it provides the
-access point to the complete lifecycle management of your entities
-and transforms entities from and back to persistence. You have to
-configure and create it to use your entities with Doctrine 2. I
-will show the configuration steps and then discuss them step by
-step:
-
-.. code-block:: php
-
- 'pdo_sqlite',
- 'path' => __DIR__ . '/db.sqlite',
- );
-
- // obtaining the entity manager
- $entityManager = EntityManager::create($conn, $config);
-
-The first require statement sets up the autoloading capabilities of Doctrine
-using the Composer autoload.
-
-The second block consists of the instantiation of the ORM
-``Configuration`` object using the Setup helper. It assumes a bunch
-of defaults that you don't have to bother about for now. You can
-read up on the configuration details in the
-:doc:`reference chapter on configuration <../reference/configuration>`.
-
-The third block shows the configuration options required to connect
-to a database, in my case a file-based sqlite database. All the
-configuration options for all the shipped drivers are given in the
-`DBAL Configuration section of the manual `_.
-
-The last block shows how the ``EntityManager`` is obtained from a
-factory method.
-
-Generating the Database Schema
+Implementing more Requirements
------------------------------
-Now that we have defined the Metadata Mappings and bootstrapped the
-EntityManager we want to generate the relational database schema
-from it. Doctrine has a Command-Line-Interface that allows you to
-access the SchemaTool, a component that generates the required
-tables to work with the metadata.
-
-For the command-line tool to work a cli-config.php file has to be
-present in the project root directory, where you will execute the
-doctrine command. Its a fairly simple file:
-
-.. code-block:: php
-
- new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($entityManager)
- ));
-
-You can then change into your project directory and call the
-Doctrine command-line tool:
-
-::
-
- $ cd project/
- $ php vendor/bin/doctrine orm:schema-tool:create
-
-During the development you probably need to re-create the database
-several times when changing the Entity metadata. You can then
-either re-create the database:
-
-::
-
- $ php vendor/bin/doctrine orm:schema-tool:drop --force
- $ php vendor/bin/doctrine orm:schema-tool:create
-
-Or use the update functionality:
-
-::
-
- $ php vendor/bin/doctrine orm:schema-tool:update --force
-
-The updating of databases uses a Diff Algorithm for a given
-Database Schema, a cornerstone of the ``Doctrine\DBAL`` package,
-which can even be used without the Doctrine ORM package. However
-its not available in SQLite since it does not support ALTER TABLE.
-
-Writing Entities into the Database
-----------------------------------
-
-.. note::
-
- This tutorial assumes you call all the example scripts from the CLI.
-
-Having created the schema we can now start and save entities in the
-database. For starters we need a create user use-case:
+For starters we need a create user entities:
.. code-block:: php
@@ -903,59 +950,14 @@ database. For starters we need a create user use-case:
echo "Created User with ID " . $user->getId() . "\n";
-Products can also be created:
-
-.. code-block:: php
-
- setName($newProductName);
-
- $entityManager->persist($product);
- $entityManager->flush();
-
- echo "Created Product with ID " . $product->getId() . "\n";
-
Now call:
::
$ php create_user.php beberlei
- $ php create_product.php MyProduct
-So what is happening in those two snippets? In both examples the
-code that works on User and Product is pretty standard OOP. The interesting bits are the
-communication with the ``EntityManager``. To notify the
-EntityManager that a new entity should be inserted into the
-database you have to call ``persist()``. However the EntityManager
-does not act on this command, its merely notified. You have to explicitly
-call ``flush()`` to have the EntityManager write those two entities
-to the database.
-
-You might wonder why does this distinction between persist
-notification and flush exist: Doctrine 2 uses the UnitOfWork
-pattern to aggregate all writes (INSERT, UPDATE, DELETE) into one
-single transaction, which is executed when flush is called.
-Using this approach the write-performance is significantly better
-than in a scenario where updates are done for each entity in
-isolation. In more complex scenarios than the previous two, you are
-free to request updates on many different entities and all flush
-them at once.
-
-Doctrine's UnitOfWork detects entities that have changed after
-retrieval from the database automatically when the flush operation
-is called, so that you only have to keep track of those entities
-that are new or to be removed and pass them to
-``EntityManager#persist()`` and ``EntityManager#remove()``
-respectively.
-
-We are now getting to the "Create a New Bug" requirement and the
-code for this scenario may look like this:
+We now have the data to create a bug and the code for this scenario may look
+like this:
.. code-block:: php
@@ -1462,4 +1464,3 @@ will be added to this tutorial incrementally, topics will include:
Additional details on all the topics discussed here can be found in
the respective manual chapters.
-
From c399dcfe58865b839309a710d39c36a4faf9cd32 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 17 Mar 2013 19:18:49 +0100
Subject: [PATCH 042/332] Add simpler section for 2.4 CLI integration
---
docs/en/reference/configuration.rst | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst
index 4743971fe..eb4b0a497 100644
--- a/docs/en/reference/configuration.rst
+++ b/docs/en/reference/configuration.rst
@@ -107,6 +107,23 @@ You need to register your applications EntityManager to the console tool
to make use of the tasks by creating a ``cli-config.php`` file with the
following content:
+On Doctrine 2.4 and above:
+
+.. code-block:: php
+
+ new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
From acae1aeaaa8465a562f2ecc9ba40cf7c1da24f58 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 17 Mar 2013 19:43:09 +0100
Subject: [PATCH 043/332] Fix link in docs
---
docs/en/reference/configuration.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/en/reference/configuration.rst b/docs/en/reference/configuration.rst
index eb4b0a497..d8e718b5c 100644
--- a/docs/en/reference/configuration.rst
+++ b/docs/en/reference/configuration.rst
@@ -79,12 +79,13 @@ Or if you prefer YAML:
Inside the ``Setup`` methods several assumptions are made:
-- If `$devMode` is true always use an ``ArrayCache`` and set ``setAutoGenerateProxyClasses(true)``.
+- If `$devMode` is true always use an ``ArrayCache`` (in-memory) and regenerate proxies on every request.
- If `$devMode` is false, check for Caches in the order APC, Xcache, Memcache (127.0.0.1:11211), Redis (127.0.0.1:6379) unless `$cache` is passed as fourth argument.
-- If `$devMode` is false, set ``setAutoGenerateProxyClasses(false)``
+- If `$devMode` is false, set then proxy classes have to be explicitly created
+ through the command line.
- If third argument `$proxyDir` is not set, use the systems temporary directory.
-If you want to configure Doctrine in more detail, take a look at the `Advanced
+If you want to configure Doctrine in more detail, take a look at the :doc:`Advanced
Configuration ` section.
.. note::
From 39ea24675da38a160cecf2a131b6917ea0bbde3d Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Sun, 17 Mar 2013 16:59:33 -0300
Subject: [PATCH 044/332] Fix DDC-2090
---
.../Query/Exec/MultiTableUpdateExecutor.php | 29 ++---
.../ORM/Functional/Ticket/DDC2090Test.php | 110 ++++++++++++++++++
2 files changed, 120 insertions(+), 19 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php
diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php
index cc15cea92..8ceefe3a9 100644
--- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php
+++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php
@@ -124,19 +124,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
$updateSql .= $sqlWalker->walkUpdateItem($updateItem);
- //FIXME: parameters can be more deeply nested. traverse the tree.
- //FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
if ($newValue instanceof AST\InputParameter) {
- $parameterName = $newValue->name;
- $parameter = $sqlWalker->getQuery()->getParameter($parameterName);
-
- $value = $sqlWalker->getQuery()->processParameterValue($parameter->getValue());
- $type = ($parameter->getValue() === $value)
- ? $parameter->getType()
- : ParameterTypeInferer::inferType($value);
-
- $this->_sqlParameters[$i]['parameters'][] = $value;
- $this->_sqlParameters[$i]['types'][] = $type;
+ $this->_sqlParameters[$i][] = $newValue->name;
++$this->_numParametersInUpdateClause;
}
@@ -188,16 +177,18 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
);
// Execute UPDATE statements
- for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) {
- $parameters = array();
- $types = array();
+ foreach ($this->_sqlStatements as $key => $statement) {
+ $paramValues = array();
+ $paramTypes = array();
- if (isset($this->_sqlParameters[$i])) {
- $parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array();
- $types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array();
+ if (isset($this->_sqlParameters[$key])) {
+ foreach ($this->_sqlParameters[$key] as $parameterKey => $parameterName) {
+ $paramValues[] = $params[$parameterKey];
+ $paramTypes[] = isset($types[$parameterKey]) ? $types[$parameterKey] : ParameterTypeInferer::inferType($params[$parameterKey]);
+ }
}
- $conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types);
+ $conn->executeUpdate($statement, $paramValues, $paramTypes);
}
} catch (\Exception $exception) {
// FAILURE! Drop temporary table to avoid possible collisions
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php
new file mode 100644
index 000000000..c5da3deae
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2090Test.php
@@ -0,0 +1,110 @@
+useModelSet('company');
+ parent::setUp();
+ }
+
+ public function testIssue()
+ {
+ $className = 'Doctrine\Tests\Models\Company\CompanyEmployee';
+ $date1 = new \DateTime('2011-11-11 11:11:11');
+ $date2 = new \DateTime('2012-12-12 12:12:12');
+ $employee1 = new CompanyEmployee;
+ $employee2 = new CompanyEmployee;
+
+ $employee1->setName("Fabio B. Silva");
+ $employee1->setStartDate(new \DateTime('yesterday'));
+ $employee1->setDepartment("R&D");
+ $employee1->setSalary(100);
+
+ $employee2->setName("Doctrine Bot");
+ $employee1->setStartDate(new \DateTime('yesterday'));
+ $employee2->setDepartment("QA");
+ $employee2->setSalary(100);
+
+ $this->_em->persist($employee1);
+ $this->_em->persist($employee2);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $this->_em->createQueryBuilder()
+ ->update($className, 'e')
+ ->set('e.startDate', ':date')
+ ->set('e.salary', ':salary')
+ ->where('e = :e')
+ ->setParameters(array(
+ 'e' => $employee1,
+ 'date' => $date1,
+ 'salary' => 101,
+ ))
+ ->getQuery()
+ ->useQueryCache(true)
+ ->execute();
+
+ $this->_em->createQueryBuilder()
+ ->update($className, 'e')
+ ->set('e.startDate', ':date')
+ ->set('e.salary', ':salary')
+ ->where('e = :e')
+ ->setParameters(array(
+ 'e' => $employee2,
+ 'date' => $date2,
+ 'salary' => 102,
+ ))
+ ->getQuery()
+ ->useQueryCache(true)
+ ->execute();
+
+ $this->_em->clear();
+
+ $e1 = $this->_em->find($className, $employee1->getId());
+ $e2 = $this->_em->find($className, $employee2->getId());
+
+ $this->assertEquals(101, $e1->getSalary());
+ $this->assertEquals(102, $e2->getSalary());
+ $this->assertEquals($date1, $e1->getStartDate());
+ $this->assertEquals($date2, $e2->getStartDate());
+
+ $this->_em->createQueryBuilder()
+ ->update($className, 'e')
+ ->set('e.startDate', '?1')
+ ->set('e.salary', '?2')
+ ->where('e = ?0')
+ ->setParameters(array($employee1, $date1, 101))
+ ->getQuery()
+ ->useQueryCache(true)
+ ->execute();
+
+ $this->_em->createQueryBuilder()
+ ->update($className, 'e')
+ ->set('e.startDate', '?1')
+ ->set('e.salary', '?2')
+ ->where('e = ?0')
+ ->setParameters(array($employee2, $date2, 102))
+ ->getQuery()
+ ->useQueryCache(true)
+ ->execute();
+
+
+ $this->_em->clear();
+
+ $e1 = $this->_em->find($className, $employee1->getId());
+ $e2 = $this->_em->find($className, $employee2->getId());
+
+ $this->assertEquals(101, $e1->getSalary());
+ $this->assertEquals(102, $e2->getSalary());
+ $this->assertEquals($date1, $e1->getStartDate());
+ $this->assertEquals($date2, $e2->getStartDate());
+ }
+}
\ No newline at end of file
From 220f3676582ac2f794e7036cae9d0012c07870f4 Mon Sep 17 00:00:00 2001
From: David Buchmann
Date: Wed, 20 Mar 2013 00:46:11 +0100
Subject: [PATCH 045/332] adding some more doc and examples for lifecycle event
listeners and subscribers
---
docs/en/reference/events.rst | 169 +++++++++++++++++++++++++----------
1 file changed, 120 insertions(+), 49 deletions(-)
diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst
index df8c594bc..ca3578cde 100644
--- a/docs/en/reference/events.rst
+++ b/docs/en/reference/events.rst
@@ -2,7 +2,9 @@ Events
======
Doctrine 2 features a lightweight event system that is part of the
-Common package.
+Common package. Doctrine uses it to dispatch system events, mainly
+:ref:`lifecycle events `.
+You can also use it for your own custom events.
The Event System
----------------
@@ -27,28 +29,28 @@ Now we can add some event listeners to the ``$evm``. Let's create a
{
const preFoo = 'preFoo';
const postFoo = 'postFoo';
-
+
private $_evm;
-
+
public $preFooInvoked = false;
public $postFooInvoked = false;
-
+
public function __construct($evm)
{
$evm->addEventListener(array(self::preFoo, self::postFoo), $this);
}
-
+
public function preFoo(EventArgs $e)
{
$this->preFooInvoked = true;
}
-
+
public function postFoo(EventArgs $e)
{
$this->postFooInvoked = true;
}
}
-
+
// Create a new instance
$test = new EventTest($evm);
@@ -80,22 +82,30 @@ array of events it should be subscribed to.
class TestEventSubscriber implements \Doctrine\Common\EventSubscriber
{
public $preFooInvoked = false;
-
+
public function preFoo()
{
$this->preFooInvoked = true;
}
-
+
public function getSubscribedEvents()
{
return array(TestEvent::preFoo);
}
}
-
+
$eventSubscriber = new TestEventSubscriber();
$evm->addEventSubscriber($eventSubscriber);
-Now when you dispatch an event any event subscribers will be
+.. note::
+
+ If you are familiar with the Symfony2 event manager, note that
+ the array returned by getSubscribedEvents is different. For
+ doctrine, the array values must be the event names, and the
+ names are used as method names that will be called when the
+ event occurs.
+
+Now when you dispatch an event, any event subscribers will be
notified for that event.
.. code-block:: php
@@ -133,6 +143,8 @@ several reasons:
An example for a correct notation can be found in the example
``EventTest`` above.
+.. _reference-events-lifecycle-events:
+
Lifecycle Events
----------------
@@ -164,7 +176,7 @@ the life-time of their registered entities.
- loadClassMetadata - The loadClassMetadata event occurs after the
mapping metadata for a class has been loaded from a mapping source
(annotations/xml/yaml).
-- preFlush - The preFlush event occurs at the very beginning of a flush
+- preFlush - The preFlush event occurs at the very beginning of a flush
operation. This event is not a lifecycle callback.
- onFlush - The onFlush event occurs after the change-sets of all
managed entities are computed. This event is not a lifecycle
@@ -198,7 +210,7 @@ listeners:
- Lifecycle Callbacks are methods on the entity classes that are
called when the event is triggered. They receives some kind of ``EventArgs``.
-- Lifecycle Event Listeners are classes with specific callback
+- Lifecycle Event Listeners and Subscribers are classes with specific callback
methods that receives some kind of ``EventArgs`` instance which
give access to the entity, EntityManager or other relevant data.
@@ -222,44 +234,44 @@ event occurs.
.. code-block:: php
createdAt = date('Y-m-d H:i:s');
}
-
+
/** @PrePersist */
public function doOtherStuffOnPrePersist()
{
$this->value = 'changed from prePersist callback!';
}
-
+
/** @PostPersist */
public function doStuffOnPostPersist()
{
$this->value = 'changed from postPersist callback!';
}
-
+
/** @PostLoad */
public function doStuffOnPostLoad()
{
$this->value = 'changed from postLoad callback!';
}
-
+
/** @PreUpdate */
public function doStuffOnPreUpdate()
{
@@ -283,28 +295,28 @@ can do it with the following.
type: string(50)
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
- postPersist: [ doStuffOnPostPersist ]
+ postPersist: [ doStuffOnPostPersist ]
XML would look something like this:
.. code-block:: xml
-
+
-
+
-
+
-
+
-
+
You just need to make sure a public ``doStuffOnPrePersist()`` and
@@ -315,16 +327,16 @@ model.
getObject();
+ $entityManager = $args->getObjectManager();
+
+ // perhaps you only want to act on some "Product" entity
+ if ($entity instanceof Product) {
+ // do something with the Product
+ }
+ }
+ }
+
+A lifecycle event subscriber may looks like this:
+
+.. code-block:: php
+
+ getObject();
+ $entityManager = $args->getObjectManager();
+
+ // perhaps you only want to act on some "Product" entity
+ if ($entity instanceof Product) {
+ // do something with the Product
+ }
+ }
+
+.. note::
+
+ Lifecycle events are triggered for all entities. It is the responsibility
+ of the listeners and subscribers to check if the entity is of a type
+ it wants to handle.
+
+To register an event listener or subscriber, you have to hook it into the
EventManager that is passed to the EntityManager factory:
.. code-block:: php
@@ -380,7 +451,7 @@ EventManager that is passed to the EntityManager factory:
$eventManager = new EventManager();
$eventManager->addEventListener(array(Events::preUpdate), new MyEventListener());
$eventManager->addEventSubscriber(new MyEventSubscriber());
-
+
$entityManager = EntityManager::create($dbOpts, $config, $eventManager);
You can also retrieve the event manager instance after the
@@ -451,8 +522,8 @@ called during a flush operation.
preFlush
~~~~~~~~
-``preFlush`` is called at ``EntityManager#flush()`` before
-anything else. ``EntityManager#flush()`` can be called safely
+``preFlush`` is called at ``EntityManager#flush()`` before
+anything else. ``EntityManager#flush()`` can be called safely
inside its listeners.
.. code-block:: php
@@ -497,25 +568,25 @@ mentioned sets. See this example:
{
$em = $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();
-
+
foreach ($uow->getScheduledEntityInsertions() AS $entity) {
-
+
}
-
+
foreach ($uow->getScheduledEntityUpdates() AS $entity) {
-
+
}
-
+
foreach ($uow->getScheduledEntityDeletions() AS $entity) {
-
+
}
-
+
foreach ($uow->getScheduledCollectionDeletions() AS $col) {
-
+
}
-
+
foreach ($uow->getScheduledCollectionUpdates() AS $col) {
-
+
}
}
}
@@ -615,7 +686,7 @@ lifecycle callback when there are expensive validations to call:
}
}
}
-
+
private function validateCreditCard($no)
{
// throw an exception to interrupt flush event. Transaction will be rolled back.
@@ -788,7 +859,7 @@ you should map the listener method using the event type mapping.
postRemove: [postRemoveHandler]
preRemove: [preRemoveHandler]
# ....
-
+
Entity listeners resolver
@@ -867,7 +938,7 @@ process and manipulate the instance.
$metadataFactory = $em->getMetadataFactory();
$evm = $em->getEventManager();
$evm->addEventListener(Events::loadClassMetadata, $test);
-
+
class EventTest
{
public function loadClassMetadata(\Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs)
From 204c1afe9ad5bc30afd11ba5800c900c825ba45a Mon Sep 17 00:00:00 2001
From: David Buchmann
Date: Thu, 21 Mar 2013 10:43:01 +0100
Subject: [PATCH 046/332] cleanup event subscriber note
---
docs/en/reference/events.rst | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst
index ca3578cde..517f2ec5b 100644
--- a/docs/en/reference/events.rst
+++ b/docs/en/reference/events.rst
@@ -99,11 +99,9 @@ array of events it should be subscribed to.
.. note::
- If you are familiar with the Symfony2 event manager, note that
- the array returned by getSubscribedEvents is different. For
- doctrine, the array values must be the event names, and the
- names are used as method names that will be called when the
- event occurs.
+ The array to return in the ``getSubscribedEvents`` method is a simple array
+ with the values being the event names. The subscriber must have a method
+ that is named exactly like the event.
Now when you dispatch an event, any event subscribers will be
notified for that event.
@@ -413,6 +411,7 @@ A lifecycle event subscriber may looks like this:
.. code-block:: php
Date: Thu, 21 Mar 2013 15:49:00 +0100
Subject: [PATCH 047/332] Import EntityManager in ConsoleRunner
---
lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php b/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
index f263a4f0b..077ae8930 100644
--- a/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
+++ b/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
@@ -22,6 +22,7 @@ namespace Doctrine\ORM\Tools\Console;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\HelperSet;
use Doctrine\ORM\Version;
+use Doctrine\ORM\EntityManager;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
From 94ceb0e410ea995e858fa18246cf53ee53d02c59 Mon Sep 17 00:00:00 2001
From: Chuan Ma
Date: Fri, 22 Mar 2013 17:52:37 -0400
Subject: [PATCH 048/332] Document: delete the doc for a number of cache
provider methods that don't exist
---
docs/en/reference/caching.rst | 54 -----------------------------------
1 file changed, 54 deletions(-)
diff --git a/docs/en/reference/caching.rst b/docs/en/reference/caching.rst
index a008aa558..1e87efaff 100644
--- a/docs/en/reference/caching.rst
+++ b/docs/en/reference/caching.rst
@@ -211,49 +211,6 @@ By Cache ID
delete('my_array');
-You can also pass wild cards to the ``delete()`` method and it will
-return an array of IDs that were matched and deleted.
-
-.. code-block:: php
-
- delete('users_*');
-
-By Regular Expression
-^^^^^^^^^^^^^^^^^^^^^
-
-If you need a little more control than wild cards you can use a PHP
-regular expression to delete cache entries.
-
-.. code-block:: php
-
- deleteByRegex('/users_.*/');
-
-By Prefix
-^^^^^^^^^
-
-Because regular expressions are kind of slow, if simply deleting by
-a prefix or suffix is sufficient, it is recommended that you do
-that instead of using a regular expression because it will be much
-faster if you have many cache entries.
-
-.. code-block:: php
-
- deleteByPrefix('users_');
-
-By Suffix
-^^^^^^^^^
-
-Just like we did above with the prefix you can do the same with a
-suffix.
-
-.. code-block:: php
-
- deleteBySuffix('_my_account');
-
All
^^^
@@ -265,17 +222,6 @@ the ``deleteAll()`` method.
deleteAll();
-Counting
-~~~~~~~~
-
-If you want to count how many entries are stored in the cache
-driver instance you can use the ``count()`` method.
-
-.. code-block:: php
-
- count();
-
Namespaces
~~~~~~~~~~
From 10c48bad7b79af84855f7c63590f1f426770ed6b Mon Sep 17 00:00:00 2001
From: Fran Moreno
Date: Sun, 24 Mar 2013 02:07:05 +0100
Subject: [PATCH 049/332] [Docs] Fix field name in inversedby parameter
---
docs/en/reference/working-with-associations.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/reference/working-with-associations.rst b/docs/en/reference/working-with-associations.rst
index 7f46eba6a..0efba84f2 100644
--- a/docs/en/reference/working-with-associations.rst
+++ b/docs/en/reference/working-with-associations.rst
@@ -93,7 +93,7 @@ information about its type and if it's the owning or inverse side.
/**
* Bidirectional - Many Comments are authored by one user (OWNING SIDE)
*
- * @ManyToOne(targetEntity="User", inversedBy="authoredComments")
+ * @ManyToOne(targetEntity="User", inversedBy="commentsAuthored")
*/
private $author;
}
From d4061ff41b811666c68923a70d35f71dc9204486 Mon Sep 17 00:00:00 2001
From: Dustin Moorman
Date: Sun, 24 Mar 2013 03:16:00 -0500
Subject: [PATCH 050/332] Fixed typos in Doctrine Mapping Types section.
---
docs/en/reference/basic-mapping.rst | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/docs/en/reference/basic-mapping.rst b/docs/en/reference/basic-mapping.rst
index adf2ff0dd..2909048dd 100644
--- a/docs/en/reference/basic-mapping.rst
+++ b/docs/en/reference/basic-mapping.rst
@@ -138,32 +138,32 @@ Doctrine Mapping Types
----------------------
A Doctrine Mapping Type defines the mapping between a PHP type and
-an SQL type. All Doctrine Mapping Types that ship with Doctrine are
+a SQL type. All Doctrine Mapping Types that ship with Doctrine are
fully portable between different RDBMS. You can even write your own
custom mapping types that might or might not be portable, which is
explained later in this chapter.
For example, the Doctrine Mapping Type ``string`` defines the
-mapping from a PHP string to an SQL VARCHAR (or VARCHAR2 etc.
+mapping from a PHP string to a SQL VARCHAR (or VARCHAR2 etc.
depending on the RDBMS brand). Here is a quick overview of the
built-in mapping types:
-- ``string``: Type that maps an SQL VARCHAR to a PHP string.
-- ``integer``: Type that maps an SQL INT to a PHP integer.
+- ``string``: Type that maps a SQL VARCHAR to a PHP string.
+- ``integer``: Type that maps a SQL INT to a PHP integer.
- ``smallint``: Type that maps a database SMALLINT to a PHP
integer.
- ``bigint``: Type that maps a database BIGINT to a PHP string.
-- ``boolean``: Type that maps an SQL boolean to a PHP boolean.
-- ``decimal``: Type that maps an SQL DECIMAL to a PHP string.
-- ``date``: Type that maps an SQL DATETIME to a PHP DateTime
+- ``boolean``: Type that maps a SQL boolean to a PHP boolean.
+- ``decimal``: Type that maps a SQL DECIMAL to a PHP string.
+- ``date``: Type that maps a SQL DATETIME to a PHP DateTime
object.
-- ``time``: Type that maps an SQL TIME to a PHP DateTime object.
-- ``datetime``: Type that maps an SQL DATETIME/TIMESTAMP to a PHP
+- ``time``: Type that maps a SQL TIME to a PHP DateTime object.
+- ``datetime``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP
DateTime object.
-- ``datetimetz``: Type that maps an SQL DATETIME/TIMESTAMP to a PHP
+- ``datetimetz``: Type that maps a SQL DATETIME/TIMESTAMP to a PHP
DateTime object with timezone.
-- ``text``: Type that maps an SQL CLOB to a PHP string.
+- ``text``: Type that maps a SQL CLOB to a PHP string.
- ``object``: Type that maps a SQL CLOB to a PHP object using
``serialize()`` and ``unserialize()``
- ``array``: Type that maps a SQL CLOB to a PHP array using
@@ -178,7 +178,7 @@ built-in mapping types:
decimal points as separator.
- ``guid``: Type that maps a database GUID/UUID to a PHP string. Defaults to
varchar but uses a specific type if the platform supports it.
-- ``blob``: Type that maps an SQL BLOB to a PHP resource stream
+- ``blob``: Type that maps a SQL BLOB to a PHP resource stream
.. note::
From 57020322cb3c9788c8f8f673177727da8055e245 Mon Sep 17 00:00:00 2001
From: Marco Pivetta
Date: Sun, 24 Mar 2013 19:40:53 +0100
Subject: [PATCH 051/332] Adding failing test for DDC-2359
Doctrine\ORM\Mapping\ClassMetadataFactory#wakeupReflection is called twice
---
.../ORM/Functional/Ticket/DDC2359Test.php | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
new file mode 100644
index 000000000..b9670d27a
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
@@ -0,0 +1,55 @@
+getMock('Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriver');
+ $mockMetadata = $this->getMock('Doctrine\\ORM\\Mapping\\ClassMetadata', array(), array(), '', false);
+ $entityManager = $this->getMock('Doctrine\\ORM\\EntityManager', array(), array(), '', false);
+ /* @var $metadataFactory \Doctrine\ORM\Mapping\ClassMetadataFactory|\PHPUnit_Framework_MockObject_MockObject */
+ $metadataFactory = $this->getMock(
+ 'Doctrine\\ORM\\Mapping\\ClassMetadataFactory',
+ array('newClassMetadataInstance', 'wakeupReflection')
+ );
+ $configuration = $this->getMock('Doctrine\\ORM\\Configuration');
+ $connection = $this->getMock('Doctrine\\DBAL\\Connection', array(), array(), '', false);
+
+ $configuration
+ ->expects($this->any())
+ ->method('getMetadataDriverImpl')
+ ->will($this->returnValue($mockDriver));
+ $entityManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
+ $entityManager->expects($this->any())->method('getConnection')->will($this->returnValue($connection));
+ $entityManager
+ ->expects($this->any())
+ ->method('getEventManager')
+ ->will($this->returnValue($this->getMock('Doctrine\\Common\\EventManager')));
+
+ $metadataFactory->expects($this->any())->method('newClassMetadataInstance')->will($this->returnValue($mockMetadata));
+ $metadataFactory->expects($this->once())->method('wakeupReflection');
+
+ $metadataFactory->setEntityManager($entityManager);
+
+ $this->assertSame($mockMetadata, $metadataFactory->getMetadataFor(__NAMESPACE__ . '\\DDC2359Foo'));
+ }
+}
+
+/** @Entity */
+class DDC2359Foo
+{
+ /** @Id @Column(type="integer") @GeneratedValue */
+ public $id;
+}
\ No newline at end of file
From 7afe5af73a4422d06283b67a5f9c55e3866cc128 Mon Sep 17 00:00:00 2001
From: Marco Pivetta
Date: Sun, 24 Mar 2013 19:42:50 +0100
Subject: [PATCH 052/332] Fix for DDC-2359
---
lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index 242a9099f..a1da3ffcf 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -171,7 +171,6 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
- $this->wakeupReflection($class, $this->getReflectionService());
$this->validateRuntimeMetadata($class, $parent);
}
From 827f1f84cb3856d72c53e8cbfd0c90eeef04f7d9 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 24 Mar 2013 19:58:19 +0100
Subject: [PATCH 053/332] Release 2.4.0-BETA1
---
composer.json | 4 ++--
lib/Doctrine/ORM/Version.php | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/composer.json b/composer.json
index 89d62f2f6..cb46a2378 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
- "type": "library",
+ "type": "library","version":"2.4.0-BETA1",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
@@ -16,7 +16,7 @@
"php": ">=5.3.2",
"ext-pdo": "*",
"doctrine/collections": "~1.1",
- "doctrine/dbal": ">=2.4-dev,<2.5-dev",
+ "doctrine/dbal": ">=2.4-beta,<2.5-dev",
"symfony/console": "2.*"
},
"suggest": {
diff --git a/lib/Doctrine/ORM/Version.php b/lib/Doctrine/ORM/Version.php
index 4dba7902f..522f68b6f 100644
--- a/lib/Doctrine/ORM/Version.php
+++ b/lib/Doctrine/ORM/Version.php
@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
- const VERSION = '2.4.0-DEV';
+ const VERSION = '2.4.0-BETA1';
/**
* Compares a Doctrine version with the current one.
From 7f26e9ac27024682cabcb435452690174d1ba7bc Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 24 Mar 2013 19:58:19 +0100
Subject: [PATCH 054/332] Bump dev version to 2.4.0
---
composer.json | 2 +-
lib/Doctrine/ORM/Version.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/composer.json b/composer.json
index cb46a2378..52960133d 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
- "type": "library","version":"2.4.0-BETA1",
+ "type": "library",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
diff --git a/lib/Doctrine/ORM/Version.php b/lib/Doctrine/ORM/Version.php
index 522f68b6f..4dba7902f 100644
--- a/lib/Doctrine/ORM/Version.php
+++ b/lib/Doctrine/ORM/Version.php
@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
- const VERSION = '2.4.0-BETA1';
+ const VERSION = '2.4.0-DEV';
/**
* Compares a Doctrine version with the current one.
From 3e8dd1e45c083eca14886a50d71d61d0d6b69df2 Mon Sep 17 00:00:00 2001
From: Aaron Muylaert
Date: Tue, 26 Mar 2013 16:47:41 +0100
Subject: [PATCH 055/332] Update query-builder.rst
Fix typo in one of the orderBy examples.
---
docs/en/reference/query-builder.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/reference/query-builder.rst b/docs/en/reference/query-builder.rst
index 7d9ee9a8a..8029822b5 100644
--- a/docs/en/reference/query-builder.rst
+++ b/docs/en/reference/query-builder.rst
@@ -222,7 +222,7 @@ alternative syntax is available:
$qb->select('u')
->from('User u')
->where('u.id = :identifier')
- ->orderBy('u.name ASC');
+ ->orderBy('u.name', 'ASC');
->setParameter('identifier', 100); // Sets :identifier to 100, and thus we will fetch a user with u.id = 100
Note that numeric placeholders start with a ? followed by a number
From 521276f1ede77794f71b3e4cd3c315ac668ca412 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Tue, 26 Mar 2013 20:52:57 +0100
Subject: [PATCH 056/332] entity generator - ignore trait properties and
methods
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 082720bf7..945bbd935 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -709,6 +709,15 @@ public function __construct()
}
}
+ // check traits for existing property
+ $reflClass = new \ReflectionClass($metadata->name);
+
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
+ }
+ }
+
return (
isset($this->staticReflection[$metadata->name]) &&
in_array($property, $this->staticReflection[$metadata->name]['properties'])
@@ -732,6 +741,15 @@ public function __construct()
}
}
+ // check traits for existing method
+ $reflClass = new \ReflectionClass($metadata->name);
+
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
+ }
+ }
+
return (
isset($this->staticReflection[$metadata->name]) &&
in_array($method, $this->staticReflection[$metadata->name]['methods'])
From 02d34bbba6e3055b6b72918a3f08d43d4f29469e Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Tue, 19 Feb 2013 19:04:13 +0100
Subject: [PATCH 057/332] [DDC-93] Started ValueObjectsTest
---
.../Tests/ORM/Functional/ValueObjectsTest.php | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
new file mode 100644
index 000000000..916f06bf9
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
@@ -0,0 +1,25 @@
+
Date: Tue, 26 Mar 2013 21:14:52 +0100
Subject: [PATCH 058/332] only use already existing reflections
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 945bbd935..97a40e8ad 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -710,11 +710,13 @@ public function __construct()
}
// check traits for existing property
- $reflClass = new \ReflectionClass($metadata->name);
+ if (isset($this->staticReflection[$metadata->name])) {
+ $reflClass = $this->staticReflection[$metadata->name];
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasProperty($property)) {
- return true;
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
+ }
}
}
@@ -742,11 +744,13 @@ public function __construct()
}
// check traits for existing method
- $reflClass = new \ReflectionClass($metadata->name);
+ if (isset($this->staticReflection[$metadata->name])) {
+ $reflClass = $this->staticReflection[$metadata->name];
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasMethod($method)) {
- return true;
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
+ }
}
}
From 8e3e2e770a2271caf15899cb3f9a840d94443fa7 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Tue, 26 Mar 2013 21:17:59 +0100
Subject: [PATCH 059/332] Revert "only use already existing reflections"
This reverts commit bb5bdcf0f4ccd6fc83692490ec70a697c90573fb.
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 97a40e8ad..945bbd935 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -710,13 +710,11 @@ public function __construct()
}
// check traits for existing property
- if (isset($this->staticReflection[$metadata->name])) {
- $reflClass = $this->staticReflection[$metadata->name];
+ $reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasProperty($property)) {
- return true;
- }
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
}
}
@@ -744,13 +742,11 @@ public function __construct()
}
// check traits for existing method
- if (isset($this->staticReflection[$metadata->name])) {
- $reflClass = $this->staticReflection[$metadata->name];
+ $reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasMethod($method)) {
- return true;
- }
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
}
}
From 8898c91dfc1c6a433fc6cb1de5235c35a46f25b7 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Tue, 26 Mar 2013 21:28:09 +0100
Subject: [PATCH 060/332] only check for traits when class exists
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 945bbd935..2946935b3 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -710,11 +710,13 @@ public function __construct()
}
// check traits for existing property
- $reflClass = new \ReflectionClass($metadata->name);
+ if (class_exists($metadata->name)) {
+ $reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasProperty($property)) {
- return true;
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
+ }
}
}
@@ -742,11 +744,13 @@ public function __construct()
}
// check traits for existing method
- $reflClass = new \ReflectionClass($metadata->name);
+ if (class_exists($metadata->name)) {
+ $reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasMethod($method)) {
- return true;
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
+ }
}
}
From 32988b3cdf050f2531c4d4f6d85971f896cd8303 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Tue, 26 Mar 2013 21:45:15 +0100
Subject: [PATCH 061/332] [DDC-93] Parse @Embedded and @Embeddable during
SchemaTool processing to make parsing work.
---
.../ORM/Mapping/ClassMetadataInfo.php | 13 ++++-
.../ORM/Mapping/Driver/AnnotationDriver.php | 2 +
.../Mapping/Driver/DoctrineAnnotations.php | 4 +-
lib/Doctrine/ORM/Mapping/Embeddable.php | 28 ++++++++++
lib/Doctrine/ORM/Mapping/Embedded.php | 32 +++++++++++
lib/Doctrine/ORM/Tools/SchemaTool.php | 1 +
.../Tests/ORM/Functional/ValueObjectsTest.php | 53 ++++++++++++++++++-
7 files changed, 130 insertions(+), 3 deletions(-)
create mode 100644 lib/Doctrine/ORM/Mapping/Embeddable.php
create mode 100644 lib/Doctrine/ORM/Mapping/Embedded.php
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 1e038d659..63c324a62 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -246,6 +246,13 @@ class ClassMetadataInfo implements ClassMetadata
*/
public $isMappedSuperclass = false;
+ /**
+ * READ-ONLY: Wheather this class describes the mapping of an embeddable class.
+ *
+ * @var boolean
+ */
+ public $isEmbeddedClass = false;
+
/**
* READ-ONLY: The names of the parent classes (ancestors).
*
@@ -921,8 +928,12 @@ class ClassMetadataInfo implements ClassMetadata
*/
public function validateIdentifier()
{
+ if ($this->isMappedSuperclass || $this->isEmbeddedClass) {
+ return;
+ }
+
// Verify & complete identifier mapping
- if ( ! $this->identifier && ! $this->isMappedSuperclass) {
+ if ( ! $this->identifier) {
throw MappingException::identifierRequired($this->name);
}
diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
index 9e1c734cc..56b693e67 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -85,6 +85,8 @@ class AnnotationDriver extends AbstractAnnotationDriver
$mappedSuperclassAnnot = $classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'];
$metadata->setCustomRepositoryClass($mappedSuperclassAnnot->repositoryClass);
$metadata->isMappedSuperclass = true;
+ } else if (isset($classAnnotations['Doctrine\ORM\Mapping\Embeddable'])) {
+ $metadata->isEmbeddedClass = true;
} else {
throw MappingException::classIsNotAValidEntityOrMappedSuperClass($className);
}
diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
index 14abadb9e..3ba65f772 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php
@@ -19,6 +19,8 @@
require_once __DIR__.'/../Annotation.php';
require_once __DIR__.'/../Entity.php';
+require_once __DIR__.'/../Embeddable.php';
+require_once __DIR__.'/../Embedded.php';
require_once __DIR__.'/../MappedSuperclass.php';
require_once __DIR__.'/../InheritanceType.php';
require_once __DIR__.'/../DiscriminatorColumn.php';
@@ -64,4 +66,4 @@ require_once __DIR__.'/../AssociationOverride.php';
require_once __DIR__.'/../AssociationOverrides.php';
require_once __DIR__.'/../AttributeOverride.php';
require_once __DIR__.'/../AttributeOverrides.php';
-require_once __DIR__.'/../EntityListeners.php';
\ No newline at end of file
+require_once __DIR__.'/../EntityListeners.php';
diff --git a/lib/Doctrine/ORM/Mapping/Embeddable.php b/lib/Doctrine/ORM/Mapping/Embeddable.php
new file mode 100644
index 000000000..34cdcd1f1
--- /dev/null
+++ b/lib/Doctrine/ORM/Mapping/Embeddable.php
@@ -0,0 +1,28 @@
+.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("PROPERTY")
+ */
+final class Embeddable implements Annotation
+{
+}
diff --git a/lib/Doctrine/ORM/Mapping/Embedded.php b/lib/Doctrine/ORM/Mapping/Embedded.php
new file mode 100644
index 000000000..c3dcb0837
--- /dev/null
+++ b/lib/Doctrine/ORM/Mapping/Embedded.php
@@ -0,0 +1,32 @@
+.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * @Annotation
+ * @Target("CLASS")
+ */
+final class Embedded implements Annotation
+{
+ /**
+ * @var string
+ */
+ public $class;
+}
diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php
index f66a49d15..a8baa02aa 100644
--- a/lib/Doctrine/ORM/Tools/SchemaTool.php
+++ b/lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -126,6 +126,7 @@ class SchemaTool
return (
isset($processedClasses[$class->name]) ||
$class->isMappedSuperclass ||
+ $class->isEmbeddedClass ||
($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
index 916f06bf9..ac0f332a1 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
@@ -2,10 +2,37 @@
namespace Doctrine\Tests\ORM\Functional;
+/**
+ * @group DDC-93
+ */
class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
+ parent::setUp();
+
+ $this->_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'),
+ ));
+ }
+
+ public function testMetadata()
+ {
+ $person = new DDC93Person();
+ $person->name = "Tara";
+ $person->address = new DDC93Address();
+ $person->address->street = "United States of Tara Street";
+ $person->address->zip = "12345";
+ $person->address->city = "funkytown";
+
+ $this->_em->persist($person);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $person = $this->_em->find(DDC93Person::CLASSNAME, $person->id);
+ $this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address);
}
}
@@ -14,12 +41,36 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
*/
class DDC93Person
{
+ const CLASSNAME = __CLASS__;
+
/** @Id @GeneratedValue @Column(type="integer") */
public $id;
/** @Column(type="string") */
public $name;
- /** @Embedded */
+ /** @Embedded(class="DDC93Address") */
public $address;
}
+
+/**
+ * @Embeddable
+ */
+class DDC93Address
+{
+ const CLASSNAME = __CLASS__;
+
+ /**
+ * @Column(type="string")
+ */
+ public $street;
+ /**
+ * @Column(type="string")
+ */
+ public $zip;
+ /**
+ * @Column(type="string")
+ */
+ public $city;
+}
+
From 0204a8b69a33883c83a26be108b528fac320c729 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 27 Mar 2013 00:10:30 +0100
Subject: [PATCH 062/332] [DDC-93] Implement first working version of value
objects using a ReflectionProxy object, bypassing changes to UnitOfWork,
Persisters and Hydrators.
---
.../ORM/Mapping/ClassMetadataFactory.php | 5 ++
.../ORM/Mapping/ClassMetadataInfo.php | 70 +++++++++++++++++--
.../ORM/Mapping/Driver/AnnotationDriver.php | 3 +
lib/Doctrine/ORM/Mapping/ReflectionProxy.php | 64 +++++++++++++++++
.../Tests/ORM/Functional/ValueObjectsTest.php | 4 ++
5 files changed, 140 insertions(+), 6 deletions(-)
create mode 100644 lib/Doctrine/ORM/Mapping/ReflectionProxy.php
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index a1da3ffcf..d661eb7a3 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -136,6 +136,11 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
$this->completeIdGeneratorMapping($class);
}
+ foreach ($class->embeddedClasses as $property => $embeddableClass) {
+ $embeddableMetadata = $this->getMetadataFor($embeddableClass);
+ $class->inlineEmbeddable($property, $embeddableMetadata);
+ }
+
if ($parent && $parent->isInheritanceTypeSingleTable()) {
$class->setPrimaryTable($parent->table);
}
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 63c324a62..9ab80a72c 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -267,6 +267,13 @@ class ClassMetadataInfo implements ClassMetadata
*/
public $subClasses = array();
+ /**
+ * READ-ONLY: The names of all embedded classes based on properties.
+ *
+ * @var array
+ */
+ public $embeddedClasses = array();
+
/**
* READ-ONLY: The named queries allowed to be called directly from Repository.
*
@@ -887,6 +894,15 @@ class ClassMetadataInfo implements ClassMetadata
$this->reflClass = $reflService->getClass($this->name);
foreach ($this->fieldMappings as $field => $mapping) {
+ if (isset($mapping['declaredField'])) {
+ $this->reflFields[$field] = new ReflectionProxy(
+ $reflService->getAccessibleProperty($this->name, $mapping['declaredField']),
+ $reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']], $mapping['originalField']),
+ $this->embeddedClasses[$mapping['declaredField']]
+ );
+ continue;
+ }
+
$this->reflFields[$field] = isset($mapping['declared'])
? $reflService->getAccessibleProperty($mapping['declared'], $field)
: $reflService->getAccessibleProperty($this->name, $field);
@@ -2166,9 +2182,8 @@ class ClassMetadataInfo implements ClassMetadata
public function mapField(array $mapping)
{
$this->_validateAndCompleteFieldMapping($mapping);
- if (isset($this->fieldMappings[$mapping['fieldName']]) || isset($this->associationMappings[$mapping['fieldName']])) {
- throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']);
- }
+ $this->assertFieldNotMapped($mapping['fieldName']);
+
$this->fieldMappings[$mapping['fieldName']] = $mapping;
}
@@ -2416,9 +2431,7 @@ class ClassMetadataInfo implements ClassMetadata
{
$sourceFieldName = $assocMapping['fieldName'];
- if (isset($this->fieldMappings[$sourceFieldName]) || isset($this->associationMappings[$sourceFieldName])) {
- throw MappingException::duplicateFieldMapping($this->name, $sourceFieldName);
- }
+ $this->assertFieldNotMapped($sourceFieldName);
$this->associationMappings[$sourceFieldName] = $assocMapping;
}
@@ -3030,4 +3043,49 @@ class ClassMetadataInfo implements ClassMetadata
return $className;
}
+
+ /**
+ * Map Embedded Class
+ *
+ * @array $mapping
+ * @return void
+ */
+ public function mapEmbedded(array $mapping)
+ {
+ $this->assertFieldNotMapped($mapping['fieldName']);
+
+ $this->embeddedClasses[$mapping['fieldName']] = $this->fullyQualifiedClassName($mapping['class']);
+ }
+
+ /**
+ * Inline the embeddable class
+ *
+ * @param string $property
+ * @param ClassMetadataInfo $embeddable
+ */
+ public function inlineEmbeddable($property, ClassMetadataInfo $embeddable)
+ {
+ foreach ($embeddable->fieldMappings as $fieldMapping) {
+ $fieldMapping['declaredField'] = $property;
+ $fieldMapping['originalField'] = $fieldMapping['fieldName'];
+ $fieldMapping['fieldName'] = $property . $fieldMapping['fieldName'];
+ $fieldMapping['columnName'] = $property . "_" . $fieldMapping['columnName'];
+
+ $this->mapField($fieldMapping);
+ }
+ }
+
+ /**
+ * @param string $fieldName
+ * @throws MappingException
+ */
+ private function assertFieldNotMapped($fieldName)
+ {
+ if (isset($this->fieldMappings[$fieldName]) ||
+ isset($this->associationMappings[$fieldName]) ||
+ isset($this->embeddedClasses[$fieldName])) {
+
+ throw MappingException::duplicateFieldMapping($this->name, $fieldName);
+ }
+ }
}
diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
index 56b693e67..2529edeed 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -366,6 +366,9 @@ class AnnotationDriver extends AbstractAnnotationDriver
}
$metadata->mapManyToMany($mapping);
+ } else if ($embeddedAnnot = $this->reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Embedded')) {
+ $mapping['class'] = $embeddedAnnot->class;
+ $metadata->mapEmbedded($mapping);
}
}
diff --git a/lib/Doctrine/ORM/Mapping/ReflectionProxy.php b/lib/Doctrine/ORM/Mapping/ReflectionProxy.php
new file mode 100644
index 000000000..9d391d9a8
--- /dev/null
+++ b/lib/Doctrine/ORM/Mapping/ReflectionProxy.php
@@ -0,0 +1,64 @@
+.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+/**
+ * Acts as a proxy to a nested Property structure, making it look like
+ * just a single scalar property.
+ *
+ * This way value objects "just work" without UnitOfWork, Persisters or Hydrators
+ * needing any changes.
+ */
+class ReflectionProxy
+{
+ private $parentProperty;
+ private $childProperty;
+ private $class;
+
+ public function __construct($parentProperty, $childProperty, $class)
+ {
+ $this->parentProperty = $parentProperty;
+ $this->childProperty = $childProperty;
+ $this->class = $class;
+ }
+
+ public function getValue($object)
+ {
+ $embeddedObject = $this->parentProperty->getValue($object);
+
+ if ($embeddedObject === null) {
+ return null;
+ }
+
+ return $this->childProperty->getValue($embeddedObject);
+ }
+
+ public function setValue($object, $value)
+ {
+ $embeddedObject = $this->parentProperty->getValue($object);
+
+ if ($embeddedObject === null) {
+ $embeddedObject = new $this->class; // TODO
+ $this->parentProperty->setValue($object, $embeddedObject);
+ }
+
+ $this->childProperty->setValue($embeddedObject, $value);
+ }
+}
diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
index ac0f332a1..26f129c71 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
@@ -32,7 +32,11 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->clear();
$person = $this->_em->find(DDC93Person::CLASSNAME, $person->id);
+
$this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address);
+ $this->assertEquals('United States of Tara Street', $person->address->street);
+ $this->assertEquals('12345', $person->address->zip);
+ $this->assertEquals('funkytown', $person->address->city);
}
}
From 011776f02ffa279afc0016b2de76b662b87dfc95 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 27 Mar 2013 00:18:21 +0100
Subject: [PATCH 063/332] [DDC-93] Add some TODOs in code.
---
lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 9ab80a72c..8a444d9ae 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -3068,8 +3068,8 @@ class ClassMetadataInfo implements ClassMetadata
foreach ($embeddable->fieldMappings as $fieldMapping) {
$fieldMapping['declaredField'] = $property;
$fieldMapping['originalField'] = $fieldMapping['fieldName'];
- $fieldMapping['fieldName'] = $property . $fieldMapping['fieldName'];
- $fieldMapping['columnName'] = $property . "_" . $fieldMapping['columnName'];
+ $fieldMapping['fieldName'] = $property . "." . $fieldMapping['fieldName']; // TODO: Change DQL parser to accept this dot notation
+ $fieldMapping['columnName'] = $property . "_" . $fieldMapping['columnName']; // TODO: Use naming strategy
$this->mapField($fieldMapping);
}
From 9797177193b4757df7d3f06cd60c7e06e559aa74 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Wed, 27 Mar 2013 02:48:35 +0100
Subject: [PATCH 064/332] check if ReflectionClass::getTraits() method exists
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 2946935b3..6aad04fb6 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -713,9 +713,11 @@ public function __construct()
if (class_exists($metadata->name)) {
$reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasProperty($property)) {
- return true;
+ if (method_exists($reflClass, 'getTraits')) {
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
+ }
}
}
}
@@ -747,9 +749,11 @@ public function __construct()
if (class_exists($metadata->name)) {
$reflClass = new \ReflectionClass($metadata->name);
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasMethod($method)) {
- return true;
+ if (method_exists($reflClass, 'getTraits')) {
+ foreach ($reflClass->getTraits() as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
+ }
}
}
}
From 879ab6e52b1d20565074b5abfeb995926505461a Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 27 Mar 2013 07:44:47 +0100
Subject: [PATCH 065/332] [DDC-93] Show CRUD with value objects with current
change tracking assumptions.
---
.../Tests/ORM/Functional/ValueObjectsTest.php | 25 ++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
index 26f129c71..d1f81189c 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
@@ -17,7 +17,7 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
));
}
- public function testMetadata()
+ public function testCRUD()
{
$person = new DDC93Person();
$person->name = "Tara";
@@ -26,17 +26,40 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
$person->address->zip = "12345";
$person->address->city = "funkytown";
+ // 1. check saving value objects works
$this->_em->persist($person);
$this->_em->flush();
$this->_em->clear();
+ // 2. check loading value objects works
$person = $this->_em->find(DDC93Person::CLASSNAME, $person->id);
$this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address);
$this->assertEquals('United States of Tara Street', $person->address->street);
$this->assertEquals('12345', $person->address->zip);
$this->assertEquals('funkytown', $person->address->city);
+
+ // 3. check changing value objects works
+ $person->address->street = "Street";
+ $person->address->zip = "54321";
+ $person->address->city = "another town";
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $person = $this->_em->find(DDC93Person::CLASSNAME, $person->id);
+
+ $this->assertEquals('Street', $person->address->street);
+ $this->assertEquals('54321', $person->address->zip);
+ $this->assertEquals('another town', $person->address->city);
+
+ // 4. check deleting works
+ $personId = $person->id;;
+ $this->_em->remove($person);
+ $this->_em->flush();
+
+ $this->assertNull($this->_em->find(DDC93Person::CLASSNAME, $personId));
}
}
From 9613f1d8cb40c552ea5e57ad12b3adf0a654d167 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 27 Mar 2013 21:45:16 +0100
Subject: [PATCH 066/332] [DDC-93] Rename ReflectionProxy to
ReflectionEmbeddedProperty, Add DQL test with Object and Array Hydration.
---
.../ORM/Mapping/ClassMetadataInfo.php | 2 +-
...oxy.php => ReflectionEmbeddedProperty.php} | 4 +-
.../Tests/ORM/Functional/ValueObjectsTest.php | 48 +++++++++++++++++--
3 files changed, 48 insertions(+), 6 deletions(-)
rename lib/Doctrine/ORM/Mapping/{ReflectionProxy.php => ReflectionEmbeddedProperty.php} (96%)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 8a444d9ae..6a2931fe6 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -895,7 +895,7 @@ class ClassMetadataInfo implements ClassMetadata
foreach ($this->fieldMappings as $field => $mapping) {
if (isset($mapping['declaredField'])) {
- $this->reflFields[$field] = new ReflectionProxy(
+ $this->reflFields[$field] = new ReflectionEmbeddedProperty(
$reflService->getAccessibleProperty($this->name, $mapping['declaredField']),
$reflService->getAccessibleProperty($this->embeddedClasses[$mapping['declaredField']], $mapping['originalField']),
$this->embeddedClasses[$mapping['declaredField']]
diff --git a/lib/Doctrine/ORM/Mapping/ReflectionProxy.php b/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php
similarity index 96%
rename from lib/Doctrine/ORM/Mapping/ReflectionProxy.php
rename to lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php
index 9d391d9a8..b68d7d818 100644
--- a/lib/Doctrine/ORM/Mapping/ReflectionProxy.php
+++ b/lib/Doctrine/ORM/Mapping/ReflectionEmbeddedProperty.php
@@ -25,8 +25,10 @@ namespace Doctrine\ORM\Mapping;
*
* This way value objects "just work" without UnitOfWork, Persisters or Hydrators
* needing any changes.
+ *
+ * TODO: Move this class into Common\Reflection
*/
-class ReflectionProxy
+class ReflectionEmbeddedProperty
{
private $parentProperty;
private $childProperty;
diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
index d1f81189c..89a51a406 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ValueObjectsTest.php
@@ -11,10 +11,13 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
parent::setUp();
- $this->_schemaTool->createSchema(array(
- $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'),
- $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'),
- ));
+ try {
+ $this->_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Person'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC93Address'),
+ ));
+ } catch(\Exception $e) {
+ }
}
public function testCRUD()
@@ -61,6 +64,43 @@ class ValueObjectsTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertNull($this->_em->find(DDC93Person::CLASSNAME, $personId));
}
+
+ public function testLoadDql()
+ {
+ for ($i = 0; $i < 3; $i++) {
+ $person = new DDC93Person();
+ $person->name = "Donkey Kong$i";
+ $person->address = new DDC93Address();
+ $person->address->street = "Tree";
+ $person->address->zip = "12345";
+ $person->address->city = "funkytown";
+
+ $this->_em->persist($person);
+ }
+
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
+ $persons = $this->_em->createQuery($dql)->getResult();
+
+ $this->assertCount(3, $persons);
+ foreach ($persons as $person) {
+ $this->assertInstanceOf(DDC93Address::CLASSNAME, $person->address);
+ $this->assertEquals('Tree', $person->address->street);
+ $this->assertEquals('12345', $person->address->zip);
+ $this->assertEquals('funkytown', $person->address->city);
+ }
+
+ $dql = "SELECT p FROM " . __NAMESPACE__ . "\DDC93Person p";
+ $persons = $this->_em->createQuery($dql)->getArrayResult();
+
+ foreach ($persons as $person) {
+ $this->assertEquals('Tree', $person['address.street']);
+ $this->assertEquals('12345', $person['address.zip']);
+ $this->assertEquals('funkytown', $person['address.city']);
+ }
+ }
}
/**
From 51bcda51c5593155697f1752b49f88916bdaaaeb Mon Sep 17 00:00:00 2001
From: Dustin Moorman
Date: Wed, 27 Mar 2013 22:43:58 -0500
Subject: [PATCH 067/332] Fixed typos in documentation.
---
docs/en/reference/dql-doctrine-query-language.rst | 4 ++--
docs/en/reference/faq.rst | 2 +-
docs/en/reference/filters.rst | 2 +-
docs/en/reference/native-sql.rst | 12 ++++++------
docs/en/reference/transactions-and-concurrency.rst | 2 +-
docs/en/reference/unitofwork.rst | 2 +-
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst
index ba694a101..c140d5599 100644
--- a/docs/en/reference/dql-doctrine-query-language.rst
+++ b/docs/en/reference/dql-doctrine-query-language.rst
@@ -909,7 +909,7 @@ Query Result Formats
The format in which the result of a DQL SELECT query is returned
can be influenced by a so-called ``hydration mode``. A hydration
-mode specifies a particular way in which an SQL result set is
+mode specifies a particular way in which a SQL result set is
transformed. Each hydration mode has its own dedicated method on
the Query class. Here they are:
@@ -1290,7 +1290,7 @@ userland:
Query Cache (DQL Query Only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Parsing a DQL query and converting it into an SQL query against the
+Parsing a DQL query and converting it into a SQL query against the
underlying database platform obviously has some overhead in
contrast to directly executing Native SQL queries. That is why
there is a dedicated Query Cache for caching the DQL parser
diff --git a/docs/en/reference/faq.rst b/docs/en/reference/faq.rst
index 800b168bd..28e3a42c4 100644
--- a/docs/en/reference/faq.rst
+++ b/docs/en/reference/faq.rst
@@ -147,7 +147,7 @@ Why does Doctrine not create proxy objects for my inheritance hierarchy?
If you set a many-to-one or one-to-one association target-entity to any parent class of
an inheritance hierarchy Doctrine does not know what PHP class the foreign is actually of.
-To find this out it has to execute an SQL query to look this information up in the database.
+To find this out it has to execute a SQL query to look this information up in the database.
EntityGenerator
---------------
diff --git a/docs/en/reference/filters.rst b/docs/en/reference/filters.rst
index 03623806f..a5c0ee4cf 100644
--- a/docs/en/reference/filters.rst
+++ b/docs/en/reference/filters.rst
@@ -7,7 +7,7 @@ Doctrine 2.2 features a filter system that allows the developer to add SQL to
the conditional clauses of queries, regardless the place where the SQL is
generated (e.g. from a DQL query, or by loading associated entities).
-The filter functionality works on SQL level. Whether an SQL query is generated
+The filter functionality works on SQL level. Whether a SQL query is generated
in a Persister, during lazy loading, in extra lazy collections or from DQL.
Each time the system iterates over all the enabled filters, adding a new SQL
part as a filter returns.
diff --git a/docs/en/reference/native-sql.rst b/docs/en/reference/native-sql.rst
index b8a91000e..21f0a6ca9 100644
--- a/docs/en/reference/native-sql.rst
+++ b/docs/en/reference/native-sql.rst
@@ -3,7 +3,7 @@ Native SQL
A ``NativeQuery`` lets you execute native SELECT SQL statements, mapping the results
according to your specifications. Such a specification that
-describes how an SQL result set is mapped to a Doctrine result is
+describes how a SQL result set is mapped to a Doctrine result is
represented by a ``ResultSetMapping``. It describes how each column
of the database result should be mapped by Doctrine in terms of the
object graph. This allows you to map arbitrary SQL code to objects,
@@ -136,7 +136,7 @@ joined entity result.
Field results
~~~~~~~~~~~~~
-A field result describes the mapping of a single column in an SQL
+A field result describes the mapping of a single column in a SQL
result set to a field in an entity. As such, field results are
inherently bound to entity results. You add a field result through
``ResultSetMapping#addFieldResult()``. Again, let's examine the
@@ -165,7 +165,7 @@ column should be set.
Scalar results
~~~~~~~~~~~~~~
-A scalar result describes the mapping of a single column in an SQL
+A scalar result describes the mapping of a single column in a SQL
result set to a scalar value in the Doctrine result. Scalar results
are typically used for aggregate values but any column in the SQL
result set can be mapped as a scalar value. To add a scalar result
@@ -190,7 +190,7 @@ of the column will be placed in the transformed Doctrine result.
Meta results
~~~~~~~~~~~~
-A meta result describes a single column in an SQL result set that
+A meta result describes a single column in a SQL result set that
is either a foreign key or a discriminator column. These columns
are essential for Doctrine to properly construct objects out of SQL
result sets. To add a column as a meta result use
@@ -546,12 +546,12 @@ it represents the name of a defined @SqlResultSetMapping.
Things to note:
- The resultset mapping declares the entities retrieved by this native query.
- - Each field of the entity is bound to an SQL alias (or column name).
+ - Each field of the entity is bound to a SQL alias (or column name).
- All fields of the entity including the ones of subclasses
and the foreign key columns of related entities have to be present in the SQL query.
- Field definitions are optional provided that they map to the same
column name as the one declared on the class property.
- - ``__CLASS__`` is a alias for the mapped class
+ - ``__CLASS__`` is an alias for the mapped class
In the above example,
diff --git a/docs/en/reference/transactions-and-concurrency.rst b/docs/en/reference/transactions-and-concurrency.rst
index 0a752ad5b..1b06156e9 100644
--- a/docs/en/reference/transactions-and-concurrency.rst
+++ b/docs/en/reference/transactions-and-concurrency.rst
@@ -182,7 +182,7 @@ example we'll use an integer.
// ...
}
-Alternatively a datetime type can be used (which maps to an SQL
+Alternatively a datetime type can be used (which maps to a SQL
timestamp or datetime):
.. code-block:: php
diff --git a/docs/en/reference/unitofwork.rst b/docs/en/reference/unitofwork.rst
index 48f1029c6..f01c3f91d 100644
--- a/docs/en/reference/unitofwork.rst
+++ b/docs/en/reference/unitofwork.rst
@@ -117,7 +117,7 @@ that consume new memory.
Now whenever you call ``EntityManager#flush`` Doctrine will iterate over the
Identity Map and for each object compares the original property and association
values with the values that are currently set on the object. If changes are
-detected then the object is queued for an SQL UPDATE operation. Only the fields
+detected then the object is queued for a SQL UPDATE operation. Only the fields
that actually changed are updated.
This process has an obvious performance impact. The larger the size of the
From 2e8272e18f13a9e3a9653ab1b62301400f15a442 Mon Sep 17 00:00:00 2001
From: Valentin Ferriere
Date: Fri, 29 Mar 2013 16:39:55 +0100
Subject: [PATCH 068/332] Update association-mapping.rst
---
docs/en/reference/association-mapping.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/reference/association-mapping.rst b/docs/en/reference/association-mapping.rst
index 3a597f6db..f41bb610f 100644
--- a/docs/en/reference/association-mapping.rst
+++ b/docs/en/reference/association-mapping.rst
@@ -83,6 +83,7 @@ Generated MySQL Schema:
CREATE TABLE Product (
id INT AUTO_INCREMENT NOT NULL,
shipping_id INT DEFAULT NULL,
+ UNIQUE INDEX UNIQ_6FBC94267FE4B2B (shipping_id),
PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Shipping (
From 937ba6385e6823c183daf2230b1447dbbbedfcec Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Sun, 31 Mar 2013 00:47:24 +0100
Subject: [PATCH 069/332] fixed code duplication issue
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 44 +++++++++++++---------
1 file changed, 26 insertions(+), 18 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 6aad04fb6..948a4e689 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -710,15 +710,9 @@ public function __construct()
}
// check traits for existing property
- if (class_exists($metadata->name)) {
- $reflClass = new \ReflectionClass($metadata->name);
-
- if (method_exists($reflClass, 'getTraits')) {
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasProperty($property)) {
- return true;
- }
- }
+ foreach ($this->getTraits($metadata) as $trait) {
+ if ($trait->hasProperty($property)) {
+ return true;
}
}
@@ -746,15 +740,9 @@ public function __construct()
}
// check traits for existing method
- if (class_exists($metadata->name)) {
- $reflClass = new \ReflectionClass($metadata->name);
-
- if (method_exists($reflClass, 'getTraits')) {
- foreach ($reflClass->getTraits() as $trait) {
- if ($trait->hasMethod($method)) {
- return true;
- }
- }
+ foreach ($this->getTraits($metadata) as $trait) {
+ if ($trait->hasMethod($method)) {
+ return true;
}
}
@@ -764,6 +752,26 @@ public function __construct()
);
}
+ /**
+ * @param ClassMetadataInfo $metadata
+ *
+ * @return array
+ */
+ protected function getTraits(ClassMetadataInfo $metadata)
+ {
+ if ($metadata->reflClass != null || class_exists($metadata->name)) {
+ $reflClass = $metadata->reflClass == null
+ ? new \ReflectionClass($metadata->name)
+ : $metadata->reflClass;
+
+ if (method_exists($reflClass, 'getTraits')) {
+ return $reflClass->getTraits();
+ }
+ }
+
+ return array();
+ }
+
/**
* @param ClassMetadataInfo $metadata
*
From b3414e3c1ab70050d2b0a206e74bf827cb39f8f4 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Sun, 31 Mar 2013 00:47:45 +0100
Subject: [PATCH 070/332] added unit test
---
.../Tests/ORM/Tools/EntityGeneratorTest.php | 58 ++++++++++++++-----
tests/Doctrine/Tests/TestInit.php | 1 +
tools/sandbox/Entities/TraitedUser.php | 34 +++++++++++
.../sandbox/Entities/Traits/AddressTrait.php | 25 ++++++++
4 files changed, 104 insertions(+), 14 deletions(-)
create mode 100644 tools/sandbox/Entities/TraitedUser.php
create mode 100644 tools/sandbox/Entities/Traits/AddressTrait.php
diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
index a55b603d5..694918d13 100644
--- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
@@ -2,10 +2,12 @@
namespace Doctrine\Tests\ORM\Tools;
-use Doctrine\ORM\Tools\SchemaTool,
- Doctrine\ORM\Tools\EntityGenerator,
- Doctrine\ORM\Tools\Export\ClassMetadataExporter,
- Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\ORM\Tools\SchemaTool;
+use Doctrine\ORM\Tools\EntityGenerator;
+use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\ORM\Mapping\ClassMetadataFactory;
+use Entities\TraitedUser;
require_once __DIR__ . '/../../TestInit.php';
@@ -282,7 +284,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$filename = $this->_tmpDir . DIRECTORY_SEPARATOR
. $this->_namespace . DIRECTORY_SEPARATOR . 'DDC1784Entity.php';
-
+
$this->assertFileExists($filename);
require_once $filename;
@@ -330,7 +332,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$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);
@@ -436,7 +438,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$entity = new $metadata->name;
$reflClass = new \ReflectionClass($metadata->name);
-
+
$type = $field['phpType'];
$name = $field['fieldName'];
$value = $field['value'];
@@ -451,6 +453,34 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals($value, $entity->{$getter}());
}
+ /**
+ * @group DDC-2372
+ */
+ public function testTraitPropertiesAndMethodsAreNotDuplicated()
+ {
+ if (function_exists('trait_exists')) {
+ $cmf = new ClassMetadataFactory();
+ $em = $this->_getTestEntityManager();
+ $cmf->setEntityManager($em);
+
+ $user = new TraitedUser();
+ $metadata = $cmf->getMetadataFor(get_class($user));
+ $metadata->name = $this->_namespace . "\TraitedUser";
+ $metadata->namespace = $this->_namespace;
+
+ $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+ $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/TraitedUser.php");
+ require $this->_tmpDir . "/" . $this->_namespace . "/TraitedUser.php";
+
+ $reflClass = new \ReflectionClass($metadata->name);
+
+ $this->assertSame($reflClass->hasProperty('address'), false);
+ $this->assertSame($reflClass->hasMethod('setAddress'), false);
+ $this->assertSame($reflClass->hasMethod('getAddress'), false);
+ }
+ }
+
/**
* @return array
*/
@@ -470,43 +500,43 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
'value' => new \DateTime
)),
array(array(
- 'fieldName' => 'date',
+ 'fieldName' => 'date',
'phpType' => '\\DateTime',
'dbType' => 'date',
'value' => new \DateTime
)),
array(array(
- 'fieldName' => 'time',
+ 'fieldName' => 'time',
'phpType' => '\DateTime',
'dbType' => 'time',
'value' => new \DateTime
)),
array(array(
- 'fieldName' => 'object',
+ 'fieldName' => 'object',
'phpType' => '\stdClass',
'dbType' => 'object',
'value' => new \stdClass()
)),
array(array(
- 'fieldName' => 'bigint',
+ 'fieldName' => 'bigint',
'phpType' => 'integer',
'dbType' => 'bigint',
'value' => 11
)),
array(array(
- 'fieldName' => 'smallint',
+ 'fieldName' => 'smallint',
'phpType' => 'integer',
'dbType' => 'smallint',
'value' => 22
)),
array(array(
- 'fieldName' => 'text',
+ 'fieldName' => 'text',
'phpType' => 'string',
'dbType' => 'text',
'value' => 'text'
)),
array(array(
- 'fieldName' => 'blob',
+ 'fieldName' => 'blob',
'phpType' => 'string',
'dbType' => 'blob',
'value' => 'blob'
diff --git a/tests/Doctrine/Tests/TestInit.php b/tests/Doctrine/Tests/TestInit.php
index c257a75b6..ac7f7354b 100644
--- a/tests/Doctrine/Tests/TestInit.php
+++ b/tests/Doctrine/Tests/TestInit.php
@@ -17,6 +17,7 @@ if (file_exists(__DIR__ . '/../../../vendor/autoload.php')) {
}
/* @var $classLoader \Composer\Autoload\ClassLoader */
+$classLoader->add('Entities', __DIR__ . '/../../../tools/sandbox');
$classLoader->add('Doctrine\\Tests\\', __DIR__ . '/../../');
unset($classLoader);
diff --git a/tools/sandbox/Entities/TraitedUser.php b/tools/sandbox/Entities/TraitedUser.php
new file mode 100644
index 000000000..fe0b68754
--- /dev/null
+++ b/tools/sandbox/Entities/TraitedUser.php
@@ -0,0 +1,34 @@
+id;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function setName($name)
+ {
+ $this->name = $name;
+ }
+}
\ No newline at end of file
diff --git a/tools/sandbox/Entities/Traits/AddressTrait.php b/tools/sandbox/Entities/Traits/AddressTrait.php
new file mode 100644
index 000000000..9fb3e23a5
--- /dev/null
+++ b/tools/sandbox/Entities/Traits/AddressTrait.php
@@ -0,0 +1,25 @@
+address;
+ }
+
+ public function setAddress(Address $address)
+ {
+ if ($this->address !== $address) {
+ $this->address = $address;
+ $address->setUser($this);
+ }
+ }
+}
\ No newline at end of file
From 6fc18e330d8ecd57dc9a4af871d6cc30cffd3f7d Mon Sep 17 00:00:00 2001
From: Asmir Mustafic
Date: Tue, 2 Apr 2013 10:04:15 +0200
Subject: [PATCH 071/332] indexby metadata column
---
lib/Doctrine/ORM/Query/ResultSetMapping.php | 2 +-
.../Tests/ORM/Hydration/ResultSetMappingTest.php | 13 +++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php
index 50dacea41..b06b68385 100644
--- a/lib/Doctrine/ORM/Query/ResultSetMapping.php
+++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php
@@ -211,7 +211,7 @@ class ResultSetMapping
{
$found = false;
- foreach ($this->fieldMappings as $columnName => $columnFieldName) {
+ foreach (array_merge($this->metaMappings, $this->fieldMappings) as $columnName => $columnFieldName) {
if ( ! ($columnFieldName === $fieldName && $this->columnOwnerMap[$columnName] === $alias)) continue;
$this->addIndexByColumn($alias, $columnName);
diff --git a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
index 801937f2d..5a198a944 100644
--- a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
+++ b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
@@ -255,5 +255,18 @@ class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('status'));
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('username'));
}
+ public function testIndexByMetadataColumn()
+ {
+ $rms = $this->_rsm;
+ $rms->addEntityResult('Doctrine\Tests\Models\Legacy\LegacyUser', 'u')
+ ->addJoinedEntityResult('Doctrine\Tests\Models\Legacy', 'lu', 'u', '_references')
+ ->addMetaResult('lu', '_source', '_source', true)
+ ->addMetaResult('lu', '_target', '_target', true)
+ ->addIndexBy('lu', '_source');
+
+
+ $this->assertTrue($rms->hasIndexBy('lu'));
+
+ }
}
From 3196b0c05a9cd4507463a82b706f691f686a8224 Mon Sep 17 00:00:00 2001
From: Asmir Mustafic
Date: Tue, 2 Apr 2013 10:14:24 +0200
Subject: [PATCH 072/332] missing new line
---
tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
index 5a198a944..fac93b6e6 100644
--- a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
+++ b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
@@ -255,6 +255,7 @@ class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('status'));
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('username'));
}
+
public function testIndexByMetadataColumn()
{
$rms = $this->_rsm;
From 3e8796f78188e193aac7386b38b7e17da3df5718 Mon Sep 17 00:00:00 2001
From: denkiryokuhatsuden
Date: Tue, 2 Apr 2013 18:54:55 +0900
Subject: [PATCH 073/332] Add hidden field ordering for postgresql
In postgresql environment, when some hidden fields are used in orderBy clause,
they're not property added because $rsm->scalarMappings don't have information about them.
---
.../Pagination/LimitSubqueryOutputWalker.php | 20 ++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
index 3943cb5e6..a0a22b03b 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
@@ -91,7 +91,25 @@ class LimitSubqueryOutputWalker extends SqlWalker
*/
public function walkSelectStatement(SelectStatement $AST)
{
- $innerSql = parent::walkSelectStatement($AST);
+ if ($this->platform instanceof PostgreSqlPlatform) {
+ // Set every select expression as visible(hidden = false) to
+ // make $AST to have scalar mappings properly
+ $hiddens = array();
+ foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
+ $hiddens[$idx] = $expr->hiddenAliasResultVariable;
+ $expr->hiddenAliasResultVariable = false;
+ }
+
+ $innerSql = parent::walkSelectStatement($AST);
+
+ // Restore hiddens
+ foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
+ $expr->hiddenAliasResultVariable = $hiddens[$idx];
+ }
+ } else {
+ $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
From 786d904328d26d80cfd829a73c4e36b5c1e8ff2a Mon Sep 17 00:00:00 2001
From: denkiryokuhatsuden
Date: Wed, 3 Apr 2013 17:14:31 +0900
Subject: [PATCH 074/332] Revert "Add hidden field ordering for postgresql"
This reverts commit 3e8796f78188e193aac7386b38b7e17da3df5718.
---
.../Pagination/LimitSubqueryOutputWalker.php | 20 +------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
index a0a22b03b..3943cb5e6 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
@@ -91,25 +91,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
*/
public function walkSelectStatement(SelectStatement $AST)
{
- if ($this->platform instanceof PostgreSqlPlatform) {
- // Set every select expression as visible(hidden = false) to
- // make $AST to have scalar mappings properly
- $hiddens = array();
- foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
- $hiddens[$idx] = $expr->hiddenAliasResultVariable;
- $expr->hiddenAliasResultVariable = false;
- }
-
- $innerSql = parent::walkSelectStatement($AST);
-
- // Restore hiddens
- foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
- $expr->hiddenAliasResultVariable = $hiddens[$idx];
- }
- } else {
- $innerSql = 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
From e54c11e3bb9c510340957d7c2e91c86433eef98b Mon Sep 17 00:00:00 2001
From: denkiryokuhatsuden
Date: Wed, 3 Apr 2013 17:21:51 +0900
Subject: [PATCH 075/332] Add test for postgresql hidden scalar sorting
---
.../LimitSubqueryOutputWalkerTest.php | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
index f19b8520b..6c533084f 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
@@ -74,6 +74,25 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
+ public function testLimitSubqueryWithHiddenScalarSortPg()
+ {
+ $odp = $this->entityManager->getConnection()->getDatabasePlatform();
+ $this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
+
+ $query = $this->entityManager->createQuery(
+ 'SELECT u, g, COUNT(g.id) AS hidden g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC'
+ );
+ $limitQuery = clone $query;
+ $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
+
+ $this->assertEquals(
+ "SELECT DISTINCT id1, sclr0 FROM (SELECT COUNT(g0_.id) AS sclr0, u1_.id AS id1, g0_.id AS id2 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id ORDER BY sclr0 ASC, u1_.id DESC) dctrn_result ORDER BY sclr0 ASC, id1 DESC",
+ $limitQuery->getSql()
+ );
+
+ $this->entityManager->getConnection()->setDatabasePlatform($odp);
+ }
+
public function testLimitSubqueryPg()
{
$odp = $this->entityManager->getConnection()->getDatabasePlatform();
From 7af84e79e5a2a54120cf81da7a0f17c98dfe87fa Mon Sep 17 00:00:00 2001
From: denkiryokuhatsuden
Date: Wed, 3 Apr 2013 17:22:31 +0900
Subject: [PATCH 076/332] Fixed postgresql hidden scalar sort
---
.../Pagination/LimitSubqueryOutputWalker.php | 20 ++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
index 3943cb5e6..a0a22b03b 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
@@ -91,7 +91,25 @@ class LimitSubqueryOutputWalker extends SqlWalker
*/
public function walkSelectStatement(SelectStatement $AST)
{
- $innerSql = parent::walkSelectStatement($AST);
+ if ($this->platform instanceof PostgreSqlPlatform) {
+ // Set every select expression as visible(hidden = false) to
+ // make $AST to have scalar mappings properly
+ $hiddens = array();
+ foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
+ $hiddens[$idx] = $expr->hiddenAliasResultVariable;
+ $expr->hiddenAliasResultVariable = false;
+ }
+
+ $innerSql = parent::walkSelectStatement($AST);
+
+ // Restore hiddens
+ foreach ($AST->selectClause->selectExpressions as $idx => $expr) {
+ $expr->hiddenAliasResultVariable = $hiddens[$idx];
+ }
+ } else {
+ $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
From 1278b79c79da6a871ed41c11d97ead14d77ae53a Mon Sep 17 00:00:00 2001
From: Anthony
Date: Wed, 3 Apr 2013 13:31:07 -0300
Subject: [PATCH 077/332] Added yml example in ordered-associations.rst
And modified it to be in a configuration-block instead of separate code-block
---
docs/en/tutorials/ordered-associations.rst | 65 ++++++++++++++--------
1 file changed, 42 insertions(+), 23 deletions(-)
diff --git a/docs/en/tutorials/ordered-associations.rst b/docs/en/tutorials/ordered-associations.rst
index e2a48ffcb..121bd145d 100644
--- a/docs/en/tutorials/ordered-associations.rst
+++ b/docs/en/tutorials/ordered-associations.rst
@@ -12,32 +12,51 @@ collection.
Additional to any ``@OneToMany`` or ``@ManyToMany`` annotation you
can specify the ``@OrderBy`` in the following way:
-.. code-block:: php
+.. configuration-block::
-
-
-
-
-
-
-
-
-
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+
+
+ .. code-block:: yaml
+
+ User:
+ type: entity
+ manyToMany:
+ groups:
+ orderBy: { 'name': 'ASC' }
+ targetEntity: Group
+ joinTable:
+ name: users_groups
+ joinColumns:
+ user_id:
+ referencedColumnName: id
+ inverseJoinColumns:
+ group_id:
+ referencedColumnName: id
The DQL Snippet in OrderBy is only allowed to consist of
unqualified, unquoted field names and of an optional ASC/DESC
From 3b7b457d35657911d551ef69639e4a9db111501c Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Thu, 4 Apr 2013 20:07:21 +0200
Subject: [PATCH 078/332] minor fixes
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 6 +++---
tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 948a4e689..1c55eb1bc 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -759,12 +759,12 @@ public function __construct()
*/
protected function getTraits(ClassMetadataInfo $metadata)
{
- if ($metadata->reflClass != null || class_exists($metadata->name)) {
- $reflClass = $metadata->reflClass == null
+ if ($metadata->reflClass !== null || class_exists($metadata->name)) {
+ $reflClass = $metadata->reflClass === null
? new \ReflectionClass($metadata->name)
: $metadata->reflClass;
- if (method_exists($reflClass, 'getTraits')) {
+ if (PHP_VERSION_ID >= 50400) {
return $reflClass->getTraits();
}
}
diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
index 694918d13..cd6430a2a 100644
--- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
@@ -458,7 +458,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
*/
public function testTraitPropertiesAndMethodsAreNotDuplicated()
{
- if (function_exists('trait_exists')) {
+ if (PHP_VERSION_ID >= 50400) {
$cmf = new ClassMetadataFactory();
$em = $this->_getTestEntityManager();
$cmf->setEntityManager($em);
From 64b2ecfefc8a6db94a0ec931dfc1e8012a5eb8a2 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 4 Apr 2013 20:20:23 +0200
Subject: [PATCH 079/332] [DDC-2224] Rewrite instanceof feature with parameter
needle ClassMetadata breaks caching of queries.
---
lib/Doctrine/ORM/AbstractQuery.php | 4 +++
lib/Doctrine/ORM/Query/SqlWalker.php | 29 +++++++------------
tests/Doctrine/Tests/ORM/Query/QueryTest.php | 12 ++++++++
.../ORM/Query/SelectSqlGenerationTest.php | 2 +-
4 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php
index 52f6ef507..18d563b10 100644
--- a/lib/Doctrine/ORM/AbstractQuery.php
+++ b/lib/Doctrine/ORM/AbstractQuery.php
@@ -284,6 +284,10 @@ abstract class AbstractQuery
}
}
+ if ($value instanceof Mapping\ClassMetadata) {
+ return $value->name;
+ }
+
return $value;
}
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 30a39924e..08d5e0cda 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -1932,31 +1932,22 @@ class SqlWalker implements TreeWalker
foreach ($instanceOfExpr->value as $parameter) {
if ($parameter instanceof AST\InputParameter) {
- // We need to modify the parameter value to be its correspondent mapped value
- $dqlParamKey = $parameter->name;
- $dqlParam = $this->query->getParameter($dqlParamKey);
- $paramValue = $this->query->processParameterValue($dqlParam->getValue());
-
- if ( ! ($paramValue instanceof \Doctrine\ORM\Mapping\ClassMetadata)) {
- throw QueryException::invalidParameterType('ClassMetadata', get_class($paramValue));
- }
-
- $entityClassName = $paramValue->name;
+ $sqlParameterList[] = $this->walkInputParameter($parameter);
} else {
// Get name from ClassMetadata to resolve aliases.
$entityClassName = $this->em->getClassMetadata($parameter)->name;
- }
- if ($entityClassName == $class->name) {
- $sqlParameterList[] = $this->conn->quote($class->discriminatorValue);
- } else {
- $discrMap = array_flip($class->discriminatorMap);
+ if ($entityClassName == $class->name) {
+ $sqlParameterList[] = $this->conn->quote($class->discriminatorValue);
+ } else {
+ $discrMap = array_flip($class->discriminatorMap);
- if (!isset($discrMap[$entityClassName])) {
- throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
+ if (!isset($discrMap[$entityClassName])) {
+ throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
+ }
+
+ $sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]);
}
-
- $sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]);
}
}
diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php
index de160d096..9617fa873 100644
--- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php
@@ -163,4 +163,16 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('cities', $parameter->getName());
$this->assertEquals($cities, $parameter->getValue());
}
+
+ /**
+ * @group DDC-2224
+ */
+ public function testProcessParameterValueClassMetadata()
+ {
+ $query = $this->_em->createQuery("SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.city IN (:cities)");
+ $this->assertEquals(
+ 'Doctrine\Tests\Models\CMS\CmsAddress',
+ $query->processParameterValue($this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress'))
+ );
+ }
}
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index fccacbdab..cb4aac47e 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -482,7 +482,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertSqlGeneration(
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1",
- "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')",
+ "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN (?)",
array(), array(1 => $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee'))
);
}
From 30b050b44ce20631ab9931ba2ea97044595f0c15 Mon Sep 17 00:00:00 2001
From: Pascal Borreli
Date: Sat, 6 Apr 2013 14:11:52 +0000
Subject: [PATCH 080/332] Fixed typos
---
lib/Doctrine/ORM/AbstractQuery.php | 2 +-
lib/Doctrine/ORM/Event/ListenersInvoker.php | 2 +-
lib/Doctrine/ORM/Id/AssignedGenerator.php | 2 +-
lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php | 6 +++---
lib/Doctrine/ORM/Id/IdentityGenerator.php | 6 +++---
lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php | 1 +
lib/Doctrine/ORM/Mapping/EntityListenerResolver.php | 2 +-
lib/Doctrine/ORM/Mapping/MappingException.php | 2 +-
.../ORM/Persisters/AbstractCollectionPersister.php | 4 ++--
lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php | 2 +-
lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php | 4 ++--
lib/Doctrine/ORM/Query/Parser.php | 8 ++++----
lib/Doctrine/ORM/Query/SqlWalker.php | 2 +-
lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php | 1 +
lib/Doctrine/ORM/Tools/EntityGenerator.php | 4 ++--
lib/Doctrine/ORM/UnitOfWork.php | 6 +++---
16 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php
index 18d563b10..b32310512 100644
--- a/lib/Doctrine/ORM/AbstractQuery.php
+++ b/lib/Doctrine/ORM/AbstractQuery.php
@@ -309,7 +309,7 @@ abstract class AbstractQuery
/**
* Allows to translate entity namespaces to full qualified names.
*
- * @param EntityManager $em
+ * @param Query\ResultSetMapping $rsm
*
* @return void
*/
diff --git a/lib/Doctrine/ORM/Event/ListenersInvoker.php b/lib/Doctrine/ORM/Event/ListenersInvoker.php
index 96fa4e67a..125855bef 100644
--- a/lib/Doctrine/ORM/Event/ListenersInvoker.php
+++ b/lib/Doctrine/ORM/Event/ListenersInvoker.php
@@ -91,7 +91,7 @@ class ListenersInvoker
*
* @param \Doctrine\ORM\Mapping\ClassMetadata $metadata The entity metadata.
* @param string $eventName The entity lifecycle event.
- * @param object $entity The Entity on which the event occured.
+ * @param object $entity The Entity on which the event occurred.
* @param \Doctrine\Common\EventArgs $event The Event args.
* @param integer $invoke Bitmask to invoke listeners.
*/
diff --git a/lib/Doctrine/ORM/Id/AssignedGenerator.php b/lib/Doctrine/ORM/Id/AssignedGenerator.php
index 121cc8fd0..4e3321593 100644
--- a/lib/Doctrine/ORM/Id/AssignedGenerator.php
+++ b/lib/Doctrine/ORM/Id/AssignedGenerator.php
@@ -23,7 +23,7 @@ use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMException;
/**
- * Special generator for application-assigned identifiers (doesnt really generate anything).
+ * Special generator for application-assigned identifiers (doesn't really generate anything).
*
* @since 2.0
* @author Benjamin Eberlei
diff --git a/lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php b/lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php
index e387023b4..1b4ed9a06 100644
--- a/lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php
+++ b/lib/Doctrine/ORM/Id/BigIntegerIdentityGenerator.php
@@ -38,9 +38,9 @@ class BigIntegerIdentityGenerator extends AbstractIdGenerator
/**
* Constructor.
*
- * @param string|null $seqName The name of the sequence to pass to lastInsertId()
- * to obtain the last generated identifier within the current
- * database session/connection, if any.
+ * @param string|null $sequenceName The name of the sequence to pass to lastInsertId()
+ * to obtain the last generated identifier within the current
+ * database session/connection, if any.
*/
public function __construct($sequenceName = null)
{
diff --git a/lib/Doctrine/ORM/Id/IdentityGenerator.php b/lib/Doctrine/ORM/Id/IdentityGenerator.php
index d0bf327bb..7945c6936 100644
--- a/lib/Doctrine/ORM/Id/IdentityGenerator.php
+++ b/lib/Doctrine/ORM/Id/IdentityGenerator.php
@@ -38,9 +38,9 @@ class IdentityGenerator extends AbstractIdGenerator
/**
* Constructor.
*
- * @param string|null $seqName The name of the sequence to pass to lastInsertId()
- * to obtain the last generated identifier within the current
- * database session/connection, if any.
+ * @param string|null $sequenceName The name of the sequence to pass to lastInsertId()
+ * to obtain the last generated identifier within the current
+ * database session/connection, if any.
*/
public function __construct($sequenceName = null)
{
diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
index 9e1c734cc..f9aaddba7 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php
@@ -533,6 +533,7 @@ class AnnotationDriver extends AbstractAnnotationDriver
/**
* Parse the given JoinColumn as array
*
+ * @param JoinColumn $joinColumn
* @return array
*/
private function joinColumnToArray(JoinColumn $joinColumn)
diff --git a/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php b/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php
index bbf498dc3..2d5ecf714 100644
--- a/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php
+++ b/lib/Doctrine/ORM/Mapping/EntityListenerResolver.php
@@ -49,7 +49,7 @@ interface EntityListenerResolver
/**
* Register a entity listener instance.
*
- * @return object An entity listener
+ * @param object $object An entity listener
*/
function register($object);
}
\ No newline at end of file
diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php
index a8345bbd6..a9d5d1214 100644
--- a/lib/Doctrine/ORM/Mapping/MappingException.php
+++ b/lib/Doctrine/ORM/Mapping/MappingException.php
@@ -685,8 +685,8 @@ class MappingException extends \Doctrine\ORM\ORMException
}
/**
+ * @param string $listenerName
* @param string $className
- * @param string $methodName
*
* @return \Doctrine\ORM\Mapping\MappingException
*/
diff --git a/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php b/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
index e1cad36bc..fdc54aee1 100644
--- a/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
+++ b/lib/Doctrine/ORM/Persisters/AbstractCollectionPersister.php
@@ -98,7 +98,7 @@ abstract class AbstractCollectionPersister
*
* @param \Doctrine\ORM\PersistentCollection $coll
*
- * @return void
+ * @return string
*/
abstract protected function getDeleteSQL(PersistentCollection $coll);
@@ -108,7 +108,7 @@ abstract class AbstractCollectionPersister
*
* @param \Doctrine\ORM\PersistentCollection $coll
*
- * @return void
+ * @return array
*/
abstract protected function getDeleteSQLParameters(PersistentCollection $coll);
diff --git a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php
index 6e9b95afc..2f33c9da3 100644
--- a/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php
+++ b/lib/Doctrine/ORM/Query/AST/Functions/FunctionNode.php
@@ -22,7 +22,7 @@ namespace Doctrine\ORM\Query\AST\Functions;
use Doctrine\ORM\Query\AST\Node;
/**
- * Abtract Function Node.
+ * Abstract Function Node.
*
*
* @link www.doctrine-project.org
diff --git a/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
index 7e1d75aee..5f51a9044 100644
--- a/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
+++ b/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
@@ -83,9 +83,9 @@ class IdentityFunction extends FunctionNode
}
$tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
- $columName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform);
+ $columnName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform);
- return $tableAlias . '.' . $columName;
+ return $tableAlias . '.' . $columnName;
}
/**
diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php
index e7a0e3ed2..79f18a4cd 100644
--- a/lib/Doctrine/ORM/Query/Parser.php
+++ b/lib/Doctrine/ORM/Query/Parser.php
@@ -2,7 +2,7 @@
/*
* 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 MERCHARNTABILITY AND FITNESS FOR
+ * 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
@@ -1064,7 +1064,7 @@ class Parser
// Creating AST node
$pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $field);
- // Defer PathExpression validation if requested to be defered
+ // Defer PathExpression validation if requested to be deferred
$this->deferredPathExpressions[] = array(
'expression' => $pathExpr,
'nestingLevel' => $this->nestingLevel,
@@ -2413,7 +2413,7 @@ class Parser
}
if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER || $this->isFunction()) {
- // Peek beyond the matching closing paranthesis.
+ // Peek beyond the matching closing parenthesis.
$beyond = $this->lexer->peek();
switch ($peek['value']) {
@@ -2765,7 +2765,7 @@ class Parser
* StringExpression ::= StringPrimary | "(" Subselect ")"
*
* @return \Doctrine\ORM\Query\AST\StringPrimary |
- * \Doctrine]ORM\Query\AST\Subselect
+ * \Doctrine\ORM\Query\AST\Subselect
*/
public function StringExpression()
{
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 08d5e0cda..cb51a9228 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -428,7 +428,7 @@ class SqlWalker implements TreeWalker
$conn = $this->em->getConnection();
$values = array();
- if ($class->discriminatorValue !== null) { // discrimnators can be 0
+ if ($class->discriminatorValue !== null) { // discriminators can be 0
$values[] = $conn->quote($class->discriminatorValue);
}
diff --git a/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php b/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
index 077ae8930..365fcb415 100644
--- a/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
+++ b/lib/Doctrine/ORM/Tools/Console/ConsoleRunner.php
@@ -35,6 +35,7 @@ class ConsoleRunner
/**
* Create a Symfony Console HelperSet
*
+ * @param EntityManager $entityManager
* @return HelperSet
*/
public static function createHelperSet(EntityManager $entityManager)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 082720bf7..98a65fb98 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -475,7 +475,7 @@ public function __construct()
public function setFieldVisibility($visibility)
{
if ($visibility !== self::FIELD_VISIBLE_PRIVATE && $visibility !== self::FIELD_VISIBLE_PROTECTED) {
- throw new \InvalidArgumentException('Invalid provided visibilty (only private and protected are allowed): ' . $visibility);
+ throw new \InvalidArgumentException('Invalid provided visibility (only private and protected are allowed): ' . $visibility);
}
$this->fieldVisibility = $visibility;
@@ -1480,7 +1480,7 @@ public function __construct()
/**
* @param integer $type The generator to use for the mapped class.
*
- * @return string The literal string for the generetor type.
+ * @return string The literal string for the generator type.
*
* @throws \InvalidArgumentException When the generator type does not exists.
*/
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 4c3f3720c..928c90f2c 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -597,7 +597,7 @@ class UnitOfWork implements PropertyChangedListener
$orgValue = $originalData[$propName];
- // skip if value havent changed
+ // skip if value haven't changed
if ($orgValue === $actualValue) {
continue;
}
@@ -1055,7 +1055,7 @@ class UnitOfWork implements PropertyChangedListener
$calc = $this->getCommitOrderCalculator();
// See if there are any new classes in the changeset, that are not in the
- // commit order graph yet (dont have a node).
+ // commit order graph yet (don't have a node).
// We have to inspect changeSet to be able to correctly build dependencies.
// It is not possible to use IdentityMap here because post inserted ids
// are not yet available.
@@ -1820,7 +1820,7 @@ class UnitOfWork implements PropertyChangedListener
$managedCopyVersion = $reflField->getValue($managedCopy);
$entityVersion = $reflField->getValue($entity);
- // Throw exception if versions dont match.
+ // Throw exception if versions don't match.
if ($managedCopyVersion != $entityVersion) {
throw OptimisticLockException::lockFailedVersionMismatch($entity, $entityVersion, $managedCopyVersion);
}
From 8109db02b5d4c0f986af77eb7aa5a442d72a8fd9 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Sat, 6 Apr 2013 13:02:43 -0300
Subject: [PATCH 081/332] Document Parenthesis BC break.
---
UPGRADE.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/UPGRADE.md b/UPGRADE.md
index e80aa55ad..df174de76 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -11,6 +11,23 @@ Before 2.4 the postFlush and onFlush events were only called when there were
actually entities that changed. Now these events are called no matter if there
are entities in the UoW or changes are found.
+## Parenthesis are now considered in arithmetic expression
+
+Before 2.4 parenthesis are not considered in arithmetic primary expression.
+That's conceptually wrong, since it might result in wrong values. For example:
+
+The DQL:
+
+ SELECT 100/(2*2) FROM MyEntity
+
+Before 2.4 it generates the SQL:
+
+ SELECT 100/2*2 my_entity
+
+Now parenthesis are considered, the previous DQL will generate:
+
+ SELECT (100/2*2) my_entity
+
# Upgrade to 2.3
## EntityManager#find() not calls EntityRepository#find() anymore
From 2ad65656326373420f1e14513f6b8b9c923cd838 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Sat, 6 Apr 2013 14:53:36 -0300
Subject: [PATCH 082/332] Fix parenthesis example
---
UPGRADE.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/UPGRADE.md b/UPGRADE.md
index df174de76..fe5f52528 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -18,15 +18,15 @@ That's conceptually wrong, since it might result in wrong values. For example:
The DQL:
- SELECT 100/(2*2) FROM MyEntity
+ SELECT 100 / ( 2 * 2 ) FROM MyEntity
Before 2.4 it generates the SQL:
- SELECT 100/2*2 my_entity
+ SELECT 100 / 2 * 2 FROM my_entity
Now parenthesis are considered, the previous DQL will generate:
- SELECT (100/2*2) my_entity
+ SELECT 100 / (2 * 2) FROM my_entity
# Upgrade to 2.3
From b2e29eaf970da01e0daefb879e786d29d852345f Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 7 Apr 2013 14:01:27 +0200
Subject: [PATCH 083/332] Rework NativeSQL doc chapter and document SELECT
clause generation (ref DDC-2055).
---
docs/en/conf.py | 9 ++-
docs/en/reference/native-sql.rst | 126 ++++++++++++++++++++-----------
2 files changed, 89 insertions(+), 46 deletions(-)
diff --git a/docs/en/conf.py b/docs/en/conf.py
index 5b35389ce..4e0c87b50 100644
--- a/docs/en/conf.py
+++ b/docs/en/conf.py
@@ -22,7 +22,7 @@ sys.path.append(os.path.abspath('_exts'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['configurationblock']
+extensions = ['configurationblock', 'sphinx.ext.linkcode']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -192,3 +192,10 @@ latex_documents = [
# If false, no module index is generated.
#latex_use_modindex = True
+
+primary_domain = "dcorm"
+
+def linkcode_resolve(domain, info):
+ if domain == 'dcorm':
+ return 'http://'
+ return None
diff --git a/docs/en/reference/native-sql.rst b/docs/en/reference/native-sql.rst
index 21f0a6ca9..cc59f1630 100644
--- a/docs/en/reference/native-sql.rst
+++ b/docs/en/reference/native-sql.rst
@@ -1,17 +1,21 @@
Native SQL
==========
-A ``NativeQuery`` lets you execute native SELECT SQL statements, mapping the results
-according to your specifications. Such a specification that
-describes how a SQL result set is mapped to a Doctrine result is
-represented by a ``ResultSetMapping``. It describes how each column
-of the database result should be mapped by Doctrine in terms of the
-object graph. This allows you to map arbitrary SQL code to objects,
-such as highly vendor-optimized SQL or stored-procedures.
+With ``NativeQuery`` you can execute native SELECT SQL statements
+and map the results to Doctrine entities or any other result format
+supported by Doctrine.
-Because writing ``ResultSetMapping`` is not so simple, there is a convenience
-wrapper around it called a ``ResultSetMappingBuilder``. The last section
-of this chapter describes its usage.
+In order to make this mapping possible, you need to describe
+to Doctrine what columns in the result map to which entity property.
+This description is represented by a ``ResultSetMapping`` object.
+
+With this feature you can map arbitrary SQL code to objects, such as highly
+vendor-optimized SQL or stored-procedures.
+
+Writing ``ResultSetMapping`` from scratch is complex, but there is a convenience
+wrapper around it called a ``ResultSetMappingBuilder``. It can generate
+the mappings for you based on Entities and even generates the ``SELECT``
+clause based on this information for you.
.. note::
@@ -25,14 +29,75 @@ The NativeQuery class
---------------------
To create a ``NativeQuery`` you use the method
-``EntityManager#createNativeQuery($sql, $resultSetMapping)``. As
-you can see in the signature of this method, it expects 2
-ingredients: The SQL you want to execute and the
-``ResultSetMapping`` that describes how the results will be
+``EntityManager#createNativeQuery($sql, $resultSetMapping)``. As you can see in
+the signature of this method, it expects 2 ingredients: The SQL you want to
+execute and the ``ResultSetMapping`` that describes how the results will be
mapped.
-Once you obtained an instance of a ``NativeQuery``, you can bind
-parameters to it and finally execute it.
+Once you obtained an instance of a ``NativeQuery``, you can bind parameters to
+it with the same API that ``Query`` has and execute it.
+
+.. code-block:: php
+
+ createNativeQuery('SELECT id, name, discr FROM users WHERE name = ?', $rsm);
+ $query->setParameter(1, 'romanb');
+
+ $users = $query->getResult();
+
+ResultSetMappingBuilder
+-----------------------
+
+An easy start into ResultSet mapping is the ``ResultSetMappingBuilder`` object.
+This has several benefits:
+
+- The builder takes care of automatically updating your ``ResultSetMapping``
+ when the fields or associations change on the metadata of an entity.
+- You can generate the required ``SELECT`` expression for a builder
+ by converting it to a string.
+- The API is much simpler than the usual ``ResultSetMapping`` API.
+
+One downside is that the builder API does not yet support entities
+with inheritance hierachies.
+
+.. code-block:: php
+
+ addRootEntityFromClassMetadata('MyProject\User', 'u');
+ $rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', 'u', 'address', array('id' => 'address_id'));
+
+The builder extends the ``ResultSetMapping`` class and as such has all the functionality of it as well.
+
+..versionadded:: 2.4
+
+Starting with Doctrine ORM 2.4 you can generate the ``SELECT`` clause
+from a ``ResultSetMappingBuilder``. You can either cast the builder
+object to ``(string)`` and the DQL aliases are used as SQL table aliases
+or use the ``generateSelectClause($tableAliases)`` method and pass
+a mapping from DQL alias (key) to SQL alias (value)
+
+.. code-block:: php
+
+ generateSelectClause(array(
+ 'u' => 't1',
+ 'g' => 't2'
+ ));
+ $sql = "SELECT " . $selectClause . " FROM users t1 JOIN groups t2 ON t1.group_id = t2.id";
+
The ResultSetMapping
--------------------
@@ -369,35 +434,6 @@ are actually a subtype of User. When using DQL, Doctrine
automatically includes the necessary joins for this mapping
strategy but with native SQL it is your responsibility.
-ResultSetMappingBuilder
------------------------
-
-There are some downsides with Native SQL queries. The primary one is that you have to adjust all result set mapping
-definitions if names of columns change. In DQL this is detected dynamically when the Query is regenerated with
-the current metadata.
-
-To avoid this hassle you can use the ``ResultSetMappingBuilder`` class. It allows to add all columns of an entity
-to a result set mapping. To avoid clashes you can optionally rename specific columns when you are doing the same
-in your sQL statement:
-
-.. code-block:: php
-
- addRootEntityFromClassMetadata('MyProject\User', 'u');
- $rsm->addJoinedEntityFromClassMetadata('MyProject\Address', 'a', 'u', 'address', array('id' => 'address_id'));
-
-For entities with more columns the builder is very convenient to use. It extends the ``ResultSetMapping`` class
-and as such has all the functionality of it as well. Currently the ``ResultSetMappingBuilder`` does not support
-entities with inheritance.
-
-
Named Native Query
------------------
From 34374db56ec777911868f28d6914491b1804a689 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 7 Apr 2013 14:02:47 +0200
Subject: [PATCH 084/332] Enhance documentation on IDENTITY() for composite
keys (ref DDC-2202)
---
docs/en/reference/dql-doctrine-query-language.rst | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst
index c140d5599..b82cbabda 100644
--- a/docs/en/reference/dql-doctrine-query-language.rst
+++ b/docs/en/reference/dql-doctrine-query-language.rst
@@ -427,13 +427,14 @@ Get all users visible on a given website that have chosen certain gender:
createQuery('SELECT u FROM User u WHERE u.gender IN (SELECT IDENTITY(agl.gender) FROM Site s JOIN s.activeGenderList agl WHERE s.id = ?1)');
-IDENTITY() DQL Function when the association has a composite primary key:
+Starting with 2.4, the IDENTITY() DQL function also works for composite primary keys:
.. code-block:: php
createQuery('SELECT IDENTITY(c.location, 'latitude') AS latitude, IDENTITY(c.location, 'longitude') AS longitude FROM Checkpoint c WHERE c.user = ?1');
+
Partial Object Syntax
^^^^^^^^^^^^^^^^^^^^^
From d1f8e18d023bd50b0144d20fd8adbd6e49a6f450 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sun, 7 Apr 2013 14:05:42 +0200
Subject: [PATCH 085/332] Enhance documentation on NEW() keyword. (ref
DDC-1574)
---
docs/en/reference/dql-doctrine-query-language.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst
index b82cbabda..856a4b077 100644
--- a/docs/en/reference/dql-doctrine-query-language.rst
+++ b/docs/en/reference/dql-doctrine-query-language.rst
@@ -464,14 +464,15 @@ You use the partial syntax when joining as well:
"NEW" Operator Syntax
^^^^^^^^^^^^^^^^^^^^^
-Using the ``NEW`` operator you can construct DTOs from queries.
+.. versionadded:: 2.4
+
+Using the ``NEW`` operator you can construct Data Transfer Objects (DTOs) directly from DQL queries.
- When using ``SELECT NEW`` you don't need to specify a mapped entity.
-- You can specify any PHP class, it's only require that you have a matching constructor in your class.
+- You can specify any PHP class, it's only require that the constructor of this class matches the ``NEW`` statement.
- This approach involves determining exactly which columns you really need,
and instantiating data-transfer object that containing a constructor with those arguments.
-
If you want to select data-transfer objects you should create a class:
.. code-block:: php
From b7b107b08ac22ec385b6461538832bd25e6f6547 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Sun, 7 Apr 2013 16:26:05 +0200
Subject: [PATCH 086/332] moved test entities from sandbox
---
.../Tests/Models/DDC2372/DDC2372Address.php | 45 +++++++++++++++++++
.../Tests/Models/DDC2372/DDC2372User.php | 10 ++---
.../DDC2372/Traits/DDC2372AddressTrait.php | 6 +--
.../Tests/ORM/Tools/EntityGeneratorTest.php | 10 ++---
tests/Doctrine/Tests/TestInit.php | 1 -
5 files changed, 58 insertions(+), 14 deletions(-)
create mode 100644 tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php
rename tools/sandbox/Entities/TraitedUser.php => tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php (68%)
rename tools/sandbox/Entities/Traits/AddressTrait.php => tests/Doctrine/Tests/Models/DDC2372/Traits/DDC2372AddressTrait.php (69%)
diff --git a/tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php b/tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php
new file mode 100644
index 000000000..26144c61d
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/DDC2372/DDC2372Address.php
@@ -0,0 +1,45 @@
+id;
+ }
+
+ public function getStreet()
+ {
+ return $this->street;
+ }
+
+ public function setStreet($street)
+ {
+ $this->street = $street;
+ }
+
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ public function setUser(User $user)
+ {
+ if ($this->user !== $user) {
+ $this->user = $user;
+ $user->setAddress($this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/sandbox/Entities/TraitedUser.php b/tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php
similarity index 68%
rename from tools/sandbox/Entities/TraitedUser.php
rename to tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php
index fe0b68754..4df0df6a5 100644
--- a/tools/sandbox/Entities/TraitedUser.php
+++ b/tests/Doctrine/Tests/Models/DDC2372/DDC2372User.php
@@ -1,13 +1,13 @@
_getTestEntityManager();
$cmf->setEntityManager($em);
- $user = new TraitedUser();
+ $user = new DDC2372User();
$metadata = $cmf->getMetadataFor(get_class($user));
- $metadata->name = $this->_namespace . "\TraitedUser";
+ $metadata->name = $this->_namespace . "\DDC2372User";
$metadata->namespace = $this->_namespace;
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
- $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/TraitedUser.php");
- require $this->_tmpDir . "/" . $this->_namespace . "/TraitedUser.php";
+ $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php");
+ require $this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php";
$reflClass = new \ReflectionClass($metadata->name);
diff --git a/tests/Doctrine/Tests/TestInit.php b/tests/Doctrine/Tests/TestInit.php
index ac7f7354b..c257a75b6 100644
--- a/tests/Doctrine/Tests/TestInit.php
+++ b/tests/Doctrine/Tests/TestInit.php
@@ -17,7 +17,6 @@ if (file_exists(__DIR__ . '/../../../vendor/autoload.php')) {
}
/* @var $classLoader \Composer\Autoload\ClassLoader */
-$classLoader->add('Entities', __DIR__ . '/../../../tools/sandbox');
$classLoader->add('Doctrine\\Tests\\', __DIR__ . '/../../');
unset($classLoader);
From e561f47cb2205565eb873f0643637477bfcfc2ff Mon Sep 17 00:00:00 2001
From: Stefan Kleff
Date: Mon, 8 Apr 2013 11:27:22 +0200
Subject: [PATCH 087/332] Added constant
---
.../ORM/Internal/Hydration/ObjectHydrator.php | 7 ++++---
lib/Doctrine/ORM/Persisters/BasicEntityPersister.php | 10 +++++-----
lib/Doctrine/ORM/UnitOfWork.php | 11 +++++++++--
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
index 04d741cbb..fafc497c0 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/ObjectHydrator.php
@@ -19,6 +19,7 @@
namespace Doctrine\ORM\Internal\Hydration;
+use Doctrine\ORM\UnitOfWork;
use PDO;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\PersistentCollection;
@@ -94,8 +95,8 @@ class ObjectHydrator extends AbstractHydrator
$this->resultCounter = 0;
- if ( ! isset($this->_hints['deferEagerLoad'])) {
- $this->_hints['deferEagerLoad'] = true;
+ if ( ! isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) {
+ $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] = true;
}
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
@@ -152,7 +153,7 @@ class ObjectHydrator extends AbstractHydrator
*/
protected function cleanup()
{
- $eagerLoad = (isset($this->_hints['deferEagerLoad'])) && $this->_hints['deferEagerLoad'] == true;
+ $eagerLoad = (isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) && $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] == true;
parent::cleanup();
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index 570f27ea8..894ac3ffe 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -851,7 +851,7 @@ class BasicEntityPersister
$stmt = $this->conn->executeQuery($query, $params, $types);
$hydrator = $this->em->newHydrator(($this->selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
- return $hydrator->hydrateAll($stmt, $this->rsm, array('deferEagerLoad' => true));
+ return $hydrator->hydrateAll($stmt, $this->rsm, array(UnitOfWork::HINT_DEFEREAGERLOAD => true));
}
/**
@@ -908,7 +908,7 @@ class BasicEntityPersister
$hydrator = $this->em->newHydrator(($this->selectJoinSql) ? Query::HYDRATE_OBJECT : Query::HYDRATE_SIMPLEOBJECT);
- return $hydrator->hydrateAll($stmt, $this->rsm, array('deferEagerLoad' => true));
+ return $hydrator->hydrateAll($stmt, $this->rsm, array(UnitOfWork::HINT_DEFEREAGERLOAD => true));
}
/**
@@ -939,7 +939,7 @@ class BasicEntityPersister
private function loadArrayFromStatement($assoc, $stmt)
{
$rsm = $this->rsm;
- $hints = array('deferEagerLoad' => true);
+ $hints = array(UnitOfWork::HINT_DEFEREAGERLOAD => true);
if (isset($assoc['indexBy'])) {
$rsm = clone ($this->rsm); // this is necessary because the "default rsm" should be changed.
@@ -962,8 +962,8 @@ class BasicEntityPersister
{
$rsm = $this->rsm;
$hints = array(
- 'deferEagerLoad' => true,
- 'collection' => $coll
+ UnitOfWork::HINT_DEFEREAGERLOAD => true,
+ 'collection' => $coll
);
if (isset($assoc['indexBy'])) {
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 4c3f3720c..fa569caf7 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -76,6 +76,13 @@ class UnitOfWork implements PropertyChangedListener
*/
const STATE_REMOVED = 4;
+ /**
+ * Hint used to collect all primary keys of associated entities during hydration
+ * and execute it in a dedicated query afterwards
+ * @see https://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html?highlight=eager#temporarily-change-fetch-mode-in-dql
+ */
+ const HINT_DEFEREAGERLOAD = 'deferEagerLoad';
+
/**
* The identity map that holds references to all managed entities that have
* an identity. The entities are grouped by their class name.
@@ -2616,7 +2623,7 @@ class UnitOfWork implements PropertyChangedListener
// this association is marked as eager fetch, and its an uninitialized proxy (wtf!)
// then we can append this entity for eager loading!
if ($hints['fetchMode'][$class->name][$field] == ClassMetadata::FETCH_EAGER &&
- isset($hints['deferEagerLoad']) &&
+ isset($hints[self::HINT_DEFEREAGERLOAD]) &&
!$targetClass->isIdentifierComposite &&
$newValue instanceof Proxy &&
$newValue->__isInitialized__ === false) {
@@ -2641,7 +2648,7 @@ class UnitOfWork implements PropertyChangedListener
break;
// Deferred eager load only works for single identifier classes
- case (isset($hints['deferEagerLoad']) && ! $targetClass->isIdentifierComposite):
+ case (isset($hints[self::HINT_DEFEREAGERLOAD]) && ! $targetClass->isIdentifierComposite):
// TODO: Is there a faster approach?
$this->eagerLoadingEntities[$targetClass->rootEntityName][$relatedIdHash] = current($associatedId);
From 142c20aad1413e64082a5a9a2e5ee49617e3a1a0 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Tue, 9 Apr 2013 00:00:16 +0200
Subject: [PATCH 088/332] Work on the Tutorial
---
docs/en/tutorials/getting-started.rst | 175 ++++++++++++++++++--------
1 file changed, 124 insertions(+), 51 deletions(-)
diff --git a/docs/en/tutorials/getting-started.rst b/docs/en/tutorials/getting-started.rst
index f34590de2..2faea8218 100644
--- a/docs/en/tutorials/getting-started.rst
+++ b/docs/en/tutorials/getting-started.rst
@@ -258,8 +258,8 @@ entity definition in there:
}
Note how the properties have getter and setter methods defined except
-`$id`. To access data from entities Doctrine 2 uses the Reflection API, so it
-is possible for Doctrine to access the value of `$id`. You don't have to
+``$id``. To access data from entities Doctrine 2 uses the Reflection API, so it
+is possible for Doctrine to access the value of ``$id``. You don't have to
take Doctrine into account when designing access to the state of your objects.
The next step for persistence with Doctrine is to describe the
@@ -268,9 +268,8 @@ language. The metadata language describes how entities, their
properties and references should be persisted and what constraints
should be applied to them.
-Metadata for entities are configured using a
-XML, YAML or Docblock Annotations. This
-Getting Started Guide will show the mappings for all Mapping Drivers.
+Metadata for entities are configured using a XML, YAML or Docblock Annotations.
+This Getting Started Guide will show the mappings for all Mapping Drivers.
References in the text will be made to the XML mapping.
.. configuration-block::
@@ -337,9 +336,12 @@ You have to update the database now, because we have a first Entity now:
::
- $ php vendor/bin/doctrine orm:schema-tool:update
+ $ php vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
-Now create a simple script to create a new product:
+Specifying both flags ``--force`` and ``-dump-sql`` prints and executes the DDL
+statements.
+
+Now create a new script that will insert products into the database:
.. code-block:: php
@@ -357,41 +359,37 @@ Now create a simple script to create a new product:
echo "Created Product with ID " . $product->getId() . "\n";
-Call this script to see how new products are created:
+Call this script from the command line to see how new products are created:
::
$ php create_product.php ORM
$ php create_product.php DBAL
-What is happening here? In the code using the Product is pretty standard OOP.
-The interesting bits are the communication with the ``EntityManager``. To
+What is happening here? Using the ``Product`` is pretty standard OOP.
+The interesting bits are the use of the ``EntityManager`` service. To
notify the EntityManager that a new entity should be inserted into the database
-you have to call ``persist()``. However the EntityManager does not act on this
-command, its merely notified. You have to explicitly call ``flush()`` to have
-the EntityManager write those two entities to the database.
+you have to call ``persist()``. To intiate a transaction to actually perform
+the insertion, You have to explicitly call ``flush()`` on the ``EntityManager``.
-You might wonder why does this distinction between persist notification and
-flush exist: Doctrine 2 uses the UnitOfWork pattern to aggregate all writes
+This distinction between persist and flush is allows to aggregate all writes
(INSERT, UPDATE, DELETE) into one single transaction, which is executed when
-flush is called. Using this approach the write-performance is significantly
+flush is called. Using this approach the write-performance is significantly
better than in a scenario where updates are done for each entity in isolation.
-In more complex scenarios than the previous two, you are free to request
-updates on many different entities and all flush them at once.
-Doctrine's UnitOfWork detects entities that have changed after retrieval from
-the database automatically when the flush operation is called, so that you only
-have to keep track of those entities that are new or to be removed and pass
-them to ``EntityManager#persist()`` and ``EntityManager#remove()``
-respectively.
+Doctrine follows the UnitOfWork pattern which additionally detects all entities
+that were fetched and have changed during the request. You don't have to keep track of
+entities yourself, when Doctrine already knowns about them.
-We want to see a list of all the products now, so lets create a new script for
-this:
+As a next step we want to fetch a list of all the products. Let's create a
+new script for this:
.. code-block:: php
getRepository('Product');
$products = $productRepository->findAll();
@@ -399,65 +397,144 @@ this:
echo sprintf("-%s\n", $product->getName());
}
-The ``EntityRepository`` fetched through the ``EntityManager#getRepository()``
-method exists for every entity and is provided by Doctrine. It contains
-some finder methods such as ``findAll()`` we used here.
+The ``EntityManager#getRepository()`` method can create a finder object (called
+repository) for every entity. It is provided by Doctrine and contains some
+finder methods such as ``findAll()``.
-Lets display the name of a product based on its ID:
+Let's continue with displaying the name of a product based on its ID:
.. code-block:: php
+ require_once "bootstrap.php";
+
$id = $argv[1];
$product = $entityManager->find('Product', $id);
+ if ($product === null) {
+ echo "No product found.\n";
+ exit(1);
+ }
+
echo sprintf("-%s\n", $product->getName());
+Updating a product name demonstrates the functionality UnitOfWork of pattern
+discussed before. We only need to find a product entity and all changes to its
+properties are written to the database:
+
+.. code-block:: php
+
+
+ require_once "bootstrap.php";
+
+ $id = $argv[1];
+ $newName = $argv[2];
+
+ $product = $entityManager->find('Product', $id);
+
+ if ($product === null) {
+ echo "Product $id does not exist.\n";
+ exit(1);
+ }
+
+ $product->setName($newName);
+
+ $entityManager->flush();
+
+After calling this script on one of the existing products, you can verify the
+product name changed by calling the ``show_product.php`` script.
+
Adding Bug and User Entities
----------------------------
-We continue with the bug tracker domain, by creating the missing
-classes ``Bug`` and ``User`` and putting them into
-`src/Bug.php` and `src/User.php`
-respectively.
+We continue with the bug tracker domain, by creating the missing classes
+``Bug`` and ``User`` and putting them into ``src/Bug.php`` and
+``src/User.php`` respectively.
.. code-block:: php
id;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function setDescription($description)
+ {
+ $this->description = $description;
+ }
+
+ public function setCreated(DateTime $created)
+ {
+ $this->created = $created;
+ }
+
+ public function getCreated()
+ {
+ return $this->created;
+ }
+
+ public function setStatus($status)
+ {
+ $this->status = $status;
+ }
+
+ public function getStatus()
+ {
+ return $this->status;
+ }
+ }
.. code-block:: php
Date: Tue, 9 Apr 2013 17:00:06 -0300
Subject: [PATCH 089/332] Fix Oracle subquery ordering lost bug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
See http://www.doctrine-project.org/jira/browse/DDC-1800 for a full description.
---
.../Tools/Pagination/LimitSubqueryOutputWalker.php | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
index 3943cb5e6..274dac271 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
@@ -137,9 +137,16 @@ class LimitSubqueryOutputWalker extends SqlWalker
));
}
- // Build the counter query.
- $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
- implode(', ', $sqlIdentifier), $innerSql);
+ // Build the counter query
+ if ($this->platform instanceof OraclePlatform) {
+ // Ordering is lost in Oracle with subqueries
+ // http://www.doctrine-project.org/jira/browse/DDC-1800
+ $sql = sprintf('SELECT DISTINCT %s, ROWNUM FROM (%s) dctrn_result ORDER BY ROWNUM ASC',
+ implode(', ', $sqlIdentifier), $innerSql);
+ } else {
+ $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
+ implode(', ', $sqlIdentifier), $innerSql);
+ }
if ($this->platform instanceof PostgreSqlPlatform) {
//http://www.doctrine-project.org/jira/browse/DDC-1958
From 4bafcc5b317a1feb8f05febf7985d8cfd87d31d7 Mon Sep 17 00:00:00 2001
From: Raymond Kolbe
Date: Tue, 9 Apr 2013 17:30:54 -0300
Subject: [PATCH 090/332] Fix Oracle subquery ordering
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
See http://www.doctrine-project.org/jira/browse/DDC-1800 and http://www.doctrine-project.org/jira/browse/DDC-1958#comment-19969
---
.../Pagination/LimitSubqueryOutputWalker.php | 23 ++++++++-----------
1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
index 274dac271..a6c24ee34 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/LimitSubqueryOutputWalker.php
@@ -16,6 +16,7 @@ namespace Doctrine\ORM\Tools\Pagination;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\AST\SelectStatement;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
+use Doctrine\DBAL\Platforms\OraclePlatform;
/**
* Wraps the query in order to select root entity IDs for pagination.
@@ -138,19 +139,13 @@ class LimitSubqueryOutputWalker extends SqlWalker
}
// Build the counter query
- if ($this->platform instanceof OraclePlatform) {
- // Ordering is lost in Oracle with subqueries
- // http://www.doctrine-project.org/jira/browse/DDC-1800
- $sql = sprintf('SELECT DISTINCT %s, ROWNUM FROM (%s) dctrn_result ORDER BY ROWNUM ASC',
- implode(', ', $sqlIdentifier), $innerSql);
- } else {
- $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
- implode(', ', $sqlIdentifier), $innerSql);
- }
+ $sql = sprintf('SELECT DISTINCT %s FROM (%s) dctrn_result',
+ implode(', ', $sqlIdentifier), $innerSql);
- if ($this->platform instanceof PostgreSqlPlatform) {
+ if ($this->platform instanceof PostgreSqlPlatform ||
+ $this->platform instanceof OraclePlatform) {
//http://www.doctrine-project.org/jira/browse/DDC-1958
- $this->getPostgresqlSql($AST, $sqlIdentifier, $innerSql, $sql);
+ $this->preserveSqlOrdering($AST, $sqlIdentifier, $innerSql, $sql);
}
// Apply the limit and offset.
@@ -168,9 +163,9 @@ class LimitSubqueryOutputWalker extends SqlWalker
return $sql;
}
-
+
/**
- * Generates new SQL for postgresql if necessary.
+ * Generates new SQL for Postgresql or Oracle if necessary.
*
* @param SelectStatement $AST
* @param array $sqlIdentifier
@@ -179,7 +174,7 @@ class LimitSubqueryOutputWalker extends SqlWalker
*
* @return void
*/
- public function getPostgresqlSql(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
+ public function preserveSqlOrdering(SelectStatement $AST, array $sqlIdentifier, $innerSql, &$sql)
{
// For every order by, find out the SQL alias by inspecting the ResultSetMapping.
$sqlOrderColumns = array();
From 27e23faa5a74c3eb4500d470d097e86d1962ca48 Mon Sep 17 00:00:00 2001
From: Raymond Kolbe
Date: Wed, 10 Apr 2013 13:07:09 -0300
Subject: [PATCH 091/332] Accompanying tests for PR #646
---
.../LimitSubqueryOutputWalkerTest.php | 76 +++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
index f19b8520b..07ce5afd9 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Pagination/LimitSubqueryOutputWalkerTest.php
@@ -83,6 +83,82 @@ class LimitSubqueryOutputWalkerTest extends PaginationTestCase
$this->entityManager->getConnection()->setDatabasePlatform($odp);
}
+
+ public function testLimitSubqueryWithSortOracle()
+ {
+ $odp = $this->entityManager->getConnection()->getDatabasePlatform();
+ $this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
+
+ $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');
+ $query->expireQueryCache(true);
+ $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 testLimitSubqueryWithScalarSortOracle()
+ {
+ $odp = $this->entityManager->getConnection()->getDatabasePlatform();
+ $this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
+
+ $query = $this->entityManager->createQuery(
+ 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity'
+ );
+ $query->expireQueryCache(true);
+ $limitQuery = clone $query;
+ $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
+
+ $this->assertEquals(
+ "SELECT DISTINCT ID1, SCLR0 FROM (SELECT COUNT(g0_.id) AS SCLR0, u1_.id AS ID1, g0_.id AS ID2 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id ORDER BY SCLR0 ASC) dctrn_result ORDER BY SCLR0 ASC",
+ $limitQuery->getSql()
+ );
+
+ $this->entityManager->getConnection()->setDatabasePlatform($odp);
+ }
+
+ public function testLimitSubqueryWithMixedSortOracle()
+ {
+ $odp = $this->entityManager->getConnection()->getDatabasePlatform();
+ $this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
+
+ $query = $this->entityManager->createQuery(
+ 'SELECT u, g, COUNT(g.id) AS g_quantity FROM Doctrine\Tests\ORM\Tools\Pagination\User u JOIN u.groups g ORDER BY g_quantity, u.id DESC'
+ );
+ $query->expireQueryCache(true);
+ $limitQuery = clone $query;
+ $limitQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
+
+ $this->assertEquals(
+ "SELECT DISTINCT ID1, SCLR0 FROM (SELECT COUNT(g0_.id) AS SCLR0, u1_.id AS ID1, g0_.id AS ID2 FROM User u1_ INNER JOIN user_group u2_ ON u1_.id = u2_.user_id INNER JOIN groups g0_ ON g0_.id = u2_.group_id ORDER BY SCLR0 ASC, u1_.id DESC) dctrn_result ORDER BY SCLR0 ASC, ID1 DESC",
+ $limitQuery->getSql()
+ );
+
+ $this->entityManager->getConnection()->setDatabasePlatform($odp);
+ }
+
+ public function testLimitSubqueryOracle()
+ {
+ $odp = $this->entityManager->getConnection()->getDatabasePlatform();
+ $this->entityManager->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
+
+ $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, 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()
+ );
+
+ $this->entityManager->getConnection()->setDatabasePlatform($odp);
+ }
public function testCountQuery_MixedResultsWithName()
{
From bf92a40171e98c47a9c607bcded37daa0cb89a93 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Fri, 19 Apr 2013 14:49:32 +0200
Subject: [PATCH 092/332] skip test if php 5.3
---
.../Tests/ORM/Tools/EntityGeneratorTest.php | 42 ++++++++++---------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
index bdf2090ef..f687d06ed 100644
--- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
@@ -458,27 +458,29 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
*/
public function testTraitPropertiesAndMethodsAreNotDuplicated()
{
- if (PHP_VERSION_ID >= 50400) {
- $cmf = new ClassMetadataFactory();
- $em = $this->_getTestEntityManager();
- $cmf->setEntityManager($em);
-
- $user = new DDC2372User();
- $metadata = $cmf->getMetadataFor(get_class($user));
- $metadata->name = $this->_namespace . "\DDC2372User";
- $metadata->namespace = $this->_namespace;
-
- $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
-
- $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php");
- require $this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php";
-
- $reflClass = new \ReflectionClass($metadata->name);
-
- $this->assertSame($reflClass->hasProperty('address'), false);
- $this->assertSame($reflClass->hasMethod('setAddress'), false);
- $this->assertSame($reflClass->hasMethod('getAddress'), false);
+ if (PHP_VERSION_ID < 50400) {
+ $this->markTestSkipped('Traits are not available before php 5.4.');
}
+
+ $cmf = new ClassMetadataFactory();
+ $em = $this->_getTestEntityManager();
+ $cmf->setEntityManager($em);
+
+ $user = new DDC2372User();
+ $metadata = $cmf->getMetadataFor(get_class($user));
+ $metadata->name = $this->_namespace . "\DDC2372User";
+ $metadata->namespace = $this->_namespace;
+
+ $this->_generator->writeEntityClass($metadata, $this->_tmpDir);
+
+ $this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php");
+ require $this->_tmpDir . "/" . $this->_namespace . "/DDC2372User.php";
+
+ $reflClass = new \ReflectionClass($metadata->name);
+
+ $this->assertSame($reflClass->hasProperty('address'), false);
+ $this->assertSame($reflClass->hasMethod('setAddress'), false);
+ $this->assertSame($reflClass->hasMethod('getAddress'), false);
}
/**
From 92b41e017a1d67b355de6d0213e283728756024f Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sat, 20 Apr 2013 10:25:36 +0200
Subject: [PATCH 093/332] [DDC-2407] Fix missing support for UUID and CUSTOM id
generators in Exporter
---
lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
index 65169124c..d40d0786e 100644
--- a/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
+++ b/lib/Doctrine/ORM/Tools/Export/Driver/AbstractExporter.php
@@ -238,6 +238,12 @@ abstract class AbstractExporter
case ClassMetadataInfo::GENERATOR_TYPE_IDENTITY:
return 'IDENTITY';
+
+ case ClassMetadataInfo::GENERATOR_TYPE_UUID:
+ return 'UUID';
+
+ case ClassMetadataInfo::GENERATOR_TYPE_CUSTOM:
+ return 'CUSTOM';
}
}
}
From c2967b35ff81617ad283aca1770c34879be656b3 Mon Sep 17 00:00:00 2001
From: Calum Brodie
Date: Sun, 21 Apr 2013 20:43:48 +0200
Subject: [PATCH 094/332] Update coding standards
Removing underscores from property/method names and change use statements to PSR-2
---
...enting-the-notify-changetracking-policy.rst | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
index a3cc74b8d..b8fd6ff7d 100644
--- a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
+++ b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
@@ -22,21 +22,21 @@ implement the ``NotifyPropertyChanged`` interface from the
.. code-block:: php
_listeners[] = $listener;
+ $this->listeners[] = $listener;
}
/** Notifies listeners of a change. */
- protected function _onPropertyChanged($propName, $oldValue, $newValue) {
- if ($this->_listeners) {
- foreach ($this->_listeners as $listener) {
+ protected function onPropertyChanged($propName, $oldValue, $newValue) {
+ if ($this->listeners) {
+ foreach ($this->listeners as $listener) {
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
}
}
@@ -44,7 +44,7 @@ implement the ``NotifyPropertyChanged`` interface from the
}
Then, in each property setter of concrete, derived domain classes,
-you need to invoke \_onPropertyChanged as follows to notify
+you need to invoke \onPropertyChanged as follows to notify
listeners:
.. code-block:: php
@@ -58,7 +58,7 @@ listeners:
public function setData($data) {
if ($data != $this->data) { // check: is it actually modified?
- $this->_onPropertyChanged('data', $this->data, $data);
+ $this->onPropertyChanged('data', $this->data, $data);
$this->data = $data;
}
}
From a0a133b02c872981e76b02b6dc1c4839f105e757 Mon Sep 17 00:00:00 2001
From: Calum Brodie
Date: Sun, 21 Apr 2013 20:55:54 +0200
Subject: [PATCH 095/332] Removed unneeded escape character
Removed backslash
---
.../cookbook/implementing-the-notify-changetracking-policy.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
index b8fd6ff7d..44035ccf7 100644
--- a/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
+++ b/docs/en/cookbook/implementing-the-notify-changetracking-policy.rst
@@ -44,7 +44,7 @@ implement the ``NotifyPropertyChanged`` interface from the
}
Then, in each property setter of concrete, derived domain classes,
-you need to invoke \onPropertyChanged as follows to notify
+you need to invoke onPropertyChanged as follows to notify
listeners:
.. code-block:: php
From 99ec4dc72cb172dd486efdc3227a231f43477f34 Mon Sep 17 00:00:00 2001
From: EuKov
Date: Tue, 23 Apr 2013 20:46:19 +0300
Subject: [PATCH 096/332] Fixed typo in SQLFilter (use statement ClassMetadata)
---
lib/Doctrine/ORM/Query/Filter/SQLFilter.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/Filter/SQLFilter.php b/lib/Doctrine/ORM/Query/Filter/SQLFilter.php
index 61bc1192d..fc749f151 100644
--- a/lib/Doctrine/ORM/Query/Filter/SQLFilter.php
+++ b/lib/Doctrine/ORM/Query/Filter/SQLFilter.php
@@ -20,7 +20,7 @@
namespace Doctrine\ORM\Query\Filter;
use Doctrine\ORM\EntityManager;
-use Doctrine\ORM\Mapping\ClassMetaData;
+use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\ParameterTypeInferer;
/**
From 408eef1356da8c15fdc0e2d34de4d265db57d743 Mon Sep 17 00:00:00 2001
From: Danny Kopping
Date: Fri, 26 Apr 2013 12:05:50 +0300
Subject: [PATCH 097/332] Fixed entities path
In the tutorial, the user is told to create a new file in the '/src' folder, and the 'entities' folder is never referenced. Updating the SQLite schema according to the tutorial fails with the 'No Metadata Classes to process.' message. Changing the folder to '/src' fixes this, ostensibly.
---
docs/en/tutorials/getting-started.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/tutorials/getting-started.rst b/docs/en/tutorials/getting-started.rst
index 2faea8218..1ff524529 100644
--- a/docs/en/tutorials/getting-started.rst
+++ b/docs/en/tutorials/getting-started.rst
@@ -137,7 +137,7 @@ step:
// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
- $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/entities"), $isDevMode);
+ $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src"), $isDevMode);
// or if you prefer yaml or XML
//$config = Setup::createXMLMetadataConfiguration(array(__DIR__."/config/xml"), $isDevMode);
//$config = Setup::createYAMLMetadataConfiguration(array(__DIR__."/config/yaml"), $isDevMode);
From 7c2da2d5b84b655b78e521b3f1be94e8c48968c7 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 26 Apr 2013 16:11:04 -0300
Subject: [PATCH 098/332] Fix DDC-2415
---
.../ORM/Mapping/ClassMetadataFactory.php | 4 +
.../ORM/Functional/Ticket/DDC2415Test.php | 106 ++++++++++++++++++
2 files changed, 110 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
index a1da3ffcf..9320d1b6d 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php
@@ -103,6 +103,10 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
$class->setLifecycleCallbacks($parent->lifecycleCallbacks);
$class->setChangeTrackingPolicy($parent->changeTrackingPolicy);
+ if ( ! empty($parent->customGeneratorDefinition)) {
+ $class->setCustomGeneratorDefinition($parent->customGeneratorDefinition);
+ }
+
if ($parent->isMappedSuperclass) {
$class->setCustomRepositoryClass($parent->customRepositoryClassName);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php
new file mode 100644
index 000000000..a440007a0
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2415Test.php
@@ -0,0 +1,106 @@
+_em->getConfiguration()->setMetadataDriverImpl(new StaticPHPDriver(array()));
+
+ $this->_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2415ParentEntity'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2415ChildEntity'),
+ ));
+ }
+
+ public function testTicket()
+ {
+ $parentMetadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2415ParentEntity');
+ $childMetadata = $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2415ChildEntity');
+
+ $this->assertEquals($parentMetadata->generatorType, $childMetadata->generatorType);
+ $this->assertEquals($parentMetadata->customGeneratorDefinition, $childMetadata->customGeneratorDefinition);
+ $this->assertEquals('Doctrine\Tests\ORM\Functional\Ticket\DDC2415Generator', $parentMetadata->customGeneratorDefinition['class']);
+
+ $e1 = new DDC2415ChildEntity("ChildEntity 1");
+ $e2 = new DDC2415ChildEntity("ChildEntity 2");
+
+ $this->_em->persist($e1);
+ $this->_em->persist($e2);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $this->assertEquals(md5($e1->getName()), $e1->getId());
+ $this->assertEquals(md5($e2->getName()), $e2->getId());
+ }
+}
+
+class DDC2415ParentEntity
+{
+ protected $id;
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public static function loadMetadata(ClassMetadataInfo $metadata)
+ {
+ $metadata->mapField(array (
+ 'id' => true,
+ 'fieldName' => 'id',
+ 'type' => 'string',
+ ));
+
+ $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_CUSTOM);
+ $metadata->setCustomGeneratorDefinition(array(
+ 'class' => 'Doctrine\Tests\ORM\Functional\Ticket\DDC2415Generator'
+ ));
+
+ $metadata->isMappedSuperclass = true;
+ }
+}
+
+class DDC2415ChildEntity extends DDC2415ParentEntity
+{
+ protected $name;
+
+ public function __construct($name)
+ {
+ $this->name = $name;
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public static function loadMetadata(ClassMetadataInfo $metadata)
+ {
+ $metadata->mapField(array (
+ 'fieldName' => 'name',
+ 'type' => 'string',
+ ));
+ }
+}
+
+class DDC2415Generator extends AbstractIdGenerator
+{
+ public function generate(EntityManager $em, $entity)
+ {
+ return md5($entity->getName());
+ }
+}
\ No newline at end of file
From 5cdc73e13bf03db1435088359df8925d7b348743 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Sun, 28 Apr 2013 16:35:50 -0300
Subject: [PATCH 099/332] Fix DDC-2409
---
lib/Doctrine/ORM/UnitOfWork.php | 2 +-
.../ORM/Functional/Ticket/DDC2409Test.php | 72 +++++++++++++++++++
2 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 1d36718b9..4744a005d 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -1851,7 +1851,7 @@ class UnitOfWork implements PropertyChangedListener
// do not merge fields marked lazy that have not been fetched.
continue;
} else if ( ! $assoc2['isCascadeMerge']) {
- if ($this->getEntityState($other, self::STATE_DETACHED) !== self::STATE_MANAGED) {
+ if (($otherState = $this->getEntityState($other)) !== self::STATE_MANAGED && $otherState !== self::STATE_NEW) {
$targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
$relatedId = $targetClass->getIdentifierValues($other);
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php
new file mode 100644
index 000000000..c8b85f24f
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2409Test.php
@@ -0,0 +1,72 @@
+useModelSet('cms');
+ parent::setUp();
+ }
+
+ public function testIssue()
+ {
+ $em = $this->_em;
+ $uow = $em->getUnitOfWork();
+
+ $originalArticle = new CmsArticle();
+ $originalUser = new CmsUser();
+
+ $originalArticle->topic = 'Unit Test';
+ $originalArticle->text = 'How to write a test';
+
+ $originalUser->name = 'Doctrine Bot';
+ $originalUser->username = 'DoctrineBot';
+ $originalUser->status = 'active';
+
+ $originalUser->addArticle($originalArticle);
+
+ $em->persist($originalUser);
+ $em->persist($originalArticle);
+ $em->flush();
+ $em->clear();
+
+ $article = $em->find('Doctrine\Tests\Models\CMS\CmsArticle', $originalArticle->id);
+ $user = new CmsUser();
+
+ $user->name = 'Doctrine Bot 2.0';
+ $user->username = 'BotDoctrine2';
+ $user->status = 'new';
+
+ $article->setAuthor($user);
+
+ $this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($originalArticle));
+ $this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($originalUser));
+ $this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($article));
+ $this->assertEquals(UnitOfWork::STATE_NEW, $uow->getEntityState($user));
+
+ $em->detach($user);
+ $em->detach($article);
+
+ $userMerged = $em->merge($user);
+ $articleMerged = $em->merge($article);
+
+ $this->assertEquals(UnitOfWork::STATE_NEW, $uow->getEntityState($user));
+ $this->assertEquals(UnitOfWork::STATE_DETACHED, $uow->getEntityState($article));
+ $this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($userMerged));
+ $this->assertEquals(UnitOfWork::STATE_MANAGED, $uow->getEntityState($articleMerged));
+
+ $this->assertNotSame($user, $userMerged);
+ $this->assertNotSame($article, $articleMerged);
+ $this->assertNotSame($userMerged, $articleMerged->user);
+ $this->assertSame($user, $articleMerged->user);
+ }
+}
\ No newline at end of file
From 34adb16ee85deb0e26caab0eeeecbcf7ae7752de Mon Sep 17 00:00:00 2001
From: Asmir Mustafic
Date: Mon, 29 Apr 2013 10:29:58 +0200
Subject: [PATCH 100/332] indexby ddc117 tests
---
.../Tests/Models/DDC117/DDC117Article.php | 10 +++++++---
.../ORM/Functional/Ticket/DDC117Test.php | 15 +++++++++++++++
.../ORM/Hydration/ResultSetMappingTest.php | 19 +++++++++----------
3 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
index d77bb942b..655ac3611 100644
--- a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
+++ b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
@@ -24,12 +24,12 @@ class DDC117Article
private $details;
/**
- * @OneToMany(targetEntity="DDC117Translation", mappedBy="article", cascade={"persist", "remove"})
+ * @OneToMany(targetEntity="DDC117Translation", mappedBy="article", indexBy="language", cascade={"persist", "remove"})
*/
private $translations;
/**
- * @OneToMany(targetEntity="DDC117Link", mappedBy="source")
+ * @OneToMany(targetEntity="DDC117Link", mappedBy="source", indexBy="target_id")
*/
private $links;
@@ -75,6 +75,10 @@ class DDC117Article
return $this->details;
}
+ public function getLinks()
+ {
+ return $this->links;
+ }
public function resetText()
{
$this->details = null;
@@ -84,4 +88,4 @@ class DDC117Article
{
return $this->translations;
}
-}
\ No newline at end of file
+}
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php
index 34e329465..6673afd1a 100644
--- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC117Test.php
@@ -8,6 +8,7 @@ use Doctrine\Tests\Models\DDC117\DDC117Reference;
use Doctrine\Tests\Models\DDC117\DDC117Translation;
use Doctrine\Tests\Models\DDC117\DDC117ApproveChanges;
use Doctrine\Tests\Models\DDC117\DDC117Editor;
+use Doctrine\Tests\Models\DDC117\DDC117Link;
require_once __DIR__ . '/../../../TestInit.php';
@@ -30,6 +31,9 @@ class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->persist($this->article2);
$this->_em->flush();
+ $link = new DDC117Link($this->article1, $this->article2, "Link-Description");
+ $this->_em->persist($link);
+
$this->reference = new DDC117Reference($this->article1, $this->article2, "Test-Description");
$this->_em->persist($this->reference);
@@ -479,4 +483,15 @@ class DDC117Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($reference));
}
+ /**
+ * @group DDC-117
+ */
+ public function testIndexByOnCompositeKeyField()
+ {
+ $article = $this->_em->find("Doctrine\Tests\Models\DDC117\DDC117Article", $this->article1->id());
+
+ $this->assertInstanceOf('Doctrine\Tests\Models\DDC117\DDC117Article', $article);
+ $this->assertEquals(1, count($article->getLinks()));
+ $this->assertTrue($article->getLinks()->offsetExists($this->article2->id()));
+ }
}
diff --git a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
index fac93b6e6..700e3fe05 100644
--- a/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
+++ b/tests/Doctrine/Tests/ORM/Hydration/ResultSetMappingTest.php
@@ -255,19 +255,18 @@ class ResultSetMappingTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('status'));
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $rsm->getDeclaringClass('username'));
}
-
+ /**
+ * @group DDC-117
+ */
public function testIndexByMetadataColumn()
{
- $rms = $this->_rsm;
- $rms->addEntityResult('Doctrine\Tests\Models\Legacy\LegacyUser', 'u')
- ->addJoinedEntityResult('Doctrine\Tests\Models\Legacy', 'lu', 'u', '_references')
- ->addMetaResult('lu', '_source', '_source', true)
- ->addMetaResult('lu', '_target', '_target', true)
- ->addIndexBy('lu', '_source');
-
-
- $this->assertTrue($rms->hasIndexBy('lu'));
+ $this->_rsm->addEntityResult('Doctrine\Tests\Models\Legacy\LegacyUser', 'u');
+ $this->_rsm->addJoinedEntityResult('Doctrine\Tests\Models\Legacy', 'lu', 'u', '_references');
+ $this->_rsm->addMetaResult('lu', '_source', '_source', true);
+ $this->_rsm->addMetaResult('lu', '_target', '_target', true);
+ $this->_rsm->addIndexBy('lu', '_source');
+ $this->assertTrue($this->_rsm->hasIndexBy('lu'));
}
}
From 2ca24375e417855b8f4adbc4a885c2b3e8424116 Mon Sep 17 00:00:00 2001
From: Asmir Mustafic
Date: Mon, 29 Apr 2013 10:32:40 +0200
Subject: [PATCH 101/332] no lang
---
tests/Doctrine/Tests/Models/DDC117/DDC117Article.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
index 655ac3611..e1df91c9a 100644
--- a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
+++ b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
@@ -24,7 +24,7 @@ class DDC117Article
private $details;
/**
- * @OneToMany(targetEntity="DDC117Translation", mappedBy="article", indexBy="language", cascade={"persist", "remove"})
+ * @OneToMany(targetEntity="DDC117Translation", mappedBy="article", cascade={"persist", "remove"})
*/
private $translations;
From 7abf46af7038559b83d0d3f963685ca04a2fbe17 Mon Sep 17 00:00:00 2001
From: Asmir Mustafic
Date: Mon, 29 Apr 2013 11:03:55 +0200
Subject: [PATCH 102/332] cascade remove persist on links
---
tests/Doctrine/Tests/Models/DDC117/DDC117Article.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
index e1df91c9a..9d57b5652 100644
--- a/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
+++ b/tests/Doctrine/Tests/Models/DDC117/DDC117Article.php
@@ -29,7 +29,7 @@ class DDC117Article
private $translations;
/**
- * @OneToMany(targetEntity="DDC117Link", mappedBy="source", indexBy="target_id")
+ * @OneToMany(targetEntity="DDC117Link", mappedBy="source", indexBy="target_id", cascade={"persist", "remove"})
*/
private $links;
From 1f08acb5760135f51cb341779df2326e6f25a8a4 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 10:42:28 +0200
Subject: [PATCH 103/332] [DBAL-483] Pass default values to DBAL mapping layer
correctly to fix default comparision bug.
---
lib/Doctrine/ORM/Tools/SchemaTool.php | 20 ++-----
.../ORM/Functional/SchemaTool/DBAL483Test.php | 56 +++++++++++++++++++
.../ORM/Functional/SchemaTool/DDC214Test.php | 8 +--
3 files changed, 65 insertions(+), 19 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php
diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php
index f66a49d15..d6f6fc960 100644
--- a/lib/Doctrine/ORM/Tools/SchemaTool.php
+++ b/lib/Doctrine/ORM/Tools/SchemaTool.php
@@ -398,22 +398,14 @@ class SchemaTool
}
if (isset($mapping['options'])) {
- if (isset($mapping['options']['comment'])) {
- $options['comment'] = $mapping['options']['comment'];
+ $knownOptions = array('comment', 'unsigned', 'fixed', 'default');
- unset($mapping['options']['comment']);
- }
+ foreach ($knownOptions as $knownOption) {
+ if ( isset($mapping['options'][$knownOption])) {
+ $options[$knownOption] = $mapping['options'][$knownOption];
- 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']);
+ unset($mapping['options'][$knownOption]);
+ }
}
$options['customSchemaOptions'] = $mapping['options'];
diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php
new file mode 100644
index 000000000..0c76edf73
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DBAL483Test.php
@@ -0,0 +1,56 @@
+_em->getConnection();
+
+ $this->schemaTool = new Tools\SchemaTool($this->_em);
+ }
+
+ /**
+ * @group DBAL-483
+ */
+ public function testDefaultValueIsComparedCorrectly()
+ {
+ $class = $this->_em->getClassMetadata(__NAMESPACE__ . '\\DBAL483Default');
+
+ $this->schemaTool->createSchema(array($class));
+
+ $updateSql = $this->schemaTool->getUpdateSchemaSql(array($class));
+
+ $updateSql = array_filter($updateSql, function ($sql) {
+ return strpos($sql, 'DBAL483') !== false;
+ });
+
+ $this->assertEquals(0, count($updateSql));
+ }
+}
+
+/**
+ * @Entity
+ */
+class DBAL483Default
+{
+ /**
+ * @Id @Column(type="integer") @GeneratedValue
+ */
+ public $id;
+
+ /**
+ * @Column(type="integer", options={"default": 0})
+ */
+ public $num;
+
+ /**
+ * @Column(type="string", options={"default": "foo"})
+ */
+ public $str = "foo";
+}
diff --git a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php
index 9b428c71e..22d2b1f8e 100644
--- a/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php
+++ b/tests/Doctrine/Tests/ORM/Functional/SchemaTool/DDC214Test.php
@@ -4,9 +4,6 @@ namespace Doctrine\Tests\ORM\Functional\SchemaTool;
use Doctrine\ORM\Tools;
-
-require_once __DIR__ . '/../../../TestInit.php';
-
/**
* WARNING: This test should be run as last test! It can affect others very easily!
*/
@@ -15,7 +12,8 @@ class DDC214Test extends \Doctrine\Tests\OrmFunctionalTestCase
private $classes = array();
private $schemaTool = null;
- public function setUp() {
+ public function setUp()
+ {
parent::setUp();
$conn = $this->_em->getConnection();
@@ -88,4 +86,4 @@ class DDC214Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, count($sql), "SQL: " . implode(PHP_EOL, $sql));
}
-}
\ No newline at end of file
+}
From 6505c96ec47538f24f460adf5af8298e7e0de112 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 10:58:44 +0200
Subject: [PATCH 104/332] Simplify condition of previous commit (5cdc73e)
---
lib/Doctrine/ORM/UnitOfWork.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 4744a005d..c1065dba2 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -1851,7 +1851,7 @@ class UnitOfWork implements PropertyChangedListener
// do not merge fields marked lazy that have not been fetched.
continue;
} else if ( ! $assoc2['isCascadeMerge']) {
- if (($otherState = $this->getEntityState($other)) !== self::STATE_MANAGED && $otherState !== self::STATE_NEW) {
+ if ($this->getEntityState($other) === self::STATE_DETACHED) {
$targetClass = $this->em->getClassMetadata($assoc2['targetEntity']);
$relatedId = $targetClass->getIdentifierValues($other);
@@ -1862,6 +1862,7 @@ class UnitOfWork implements PropertyChangedListener
$this->registerManaged($other, $relatedId, array());
}
}
+
$prop->setValue($managedCopy, $other);
}
} else {
From 640a8e58c74bc0ed3b24b8c037f731f4dd2c4c14 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 18:46:41 +0200
Subject: [PATCH 105/332] [DDC-2106] Fix entity as parameter value when its
managed but not yet with identifier.
---
.../ORM/Persisters/BasicEntityPersister.php | 11 +---
lib/Doctrine/ORM/UnitOfWork.php | 2 +-
.../ORM/Functional/Ticket/DDC2106Test.php | 64 +++++++++++++++++++
3 files changed, 66 insertions(+), 11 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index 176eb38f8..8d2aa5236 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -1848,16 +1848,7 @@ class BasicEntityPersister
return $value;
}
- if ($this->em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
- $idValues = $this->em->getUnitOfWork()->getEntityIdentifier($value);
-
- return reset($idValues);
- }
-
- $class = $this->em->getClassMetadata(get_class($value));
- $idValues = $class->getIdentifierValues($value);
-
- return reset($idValues);
+ return $this->em->getUnitOfWork()->getSingleIdentifierValue($value);
}
/**
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index c1065dba2..498c4a699 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -2860,7 +2860,7 @@ class UnitOfWork implements PropertyChangedListener
throw ORMInvalidArgumentException::invalidCompositeIdentifier();
}
- $values = ($this->getEntityState($entity) === UnitOfWork::STATE_MANAGED)
+ $values = $this->isInIdentityMap($entity)
? $this->getEntityIdentifier($entity)
: $class->getIdentifierValues($entity);
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php
new file mode 100644
index 000000000..0de386f9a
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2106Test.php
@@ -0,0 +1,64 @@
+_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2106Entity'),
+ ));
+ }
+
+ public function testDetachedEntityAsId()
+ {
+ // We want an uninitialized PersistentCollection $entity->children
+ $entity = new DDC2106Entity();
+ $this->_em->persist($entity);
+ $this->_em->flush();
+ $this->_em->detach($entity);
+ $entity = $this->_em->getRepository(__NAMESPACE__ . '\DDC2106Entity')->findOneBy(array());
+
+ // ... and a managed entity without id
+ $entityWithoutId = new DDC2106Entity();
+ $this->_em->persist($entityWithoutId);
+
+ $criteria = Criteria::create()->where(Criteria::expr()->eq('parent', $entityWithoutId));
+ $entity->children->matching($criteria)->count();
+ }
+}
+
+/**
+ * @Entity
+ */
+class DDC2106Entity
+{
+ /**
+ * @Id
+ * @GeneratedValue(strategy="IDENTITY")
+ * @Column(type="integer")
+ */
+ public $id;
+
+ /** @ManyToOne(targetEntity="DDC2106Entity", inversedBy="children") */
+ public $parent;
+
+ /**
+ * @OneToMany(targetEntity="DDC2106Entity", mappedBy="parent", cascade={"persist"})
+ */
+ public $children;
+
+ public function __construct()
+ {
+ $this->children = new \Doctrine\Common\Collections\ArrayCollection;
+ }
+}
+
From 131164b7f6082bb3f50176e3edb6be9966273271 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 19:39:21 +0200
Subject: [PATCH 106/332] [DDC-1984] Throw exception if passing null into
UnitOfWork#lock() - which can happen when EntityManager#find() tries to lock
entity that was just deleted by another process.
---
lib/Doctrine/ORM/UnitOfWork.php | 4 ++++
tests/Doctrine/Tests/ORM/UnitOfWorkTest.php | 9 +++++++++
2 files changed, 13 insertions(+)
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 498c4a699..b45e4921b 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -2270,6 +2270,10 @@ class UnitOfWork implements PropertyChangedListener
*/
public function lock($entity, $lockMode, $lockVersion = null)
{
+ if ($entity === null) {
+ throw new \InvalidArgumentException("No entity passed to UnitOfWork#lock().");
+ }
+
if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) {
throw ORMInvalidArgumentException::entityNotManaged($entity);
}
diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
index 9a645d52e..97f60f859 100644
--- a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
+++ b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
@@ -220,6 +220,15 @@ class UnitOfWorkTest extends \Doctrine\Tests\OrmTestCase
// This commit should not raise an E_NOTICE
$this->_unitOfWork->commit();
}
+
+ /**
+ * @group DDC-1984
+ */
+ public function testLockWithoutEntityThrowsException()
+ {
+ $this->setExpectedException('InvalidArgumentException');
+ $this->_unitOfWork->lock(null, null, null);
+ }
}
/**
From 0864ab8adac5c31d5ba97f0eb6792e5431a75b70 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 20:30:45 +0200
Subject: [PATCH 107/332] [DDC-1998] Pass types to Connection#delete() to allow
custom conversions to happen.
---
.../ORM/Persisters/BasicEntityPersister.php | 28 ++++-
.../ORM/Functional/Ticket/DDC1998Test.php | 102 ++++++++++++++++++
2 files changed, 127 insertions(+), 3 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index 8d2aa5236..96f144934 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -560,13 +560,35 @@ class BasicEntityPersister
*/
public function delete($entity)
{
+ $class = $this->class;
+ $em = $this->em;
+
$identifier = $this->em->getUnitOfWork()->getEntityIdentifier($entity);
- $tableName = $this->quoteStrategy->getTableName($this->class, $this->platform);
- $idColumns = $this->quoteStrategy->getIdentifierColumnNames($this->class, $this->platform);
+ $tableName = $this->quoteStrategy->getTableName($class, $this->platform);
+ $idColumns = $this->quoteStrategy->getIdentifierColumnNames($class, $this->platform);
$id = array_combine($idColumns, $identifier);
+ $types = array_map(function ($identifier) use ($class, $em) {
+ if (isset($class->fieldMappings[$identifier])) {
+ return $class->fieldMappings[$identifier]['type'];
+ }
+
+ $targetMapping = $em->getClassMetadata($class->associationMappings[$identifier]['targetEntity']);
+
+ if (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])) {
+ return $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
+ }
+
+ if (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])) {
+ $types[] = $targetMapping->associationMappings[$targetMapping->identifier[0]]['type'];
+ }
+
+ throw ORMException::unrecognizedField($targetMapping->identifier[0]);
+
+ }, $class->identifier);
+
$this->deleteJoinTableRecords($identifier);
- $this->conn->delete($tableName, $id);
+ $this->conn->delete($tableName, $id, $types);
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php
new file mode 100644
index 000000000..95e0a76f5
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1998Test.php
@@ -0,0 +1,102 @@
+_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1998Entity'),
+ ));
+
+ $entity = new DDC1998Entity();
+ $entity->id = new DDC1998Id("foo");
+
+ $this->_em->persist($entity);
+ $this->_em->flush();
+
+ $entity->num++;
+
+ $this->_em->flush();
+
+ $this->_em->remove($entity);
+ $this->_em->flush();
+ $this->_em->clear();
+
+
+ $found = $this->_em->find(__NAMESPACE__ . '\\DDC1998Entity', $entity->id);
+ $this->assertNull($found);
+
+ $found = $this->_em->find(__NAMESPACE__ . '\\DDC1998Entity', "foo");
+ $this->assertNull($found);
+
+ $this->assertEquals(0, count($this->_em->getRepository(__NAMESPACE__ . '\\DDC1998Entity')->findAll()));
+ }
+}
+
+/**
+ * @Entity
+ */
+class DDC1998Entity
+{
+ /**
+ * @Id @Column(type="ddc1998")
+ */
+ public $id;
+
+ /**
+ * @Column(type="integer")
+ */
+ public $num = 0;
+}
+
+class DDC1998Type extends StringType
+{
+ const NAME = 'ddc1998';
+
+ /**
+ * {@inheritdoc}
+ */
+ public function convertToDatabaseValue($value, AbstractPlatform $platform)
+ {
+ return (string)$value;
+ }
+
+ public function convertToPhpValue($value, AbstractPlatform $platform)
+ {
+ return new DDC1998Id($value);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return self::NAME;
+ }
+}
+
+class DDC1998Id
+{
+ private $val;
+
+ public function __construct($val)
+ {
+ $this->val = $val;
+ }
+
+ public function __toString()
+ {
+ return $this->val;
+ }
+}
From 6d02c7e1a59a6d19d695b3c564a452d138478e1a Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Wed, 1 May 2013 23:10:13 +0200
Subject: [PATCH 108/332] [DDC-2136] Fix exporting to YAML and XML with
assocation keys.
---
.travis.yml | 4 ++--
composer.json | 3 +++
lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php | 1 +
.../ORM/Tools/Export/Driver/XmlExporter.php | 14 +++++++++++++-
.../ORM/Tools/Export/Driver/YamlExporter.php | 8 +++++---
.../Export/AbstractClassMetadataExporterTest.php | 2 +-
6 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 177b5ba6c..a97513344 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,6 +19,6 @@ before_script:
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests;' -U postgres; fi"
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database doctrine_tests_tmp;' -U postgres; fi"
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
- - composer install --prefer-source
+ - composer install --prefer-source --dev
-script: phpunit --configuration tests/travis/$DB.travis.xml
\ No newline at end of file
+script: phpunit --configuration tests/travis/$DB.travis.xml
diff --git a/composer.json b/composer.json
index 52960133d..f74058bac 100644
--- a/composer.json
+++ b/composer.json
@@ -19,6 +19,9 @@
"doctrine/dbal": ">=2.4-beta,<2.5-dev",
"symfony/console": "2.*"
},
+ "require-dev": {
+ "symfony/yaml": "2.1"
+ },
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},
diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
index 5bd58ef79..9e8818a16 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php
@@ -307,6 +307,7 @@ class YamlDriver extends FileDriver
}
}
+
// Evaluate oneToOne relationships
if (isset($element['oneToOne'])) {
foreach ($element['oneToOne'] as $name => $oneToOneElement) {
diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
index 2d9cb4d3c..ccbbfc3be 100644
--- a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
+++ b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
@@ -129,6 +129,15 @@ class XmlExporter extends AbstractExporter
}
}
+ foreach ($metadata->associationMappings as $name => $assoc) {
+ if (isset($assoc['id']) && $assoc['id']) {
+ $id[$name] = array(
+ 'fieldName' => $name,
+ 'associationKey' => true
+ );
+ }
+ }
+
if ( ! $metadata->isIdentifierComposite && $idGeneratorType = $this->_getIdGeneratorTypeString($metadata->generatorType)) {
$id[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
}
@@ -137,7 +146,10 @@ class XmlExporter extends AbstractExporter
foreach ($id as $field) {
$idXml = $root->addChild('id');
$idXml->addAttribute('name', $field['fieldName']);
- $idXml->addAttribute('type', $field['type']);
+
+ if (isset($field['type'])) {
+ $idXml->addAttribute('type', $field['type']);
+ }
if (isset($field['columnName'])) {
$idXml->addAttribute('column', $field['columnName']);
diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
index ab5e5f968..45c431925 100644
--- a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
+++ b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php
@@ -110,9 +110,7 @@ class YamlExporter extends AbstractExporter
$ids[$metadata->getSingleIdentifierFieldName()]['generator']['strategy'] = $idGeneratorType;
}
- if ($ids) {
- $array['fields'] = $ids;
- }
+ $array['id'] = $ids;
if ($fieldMappings) {
if ( ! isset($array['fields'])) {
@@ -152,6 +150,10 @@ class YamlExporter extends AbstractExporter
'cascade' => $cascade,
);
+ if (isset($mapping['id']) && $mapping['id'] === true) {
+ $array['id'][$name]['associationKey'] = true;
+ }
+
if ($associationMapping['type'] & ClassMetadataInfo::TO_ONE) {
$joinColumns = $associationMapping['joinColumns'];
$newJoinColumns = array();
diff --git a/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php b/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php
index 37e0f0ca2..060345c83 100644
--- a/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/Export/AbstractClassMetadataExporterTest.php
@@ -178,7 +178,7 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
*/
public function testIdentifierIsExported($class)
{
- $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_IDENTITY, $class->generatorType);
+ $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_IDENTITY, $class->generatorType, "Generator Type wrong");
$this->assertEquals(array('id'), $class->identifier);
$this->assertTrue(isset($class->fieldMappings['id']['id']) && $class->fieldMappings['id']['id'] === true);
From 59fff4ddef236d373ae4d08e34114c9757cdf3d2 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Fri, 3 May 2013 13:32:42 +0200
Subject: [PATCH 109/332] Fix Docs build
---
docs/en/conf.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/conf.py b/docs/en/conf.py
index 4e0c87b50..5155ac9a6 100644
--- a/docs/en/conf.py
+++ b/docs/en/conf.py
@@ -22,7 +22,7 @@ sys.path.append(os.path.abspath('_exts'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['configurationblock', 'sphinx.ext.linkcode']
+extensions = ['configurationblock']
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
From 9adc45767d31d90790ff25675faa2d6da86d67d8 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sat, 4 May 2013 12:58:06 +0200
Subject: [PATCH 110/332] [DDC-2426] Missing length attribute in
doctrine-mapping.xsd for tag.
---
doctrine-mapping.xsd | 1 +
1 file changed, 1 insertion(+)
diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd
index 243bfcd5b..89c11a894 100644
--- a/doctrine-mapping.xsd
+++ b/doctrine-mapping.xsd
@@ -345,6 +345,7 @@
+
From 5e19e1bed3ee593e38c7a7d882232d43df710d7c Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Sat, 4 May 2013 13:36:37 +0200
Subject: [PATCH 111/332] [DDC-2267] Allow EntityManager#flush($entity) to be
called on entities scheduled for removal.
---
lib/Doctrine/ORM/UnitOfWork.php | 8 +++++---
.../Tests/ORM/Functional/BasicFunctionalTest.php | 13 +++++++++++--
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index b45e4921b..68fde5d2c 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -421,13 +421,15 @@ class UnitOfWork implements PropertyChangedListener
*/
private function computeSingleEntityChangeSet($entity)
{
- if ( $this->getEntityState($entity) !== self::STATE_MANAGED) {
- throw new \InvalidArgumentException("Entity has to be managed for single computation " . self::objToStr($entity));
+ $state = $this->getEntityState($entity);
+
+ if ($state !== self::STATE_MANAGED && $state !== self::STATE_REMOVED) {
+ throw new \InvalidArgumentException("Entity has to be managed or scheduled for removal for single computation " . self::objToStr($entity));
}
$class = $this->em->getClassMetadata(get_class($entity));
- if ($class->isChangeTrackingDeferredImplicit()) {
+ if ($state === self::STATE_MANAGED && $class->isChangeTrackingDeferredImplicit()) {
$this->persist($entity);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php
index 221bc011f..2fb830a92 100644
--- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php
@@ -1118,7 +1118,7 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user->username = 'domnikl';
$user->status = 'developer';
- $this->setExpectedException('InvalidArgumentException', 'Entity has to be managed for single computation');
+ $this->setExpectedException('InvalidArgumentException', 'Entity has to be managed or scheduled for removal for single computation');
$this->_em->flush($user);
}
@@ -1202,8 +1202,9 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
/**
* @group DDC-720
* @group DDC-1612
+ * @group DDC-2267
*/
- public function testFlushSingleNewEntity()
+ public function testFlushSingleNewEntityThenRemove()
{
$user = new CmsUser;
$user->name = 'Dominik';
@@ -1212,6 +1213,14 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->persist($user);
$this->_em->flush($user);
+
+ $userId = $user->id;
+
+ $this->_em->remove($user);
+ $this->_em->flush($user);
+ $this->_em->clear();
+
+ $this->assertNull($this->_em->find(get_class($user), $userId));
}
/**
From 33888f1b084c24d3c209888d5c70f5d2c9f4c043 Mon Sep 17 00:00:00 2001
From: Vladislav Vlastovskiy
Date: Thu, 9 May 2013 03:30:48 +0400
Subject: [PATCH 112/332] Swapped places indexBy and condition in accordance
with EBNF
---
lib/Doctrine/ORM/Query/Expr/Join.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Query/Expr/Join.php b/lib/Doctrine/ORM/Query/Expr/Join.php
index c7ca935eb..7a59e247a 100644
--- a/lib/Doctrine/ORM/Query/Expr/Join.php
+++ b/lib/Doctrine/ORM/Query/Expr/Join.php
@@ -139,7 +139,7 @@ class Join
{
return strtoupper($this->joinType) . ' JOIN ' . $this->join
. ($this->alias ? ' ' . $this->alias : '')
- . ($this->condition ? ' ' . strtoupper($this->conditionType) . ' ' . $this->condition : '')
- . ($this->indexBy ? ' INDEX BY ' . $this->indexBy : '');
+ . ($this->indexBy ? ' INDEX BY ' . $this->indexBy : '')
+ . ($this->condition ? ' ' . strtoupper($this->conditionType) . ' ' . $this->condition : '');
}
}
From 3997d0df8782927e38dd2bf8bf263c4832bb1d6f Mon Sep 17 00:00:00 2001
From: Vladislav Vlastovskiy
Date: Thu, 9 May 2013 03:32:28 +0400
Subject: [PATCH 113/332] Added test complex inner join with indexBy
---
tests/Doctrine/Tests/ORM/QueryBuilderTest.php | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php
index 19e0c0e95..6975c1510 100644
--- a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php
+++ b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php
@@ -141,6 +141,19 @@ class QueryBuilderTest extends \Doctrine\Tests\OrmTestCase
'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a ON u.id = a.author_id'
);
}
+
+ public function testComplexInnerJoinWithIndexBy()
+ {
+ $qb = $this->_em->createQueryBuilder()
+ ->select('u', 'a')
+ ->from('Doctrine\Tests\Models\CMS\CmsUser', 'u')
+ ->innerJoin('u.articles', 'a', 'ON', 'u.id = a.author_id', 'a.name');
+
+ $this->assertValidQueryBuilder(
+ $qb,
+ 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INDEX BY a.name ON u.id = a.author_id'
+ );
+ }
public function testLeftJoin()
{
From acbafd081b13885bb65f7738682317cc27056c78 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 10:23:12 +0200
Subject: [PATCH 114/332] Add documentation to EntityManager about
instantiation, decoration over inheritance, and some generic introduction.
---
lib/Doctrine/ORM/EntityManager.php | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php
index 53cbf1926..bc0d4ef18 100644
--- a/lib/Doctrine/ORM/EntityManager.php
+++ b/lib/Doctrine/ORM/EntityManager.php
@@ -34,6 +34,28 @@ use Doctrine\Common\Util\ClassUtils;
/**
* The EntityManager is the central access point to ORM functionality.
*
+ * It is a facade to all different ORM subsystems such as UnitOfWork,
+ * Query Language and Repository API. Instantiation is done through
+ * the static create() method. The quickest way to obtain a fully
+ * configured EntityManager is:
+ *
+ * use Doctrine\ORM\Tools\Setup;
+ * use Doctrine\ORM\EntityManager;
+ *
+ * $paths = array('/path/to/entity/mapping/files');
+ *
+ * $config = Setup::createAnnotationMetadataConfiguration($paths);
+ * $dbParams = array('driver' => 'pdo_sqlite', 'memory' => true);
+ * $entityManager = EntityManager::create($dbParams, $config);
+ *
+ * For more information see
+ * {@link http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/configuration.html}
+ *
+ * You should never attempt to inherit from the EntityManager: Inheritance
+ * is not a valid extension point for the EntityManager. Instead you
+ * should take a look at the {@see \Doctrine\ORM\Decorator\EntityManagerDecorator}
+ * and wrap your entity manager in a decorator.
+ *
* @since 2.0
* @author Benjamin Eberlei
* @author Guilherme Blanco
From e3b8ce7737ecd18295db760c4dd1e55037580df4 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 10:55:12 +0200
Subject: [PATCH 115/332] [DDC-2423] Fixed bug with EntityGenerator not
generating fetch="" attribute in association annotations.
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 9 +++++++++
tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php | 3 +++
2 files changed, 12 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 98a65fb98..5a55f0fc9 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -1274,6 +1274,15 @@ public function __construct()
$typeOptions[] = 'orphanRemoval=' . ($associationMapping['orphanRemoval'] ? 'true' : 'false');
}
+ if (isset($associationMapping['fetch']) && $associationMapping['fetch'] !== ClassMetadataInfo::FETCH_LAZY) {
+ $fetchMap = array(
+ ClassMetadataInfo::FETCH_EXTRA_LAZY => 'EXTRA_LAZY',
+ ClassMetadataInfo::FETCH_EAGER => 'EAGER',
+ );
+
+ $typeOptions[] = 'fetch="' . $fetchMap[$associationMapping['fetch']] . '"';
+ }
+
$lines[] = $this->spaces . ' * @' . $this->annotationsPrefix . '' . $type . '(' . implode(', ', $typeOptions) . ')';
if (isset($associationMapping['joinColumns']) && $associationMapping['joinColumns']) {
diff --git a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
index a55b603d5..d8dfa1b56 100644
--- a/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
+++ b/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php
@@ -64,6 +64,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$metadata->mapManyToMany(array(
'fieldName' => 'comments',
'targetEntity' => 'Doctrine\Tests\ORM\Tools\EntityGeneratorComment',
+ 'fetch' => ClassMetadataInfo::FETCH_EXTRA_LAZY,
'joinTable' => array(
'name' => 'book_comment',
'joinColumns' => array(array('name' => 'book_id', 'referencedColumnName' => 'id')),
@@ -223,6 +224,8 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals($cm->identifier, $metadata->identifier);
$this->assertEquals($cm->idGenerator, $metadata->idGenerator);
$this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
+
+ $this->assertEquals(ClassMetadataInfo::FETCH_EXTRA_LAZY, $cm->associationMappings['comments']['fetch']);
}
public function testLoadPrefixedMetadata()
From 7220c3c1251e149b268d73d7d09dc90b9f3656f9 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 12:10:37 +0200
Subject: [PATCH 116/332] [DDC-2387] Fix DatabaseDriver not working with
combinations of composite/association keys.
---
.../ORM/Mapping/Driver/DatabaseDriver.php | 3 +-
.../ORM/Functional/DatabaseDriverTest.php | 47 +---------------
.../ORM/Functional/DatabaseDriverTestCase.php | 55 +++++++++++++++++++
.../ORM/Functional/Ticket/DDC2387Test.php | 30 ++++++++++
4 files changed, 89 insertions(+), 46 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php
diff --git a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
index 15a4e0d2c..007be9639 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
@@ -224,7 +224,8 @@ class DatabaseDriver implements MappingDriver
}
if ($ids) {
- if (count($ids) == 1) {
+ // We need to check for the columns here, because we might have associations as id as well.
+ if (count($primaryKeyColumns) == 1) {
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
index 48140cc56..0c30a0bef 100644
--- a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
@@ -2,12 +2,9 @@
namespace Doctrine\Tests\ORM\Functional;
-require_once __DIR__ . '/../../TestInit.php';
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
-use Doctrine\ORM\Mapping\ClassMetadataInfo,
- Doctrine\Common\Util\Inflector;
-
-class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
+class DatabaseDriverTest extends DatabaseDriverTestCase
{
/**
* @var \Doctrine\DBAL\Schema\AbstractSchemaManager
@@ -148,44 +145,4 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, count($metadatas['DbdriverBaz']->associationMappings), "no association mappings should be detected.");
}
-
- protected function convertToClassMetadata(array $entityTables, array $manyTables = array())
- {
- $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($this->_sm);
- $driver->setTables($entityTables, $manyTables);
-
- $metadatas = array();
- foreach ($driver->getAllClassNames() AS $className) {
- $class = new ClassMetadataInfo($className);
- $driver->loadMetadataForClass($className, $class);
- $metadatas[$className] = $class;
- }
-
- return $metadatas;
- }
-
- /**
- * @param string $className
- * @return ClassMetadata
- */
- protected function extractClassMetadata(array $classNames)
- {
- $classNames = array_map('strtolower', $classNames);
- $metadatas = array();
-
- $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($this->_sm);
- foreach ($driver->getAllClassNames() as $className) {
- if (!in_array(strtolower($className), $classNames)) {
- continue;
- }
- $class = new ClassMetadataInfo($className);
- $driver->loadMetadataForClass($className, $class);
- $metadatas[$className] = $class;
- }
-
- if (count($metadatas) != count($classNames)) {
- $this->fail("Have not found all classes matching the names '" . implode(", ", $classNames) . "' only tables " . implode(", ", array_keys($metadatas)));
- }
- return $metadatas;
- }
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php
new file mode 100644
index 000000000..35fd8b20c
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTestCase.php
@@ -0,0 +1,55 @@
+_em->getConnection()->getSchemaManager();
+ $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($sm);
+ $driver->setTables($entityTables, $manyTables);
+
+ $metadatas = array();
+ foreach ($driver->getAllClassNames() AS $className) {
+ $class = new ClassMetadataInfo($className);
+ $driver->loadMetadataForClass($className, $class);
+ $metadatas[$className] = $class;
+ }
+
+ return $metadatas;
+ }
+
+ /**
+ * @param string $className
+ * @return ClassMetadata
+ */
+ protected function extractClassMetadata(array $classNames)
+ {
+ $classNames = array_map('strtolower', $classNames);
+ $metadatas = array();
+
+ $sm = $this->_em->getConnection()->getSchemaManager();
+ $driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($sm);
+
+ foreach ($driver->getAllClassNames() as $className) {
+ if (!in_array(strtolower($className), $classNames)) {
+ continue;
+ }
+ $class = new ClassMetadataInfo($className);
+ $driver->loadMetadataForClass($className, $class);
+ $metadatas[$className] = $class;
+ }
+
+ if (count($metadatas) != count($classNames)) {
+ $this->fail("Have not found all classes matching the names '" . implode(", ", $classNames) . "' only tables " . implode(", ", array_keys($metadatas)));
+ }
+ return $metadatas;
+ }
+}
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php
new file mode 100644
index 000000000..f74d4e15c
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2387Test.php
@@ -0,0 +1,30 @@
+addColumn('id', 'integer');
+ $product->setPrimaryKey(array('id'));
+
+ $attributes = new \Doctrine\DBAL\Schema\Table('ddc2387_attributes');
+ $attributes->addColumn('product_id', 'integer');
+ $attributes->addColumn('attribute_name', 'string');
+ $attributes->setPrimaryKey(array('product_id', 'attribute_name'));
+ $attributes->addForeignKeyConstraint('ddc2387_product', array('product_id'), array('product_id'));
+
+ $metadata = $this->convertToClassMetadata(array($product, $attributes), array());
+
+ $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_NONE, $metadata['Ddc2387Attributes']->generatorType);
+ $this->assertEquals(ClassMetadataInfo::GENERATOR_TYPE_AUTO, $metadata['Ddc2387Product']->generatorType);
+ }
+}
From 6d5afb18bc814bb578c2326b62ec6bcaa368b6c3 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 13:24:36 +0200
Subject: [PATCH 117/332] [DDC-2430] Prevent Criteria queries using the ID of
an assocation on PersistentCollections, as the in-memory ArrayCollection does
not work with this kind of query. Attention this is a BC-BREAK, that is
necessary to fix potentially very hard to debug bugs. Therefore it is not
merged back into 2.3
---
UPGRADE.md | 14 ++++++++++
lib/Doctrine/ORM/PersistentCollection.php | 6 +----
.../ORM/Persisters/BasicEntityPersister.php | 2 +-
.../ORM/Persisters/PersisterException.php | 20 ++++++++++++++
.../ORM/Persisters/SqlExpressionVisitor.php | 14 +++++++++-
.../ORM/Functional/EntityRepositoryTest.php | 26 +++++++++++++++++--
.../Functional/SingleTableInheritanceTest.php | 19 ++++++++++++--
7 files changed, 90 insertions(+), 11 deletions(-)
create mode 100644 lib/Doctrine/ORM/Persisters/PersisterException.php
diff --git a/UPGRADE.md b/UPGRADE.md
index fe5f52528..0aacaa603 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -28,6 +28,20 @@ Now parenthesis are considered, the previous DQL will generate:
SELECT 100 / (2 * 2) FROM my_entity
+## Compatibility Bugfix in PersistentCollection#matching() breaks BC
+
+In Doctrine 2.3 it was possible to use the new ``matching($criteria)``
+functionality by adding constraints for assocations based on ID:
+
+ Criteria::expr()->eq('association', $assocation->getId());
+
+This functionality does not work on InMemory collections however, because
+in memory criteria compares object values based on reference.
+As of 2.4 the above code will throw an exception. You need to change
+offending code to pass the ``$assocation`` reference directly:
+
+ Criteria::expr()->eq('association', $assocation);
+
# Upgrade to 2.3
## EntityManager#find() not calls EntityRepository#find() anymore
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index b644ec154..53ba1c1f2 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -850,12 +850,8 @@ final class PersistentCollection implements Collection, Selectable
throw new \RuntimeException("Matching Criteria on PersistentCollection only works on OneToMany associations at the moment.");
}
- $id = $this->em
- ->getClassMetadata(get_class($this->owner))
- ->getSingleIdReflectionProperty()
- ->getValue($this->owner);
$builder = Criteria::expr();
- $ownerExpression = $builder->eq($this->backRefFieldName, $id);
+ $ownerExpression = $builder->eq($this->backRefFieldName, $this->owner);
$expression = $criteria->getWhereExpression();
$expression = $expression ? $builder->andX($expression, $ownerExpression) : $ownerExpression;
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index 96f144934..8f921f2b8 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -1583,7 +1583,7 @@ class BasicEntityPersister
return '';
}
- $visitor = new SqlExpressionVisitor($this);
+ $visitor = new SqlExpressionVisitor($this, $this->class);
return $visitor->dispatch($expression);
}
diff --git a/lib/Doctrine/ORM/Persisters/PersisterException.php b/lib/Doctrine/ORM/Persisters/PersisterException.php
new file mode 100644
index 000000000..111455e5b
--- /dev/null
+++ b/lib/Doctrine/ORM/Persisters/PersisterException.php
@@ -0,0 +1,20 @@
+persister = $persister;
+ $this->classMetadata = $classMetadata;
}
/**
@@ -57,6 +65,10 @@ class SqlExpressionVisitor extends ExpressionVisitor
$field = $comparison->getField();
$value = $comparison->getValue()->getValue(); // shortcut for walkValue()
+ if (isset($this->classMetadata->associationMappings[$field]) && ! is_object($value)) {
+ throw PersisterException::matchingAssocationFieldRequiresObject($this->classMetadata->name, $field);
+ }
+
return $this->persister->getSelectConditionStatementSQL($field, $value, null, $comparison->getOperator());
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
index b45eee3d0..48e5f3389 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
@@ -7,8 +7,7 @@ use Doctrine\Tests\Models\CMS\CmsEmail;
use Doctrine\Tests\Models\CMS\CmsAddress;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
use Doctrine\Common\Collections\Criteria;
-
-require_once __DIR__ . '/../../TestInit.php';
+use Doctrine\Common\Collections\ArrayCollection;
/**
* @author robo
@@ -781,6 +780,29 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(4, count($users));
}
+ /**
+ * @group DDC-2430
+ */
+ public function testMatchingCriteriaAssocationByObjectInMemory()
+ {
+ list($userId, $addressId) = $this->loadAssociatedFixture();
+
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $userId);
+
+ $criteria = new Criteria(
+ Criteria::expr()->gte('user', $user)
+ );
+
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
+ $addresses = $repository->matching($criteria);
+
+ $this->assertEquals(1, count($addresses));
+
+ $addresses = new ArrayCollection($repository->findAll());
+
+ $this->assertEquals(1, count($addresses->matching($criteria)));
+ }
+
public function testMatchingCriteriaContainsComparison()
{
$this->loadFixture();
diff --git a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php
index 4254ce3d2..1704c8b4e 100644
--- a/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/SingleTableInheritanceTest.php
@@ -343,17 +343,32 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
$contracts = $repository->matching(new Criteria(
- Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
+ Criteria::expr()->eq('salesPerson', $this->salesPerson)
));
$this->assertEquals(3, count($contracts));
$repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyFixContract");
$contracts = $repository->matching(new Criteria(
- Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
+ Criteria::expr()->eq('salesPerson', $this->salesPerson)
));
$this->assertEquals(1, count($contracts));
}
+ /**
+ * @group DDC-2430
+ */
+ public function testMatchingNonObjectOnAssocationThrowsException()
+ {
+ $this->loadFullFixture();
+
+ $repository = $this->_em->getRepository("Doctrine\Tests\Models\Company\CompanyContract");
+
+ $this->setExpectedException('Doctrine\ORM\Persisters\PersisterException', 'annot match on Doctrine\Tests\Models\Company\CompanyContract::salesPerson with a non-object value.');
+ $contracts = $repository->matching(new Criteria(
+ Criteria::expr()->eq('salesPerson', $this->salesPerson->getId())
+ ));
+ }
+
/**
* @group DDC-834
*/
From dc674f809f3548226f867fb2eaf7c53149a0905a Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 13:40:14 +0200
Subject: [PATCH 118/332] Mention BC BREAK in PersistentCollection#matching()
more prominently.
---
UPGRADE.md | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/UPGRADE.md b/UPGRADE.md
index 0aacaa603..b864d8614 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -1,5 +1,19 @@
# Upgrade to 2.4
+## BC BREAK: Compatibility Bugfix in PersistentCollection#matching()
+
+In Doctrine 2.3 it was possible to use the new ``matching($criteria)``
+functionality by adding constraints for assocations based on ID:
+
+ Criteria::expr()->eq('association', $assocation->getId());
+
+This functionality does not work on InMemory collections however, because
+in memory criteria compares object values based on reference.
+As of 2.4 the above code will throw an exception. You need to change
+offending code to pass the ``$assocation`` reference directly:
+
+ Criteria::expr()->eq('association', $assocation);
+
## Composer is now the default autoloader
The test suite now runs with composer autoloading. Support for PEAR, and tarball autoloading is deprecated.
@@ -28,20 +42,6 @@ Now parenthesis are considered, the previous DQL will generate:
SELECT 100 / (2 * 2) FROM my_entity
-## Compatibility Bugfix in PersistentCollection#matching() breaks BC
-
-In Doctrine 2.3 it was possible to use the new ``matching($criteria)``
-functionality by adding constraints for assocations based on ID:
-
- Criteria::expr()->eq('association', $assocation->getId());
-
-This functionality does not work on InMemory collections however, because
-in memory criteria compares object values based on reference.
-As of 2.4 the above code will throw an exception. You need to change
-offending code to pass the ``$assocation`` reference directly:
-
- Criteria::expr()->eq('association', $assocation);
-
# Upgrade to 2.3
## EntityManager#find() not calls EntityRepository#find() anymore
From f8efd85ae6d3f455bc4b89aad4d37c0988030b06 Mon Sep 17 00:00:00 2001
From: HarmenM
Date: Thu, 9 May 2013 14:49:38 +0300
Subject: [PATCH 119/332] Update annotations-reference.rst
Added missing @JoinColumns in the index
---
docs/en/reference/annotations-reference.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/en/reference/annotations-reference.rst b/docs/en/reference/annotations-reference.rst
index f705cb034..d42fda4e4 100644
--- a/docs/en/reference/annotations-reference.rst
+++ b/docs/en/reference/annotations-reference.rst
@@ -21,6 +21,7 @@ Index
- :ref:`@Id `
- :ref:`@InheritanceType `
- :ref:`@JoinColumn `
+- :ref:`@JoinColumns `
- :ref:`@JoinTable `
- :ref:`@ManyToOne `
- :ref:`@ManyToMany `
From 97622b57bd9fadea77b50e2f5ced717efbac1357 Mon Sep 17 00:00:00 2001
From: Jakub Zalas
Date: Thu, 9 May 2013 15:19:58 +0100
Subject: [PATCH 120/332] Fixed a code block. Sphinx does not like the way code
was indented. Building the documentation raises the following error:
en/cookbook/resolve-target-entity-listener.rst:121: ERROR: Unexpected
indentation.
---
docs/en/cookbook/resolve-target-entity-listener.rst | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/en/cookbook/resolve-target-entity-listener.rst b/docs/en/cookbook/resolve-target-entity-listener.rst
index 71b746602..4a1b3b941 100644
--- a/docs/en/cookbook/resolve-target-entity-listener.rst
+++ b/docs/en/cookbook/resolve-target-entity-listener.rst
@@ -119,8 +119,7 @@ the targetEntity resolution will occur reliably:
$evm = new \Doctrine\Common\EventManager;
$rtel = new \Doctrine\ORM\Tools\ResolveTargetEntityListener;
- $rtel->addResolveTargetEntity('Acme\\InvoiceModule\\Model\\InvoiceSubjectInterface',
- 'Acme\\CustomerModule\\Entity\\Customer', array());
+ $rtel->addResolveTargetEntity('Acme\\InvoiceModule\\Model\\InvoiceSubjectInterface', 'Acme\\CustomerModule\\Entity\\Customer', array());
// Add the ResolveTargetEntityListener
$evm->addEventSubscriber($rtel);
From 1a0adecf291d4cdd7198d464b6c93698e52b90d2 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 16:24:19 +0200
Subject: [PATCH 121/332] [DDC-2335] Add note about filtering schema by regexp
expression to relevant commands help output.
---
.../ORM/Tools/Console/Command/ConvertMappingCommand.php | 6 ++++++
.../ORM/Tools/Console/Command/SchemaTool/CreateCommand.php | 6 ++++++
.../ORM/Tools/Console/Command/SchemaTool/DropCommand.php | 6 ++++++
.../ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php | 6 ++++++
4 files changed, 24 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
index cec5d26a3..020a4afaf 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
@@ -98,6 +98,12 @@ semantical operations on associations such as cascade.
Hint: There is no need to convert YAML or XML mapping files to annotations
every time you make changes. All mapping drivers are first class citizens
in Doctrine 2 and can be used as runtime mapping for the ORM.
+
+Hint: If you have a database with tables that should not be managed
+by the ORM, you can use a DBAL functionality to filter the tables and sequences down
+on a global level:
+
+ \$config->setFilterSchemaAssetsExpression(\$regexp);
EOT
);
}
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
index 7aaef2d55..610f25c95 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
@@ -55,6 +55,12 @@ class CreateCommand extends AbstractCommand
))
->setHelp(<<Hint: If you have a database with tables that should not be managed
+by the ORM, you can use a DBAL functionality to filter the tables and sequences down
+on a global level:
+
+ \$config->setFilterSchemaAssetsExpression(\$regexp);
EOT
);
}
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
index 596f45adf..ac003b991 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
@@ -64,6 +64,12 @@ class DropCommand extends AbstractCommand
->setHelp(<<Hint: If you have a database with tables that should not be managed
+by the ORM, you can use a DBAL functionality to filter the tables and sequences down
+on a global level:
+
+ \$config->setFilterSchemaAssetsExpression(\$regexp);
EOT
);
}
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
index 9acf8e4e3..577fb9e0f 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
@@ -93,6 +93,12 @@ task will drop all database assets (e.g. tables, etc) that are *not* described
by the current metadata. In other words, without this option, this task leaves
untouched any "extra" tables that exist in the database, but which aren't
described by any metadata.
+
+Hint: If you have a database with tables that should not be managed
+by the ORM, you can use a DBAL functionality to filter the tables and sequences down
+on a global level:
+
+ \$config->setFilterSchemaAssetsExpression(\$regexp);
EOT
);
}
From b53f4fd4cc82e4d25f8325a750e66c293fa000ef Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Thu, 9 May 2013 18:15:41 +0200
Subject: [PATCH 122/332] [DDC-2280] length attribute in was not
converted.
---
lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
index ccbbfc3be..1a8fde184 100644
--- a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
+++ b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php
@@ -155,6 +155,10 @@ class XmlExporter extends AbstractExporter
$idXml->addAttribute('column', $field['columnName']);
}
+ if (isset($field['length'])) {
+ $idXml->addAttribute('length', $field['length']);
+ }
+
if (isset($field['associationKey']) && $field['associationKey']) {
$idXml->addAttribute('association-key', 'true');
}
From 07c207081e16e07b7bd574528427212194d871a3 Mon Sep 17 00:00:00 2001
From: Marco Pivetta
Date: Thu, 9 May 2013 21:11:10 +0200
Subject: [PATCH 123/332] Adding failing test to demonstrate DDC-2432
Loading proxies with invalid identifiers will currently mark them as initialized regardless of the failure
---
.../Tests/ORM/Proxy/ProxyFactoryTest.php | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php
index 90f1d7ef7..d91a3f2b5 100644
--- a/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Proxy/ProxyFactoryTest.php
@@ -2,6 +2,7 @@
namespace Doctrine\Tests\ORM\Proxy;
+use Doctrine\ORM\EntityNotFoundException;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Proxy\ProxyFactory;
use Doctrine\Common\Proxy\ProxyGenerator;
@@ -80,6 +81,60 @@ class ProxyFactoryTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(0, $num, "No proxies generated.");
}
+
+ /**
+ * @group DDC-2432
+ */
+ public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized()
+ {
+ $persister = $this->getMock('Doctrine\ORM\Persisters\BasicEntityPersister', array('load'), array(), '', false);
+ $this->uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
+
+ /* @var $proxy \Doctrine\Common\Proxy\Proxy */
+ $proxy = $this->proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', array('id' => 42));
+
+ $persister
+ ->expects($this->atLeastOnce())
+ ->method('load')
+ ->will($this->returnValue(null));
+
+ try {
+ $proxy->getDescription();
+ $this->fail('An exception was expected to be raised');
+ } catch (EntityNotFoundException $exception) {
+ }
+
+ $this->assertFalse($proxy->__isInitialized());
+ $this->assertInstanceOf('Closure', $proxy->__getInitializer(), 'The initializer wasn\'t removed');
+ $this->assertInstanceOf('Closure', $proxy->__getCloner(), 'The cloner wasn\'t removed');
+ }
+
+ /**
+ * @group DDC-2432
+ */
+ public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized()
+ {
+ $persister = $this->getMock('Doctrine\ORM\Persisters\BasicEntityPersister', array('load'), array(), '', false);
+ $this->uowMock->setEntityPersister('Doctrine\Tests\Models\ECommerce\ECommerceFeature', $persister);
+
+ /* @var $proxy \Doctrine\Common\Proxy\Proxy */
+ $proxy = $this->proxyFactory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceFeature', array('id' => 42));
+
+ $persister
+ ->expects($this->atLeastOnce())
+ ->method('load')
+ ->will($this->returnValue(null));
+
+ try {
+ $cloned = clone $proxy;
+ $this->fail('An exception was expected to be raised');
+ } catch (EntityNotFoundException $exception) {
+ }
+
+ $this->assertFalse($proxy->__isInitialized());
+ $this->assertInstanceOf('Closure', $proxy->__getInitializer(), 'The initializer wasn\'t removed');
+ $this->assertInstanceOf('Closure', $proxy->__getCloner(), 'The cloner wasn\'t removed');
+ }
}
abstract class AbstractClass
From 22c9f6ebec3dbfe7395760da824ab50cce0f2a7d Mon Sep 17 00:00:00 2001
From: Marco Pivetta
Date: Thu, 9 May 2013 21:14:58 +0200
Subject: [PATCH 124/332] applying required fixes for DDC-2432
---
lib/Doctrine/ORM/Proxy/ProxyFactory.php | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lib/Doctrine/ORM/Proxy/ProxyFactory.php b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
index c8964804e..dfac9a3e7 100644
--- a/lib/Doctrine/ORM/Proxy/ProxyFactory.php
+++ b/lib/Doctrine/ORM/Proxy/ProxyFactory.php
@@ -117,6 +117,9 @@ class ProxyFactory extends AbstractProxyFactory
{
if ($classMetadata->getReflectionClass()->hasMethod('__wakeup')) {
return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) {
+ $initializer = $proxy->__getInitializer();
+ $cloner = $proxy->__getCloner();
+
$proxy->__setInitializer(null);
$proxy->__setCloner(null);
@@ -136,12 +139,19 @@ class ProxyFactory extends AbstractProxyFactory
$proxy->__wakeup();
if (null === $entityPersister->load($classMetadata->getIdentifierValues($proxy), $proxy)) {
+ $proxy->__setInitializer($initializer);
+ $proxy->__setCloner($cloner);
+ $proxy->__setInitialized(false);
+
throw new EntityNotFoundException();
}
};
}
return function (BaseProxy $proxy) use ($entityPersister, $classMetadata) {
+ $initializer = $proxy->__getInitializer();
+ $cloner = $proxy->__getCloner();
+
$proxy->__setInitializer(null);
$proxy->__setCloner(null);
@@ -160,6 +170,10 @@ class ProxyFactory extends AbstractProxyFactory
$proxy->__setInitialized(true);
if (null === $entityPersister->load($classMetadata->getIdentifierValues($proxy), $proxy)) {
+ $proxy->__setInitializer($initializer);
+ $proxy->__setCloner($cloner);
+ $proxy->__setInitialized(false);
+
throw new EntityNotFoundException();
}
};
From eb1a162cbc003186c346f7c0b8b58093380c2fe9 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Fri, 10 May 2013 23:31:14 +0200
Subject: [PATCH 125/332] Fix regression in DDC-2430.
---
.../ORM/Persisters/SqlExpressionVisitor.php | 5 +++-
.../ORM/Functional/EntityRepositoryTest.php | 25 ++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php b/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
index 74b86208b..b06358a20 100644
--- a/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
+++ b/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
@@ -65,7 +65,10 @@ class SqlExpressionVisitor extends ExpressionVisitor
$field = $comparison->getField();
$value = $comparison->getValue()->getValue(); // shortcut for walkValue()
- if (isset($this->classMetadata->associationMappings[$field]) && ! is_object($value)) {
+ if (isset($this->classMetadata->associationMappings[$field]) &&
+ ! is_object($value) &&
+ ! in_array($comparison->getOperator(), array(Comparison::IN, Comparison::NIN))) {
+
throw PersisterException::matchingAssocationFieldRequiresObject($this->classMetadata->name, $field);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
index 48e5f3389..517ff3d97 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
@@ -790,7 +790,30 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $userId);
$criteria = new Criteria(
- Criteria::expr()->gte('user', $user)
+ Criteria::expr()->eq('user', $user)
+ );
+
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
+ $addresses = $repository->matching($criteria);
+
+ $this->assertEquals(1, count($addresses));
+
+ $addresses = new ArrayCollection($repository->findAll());
+
+ $this->assertEquals(1, count($addresses->matching($criteria)));
+ }
+
+ /**
+ * @group DDC-2430
+ */
+ public function testMatchingCriteriaAssocationInWithArray()
+ {
+ list($userId, $addressId) = $this->loadAssociatedFixture();
+
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $userId);
+
+ $criteria = new Criteria(
+ Criteria::expr()->in('user', array($user))
);
$repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsAddress');
From b147c472be73a6f0c565080f74852a28d7318a4e Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Mon, 13 May 2013 11:04:36 -0300
Subject: [PATCH 126/332] [DDC-2429] Fix xsd definition
---
doctrine-mapping.xsd | 51 ++++++++++++++-----
.../ORM/Mapping/XmlMappingDriverTest.php | 21 +++++---
...ctrine.Tests.Models.CMS.CmsAddress.dcm.xml | 19 ++++---
.../Doctrine.Tests.Models.CMS.CmsUser.dcm.xml | 32 ++++++------
...Tests.Models.Company.CompanyPerson.dcm.xml | 12 ++---
...ts.Models.DDC117.DDC117Translation.dcm.xml | 15 +++---
.../Doctrine.Tests.ORM.Mapping.Animal.dcm.xml | 2 +-
...ine.Tests.ORM.Mapping.DDC807Entity.dcm.xml | 8 +--
8 files changed, 98 insertions(+), 62 deletions(-)
diff --git a/doctrine-mapping.xsd b/doctrine-mapping.xsd
index 89c11a894..f9c774d57 100644
--- a/doctrine-mapping.xsd
+++ b/doctrine-mapping.xsd
@@ -37,6 +37,7 @@
+
@@ -86,8 +87,11 @@
+
+
+
+
-
@@ -95,14 +99,14 @@
-
+
-
+
@@ -127,20 +131,24 @@
+
-
-
-
+
+
+
+
+
+
+
-
@@ -155,6 +163,7 @@
+
@@ -221,6 +230,7 @@
+
@@ -380,7 +390,7 @@
-
+
@@ -505,7 +515,7 @@
-
+
@@ -521,16 +531,33 @@
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php b/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php
index e69f23a35..42b871f1e 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/XmlMappingDriverTest.php
@@ -66,23 +66,32 @@ class XmlMappingDriverTest extends AbstractMappingDriverTest
/**
* @param string $xmlMappingFile
* @dataProvider dataValidSchema
+ * @group DDC-2429
*/
public function testValidateXmlSchema($xmlMappingFile)
{
- $xsdSchemaFile = __DIR__ . "/../../../../../doctrine-mapping.xsd";
+ $xsdSchemaFile = __DIR__ . '/../../../../../doctrine-mapping.xsd';
+ $dom = new \DOMDocument('UTF-8');
- $dom = new \DOMDocument('UTF-8');
$dom->load($xmlMappingFile);
+
$this->assertTrue($dom->schemaValidate($xsdSchemaFile));
}
static public function dataValidSchema()
{
- return array(
- array(__DIR__ . "/xml/Doctrine.Tests.ORM.Mapping.CTI.dcm.xml"),
- array(__DIR__ . "/xml/Doctrine.Tests.ORM.Mapping.User.dcm.xml"),
- array(__DIR__ . "/xml/CatNoId.dcm.xml"),
+ $list = glob(__DIR__ . '/xml/*.xml');
+ $invalid = array(
+ 'Doctrine.Tests.Models.DDC889.DDC889Class.dcm'
);
+
+ $list = array_filter($list, function($item) use ($invalid){
+ return ! in_array(pathinfo($item, PATHINFO_FILENAME), $invalid);
+ });
+
+ return array_map(function($item){
+ return array($item);
+ }, $list);
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml
index b35569ae4..7e7bd5aaa 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsAddress.dcm.xml
@@ -1,12 +1,10 @@
-
-
-
-
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
+ http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+
+
@@ -15,7 +13,7 @@
SELECT id, country, city FROM cms_addresses
-
+
SELECT * FROM cms_addresses WHERE id = ?
@@ -46,7 +44,7 @@
-
+
@@ -54,6 +52,7 @@
-
+
+
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml
index 64a545df6..122a45e6f 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.CMS.CmsUser.dcm.xml
@@ -15,7 +15,7 @@
SELECT id, username FROM cms_users WHERE username = ?
-
+
SELECT * FROM cms_users WHERE username = ?
@@ -90,20 +90,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -117,12 +104,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -133,7 +133,7 @@
-
+
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml
index c573504e0..2ddd88a32 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.Company.CompanyPerson.dcm.xml
@@ -7,6 +7,12 @@
+
+
+
+
+
+
SELECT id, name, discr FROM company_persons ORDER BY name
@@ -26,12 +32,6 @@
-
-
-
-
-
-
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml
index c0df0886a..ec3bc74fd 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.Models.DDC117.DDC117Translation.dcm.xml
@@ -5,18 +5,19 @@
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml
index 3f67a6b82..a4c4e9bfd 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.Animal.dcm.xml
@@ -4,11 +4,11 @@
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
+
-
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml
index 3dc9135c5..82711dc2f 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/Doctrine.Tests.ORM.Mapping.DDC807Entity.dcm.xml
@@ -5,16 +5,16 @@
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
-
-
-
-
+
+
+
+
\ No newline at end of file
From bef5b585cb30568fc04080058d0e5a523c98ceff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Haso=C5=88?=
Date: Fri, 17 May 2013 12:08:14 +0200
Subject: [PATCH 127/332] Fixed generating join column names for self
referencing entity.
---
.../ORM/Mapping/ClassMetadataInfo.php | 11 ++++---
.../Tests/ORM/Mapping/ClassMetadataTest.php | 32 ++++++++++++++++---
2 files changed, 35 insertions(+), 8 deletions(-)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 1e038d659..e4a0955df 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -1547,15 +1547,18 @@ class ClassMetadataInfo implements ClassMetadata
$mapping['joinTable']['name'] = $this->namingStrategy->joinTableName($mapping['sourceEntity'], $mapping['targetEntity'], $mapping['fieldName']);
}
+ $selfReferencingEntityWithoutJoinColumns = $mapping['sourceEntity'] == $mapping['targetEntity']
+ && (! (isset($mapping['joinTable']['joinColumns']) || isset($mapping['joinTable']['inverseJoinColumns'])));
+
if ( ! isset($mapping['joinTable']['joinColumns'])) {
$mapping['joinTable']['joinColumns'] = array(array(
- 'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity']),
+ 'name' => $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $selfReferencingEntityWithoutJoinColumns ? 'source' : null),
'referencedColumnName' => $this->namingStrategy->referenceColumnName(),
'onDelete' => 'CASCADE'));
}
if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
$mapping['joinTable']['inverseJoinColumns'] = array(array(
- 'name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity']),
+ 'name' => $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $selfReferencingEntityWithoutJoinColumns ? 'target' : null),
'referencedColumnName' => $this->namingStrategy->referenceColumnName(),
'onDelete' => 'CASCADE'));
}
@@ -2309,7 +2312,7 @@ class ClassMetadataInfo implements ClassMetadata
}
$entityResult['entityClass'] = $this->fullyQualifiedClassName($entityResult['entityClass']);
-
+
$resultMapping['entities'][$key]['entityClass'] = ltrim($entityResult['entityClass'], '\\');
$resultMapping['entities'][$key]['isSelfClass'] = $entityResult['isSelfClass'];
@@ -2429,7 +2432,7 @@ class ClassMetadataInfo implements ClassMetadata
* lifecycle callbacks and lifecycle listeners.
*
* @deprecated Deprecated since version 2.4 in favor of \Doctrine\ORM\Event\ListenersInvoker
- *
+ *
* @param string $lifecycleEvent The lifecycle event.
* @param object $entity The Entity on which the event occurred.
*
diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
index b8e0becc4..8792545ad 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -340,7 +340,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
'fieldName' => 'user',
'targetEntity' => 'CmsUser'
));
-
+
$this->assertEquals(array('USER_ID'=>'ID'), $oneToOneMetadata->associationMappings['user']['sourceToTargetKeyColumns']);
$this->assertEquals(array('USER_ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['joinColumnFieldNames']);
$this->assertEquals(array('ID'=>'USER_ID'), $oneToOneMetadata->associationMappings['user']['targetToSourceKeyColumns']);
@@ -348,7 +348,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('USER_ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['name']);
$this->assertEquals('ID', $oneToOneMetadata->associationMappings['user']['joinColumns'][0]['referencedColumnName']);
-
+
$this->assertEquals('CMS_ADDRESS_CMS_USER', $manyToManyMetadata->associationMappings['user']['joinTable']['name']);
$this->assertEquals(array('CMS_ADDRESS_ID','CMS_USER_ID'), $manyToManyMetadata->associationMappings['user']['joinTableColumns']);
@@ -770,7 +770,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
{
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
-
+
$cm->addSqlResultSetMapping(array(
'name' => 'find-all',
'entities' => array(
@@ -1000,7 +1000,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
/**
* @group DDC-1955
- *
+ *
* @expectedException Doctrine\ORM\Mapping\MappingException
* @expectedExceptionMessage Entity Listener "\InvalidClassName" declared on "Doctrine\Tests\Models\CMS\CmsUser" not found.
*/
@@ -1025,6 +1025,30 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$cm->addEntityListener(Events::postLoad, '\Doctrine\Tests\Models\Company\CompanyContractListener', 'invalidMethod');
}
+
+ public function testManyToManySelfReferencingNamingStrategyDefaults()
+ {
+ $cm = new ClassMetadata('Doctrine\Tests\Models\CustomType\CustomTypeParent');
+ $cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+ $cm->mapManyToMany(
+ array(
+ 'fieldName' => 'friendsWithMe',
+ 'targetEntity' => 'CustomTypeParent'
+ )
+ );
+
+ $this->assertEquals(
+ array(
+ 'name' => 'customtypeparent_customtypeparent',
+ 'joinColumns' => array(array('name' => 'customtypeparent_source', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
+ 'inverseJoinColumns' => array(array('name' => 'customtypeparent_target', 'referencedColumnName' => 'id', 'onDelete' => 'CASCADE')),
+ ),
+ $cm->associationMappings['friendsWithMe']['joinTable']
+ );
+ $this->assertEquals(array('customtypeparent_source', 'customtypeparent_target'), $cm->associationMappings['friendsWithMe']['joinTableColumns']);
+ $this->assertEquals(array('customtypeparent_source' => 'id'), $cm->associationMappings['friendsWithMe']['relationToSourceKeyColumns']);
+ $this->assertEquals(array('customtypeparent_target' => 'id'), $cm->associationMappings['friendsWithMe']['relationToTargetKeyColumns']);
+ }
}
class MyNamespacedNamingStrategy extends \Doctrine\ORM\Mapping\DefaultNamingStrategy
From 4d6cef1ff6fb6fe06dfbedbce45f2afc0eb14695 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 17 May 2013 11:42:11 -0300
Subject: [PATCH 128/332] [DDC-2451] Fix entity listeners serialization
---
lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 4 ++++
.../Tests/ORM/Mapping/ClassMetadataTest.php | 17 +++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index 1e038d659..1f0d4653f 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -831,6 +831,10 @@ class ClassMetadataInfo implements ClassMetadata
$serialized[] = 'lifecycleCallbacks';
}
+ if ($this->entityListeners) {
+ $serialized[] = 'entityListeners';
+ }
+
if ($this->namedQueries) {
$serialized[] = 'namedQueries';
}
diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
index b8e0becc4..4904b43f8 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -714,6 +714,23 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(1, count($cm->getNamedNativeQueries()));
}
+ /**
+ * @group DDC-2451
+ */
+ public function testSerializeEntityListeners()
+ {
+ $metadata = new ClassMetadata('Doctrine\Tests\Models\Company\CompanyContract');
+
+ $metadata->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+ $metadata->addEntityListener(\Doctrine\ORM\Events::prePersist, 'CompanyContractListener', 'prePersistHandler');
+ $metadata->addEntityListener(\Doctrine\ORM\Events::postPersist, 'CompanyContractListener', 'postPersistHandler');
+
+ $serialize = serialize($metadata);
+ $unserialize = unserialize($serialize);
+
+ $this->assertEquals($unserialize->entityListeners, $metadata->entityListeners);
+ }
+
/**
* @expectedException \Doctrine\ORM\Mapping\MappingException
* @expectedExceptionMessage Query named "userById" in "Doctrine\Tests\Models\CMS\CmsUser" was already declared, but it must be declared only once
From 1d7c72cc06a6fadc3c1d8e59c66ca4b9d679a7fe Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 17 May 2013 11:55:36 -0300
Subject: [PATCH 129/332] [DDC-2451] Fix test assert
---
tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
index 4904b43f8..330b54a3f 100644
--- a/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
+++ b/tests/Doctrine/Tests/ORM/Mapping/ClassMetadataTest.php
@@ -728,7 +728,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$serialize = serialize($metadata);
$unserialize = unserialize($serialize);
- $this->assertEquals($unserialize->entityListeners, $metadata->entityListeners);
+ $this->assertEquals($metadata->entityListeners, $unserialize->entityListeners);
}
/**
From 1e95110b08d528551e482fc7171d9ce10b5d6156 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 17 May 2013 11:59:28 -0300
Subject: [PATCH 130/332] Add missing mapping files
---
.../Tests/ORM/Mapping/xml/DDC2429Book.orm.xml | 40 ++++++++++++++++++
.../ORM/Mapping/xml/DDC2429Novel.orm.xml | 42 +++++++++++++++++++
2 files changed, 82 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml
create mode 100644 tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml
new file mode 100644
index 000000000..8640c6f51
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Book.orm.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml b/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml
new file mode 100644
index 000000000..43ce94285
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Mapping/xml/DDC2429Novel.orm.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From f92214997f0046232d8245b32d0a78f9400adb9d Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 17 May 2013 12:44:48 -0300
Subject: [PATCH 131/332] [DDC-2435] Fix column name with numbers and non
alphanumeric characters.
---
.../ORM/Mapping/DefaultQuoteStrategy.php | 9 ++++--
.../Tests/Models/Quote/NumericEntity.php | 31 +++++++++++++++++++
.../ORM/Query/SelectSqlGenerationTest.php | 21 +++++++++++++
3 files changed, 58 insertions(+), 3 deletions(-)
create mode 100644 tests/Doctrine/Tests/Models/Quote/NumericEntity.php
diff --git a/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php b/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php
index 3f5b0c853..70359de33 100644
--- a/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php
+++ b/lib/Doctrine/ORM/Mapping/DefaultQuoteStrategy.php
@@ -127,12 +127,15 @@ class DefaultQuoteStrategy implements QuoteStrategy
*/
public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
{
- // Trim the column alias to the maximum identifier length of the platform.
- // If the alias is to long, characters are cut off from the beginning.
- // And strip non alphanumeric characters
+ // 1 ) Concatenate column name and counter
+ // 2 ) Trim the column alias to the maximum identifier length of the platform.
+ // If the alias is to long, characters are cut off from the beginning.
+ // 3 ) Strip non alphanumeric characters
+ // 4 ) Prefix with "_" if the result its numeric
$columnName = $columnName . $counter;
$columnName = substr($columnName, -$platform->getMaxIdentifierLength());
$columnName = preg_replace('/[^A-Za-z0-9_]/', '', $columnName);
+ $columnName = is_numeric($columnName) ? '_' . $columnName : $columnName;
return $platform->getSQLResultCasing($columnName);
}
diff --git a/tests/Doctrine/Tests/Models/Quote/NumericEntity.php b/tests/Doctrine/Tests/Models/Quote/NumericEntity.php
new file mode 100644
index 000000000..f1186cbcc
--- /dev/null
+++ b/tests/Doctrine/Tests/Models/Quote/NumericEntity.php
@@ -0,0 +1,31 @@
+value = $value;
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index 747df24bb..d15f78d48 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1810,6 +1810,27 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
+ /**
+ * @group DDC-2435
+ */
+ public function testColumnNameWithNumbersAndNonAlphanumericCharacters()
+ {
+ $this->assertSqlGeneration(
+ 'SELECT e FROM Doctrine\Tests\Models\Quote\NumericEntity e',
+ 'SELECT t0_."1:1" AS _110, t0_."2:2" AS _221 FROM table t0_'
+ );
+
+ $this->assertSqlGeneration(
+ 'SELECT e.value FROM Doctrine\Tests\Models\Quote\NumericEntity e',
+ 'SELECT t0_."2:2" AS _220 FROM table t0_'
+ );
+
+ $this->assertSqlGeneration(
+ 'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Quote\NumericEntity e',
+ 'SELECT TRIM(t0_."2:2") AS sclr0 FROM table t0_'
+ );
+ }
+
/**
* @group DDC-1845
*/
From 7430320bac802095b773ab596c7c4215fc81f4e0 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 01:40:05 +0400
Subject: [PATCH 132/332] ready
---
tools/sandbox/bootstrap.php | 0
tools/sandbox/cli-config.php | 36 ------------------------------------
2 files changed, 36 deletions(-)
create mode 100644 tools/sandbox/bootstrap.php
delete mode 100644 tools/sandbox/cli-config.php
diff --git a/tools/sandbox/bootstrap.php b/tools/sandbox/bootstrap.php
new file mode 100644
index 000000000..e69de29bb
diff --git a/tools/sandbox/cli-config.php b/tools/sandbox/cli-config.php
deleted file mode 100644
index 2a34fd89b..000000000
--- a/tools/sandbox/cli-config.php
+++ /dev/null
@@ -1,36 +0,0 @@
-register();
-$classLoader = new \Doctrine\Common\ClassLoader('Doctrine\DBAL', realpath(__DIR__ . '/../../lib/vendor/doctrine-dbal/lib'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Doctrine\Common', realpath(__DIR__ . '/../../lib/vendor/doctrine-common/lib'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Symfony', realpath(__DIR__ . '/../../lib/vendor'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
-$classLoader->register();
-
-$config = new \Doctrine\ORM\Configuration();
-$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
-$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
-$config->setMetadataDriverImpl($driverImpl);
-
-$config->setProxyDir(__DIR__ . '/Proxies');
-$config->setProxyNamespace('Proxies');
-
-$connectionOptions = array(
- 'driver' => 'pdo_sqlite',
- 'path' => 'database.sqlite'
-);
-
-$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
-
-$helpers = new Symfony\Component\Console\Helper\HelperSet(array(
- 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
- 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
-));
\ No newline at end of file
From dca0881d943b22d0d42bed5cd451611e6e9a0343 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 01:42:55 +0400
Subject: [PATCH 133/332] forget add changes
---
tools/sandbox/bootstrap.php | 35 +++++++++++++++++++++++++++
tools/sandbox/doctrine.php | 22 ++++-------------
tools/sandbox/index.php | 48 ++++---------------------------------
3 files changed, 44 insertions(+), 61 deletions(-)
diff --git a/tools/sandbox/bootstrap.php b/tools/sandbox/bootstrap.php
index e69de29bb..0e7120544 100644
--- a/tools/sandbox/bootstrap.php
+++ b/tools/sandbox/bootstrap.php
@@ -0,0 +1,35 @@
+add('Entities', __DIR__);
+$loader->add('Proxies', __DIR__);
+
+$config = new \Doctrine\ORM\Configuration();
+
+// Set up Metadata Drivers
+$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__ . "/Entities"));
+$config->setMetadataDriverImpl($driverImpl);
+
+// Set up caches
+$cache = new ApcCache;
+$config->setMetadataCacheImpl($cache);
+$config->setQueryCacheImpl($cache);
+$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
+
+// Proxy configuration
+$config->setProxyDir(__DIR__ . '/Proxies');
+$config->setProxyNamespace('Proxies');
+
+// Database connection information
+$connectionOptions = array(
+ 'driver' => 'pdo_sqlite',
+ 'path' => 'database.sqlite'
+);
+
+return EntityManager::create($connectionOptions, $config);
\ No newline at end of file
diff --git a/tools/sandbox/doctrine.php b/tools/sandbox/doctrine.php
index 9060e6f7b..66ed4f3c1 100644
--- a/tools/sandbox/doctrine.php
+++ b/tools/sandbox/doctrine.php
@@ -1,27 +1,15 @@
register();
-$classLoader = new \Doctrine\Common\ClassLoader('Doctrine\DBAL', realpath(__DIR__ . '/../../lib/vendor/doctrine-dbal/lib'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Doctrine\Common', realpath(__DIR__ . '/../../lib/vendor/doctrine-common/lib'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Symfony', realpath(__DIR__ . '/../../lib/vendor'));
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Entities', __DIR__);
-$classLoader->register();
-$classLoader = new \Doctrine\Common\ClassLoader('Proxies', __DIR__);
-$classLoader->register();
-
-require __DIR__ . '/cli-config.php';
+$em = require_once __DIR__.'/bootstrap.php';
$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface', Doctrine\Common\Version::VERSION);
$cli->setCatchExceptions(true);
// Variable $helpers is defined inside cli-config.php
-$cli->setHelperSet($helpers);
+$cli->setHelperSet(new Symfony\Component\Console\Helper\HelperSet(array(
+ 'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
+ 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
+)));
$cli->addCommands(array(
// DBAL Commands
diff --git a/tools/sandbox/index.php b/tools/sandbox/index.php
index ad1cb9d6b..f866aeada 100644
--- a/tools/sandbox/index.php
+++ b/tools/sandbox/index.php
@@ -1,7 +1,7 @@
register();
-$classLoader = new ClassLoader('Doctrine\DBAL', realpath(__DIR__ . '/../../lib/vendor/doctrine-dbal/lib'));
-$classLoader->register();
-$classLoader = new ClassLoader('Doctrine\Common', realpath(__DIR__ . '/../../lib/vendor/doctrine-common/lib'));
-$classLoader->register();
-$classLoader = new ClassLoader('Symfony', realpath(__DIR__ . '/../../lib/vendor'));
-$classLoader->register();
-$classLoader = new ClassLoader('Entities', __DIR__);
-$classLoader->register();
-$classLoader = new ClassLoader('Proxies', __DIR__);
-$classLoader->register();
-
-// Set up caches
-$config = new Configuration;
-$cache = new ApcCache;
-$config->setMetadataCacheImpl($cache);
-$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__."/Entities"));
-$config->setMetadataDriverImpl($driverImpl);
-$config->setQueryCacheImpl($cache);
-
-// Proxy configuration
-$config->setProxyDir(__DIR__ . '/Proxies');
-$config->setProxyNamespace('Proxies');
-$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
-
-// Database connection information
-$connectionOptions = array(
- 'driver' => 'pdo_sqlite',
- 'path' => 'database.sqlite'
-);
-
-// Create EntityManager
-$em = EntityManager::create($connectionOptions, $config);
+$em = require_once __DIR__ . '/bootstrap.php';
## PUT YOUR TEST CODE BELOW
From ec57306efe40770d8a77bb92117e21252fa401c7 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 01:44:47 +0400
Subject: [PATCH 134/332] remove comment about cli-config
---
tools/sandbox/doctrine.php | 1 -
1 file changed, 1 deletion(-)
diff --git a/tools/sandbox/doctrine.php b/tools/sandbox/doctrine.php
index 66ed4f3c1..6cadae0d4 100644
--- a/tools/sandbox/doctrine.php
+++ b/tools/sandbox/doctrine.php
@@ -5,7 +5,6 @@ $em = require_once __DIR__.'/bootstrap.php';
$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface', Doctrine\Common\Version::VERSION);
$cli->setCatchExceptions(true);
-// Variable $helpers is defined inside cli-config.php
$cli->setHelperSet(new Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($em)
From 4c1869dca0b1cba45e64103b9df7daa0165f6cf5 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 02:09:07 +0400
Subject: [PATCH 135/332] ready
---
.../ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php | 2 +-
.../ORM/Tools/Console/Command/ConvertMappingCommand.php | 2 +-
.../ORM/Tools/Console/Command/GenerateEntitiesCommand.php | 2 +-
.../ORM/Tools/Console/Command/GenerateProxiesCommand.php | 2 +-
.../ORM/Tools/Console/Command/GenerateRepositoriesCommand.php | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
index 725d2bf83..0e6936ac2 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
@@ -101,7 +101,7 @@ class ConvertDoctrine1SchemaCommand extends Command
protected function configure()
{
$this
- ->setName('orm:convert-d1-schema')
+ ->setName('orm:convert:d1-schema')
->setDescription('Converts Doctrine 1.X schema into a Doctrine 2.X schema.')
->setDefinition(array(
new InputArgument(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
index 020a4afaf..039843614 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
@@ -48,7 +48,7 @@ class ConvertMappingCommand extends Command
protected function configure()
{
$this
- ->setName('orm:convert-mapping')
+ ->setName('orm:convert:mapping')
->setDescription('Convert mapping information between supported formats.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
index 764e89500..7cdce30e0 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
@@ -46,7 +46,7 @@ class GenerateEntitiesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate-entities')
+ ->setName('orm:generate:entities')
->setDescription('Generate entity classes and method stubs from your mapping information.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
index 1de9dd7dc..77e414d3d 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
@@ -44,7 +44,7 @@ class GenerateProxiesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate-proxies')
+ ->setName('orm:generate:proxies')
->setDescription('Generates proxy classes for entity classes.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
index 7d1bd4c04..fdb88d2d1 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
@@ -45,7 +45,7 @@ class GenerateRepositoriesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate-repositories')
+ ->setName('orm:generate:repositories')
->setDescription('Generate repository classes from your mapping information.')
->setDefinition(array(
new InputOption(
From 6bb3184dbfd3679c0aaf2323cb1ca711451c9321 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 02:40:18 +0400
Subject: [PATCH 136/332] fix bc
---
.../Tools/Console/Command/ConvertDoctrine1SchemaCommand.php | 3 ++-
.../ORM/Tools/Console/Command/ConvertMappingCommand.php | 3 ++-
.../ORM/Tools/Console/Command/GenerateEntitiesCommand.php | 3 ++-
.../ORM/Tools/Console/Command/GenerateProxiesCommand.php | 3 ++-
.../ORM/Tools/Console/Command/GenerateRepositoriesCommand.php | 3 ++-
5 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
index 0e6936ac2..71d72deb8 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertDoctrine1SchemaCommand.php
@@ -101,7 +101,8 @@ class ConvertDoctrine1SchemaCommand extends Command
protected function configure()
{
$this
- ->setName('orm:convert:d1-schema')
+ ->setName('orm:convert-d1-schema')
+ ->setAliases(array('orm:convert:d1-schema'))
->setDescription('Converts Doctrine 1.X schema into a Doctrine 2.X schema.')
->setDefinition(array(
new InputArgument(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
index 039843614..5300783af 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/ConvertMappingCommand.php
@@ -48,7 +48,8 @@ class ConvertMappingCommand extends Command
protected function configure()
{
$this
- ->setName('orm:convert:mapping')
+ ->setName('orm:convert-mapping')
+ ->setAliases(array('orm:convert:mapping'))
->setDescription('Convert mapping information between supported formats.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
index 7cdce30e0..a8fcac3c8 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateEntitiesCommand.php
@@ -46,7 +46,8 @@ class GenerateEntitiesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate:entities')
+ ->setName('orm:generate-entities')
+ ->setAliases(array('orm:generate:entities'))
->setDescription('Generate entity classes and method stubs from your mapping information.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
index 77e414d3d..522118794 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateProxiesCommand.php
@@ -44,7 +44,8 @@ class GenerateProxiesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate:proxies')
+ ->setName('orm:generate-proxies')
+ ->setAliases(array('orm:generate:proxies'))
->setDescription('Generates proxy classes for entity classes.')
->setDefinition(array(
new InputOption(
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
index fdb88d2d1..975bc6938 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/GenerateRepositoriesCommand.php
@@ -45,7 +45,8 @@ class GenerateRepositoriesCommand extends Command
protected function configure()
{
$this
- ->setName('orm:generate:repositories')
+ ->setName('orm:generate-repositories')
+ ->setAliases(array('orm:generate:repositories'))
->setDescription('Generate repository classes from your mapping information.')
->setDefinition(array(
new InputOption(
From 384dfa87ab4dd1483c331cbad8d6096a066318b6 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Sat, 18 May 2013 04:00:28 +0400
Subject: [PATCH 137/332] add docs
---
docs/en/reference/tools.rst | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/docs/en/reference/tools.rst b/docs/en/reference/tools.rst
index b65863ed3..a5f99d141 100644
--- a/docs/en/reference/tools.rst
+++ b/docs/en/reference/tools.rst
@@ -131,6 +131,20 @@ The following Commands are currently available:
update the database schema of EntityManager Storage Connection or
generate the SQL output.
+For these commands are also available aliases:
+
+
+- ``orm:convert:d1-schema`` is alias for ``orm:convert-d1-schema``.
+- ``orm:convert:mapping`` is alias for ``orm:convert-mapping``.
+- ``orm:generate:entities`` is alias for ``orm:generate-entities``.
+- ``orm:generate:proxies`` is alias for ``orm:generate-proxies``.
+- ``orm:generate:repositories`` is alias for ``orm:generate-repositories``.
+
+.. note::
+
+ Console also supports auto completion, for example, instead of
+ ``orm:clear-cache:query`` you can use just ``o:c:q``.
+
Database Schema Generation
--------------------------
From 1f4a65f3e05689b8725851d8bb88a0fc7f77b150 Mon Sep 17 00:00:00 2001
From: Gusakov Nikita
Date: Mon, 20 May 2013 17:08:20 +0400
Subject: [PATCH 138/332] add debug variable and check for loader
---
tools/sandbox/bootstrap.php | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/tools/sandbox/bootstrap.php b/tools/sandbox/bootstrap.php
index 0e7120544..5b97b9412 100644
--- a/tools/sandbox/bootstrap.php
+++ b/tools/sandbox/bootstrap.php
@@ -1,26 +1,32 @@
add('Entities', __DIR__);
$loader->add('Proxies', __DIR__);
+$debug = true;
$config = new \Doctrine\ORM\Configuration();
// Set up Metadata Drivers
$driverImpl = $config->newDefaultAnnotationDriver(array(__DIR__ . "/Entities"));
$config->setMetadataDriverImpl($driverImpl);
-// Set up caches
-$cache = new ApcCache;
+// Set up caches, depending on $debug variable.
+// You can use another variable to define which one of the cache systems you gonna use.
+$cache = $debug ? new Cache\ArrayCache : new Cache\ApcCache;
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
-$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
// Proxy configuration
$config->setProxyDir(__DIR__ . '/Proxies');
From 66a842c143d669707de5eb3149c2ac3143dd6977 Mon Sep 17 00:00:00 2001
From: Alexander
Date: Sun, 26 May 2013 07:41:01 +0200
Subject: [PATCH 139/332] [DDC-2471] Fix EQ/NEQ null handling of criteria
---
.../ORM/Persisters/BasicEntityPersister.php | 10 +++-
.../ORM/Persisters/SqlValueVisitor.php | 9 ++-
.../EntityRepositoryCriteriaTest.php | 56 +++++++++++++++++++
.../BasicEntityPersisterTypeValueSqlTest.php | 14 ++++-
4 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index 8f921f2b8..f101fda13 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -85,7 +85,7 @@ class BasicEntityPersister
*/
static private $comparisonMap = array(
Comparison::EQ => '= %s',
- Comparison::IS => 'IS %s',
+ Comparison::IS => '= %s',
Comparison::NEQ => '!= %s',
Comparison::GT => '> %s',
Comparison::GTE => '>= %s',
@@ -1608,6 +1608,14 @@ class BasicEntityPersister
}
if ($comparison !== null) {
+
+ // special case null value handling
+ if (($comparison === Comparison::EQ || $comparison === Comparison::IS) && $value === null) {
+ return $condition . ' IS NULL';
+ } else if ($comparison === Comparison::NEQ && $value === null) {
+ return $condition . ' IS NOT NULL';
+ }
+
return $condition . ' ' . sprintf(self::$comparisonMap[$comparison], $placeholder);
}
diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
index 79e5150e5..0e680ad07 100644
--- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
+++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php
@@ -52,7 +52,14 @@ class SqlValueVisitor extends ExpressionVisitor
{
$value = $this->getValueFromComparison($comparison);
$field = $comparison->getField();
-
+ $operator = $comparison->getOperator();
+
+ if (($operator === Comparison::EQ || $operator === Comparison::IS) && $value === null) {
+ return;
+ } else if ($operator === Comparison::NEQ && $value === null) {
+ return;
+ }
+
$this->values[] = $value;
$this->types[] = array($field, $value);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php
index 8631e529d..83c26b432 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php
@@ -84,4 +84,60 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(2, count($dates));
}
+
+ private function loadNullFieldFixtures()
+ {
+ $today = new DateTimeModel();
+ $today->datetime =
+ $today->date =
+ new \DateTime('today');
+
+ $this->_em->persist($today);
+
+ $tomorrow = new DateTimeModel();
+ $tomorrow->datetime =
+ $tomorrow->date =
+ $tomorrow->time =
+ new \DateTime('tomorrow');
+ $this->_em->persist($tomorrow);
+
+ $this->_em->flush();
+ $this->_em->clear();
+ }
+
+ public function testIsNullComparison()
+ {
+ $this->loadNullFieldFixtures();
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
+
+ $dates = $repository->matching(new Criteria(
+ Criteria::expr()->isNull('time')
+ ));
+
+ $this->assertEquals(1, count($dates));
+ }
+
+ public function testEqNullComparison()
+ {
+ $this->loadNullFieldFixtures();
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
+
+ $dates = $repository->matching(new Criteria(
+ Criteria::expr()->eq('time', null)
+ ));
+
+ $this->assertEquals(1, count($dates));
+ }
+
+ public function testNotEqNullComparison()
+ {
+ $this->loadNullFieldFixtures();
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel');
+
+ $dates = $repository->matching(new Criteria(
+ Criteria::expr()->neq('time', null)
+ ));
+
+ $this->assertEquals(1, count($dates));
+ }
}
diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php
index 018044c03..668ff13a0 100644
--- a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php
+++ b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php
@@ -96,6 +96,18 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
public function testSelectConditionStatementIsNull()
{
$statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS);
- $this->assertEquals('test IS ?', $statement);
+ $this->assertEquals('test IS NULL', $statement);
+ }
+
+ public function testSelectConditionStatementEqNull()
+ {
+ $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::EQ);
+ $this->assertEquals('test IS NULL', $statement);
+ }
+
+ public function testSelectConditionStatementNeqNull()
+ {
+ $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::NEQ);
+ $this->assertEquals('test IS NOT NULL', $statement);
}
}
From 0e29fe871a854279113f080845a009d724ef4787 Mon Sep 17 00:00:00 2001
From: John Bafford
Date: Mon, 27 May 2013 11:20:26 -0400
Subject: [PATCH 140/332] Fix an instance of doubled words
---
docs/en/reference/native-sql.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/reference/native-sql.rst b/docs/en/reference/native-sql.rst
index cc59f1630..89eb2850b 100644
--- a/docs/en/reference/native-sql.rst
+++ b/docs/en/reference/native-sql.rst
@@ -277,7 +277,7 @@ detail:
The first parameter is the alias of the entity result to which the
meta column belongs. A meta result column (foreign key or
-discriminator column) always belongs to to an entity result. The
+discriminator column) always belongs to an entity result. The
second parameter is the column alias/name of the column in the SQL
result set and the third parameter is the column name used in the
mapping.
From 6bc18402e2f2acb7735b770cbd42e183a57b7400 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Mon, 27 May 2013 21:47:16 +0200
Subject: [PATCH 141/332] Release 2.4.0-RC1
---
composer.json | 2 +-
lib/Doctrine/ORM/Version.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/composer.json b/composer.json
index f74058bac..88236f2fd 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
- "type": "library",
+ "type": "library","version":"2.4.0-RC1",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
diff --git a/lib/Doctrine/ORM/Version.php b/lib/Doctrine/ORM/Version.php
index 4dba7902f..f8347d998 100644
--- a/lib/Doctrine/ORM/Version.php
+++ b/lib/Doctrine/ORM/Version.php
@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
- const VERSION = '2.4.0-DEV';
+ const VERSION = '2.4.0-RC1';
/**
* Compares a Doctrine version with the current one.
From f269ecc3ac1bcae20d1e0e5f3c8c0670b8669dd1 Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Mon, 27 May 2013 21:47:16 +0200
Subject: [PATCH 142/332] Bump dev version to 2.4.0
---
composer.json | 2 +-
lib/Doctrine/ORM/Version.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/composer.json b/composer.json
index 88236f2fd..f74058bac 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "doctrine/orm",
- "type": "library","version":"2.4.0-RC1",
+ "type": "library",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "http://www.doctrine-project.org",
diff --git a/lib/Doctrine/ORM/Version.php b/lib/Doctrine/ORM/Version.php
index f8347d998..4dba7902f 100644
--- a/lib/Doctrine/ORM/Version.php
+++ b/lib/Doctrine/ORM/Version.php
@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
- const VERSION = '2.4.0-RC1';
+ const VERSION = '2.4.0-DEV';
/**
* Compares a Doctrine version with the current one.
From c64c149ebf862d9560cfff86f079a001c84c79f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Antonio=20J=2E=20Garc=C3=ADa=20Lagar?=
Date: Tue, 28 May 2013 08:57:17 +0200
Subject: [PATCH 143/332] Fix getting started doc to work with current version
---
docs/en/tutorials/getting-started.rst | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/docs/en/tutorials/getting-started.rst b/docs/en/tutorials/getting-started.rst
index 1ff524529..187029dfa 100644
--- a/docs/en/tutorials/getting-started.rst
+++ b/docs/en/tutorials/getting-started.rst
@@ -187,9 +187,7 @@ doctrine command. Its a fairly simple file:
// cli-config.php
require_once "bootstrap.php";
- $helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
- 'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($entityManager)
- ));
+ return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);
You can then change into your project directory and call the
Doctrine command-line tool:
From a986fe013e250b1b7af4040274bc36d2df58d3cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gr=C3=A9goire=20Paris?=
Date: Mon, 3 Jun 2013 12:07:08 +0200
Subject: [PATCH 144/332] Explicitely state what the problem is
People like me think the problem is that there is no association
mapping, when the problem in fact could be that there also is a field
mapping on the property.
This message makes it clearer why we are getting an error message.
---
lib/Doctrine/ORM/Tools/SchemaValidator.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Tools/SchemaValidator.php b/lib/Doctrine/ORM/Tools/SchemaValidator.php
index 328aeb231..958e411b6 100644
--- a/lib/Doctrine/ORM/Tools/SchemaValidator.php
+++ b/lib/Doctrine/ORM/Tools/SchemaValidator.php
@@ -115,7 +115,7 @@ class SchemaValidator
if ($assoc['mappedBy']) {
if ($targetMetadata->hasField($assoc['mappedBy'])) {
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
- "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which is not defined as association.";
+ "field " . $assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " which is not defined as association, but as field.";
}
if (!$targetMetadata->hasAssociation($assoc['mappedBy'])) {
$ce[] = "The association " . $class->name . "#" . $fieldName . " refers to the owning side ".
From 27511374ec9cf04bf92995b7544255dd63856b62 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Tue, 4 Jun 2013 23:50:43 -0400
Subject: [PATCH 145/332] Fix DDC-2475
---
lib/Doctrine/ORM/Query/SqlWalker.php | 106 +++++++++++-------
.../ORM/Query/SelectSqlGenerationTest.php | 15 +++
2 files changed, 83 insertions(+), 38 deletions(-)
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 77b8ec1d4..b971bcfe5 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -24,6 +24,7 @@ use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\QueryException;
+use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
/**
@@ -117,6 +118,13 @@ class SqlWalker implements TreeWalker
*/
private $scalarResultAliasMap = array();
+ /**
+ * Map from Table-Alias + Column-Name to OrderBy-Direction.
+ *
+ * @var array
+ */
+ private $orderedColumnsMap = array();
+
/**
* Map from DQL-Alias + Field-Name to SQL Column Alias.
*
@@ -388,25 +396,36 @@ class SqlWalker implements TreeWalker
*/
private function _generateOrderedCollectionOrderByItems()
{
- $sqlParts = array();
+ $orderedColumns = array();
foreach ($this->selectedClasses as $selectedClass) {
- $dqlAlias = $selectedClass['dqlAlias'];
- $qComp = $this->queryComponents[$dqlAlias];
+ $dqlAlias = $selectedClass['dqlAlias'];
+ $qComp = $this->queryComponents[$dqlAlias];
+ $persister = $this->em->getUnitOfWork()->getEntityPersister($qComp['metadata']->name);
- if ( ! isset($qComp['relation']['orderBy'])) continue;
+ if ( ! isset($qComp['relation']['orderBy'])) {
+ continue;
+ }
foreach ($qComp['relation']['orderBy'] as $fieldName => $orientation) {
$columnName = $this->quoteStrategy->getColumnName($fieldName, $qComp['metadata'], $this->platform);
$tableName = ($qComp['metadata']->isInheritanceTypeJoined())
- ? $this->em->getUnitOfWork()->getEntityPersister($qComp['metadata']->name)->getOwningTable($fieldName)
+ ? $persister->getOwningTable($fieldName)
: $qComp['metadata']->getTableName();
- $sqlParts[] = $this->getSQLTableAlias($tableName, $dqlAlias) . '.' . $columnName . ' ' . $orientation;
+ $orderedColumn = $this->getSQLTableAlias($tableName, $dqlAlias) . '.' . $columnName;
+
+ // OrderByClause should replace an ordered relation. see - DDC-2475
+ if (isset($this->orderedColumnsMap[$orderedColumn])) {
+ continue;
+ }
+
+ $this->orderedColumnsMap[$orderedColumn] = $orientation;
+ $orderedColumns[] = $orderedColumn . ' ' . $orientation;
}
}
- return implode(', ', $sqlParts);
+ return implode(', ', $orderedColumns);
}
/**
@@ -495,44 +514,52 @@ class SqlWalker implements TreeWalker
*/
public function walkSelectStatement(AST\SelectStatement $AST)
{
- $sql = $this->walkSelectClause($AST->selectClause);
- $sql .= $this->walkFromClause($AST->fromClause);
- $sql .= $this->walkWhereClause($AST->whereClause);
- $sql .= $AST->groupByClause ? $this->walkGroupByClause($AST->groupByClause) : '';
- $sql .= $AST->havingClause ? $this->walkHavingClause($AST->havingClause) : '';
+ $limit = $this->query->getMaxResults();
+ $offset = $this->query->getFirstResult();
+ $lockMode = $this->query->getHint(Query::HINT_LOCK_MODE);
+ $sql = $this->walkSelectClause($AST->selectClause)
+ . $this->walkFromClause($AST->fromClause)
+ . $this->walkWhereClause($AST->whereClause);
- if (($orderByClause = $AST->orderByClause) !== null) {
- $sql .= $AST->orderByClause ? $this->walkOrderByClause($AST->orderByClause) : '';
- } else if (($orderBySql = $this->_generateOrderedCollectionOrderByItems()) !== '') {
+ if ($AST->groupByClause) {
+ $sql .= $this->walkGroupByClause($AST->groupByClause);
+ }
+
+ if ($AST->havingClause) {
+ $sql .= $this->walkHavingClause($AST->havingClause);
+ }
+
+ if ($AST->orderByClause) {
+ $sql .= $this->walkOrderByClause($AST->orderByClause);
+ }
+
+ if ( ! $AST->orderByClause && ($orderBySql = $this->_generateOrderedCollectionOrderByItems())) {
$sql .= ' ORDER BY ' . $orderBySql;
}
- $sql = $this->platform->modifyLimitQuery(
- $sql, $this->query->getMaxResults(), $this->query->getFirstResult()
- );
+ if ($limit !== null || $offset !== null) {
+ $sql = $this->platform->modifyLimitQuery($sql, $limit, $offset);
+ }
- if (($lockMode = $this->query->getHint(Query::HINT_LOCK_MODE)) !== false) {
- switch ($lockMode) {
- case LockMode::PESSIMISTIC_READ:
- $sql .= ' ' . $this->platform->getReadLockSQL();
- break;
+ if ($lockMode === false || $lockMode === LockMode::NONE) {
+ return $sql;
+ }
- case LockMode::PESSIMISTIC_WRITE:
- $sql .= ' ' . $this->platform->getWriteLockSQL();
- break;
+ if ($lockMode === LockMode::PESSIMISTIC_READ) {
+ return $sql . ' ' . $this->platform->getReadLockSQL();
+ }
- case LockMode::OPTIMISTIC:
- foreach ($this->selectedClasses as $selectedClass) {
- if ( ! $selectedClass['class']->isVersioned) {
- throw \Doctrine\ORM\OptimisticLockException::lockFailed($selectedClass['class']->name);
- }
- }
- break;
- case LockMode::NONE:
- break;
+ if ($lockMode === LockMode::PESSIMISTIC_WRITE) {
+ return $sql . ' ' . $this->platform->getWriteLockSQL();
+ }
- default:
- throw \Doctrine\ORM\Query\QueryException::invalidLockMode();
+ if ($lockMode !== LockMode::OPTIMISTIC) {
+ throw QueryException::invalidLockMode();
+ }
+
+ foreach ($this->selectedClasses as $selectedClass) {
+ if ( ! $selectedClass['class']->isVersioned) {
+ throw OptimisticLockException::lockFailed($selectedClass['class']->name);
}
}
@@ -998,12 +1025,15 @@ class SqlWalker implements TreeWalker
*/
public function walkOrderByItem($orderByItem)
{
+ $type = strtoupper($orderByItem->type);
$expr = $orderByItem->expression;
$sql = ($expr instanceof AST\Node)
? $expr->dispatch($this)
: $this->walkResultVariable($this->queryComponents[$expr]['token']['value']);
- return $sql . ' ' . strtoupper($orderByItem->type);
+ $this->orderedColumnsMap[$sql] = $type;
+
+ return $sql . ' ' . $type;
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index d15f78d48..26a6a1ec1 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1971,6 +1971,21 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
+ /**
+ * @group DDC-2475
+ */
+ public function testOrderByClauseShouldReplaceOrderByRelationMapping()
+ {
+ $this->assertSqlGeneration(
+ 'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b',
+ 'SELECT r0_.id AS id0, r1_.id AS id1, r1_.passengerName AS passengerName2 FROM RoutingRoute r0_ INNER JOIN RoutingRouteBooking r1_ ON r0_.id = r1_.route_id ORDER BY r1_.passengerName ASC'
+ );
+
+ $this->assertSqlGeneration(
+ 'SELECT r, b FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.bookings b ORDER BY b.passengerName DESC',
+ 'SELECT r0_.id AS id0, r1_.id AS id1, r1_.passengerName AS passengerName2 FROM RoutingRoute r0_ INNER JOIN RoutingRouteBooking r1_ ON r0_.id = r1_.route_id ORDER BY r1_.passengerName DESC'
+ );
+ }
}
class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
From 424793c2635b91932a7cad11f118c6bb13536066 Mon Sep 17 00:00:00 2001
From: Matthieu Napoli
Date: Thu, 6 Jun 2013 11:36:02 +0300
Subject: [PATCH 146/332] Fixed rendering
Fixed some broken rendering on http://docs.doctrine-project.org/en/latest/reference/yaml-mapping.html
---
docs/en/reference/yaml-mapping.rst | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/docs/en/reference/yaml-mapping.rst b/docs/en/reference/yaml-mapping.rst
index 9a00d08b3..bc6c64c8f 100644
--- a/docs/en/reference/yaml-mapping.rst
+++ b/docs/en/reference/yaml-mapping.rst
@@ -19,8 +19,6 @@ In order to work, this requires certain conventions:
convention and you are not forced to do this. You can change the
file extension easily enough.
--
-
.. code-block:: php
Date: Thu, 6 Jun 2013 15:08:22 -0700
Subject: [PATCH 147/332] Implement QuoteStrategy on SqlWalker
walkRangeVariableDeclaration
Based on:
http://www.doctrine-project.org/jira/browse/DDC-1845
https://github.com/doctrine/doctrine2/commit/cb72219b118c158c9b5344c4b81ff2b1a9149ab0
---
lib/Doctrine/ORM/Query/SqlWalker.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index b971bcfe5..9a9ecf58c 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -844,8 +844,8 @@ class SqlWalker implements TreeWalker
$this->rootAliases[] = $dqlAlias;
- $sql = $class->getQuotedTableName($this->platform) . ' '
- . $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
+ $sql = $this->quoteStrategy->getTableName($class,$this->platform) . ' '
+ . $this->getSQLTableAlias($class->getTableName(), $dqlAlias);
if ($class->isInheritanceTypeJoined()) {
$sql .= $this->_generateClassTableInheritanceJoins($class, $dqlAlias);
From 9bea612d7405c90ac979f41171b0257d2c49d31b Mon Sep 17 00:00:00 2001
From: John Brown
Date: Thu, 6 Jun 2013 15:51:23 -0700
Subject: [PATCH 148/332] Adding simple test to ensure quoting of table names
still functions. Note: the funtionality of this change won't be noticiable
unless a custom quote strategy is implemented
---
.../Tests/ORM/Query/SelectSqlGenerationTest.php | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index 26a6a1ec1..1b2c58b8c 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1831,6 +1831,17 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
+ /**
+ * @group DDC-1845
+ */
+ public function testQuotedTableDeclaration()
+ {
+ $this->assertSqlGeneration(
+ 'SELECT u FROM Doctrine\Tests\Models\Quote\User u',
+ 'SELECT q0_."user-id" AS userid0, q0_."user-name" AS username1 FROM "quote-user" q0_'
+ );
+ }
+
/**
* @group DDC-1845
*/
From afb9c829e2fb2395924d1064a47a2ac2f64883e0 Mon Sep 17 00:00:00 2001
From: John Brown
Date: Fri, 7 Jun 2013 08:49:49 -0700
Subject: [PATCH 149/332] updating sql walker to use quote strategy in joins
---
lib/Doctrine/ORM/Query/SqlWalker.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 9a9ecf58c..820438a59 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -875,7 +875,7 @@ class SqlWalker implements TreeWalker
$relation = $this->queryComponents[$joinedDqlAlias]['relation'];
$targetClass = $this->em->getClassMetadata($relation['targetEntity']);
$sourceClass = $this->em->getClassMetadata($relation['sourceEntity']);
- $targetTableName = $targetClass->getQuotedTableName($this->platform);
+ $targetTableName = $this->quoteStrategy->getTableName($targetClass,$this->platform);
$targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName(), $joinedDqlAlias);
$sourceTableAlias = $this->getSQLTableAlias($sourceClass->getTableName(), $associationPathExpression->identificationVariable);
From 4ef043fc3b05f8f610a211d597e802c9c8131c16 Mon Sep 17 00:00:00 2001
From: John Brown
Date: Fri, 7 Jun 2013 08:56:58 -0700
Subject: [PATCH 150/332] updating sql walker to use quote strategy in joins
---
lib/Doctrine/ORM/Query/SqlWalker.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index 820438a59..abbb97374 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -930,7 +930,7 @@ class SqlWalker implements TreeWalker
// Join relation table
$joinTable = $assoc['joinTable'];
$joinTableAlias = $this->getSQLTableAlias($joinTable['name'], $joinedDqlAlias);
- $joinTableName = $sourceClass->getQuotedJoinTableName($assoc, $this->platform);
+ $joinTableName = $this->quoteStrategy->getJoinTableName($assoc, $sourceClass, $this->platform);
$conditions = array();
$relationColumns = ($relation['isOwningSide'])
From 710d0d1109720810cb3d4a226cbb2d9db8ba668f Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Fri, 7 Jun 2013 17:01:52 -0400
Subject: [PATCH 151/332] Fix DDC-1995
---
.../ORM/Mapping/ClassMetadataInfo.php | 14 ++++
lib/Doctrine/ORM/Query.php | 21 +++--
lib/Doctrine/ORM/Query/ResultSetMapping.php | 18 +++++
lib/Doctrine/ORM/Query/SqlWalker.php | 35 ++++----
.../ORM/Functional/Ticket/DDC1995Test.php | 81 +++++++++++++++++++
5 files changed, 148 insertions(+), 21 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index cda11d44b..da2b1caa6 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -3026,4 +3026,18 @@ class ClassMetadataInfo implements ClassMetadata
return $className;
}
+
+ /**
+ * @param string $name
+ *
+ * @return mixed
+ */
+ public function getMetadataValue($name) {
+
+ if (isset($this->$name)) {
+ return $this->$name;
+ }
+
+ return null;
+ }
}
diff --git a/lib/Doctrine/ORM/Query.php b/lib/Doctrine/ORM/Query.php
index 107055ed3..71f5f5550 100644
--- a/lib/Doctrine/ORM/Query.php
+++ b/lib/Doctrine/ORM/Query.php
@@ -26,6 +26,8 @@ use Doctrine\DBAL\LockMode;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\ParserResult;
use Doctrine\ORM\Query\QueryException;
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\ORM\Query\ParameterTypeInferer;
/**
* A Query object represents a DQL query.
@@ -268,6 +270,10 @@ final class Query extends AbstractQuery
$executor->setQueryCacheProfile($this->_queryCacheProfile);
}
+ if ($this->_resultSetMapping === null) {
+ $this->_resultSetMapping = $this->_parserResult->getResultSetMapping();
+ }
+
// Prepare parameters
$paramMappings = $this->_parserResult->getParameterMappings();
@@ -277,10 +283,6 @@ final class Query extends AbstractQuery
list($sqlParams, $types) = $this->processParameterMappings($paramMappings);
- if ($this->_resultSetMapping === null) {
- $this->_resultSetMapping = $this->_parserResult->getResultSetMapping();
- }
-
return $executor->execute($this->_em->getConnection(), $sqlParams, $types);
}
@@ -299,16 +301,21 @@ final class Query extends AbstractQuery
$types = array();
foreach ($this->parameters as $parameter) {
- $key = $parameter->getName();
+ $key = $parameter->getName();
+ $value = $parameter->getValue();
if ( ! isset($paramMappings[$key])) {
throw QueryException::unknownParameter($key);
}
- $value = $this->processParameterValue($parameter->getValue());
+ if (isset($this->_resultSetMapping->metadataParameterMapping[$key]) && $value instanceof ClassMetadata) {
+ $value = $value->getMetadataValue($this->_resultSetMapping->metadataParameterMapping[$key]);
+ }
+
+ $value = $this->processParameterValue($value);
$type = ($parameter->getValue() === $value)
? $parameter->getType()
- : Query\ParameterTypeInferer::inferType($value);
+ : ParameterTypeInferer::inferType($value);
foreach ($paramMappings[$key] as $position) {
$types[$position] = $type;
diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php
index b06b68385..2f1727383 100644
--- a/lib/Doctrine/ORM/Query/ResultSetMapping.php
+++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php
@@ -153,6 +153,13 @@ class ResultSetMapping
*/
public $newObjectMappings = array();
+ /**
+ * Maps metadata parameter names to the metadata attribute.
+ *
+ * @var array
+ */
+ public $metadataParameterMapping = array();
+
/**
* Adds an entity result to this ResultSetMapping.
*
@@ -371,6 +378,17 @@ class ResultSetMapping
return $this;
}
+ /**
+ * Adds a metadata parameter mappings.
+ *
+ * @param mixed $parameter The parameter name in the SQL result set.
+ * @param string $attribute The metadata attribute.
+ */
+ public function addMetadataParameterMapping($parameter, $attribute)
+ {
+ $this->metadataParameterMapping[$parameter] = $attribute;
+ }
+
/**
* Checks whether a column with a given name is mapped as a scalar result.
*
diff --git a/lib/Doctrine/ORM/Query/SqlWalker.php b/lib/Doctrine/ORM/Query/SqlWalker.php
index b971bcfe5..c048ba2c9 100644
--- a/lib/Doctrine/ORM/Query/SqlWalker.php
+++ b/lib/Doctrine/ORM/Query/SqlWalker.php
@@ -1972,24 +1972,31 @@ class SqlWalker implements TreeWalker
$sqlParameterList = array();
foreach ($instanceOfExpr->value as $parameter) {
+
if ($parameter instanceof AST\InputParameter) {
+
+ $this->rsm->addMetadataParameterMapping($parameter->name, 'discriminatorValue');
+
$sqlParameterList[] = $this->walkInputParameter($parameter);
- } else {
- // Get name from ClassMetadata to resolve aliases.
- $entityClassName = $this->em->getClassMetadata($parameter)->name;
- if ($entityClassName == $class->name) {
- $sqlParameterList[] = $this->conn->quote($class->discriminatorValue);
- } else {
- $discrMap = array_flip($class->discriminatorMap);
-
- if (!isset($discrMap[$entityClassName])) {
- throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
- }
-
- $sqlParameterList[] = $this->conn->quote($discrMap[$entityClassName]);
- }
+ continue;
}
+
+ // Get name from ClassMetadata to resolve aliases.
+ $entityClassName = $this->em->getClassMetadata($parameter)->name;
+ $discriminatorValue = $class->discriminatorValue;
+
+ if ($entityClassName !== $class->name) {
+ $discrMap = array_flip($class->discriminatorMap);
+
+ if ( ! isset($discrMap[$entityClassName])) {
+ throw QueryException::instanceOfUnrelatedClass($entityClassName, $class->rootEntityName);
+ }
+
+ $discriminatorValue = $discrMap[$entityClassName];
+ }
+
+ $sqlParameterList[] = $this->conn->quote($discriminatorValue);
}
$sql .= '(' . implode(', ', $sqlParameterList) . ')';
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php
new file mode 100644
index 000000000..0bfd73960
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1995Test.php
@@ -0,0 +1,81 @@
+useModelSet('company');
+ parent::setUp();
+ }
+
+ public function testIssue()
+ {
+ $person = new CompanyPerson;
+ $person->setName('p1');
+
+ $employee = new CompanyEmployee;
+ $employee->setName('Foo');
+ $employee->setDepartment('bar');
+ $employee->setSalary(1000);
+
+ $this->_em->persist($person);
+ $this->_em->persist($employee);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $dql = 'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1';
+ $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee');
+
+ $result = $this->_em->createQuery($dql)
+ ->setParameter(1, $class)
+ ->getResult();
+
+ $this->assertCount(1, $result);
+ $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $result[0]);
+ }
+
+ public function testQueryCache()
+ {
+ $person = new CompanyPerson;
+ $person->setName('p1');
+
+ $employee = new CompanyEmployee;
+ $employee->setName('Foo');
+ $employee->setDepartment('bar');
+ $employee->setSalary(1000);
+
+ $this->_em->persist($person);
+ $this->_em->persist($employee);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $dql = 'SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF :type';
+ $class1 = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee');
+ $class2 = $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyPerson');
+
+ $result1 = $this->_em->createQuery($dql)
+ ->setParameter('type', $class1)
+ ->useQueryCache(true)
+ ->getResult();
+
+ $result2 = $this->_em->createQuery($dql)
+ ->setParameter('type', $class2)
+ ->useQueryCache(true)
+ ->getResult();
+
+ $this->assertCount(1, $result1);
+ $this->assertCount(1, $result2);
+
+ $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $result1[0]);
+ $this->assertInstanceOf('Doctrine\Tests\Models\Company\CompanyPerson', $result2[0]);
+ $this->assertNotInstanceOf('Doctrine\Tests\Models\Company\CompanyEmployee', $result2[0]);
+ }
+}
\ No newline at end of file
From 4e99c5c127c810bf63c9a371f87f0ff5c82e3e79 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Tue, 11 Jun 2013 01:21:47 -0400
Subject: [PATCH 152/332] DDC-1858 Added coverage to ticket. Functionality
already implemented.
---
.../ORM/Query/LanguageRecognitionTest.php | 8 +++++
.../ORM/Query/SelectSqlGenerationTest.php | 30 ++++++++++++++++---
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php
index f71c5c7f1..ca9085457 100644
--- a/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/LanguageRecognitionTest.php
@@ -590,6 +590,14 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertValidDQL("select COALESCE(NULLIF(u.name, ''), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u");
}
+
+ /**
+ * @gorup DDC-1858
+ */
+ public function testHavingSupportIsNullExpression()
+ {
+ $this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL");
+ }
}
/** @Entity */
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index 26a6a1ec1..e311214b1 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1916,7 +1916,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
{
$connMock = $this->_em->getConnection();
$orgPlatform = $connMock->getDatabasePlatform();
-
+
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
$this->assertSqlGeneration(
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
@@ -1926,7 +1926,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
"SELECT CONCAT(c0_.id, c0_.name, c0_.status) AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
);
-
+
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$this->assertSqlGeneration(
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
@@ -1936,7 +1936,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
"SELECT c0_.id || c0_.name || c0_.status AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
);
-
+
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SQLServerPlatform());
$this->assertSqlGeneration(
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, u.status, 's') = ?1",
@@ -1946,7 +1946,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"SELECT CONCAT(u.id, u.name, u.status) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
"SELECT (c0_.id + c0_.name + c0_.status) AS sclr0 FROM cms_users c0_ WITH (NOLOCK) WHERE c0_.id = ?"
);
-
+
$connMock->setDatabasePlatform($orgPlatform);
}
@@ -1986,6 +1986,28 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
'SELECT r0_.id AS id0, r1_.id AS id1, r1_.passengerName AS passengerName2 FROM RoutingRoute r0_ INNER JOIN RoutingRouteBooking r1_ ON r0_.id = r1_.route_id ORDER BY r1_.passengerName DESC'
);
}
+
+ /**
+ * @group DDC-1858
+ */
+ public function testHavingSupportIsNullExpression()
+ {
+ $this->assertSqlGeneration(
+ 'SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING u.username IS NULL',
+ 'SELECT c0_.name AS name0 FROM cms_users c0_ HAVING c0_.username IS NULL'
+ );
+ }
+
+ /**
+ * @group DDC-1858
+ */
+ public function testHavingSupportResultVariableInExpression()
+ {
+ $this->assertSqlGeneration(
+ 'SELECT u.name AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u HAVING foo IN (?1)',
+ 'SELECT c0_.name AS name0 FROM cms_users c0_ HAVING name0 IN (?)'
+ );
+ }
}
class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
From 529064aff2cffb71580ee64f6fb4bb4b7f145b7e Mon Sep 17 00:00:00 2001
From: Dustin Thomson
Date: Tue, 11 Jun 2013 18:09:49 -0600
Subject: [PATCH 153/332] Modified identity function to work with joined
inheritance tables. Added regression tests
---
.../ORM/Query/AST/Functions/IdentityFunction.php | 5 ++++-
.../Tests/ORM/Query/SelectSqlGenerationTest.php | 15 +++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
index 5f51a9044..58f0dde13 100644
--- a/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
+++ b/lib/Doctrine/ORM/Query/AST/Functions/IdentityFunction.php
@@ -82,7 +82,10 @@ class IdentityFunction extends FunctionNode
}
}
- $tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
+ //The table with the relation may be a subclass, so get the table name from the association definition
+ $tableName = $sqlWalker->getEntityManager()->getClassMetadata($assoc['sourceEntity'])->getTableName();
+
+ $tableAlias = $sqlWalker->getSQLTableAlias($tableName, $dqlAlias);
$columnName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform);
return $tableAlias . '.' . $columnName;
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index e311214b1..cb610a859 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1303,6 +1303,21 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
+ public function testIdenityFunctionInJoinedSubclass()
+ {
+ //relation is in the subclass (CompanyManager) we are querying
+ $this->assertSqlGeneration(
+ 'SELECT m, IDENTITY(m.car) as car_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c2_.car_id AS sclr6, c0_.discr AS discr7 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id'
+ );
+
+ //relation is in the base class (CompanyPerson).
+ $this->assertSqlGeneration(
+ 'SELECT m, IDENTITY(m.spouse) as spouse_id FROM Doctrine\Tests\Models\Company\CompanyManager m',
+ 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.spouse_id AS sclr6, c0_.discr AS discr7 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id'
+ );
+ }
+
/**
* @group DDC-1339
*/
From ed7a4bdcf3897b91b39b1b3b281cea2e4a406fbc Mon Sep 17 00:00:00 2001
From: Dustin Thomson
Date: Tue, 11 Jun 2013 18:38:05 -0600
Subject: [PATCH 154/332] Fix typo in test name
---
tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index cb610a859..a924ed741 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1303,7 +1303,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
- public function testIdenityFunctionInJoinedSubclass()
+ public function testIdentityFunctionInJoinedSubclass()
{
//relation is in the subclass (CompanyManager) we are querying
$this->assertSqlGeneration(
From 0d834d0bd4015de2c103a03592c1543399f1b363 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Wed, 12 Jun 2013 00:31:25 -0400
Subject: [PATCH 155/332] DDC-2489 Added missing semicolon when dump-sql on
schema update.
---
.../ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
index 577fb9e0f..0c2665eda 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/UpdateCommand.php
@@ -123,7 +123,7 @@ EOT
$force = true === $input->getOption('force');
if ($dumpSql) {
- $output->writeln(implode(';' . PHP_EOL, $sqls));
+ $output->writeln(implode(';' . PHP_EOL, $sqls) . ';');
}
if ($force) {
@@ -138,7 +138,7 @@ EOT
if ($dumpSql || $force) {
return 0;
}
-
+
$output->writeln('ATTENTION: This operation should not be executed in a production environment.');
$output->writeln(' Use the incremental update to detect changes during development and use');
$output->writeln(' the SQL DDL provided to manually update your database in production.');
From 3d86c82a7fb51875d1b6c66b865134c9ccf1a878 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Wed, 12 Jun 2013 02:00:36 -0400
Subject: [PATCH 156/332] DDC-2476 Better approach for reverse engineer. Some
refactoring done to driver.
---
.../ORM/Mapping/Driver/DatabaseDriver.php | 633 +++++++++++-------
.../ORM/Functional/DatabaseDriverTest.php | 53 ++
2 files changed, 433 insertions(+), 253 deletions(-)
diff --git a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
index 007be9639..9a12bbc72 100644
--- a/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
+++ b/lib/Doctrine/ORM/Mapping/Driver/DatabaseDriver.php
@@ -19,12 +19,15 @@
namespace Doctrine\ORM\Mapping\Driver;
-use Doctrine\DBAL\Schema\AbstractSchemaManager;
-use Doctrine\DBAL\Schema\SchemaException;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
-use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\Common\Util\Inflector;
+use Doctrine\DBAL\Schema\AbstractSchemaManager;
+use Doctrine\DBAL\Schema\SchemaException;
+use Doctrine\DBAL\Schema\Table;
+use Doctrine\DBAL\Schema\Column;
+use Doctrine\DBAL\Types\Type;
+use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Mapping\MappingException;
/**
@@ -84,249 +87,15 @@ class DatabaseDriver implements MappingDriver
}
/**
- * Sets tables manually instead of relying on the reverse engineering capabilities of SchemaManager.
+ * Set the namespace for the generated entities.
*
- * @param array $entityTables
- * @param array $manyToManyTables
+ * @param string $namespace
*
* @return void
*/
- public function setTables($entityTables, $manyToManyTables)
+ public function setNamespace($namespace)
{
- $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
- foreach ($entityTables as $table) {
- $className = $this->getClassNameForTable($table->getName());
- $this->classToTableNames[$className] = $table->getName();
- $this->tables[$table->getName()] = $table;
- }
- foreach ($manyToManyTables as $table) {
- $this->manyToManyTables[$table->getName()] = $table;
- }
- }
-
- /**
- * @return void
- *
- * @throws \Doctrine\ORM\Mapping\MappingException
- */
- private function reverseEngineerMappingFromDatabase()
- {
- if ($this->tables !== null) {
- return;
- }
-
- $tables = array();
-
- foreach ($this->_sm->listTableNames() as $tableName) {
- $tables[$tableName] = $this->_sm->listTableDetails($tableName);
- }
-
- $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
- foreach ($tables as $tableName => $table) {
- /* @var $table \Doctrine\DBAL\Schema\Table */
- if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
- $foreignKeys = $table->getForeignKeys();
- } else {
- $foreignKeys = array();
- }
-
- $allForeignKeyColumns = array();
- foreach ($foreignKeys as $foreignKey) {
- $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
- }
-
- if ( ! $table->hasPrimaryKey()) {
- throw new MappingException(
- "Table " . $table->getName() . " has no primary key. Doctrine does not ".
- "support reverse engineering from tables that don't have a primary key."
- );
- }
-
- $pkColumns = $table->getPrimaryKey()->getColumns();
- sort($pkColumns);
- sort($allForeignKeyColumns);
-
- if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
- $this->manyToManyTables[$tableName] = $table;
- } else {
- // lower-casing is necessary because of Oracle Uppercase Tablenames,
- // assumption is lower-case + underscore separated.
- $className = $this->getClassNameForTable($tableName);
- $this->tables[$tableName] = $table;
- $this->classToTableNames[$className] = $tableName;
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public function loadMetadataForClass($className, ClassMetadata $metadata)
- {
- $this->reverseEngineerMappingFromDatabase();
-
- if (!isset($this->classToTableNames[$className])) {
- throw new \InvalidArgumentException("Unknown class " . $className);
- }
-
- $tableName = $this->classToTableNames[$className];
-
- $metadata->name = $className;
- $metadata->table['name'] = $tableName;
-
- $columns = $this->tables[$tableName]->getColumns();
- $indexes = $this->tables[$tableName]->getIndexes();
- try {
- $primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns();
- } catch(SchemaException $e) {
- $primaryKeyColumns = array();
- }
-
- if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
- $foreignKeys = $this->tables[$tableName]->getForeignKeys();
- } else {
- $foreignKeys = array();
- }
-
- $allForeignKeyColumns = array();
- foreach ($foreignKeys as $foreignKey) {
- $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
- }
-
- $ids = array();
- $fieldMappings = array();
- foreach ($columns as $column) {
- $fieldMapping = array();
-
- if (in_array($column->getName(), $allForeignKeyColumns)) {
- continue;
- } else if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
- $fieldMapping['id'] = true;
- }
-
- $fieldMapping['fieldName'] = $this->getFieldNameForColumn($tableName, $column->getName(), false);
- $fieldMapping['columnName'] = $column->getName();
- $fieldMapping['type'] = strtolower((string) $column->getType());
-
- if ($column->getType() instanceof \Doctrine\DBAL\Types\StringType) {
- $fieldMapping['length'] = $column->getLength();
- $fieldMapping['fixed'] = $column->getFixed();
- } else if ($column->getType() instanceof \Doctrine\DBAL\Types\IntegerType) {
- $fieldMapping['unsigned'] = $column->getUnsigned();
- }
- $fieldMapping['nullable'] = $column->getNotNull() ? false : true;
-
- if (isset($fieldMapping['id'])) {
- $ids[] = $fieldMapping;
- } else {
- $fieldMappings[] = $fieldMapping;
- }
- }
-
- if ($ids) {
- // We need to check for the columns here, because we might have associations as id as well.
- if (count($primaryKeyColumns) == 1) {
- $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
- }
-
- foreach ($ids as $id) {
- $metadata->mapField($id);
- }
- }
-
- foreach ($fieldMappings as $fieldMapping) {
- $metadata->mapField($fieldMapping);
- }
-
- foreach ($this->manyToManyTables as $manyTable) {
- foreach ($manyTable->getForeignKeys() as $foreignKey) {
- // foreign key maps to the table of the current entity, many to many association probably exists
- if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) {
- $myFk = $foreignKey;
- $otherFk = null;
- foreach ($manyTable->getForeignKeys() as $foreignKey) {
- if ($foreignKey != $myFk) {
- $otherFk = $foreignKey;
- break;
- }
- }
-
- if (!$otherFk) {
- // the definition of this many to many table does not contain
- // enough foreign key information to continue reverse engineering.
- continue;
- }
-
- $localColumn = current($myFk->getColumns());
- $associationMapping = array();
- $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true);
- $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
- if (current($manyTable->getColumns())->getName() == $localColumn) {
- $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
- $associationMapping['joinTable'] = array(
- 'name' => strtolower($manyTable->getName()),
- 'joinColumns' => array(),
- 'inverseJoinColumns' => array(),
- );
-
- $fkCols = $myFk->getForeignColumns();
- $cols = $myFk->getColumns();
- for ($i = 0; $i < count($cols); $i++) {
- $associationMapping['joinTable']['joinColumns'][] = array(
- 'name' => $cols[$i],
- 'referencedColumnName' => $fkCols[$i],
- );
- }
-
- $fkCols = $otherFk->getForeignColumns();
- $cols = $otherFk->getColumns();
- for ($i = 0; $i < count($cols); $i++) {
- $associationMapping['joinTable']['inverseJoinColumns'][] = array(
- 'name' => $cols[$i],
- 'referencedColumnName' => $fkCols[$i],
- );
- }
- } else {
- $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
- }
- $metadata->mapManyToMany($associationMapping);
- break;
- }
- }
- }
-
- foreach ($foreignKeys as $foreignKey) {
- $foreignTable = $foreignKey->getForeignTableName();
- $cols = $foreignKey->getColumns();
- $fkCols = $foreignKey->getForeignColumns();
-
- $localColumn = current($cols);
- $associationMapping = array();
- $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;
- }
-
- for ($i = 0; $i < count($cols); $i++) {
- $associationMapping['joinColumns'][] = array(
- 'name' => $cols[$i],
- 'referencedColumnName' => $fkCols[$i],
- );
- }
-
- //Here we need to check if $cols are the same as $primaryKeyColumns
- if (!array_diff($cols,$primaryKeyColumns)) {
- $metadata->mapOneToOne($associationMapping);
- } else {
- $metadata->mapManyToOne($associationMapping);
- }
- }
+ $this->namespace = $namespace;
}
/**
@@ -374,6 +143,376 @@ class DatabaseDriver implements MappingDriver
$this->fieldNamesForColumns[$tableName][$columnName] = $fieldName;
}
+ /**
+ * Sets tables manually instead of relying on the reverse engineering capabilities of SchemaManager.
+ *
+ * @param array $entityTables
+ * @param array $manyToManyTables
+ *
+ * @return void
+ */
+ public function setTables($entityTables, $manyToManyTables)
+ {
+ $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
+
+ foreach ($entityTables as $table) {
+ $className = $this->getClassNameForTable($table->getName());
+
+ $this->classToTableNames[$className] = $table->getName();
+ $this->tables[$table->getName()] = $table;
+ }
+
+ foreach ($manyToManyTables as $table) {
+ $this->manyToManyTables[$table->getName()] = $table;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function loadMetadataForClass($className, ClassMetadata $metadata)
+ {
+ $this->reverseEngineerMappingFromDatabase();
+
+ if ( ! isset($this->classToTableNames[$className])) {
+ throw new \InvalidArgumentException("Unknown class " . $className);
+ }
+
+ $tableName = $this->classToTableNames[$className];
+
+ $metadata->name = $className;
+ $metadata->table['name'] = $tableName;
+
+ $this->buildIndexes($metadata);
+ $this->buildFieldMappings($metadata);
+ $this->buildToOneAssociationMappings($metadata);
+
+ foreach ($this->manyToManyTables as $manyTable) {
+ foreach ($manyTable->getForeignKeys() as $foreignKey) {
+ // foreign key maps to the table of the current entity, many to many association probably exists
+ if ( ! (strtolower($tableName) === strtolower($foreignKey->getForeignTableName()))) {
+ continue;
+ }
+
+ $myFk = $foreignKey;
+ $otherFk = null;
+
+ foreach ($manyTable->getForeignKeys() as $foreignKey) {
+ if ($foreignKey != $myFk) {
+ $otherFk = $foreignKey;
+ break;
+ }
+ }
+
+ if ( ! $otherFk) {
+ // the definition of this many to many table does not contain
+ // enough foreign key information to continue reverse engineering.
+ continue;
+ }
+
+ $localColumn = current($myFk->getColumns());
+
+ $associationMapping = array();
+ $associationMapping['fieldName'] = $this->getFieldNameForColumn($manyTable->getName(), current($otherFk->getColumns()), true);
+ $associationMapping['targetEntity'] = $this->getClassNameForTable($otherFk->getForeignTableName());
+
+ if (current($manyTable->getColumns())->getName() == $localColumn) {
+ $associationMapping['inversedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
+ $associationMapping['joinTable'] = array(
+ 'name' => strtolower($manyTable->getName()),
+ 'joinColumns' => array(),
+ 'inverseJoinColumns' => array(),
+ );
+
+ $fkCols = $myFk->getForeignColumns();
+ $cols = $myFk->getColumns();
+
+ for ($i = 0; $i < count($cols); $i++) {
+ $associationMapping['joinTable']['joinColumns'][] = array(
+ 'name' => $cols[$i],
+ 'referencedColumnName' => $fkCols[$i],
+ );
+ }
+
+ $fkCols = $otherFk->getForeignColumns();
+ $cols = $otherFk->getColumns();
+
+ for ($i = 0; $i < count($cols); $i++) {
+ $associationMapping['joinTable']['inverseJoinColumns'][] = array(
+ 'name' => $cols[$i],
+ 'referencedColumnName' => $fkCols[$i],
+ );
+ }
+ } else {
+ $associationMapping['mappedBy'] = $this->getFieldNameForColumn($manyTable->getName(), current($myFk->getColumns()), true);
+ }
+
+ $metadata->mapManyToMany($associationMapping);
+
+ break;
+ }
+ }
+ }
+
+ /**
+ * @return void
+ *
+ * @throws \Doctrine\ORM\Mapping\MappingException
+ */
+ private function reverseEngineerMappingFromDatabase()
+ {
+ if ($this->tables !== null) {
+ return;
+ }
+
+ $tables = array();
+
+ foreach ($this->_sm->listTableNames() as $tableName) {
+ $tables[$tableName] = $this->_sm->listTableDetails($tableName);
+ }
+
+ $this->tables = $this->manyToManyTables = $this->classToTableNames = array();
+
+ foreach ($tables as $tableName => $table) {
+ $foreignKeys = ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints())
+ ? $table->getForeignKeys()
+ : array();
+
+ $allForeignKeyColumns = array();
+
+ foreach ($foreignKeys as $foreignKey) {
+ $allForeignKeyColumns = array_merge($allForeignKeyColumns, $foreignKey->getLocalColumns());
+ }
+
+ if ( ! $table->hasPrimaryKey()) {
+ throw new MappingException(
+ "Table " . $table->getName() . " has no primary key. Doctrine does not ".
+ "support reverse engineering from tables that don't have a primary key."
+ );
+ }
+
+ $pkColumns = $table->getPrimaryKey()->getColumns();
+
+ sort($pkColumns);
+ sort($allForeignKeyColumns);
+
+ if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
+ $this->manyToManyTables[$tableName] = $table;
+ } else {
+ // lower-casing is necessary because of Oracle Uppercase Tablenames,
+ // assumption is lower-case + underscore separated.
+ $className = $this->getClassNameForTable($tableName);
+
+ $this->tables[$tableName] = $table;
+ $this->classToTableNames[$className] = $tableName;
+ }
+ }
+ }
+
+ /**
+ * Build indexes from a class metadata.
+ *
+ * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
+ */
+ private function buildIndexes(ClassMetadataInfo $metadata)
+ {
+ $tableName = $metadata->table['name'];
+ $indexes = $this->tables[$tableName]->getIndexes();
+
+ foreach($indexes as $index){
+ if ($index->isPrimary()) {
+ continue;
+ }
+
+ $indexName = $index->getName();
+ $indexColumns = $index->getColumns();
+ $constraintType = $index->isUnique()
+ ? 'uniqueConstraints'
+ : 'indexes';
+
+ $metadata->table[$constraintType][$indexName]['columns'] = $indexColumns;
+ }
+ }
+
+ /**
+ * Build field mapping from class metadata.
+ *
+ * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
+ */
+ private function buildFieldMappings(ClassMetadataInfo $metadata)
+ {
+ $tableName = $metadata->table['name'];
+ $columns = $this->tables[$tableName]->getColumns();
+ $primaryKeys = $this->getTablePrimaryKeys($this->tables[$tableName]);
+ $foreignKeys = $this->getTableForeignKeys($this->tables[$tableName]);
+ $allForeignKeys = array();
+
+ foreach ($foreignKeys as $foreignKey) {
+ $allForeignKeys = array_merge($allForeignKeys, $foreignKey->getLocalColumns());
+ }
+
+ $ids = array();
+ $fieldMappings = array();
+
+ foreach ($columns as $column) {
+ if (in_array($column->getName(), $allForeignKeys)) {
+ continue;
+ }
+
+ $fieldMapping = $this->buildFieldMapping($tableName, $column);
+
+ if ($primaryKeys && in_array($column->getName(), $primaryKeys)) {
+ $fieldMapping['id'] = true;
+ $ids[] = $fieldMapping;
+ }
+
+ $fieldMappings[] = $fieldMapping;
+ }
+
+ // We need to check for the columns here, because we might have associations as id as well.
+ if ($ids && count($primaryKeys) == 1) {
+ $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
+ }
+
+ foreach ($fieldMappings as $fieldMapping) {
+ $metadata->mapField($fieldMapping);
+ }
+ }
+
+ /**
+ * Build field mapping from a schema column definition
+ *
+ * @param string $tableName
+ * @param \Doctrine\DBAL\Schema\Column $column
+ *
+ * @return array
+ */
+ private function buildFieldMapping($tableName, Column $column)
+ {
+ $fieldMapping = array(
+ 'fieldName' => $this->getFieldNameForColumn($tableName, $column->getName(), false),
+ 'columnName' => $column->getName(),
+ 'type' => strtolower((string) $column->getType()),
+ 'nullable' => ( ! $column->getNotNull()),
+ );
+
+ // Type specific elements
+ switch ($fieldMapping['type']) {
+ case Type::TARRAY:
+ case Type::BLOB:
+ case Type::GUID:
+ case Type::JSON_ARRAY:
+ case Type::OBJECT:
+ case Type::SIMPLE_ARRAY:
+ case Type::STRING:
+ case Type::TEXT:
+ $fieldMapping['length'] = $column->getLength();
+ $fieldMapping['fixed'] = $column->getFixed();
+ break;
+
+ case Type::DECIMAL:
+ case Type::FLOAT:
+ $fieldMapping['precision'] = $column->getPrecision();
+ $fieldMapping['scale'] = $column->getScale();
+ break;
+
+ case Type::INTEGER:
+ case Type::BIGINT:
+ case Type::SMALLINT:
+ $fieldMapping['unsigned'] = $column->getUnsigned();
+ break;
+ }
+
+ // Comment
+ if (($comment = $column->getComment()) !== null) {
+ $fieldMapping['comment'] = $comment;
+ }
+
+ // Default
+ if (($default = $column->getDefault()) !== null) {
+ $fieldMapping['default'] = $default;
+ }
+
+ return $fieldMapping;
+ }
+
+ /**
+ * Build to one (one to one, many to one) association mapping from class metadata.
+ *
+ * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata
+ */
+ private function buildToOneAssociationMappings(ClassMetadataInfo $metadata)
+ {
+ $tableName = $metadata->table['name'];
+ $primaryKeys = $this->getTablePrimaryKeys($this->tables[$tableName]);
+ $foreignKeys = $this->getTableForeignKeys($this->tables[$tableName]);
+
+ foreach ($foreignKeys as $foreignKey) {
+ $foreignTableName = $foreignKey->getForeignTableName();
+ $fkColumns = $foreignKey->getColumns();
+ $fkForeignColumns = $foreignKey->getForeignColumns();
+ $localColumn = current($fkColumns);
+ $associationMapping = array(
+ 'fieldName' => $this->getFieldNameForColumn($tableName, $localColumn, true),
+ 'targetEntity' => $this->getClassNameForTable($foreignTableName),
+ );
+
+ if (isset($metadata->fieldMappings[$associationMapping['fieldName']])) {
+ $associationMapping['fieldName'] .= '2'; // "foo" => "foo2"
+ }
+
+ if ($primaryKeys && in_array($localColumn, $primaryKeys)) {
+ $associationMapping['id'] = true;
+ }
+
+ for ($i = 0; $i < count($fkColumns); $i++) {
+ $associationMapping['joinColumns'][] = array(
+ 'name' => $fkColumns[$i],
+ 'referencedColumnName' => $fkForeignColumns[$i],
+ );
+ }
+
+ // Here we need to check if $fkColumns are the same as $primaryKeys
+ if ( ! array_diff($fkColumns, $primaryKeys)) {
+ $metadata->mapOneToOne($associationMapping);
+ } else {
+ $metadata->mapManyToOne($associationMapping);
+ }
+ }
+ }
+
+ /**
+ * Retreive schema table definition foreign keys.
+ *
+ * @param \Doctrine\DBAL\Schema\Table $table
+ *
+ * @return array
+ */
+ private function getTableForeignKeys(Table $table)
+ {
+ return ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints())
+ ? $table->getForeignKeys()
+ : array();
+ }
+
+ /**
+ * Retreive schema table definition primary keys.
+ *
+ * @param \Doctrine\DBAL\Schema\Table $table
+ *
+ * @return array
+ */
+ private function getTablePrimaryKeys(Table $table)
+ {
+ try {
+ return $table->getPrimaryKey()->getColumns();
+ } catch(SchemaException $e) {
+ // Do nothing
+ }
+
+ return array();
+ }
+
/**
* Returns the mapped class name for a table if it exists. Otherwise return "classified" version.
*
@@ -413,16 +552,4 @@ class DatabaseDriver implements MappingDriver
}
return Inflector::camelize($columnName);
}
-
- /**
- * Set the namespace for the generated entities.
- *
- * @param string $namespace
- *
- * @return void
- */
- public function setNamespace($namespace)
- {
- $this->namespace = $namespace;
- }
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
index 0c30a0bef..b9039e714 100644
--- a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
@@ -145,4 +145,57 @@ class DatabaseDriverTest extends DatabaseDriverTestCase
$this->assertEquals(0, count($metadatas['DbdriverBaz']->associationMappings), "no association mappings should be detected.");
}
+
+ public function testLoadMetadataFromDatabaseDetail()
+ {
+ if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
+ $this->markTestSkipped('Platform does not support foreign keys.');
+ }
+
+ $table = new \Doctrine\DBAL\Schema\Table("dbdriver_foo");
+ $table->addColumn('id', 'integer',array('unsigned'=>true));
+ $table->setPrimaryKey(array('id'));
+ $table->addColumn('column_unsigned','integer',array('unsigned'=>true));
+ $table->addColumn('column_comment','string',array('comment'=>'test_comment'));
+ $table->addColumn('column_default','string',array('default'=>'test_default'));
+ $table->addColumn('column_decimal','decimal',array('precision'=>4,'scale'=>3));
+
+ $table->addColumn('column_index1','string');
+ $table->addColumn('column_index2','string');
+ $table->addIndex(array('column_index1','column_index2'),'index1');
+
+ $table->addColumn('column_unique_index1','string');
+ $table->addColumn('column_unique_index2','string');
+ $table->addUniqueIndex(array('column_unique_index1','column_unique_index2'),'unique_index1');
+ $this->_sm->dropAndCreateTable($table);
+
+ $metadatas = $this->extractClassMetadata(array("DbdriverFoo"));
+
+ $this->assertArrayHasKey('DbdriverFoo', $metadatas);
+ $metadata = $metadatas['DbdriverFoo'];
+
+ $this->assertArrayHasKey('id', $metadata->fieldMappings);
+ $this->assertEquals('id', $metadata->fieldMappings['id']['fieldName']);
+ $this->assertEquals('id', strtolower($metadata->fieldMappings['id']['columnName']));
+ $this->assertEquals('integer', (string)$metadata->fieldMappings['id']['type']);
+
+ $this->assertArrayHasKey('columnUnsigned', $metadata->fieldMappings);
+ $this->assertTrue($metadata->fieldMappings['columnUnsigned']['unsigned']);
+
+ $this->assertArrayHasKey('columnComment', $metadata->fieldMappings);
+ $this->assertEquals('test_comment', $metadata->fieldMappings['columnComment']['comment']);
+
+ $this->assertArrayHasKey('columnDefault', $metadata->fieldMappings);
+ $this->assertEquals('test_default', $metadata->fieldMappings['columnDefault']['default']);
+
+ $this->assertArrayHasKey('columnDecimal', $metadata->fieldMappings);
+ $this->assertEquals(4, $metadata->fieldMappings['columnDecimal']['precision']);
+ $this->assertEquals(3, $metadata->fieldMappings['columnDecimal']['scale']);
+
+ $this->assertTrue(!empty($metadata->table['indexes']['index1']['columns']));
+ $this->assertEquals(array('column_index1','column_index2'),$metadata->table['indexes']['index1']['columns']);
+
+ $this->assertTrue(!empty($metadata->table['uniqueConstraints']['unique_index1']['columns']));
+ $this->assertEquals(array('column_unique_index1','column_unique_index2'),$metadata->table['uniqueConstraints']['unique_index1']['columns']);
+ }
}
From b15758bb425578159ebe386c3d8fe2f1cc04bccb Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Wed, 12 Jun 2013 02:29:08 -0400
Subject: [PATCH 157/332] DDC-2476 Commented check under PostgreSQL.
---
.../ORM/Functional/DatabaseDriverTest.php | 72 +++++++++++--------
1 file changed, 43 insertions(+), 29 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
index b9039e714..fce29d93c 100644
--- a/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/DatabaseDriverTest.php
@@ -3,6 +3,7 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
+use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
class DatabaseDriverTest extends DatabaseDriverTestCase
{
@@ -148,54 +149,67 @@ class DatabaseDriverTest extends DatabaseDriverTestCase
public function testLoadMetadataFromDatabaseDetail()
{
- if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
+ if ( ! $this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped('Platform does not support foreign keys.');
}
$table = new \Doctrine\DBAL\Schema\Table("dbdriver_foo");
- $table->addColumn('id', 'integer',array('unsigned'=>true));
+
+ $table->addColumn('id', 'integer', array('unsigned' => true));
$table->setPrimaryKey(array('id'));
- $table->addColumn('column_unsigned','integer',array('unsigned'=>true));
- $table->addColumn('column_comment','string',array('comment'=>'test_comment'));
- $table->addColumn('column_default','string',array('default'=>'test_default'));
- $table->addColumn('column_decimal','decimal',array('precision'=>4,'scale'=>3));
+ $table->addColumn('column_unsigned', 'integer', array('unsigned' => true));
+ $table->addColumn('column_comment', 'string', array('comment' => 'test_comment'));
+ $table->addColumn('column_default', 'string', array('default' => 'test_default'));
+ $table->addColumn('column_decimal', 'decimal', array('precision' => 4, 'scale' => 3));
- $table->addColumn('column_index1','string');
- $table->addColumn('column_index2','string');
- $table->addIndex(array('column_index1','column_index2'),'index1');
+ $table->addColumn('column_index1', 'string');
+ $table->addColumn('column_index2', 'string');
+ $table->addIndex(array('column_index1','column_index2'), 'index1');
+
+ $table->addColumn('column_unique_index1', 'string');
+ $table->addColumn('column_unique_index2', 'string');
+ $table->addUniqueIndex(array('column_unique_index1', 'column_unique_index2'), 'unique_index1');
- $table->addColumn('column_unique_index1','string');
- $table->addColumn('column_unique_index2','string');
- $table->addUniqueIndex(array('column_unique_index1','column_unique_index2'),'unique_index1');
$this->_sm->dropAndCreateTable($table);
$metadatas = $this->extractClassMetadata(array("DbdriverFoo"));
$this->assertArrayHasKey('DbdriverFoo', $metadatas);
+
$metadata = $metadatas['DbdriverFoo'];
- $this->assertArrayHasKey('id', $metadata->fieldMappings);
- $this->assertEquals('id', $metadata->fieldMappings['id']['fieldName']);
- $this->assertEquals('id', strtolower($metadata->fieldMappings['id']['columnName']));
- $this->assertEquals('integer', (string)$metadata->fieldMappings['id']['type']);
+ $this->assertArrayHasKey('id', $metadata->fieldMappings);
+ $this->assertEquals('id', $metadata->fieldMappings['id']['fieldName']);
+ $this->assertEquals('id', strtolower($metadata->fieldMappings['id']['columnName']));
+ $this->assertEquals('integer', (string) $metadata->fieldMappings['id']['type']);
- $this->assertArrayHasKey('columnUnsigned', $metadata->fieldMappings);
- $this->assertTrue($metadata->fieldMappings['columnUnsigned']['unsigned']);
+ // FIXME: Condition here is fugly.
+ // NOTE: PostgreSQL does not support UNSIGNED
+ if ( ! $this->_em->getConnection()->getDatabasePlatform() instanceof PostgreSqlPlatform) {
+ $this->assertArrayHasKey('columnUnsigned', $metadata->fieldMappings);
+ $this->assertTrue($metadata->fieldMappings['columnUnsigned']['unsigned']);
+ }
- $this->assertArrayHasKey('columnComment', $metadata->fieldMappings);
- $this->assertEquals('test_comment', $metadata->fieldMappings['columnComment']['comment']);
+ $this->assertArrayHasKey('columnComment', $metadata->fieldMappings);
+ $this->assertEquals('test_comment', $metadata->fieldMappings['columnComment']['comment']);
- $this->assertArrayHasKey('columnDefault', $metadata->fieldMappings);
- $this->assertEquals('test_default', $metadata->fieldMappings['columnDefault']['default']);
+ $this->assertArrayHasKey('columnDefault', $metadata->fieldMappings);
+ $this->assertEquals('test_default', $metadata->fieldMappings['columnDefault']['default']);
- $this->assertArrayHasKey('columnDecimal', $metadata->fieldMappings);
- $this->assertEquals(4, $metadata->fieldMappings['columnDecimal']['precision']);
- $this->assertEquals(3, $metadata->fieldMappings['columnDecimal']['scale']);
+ $this->assertArrayHasKey('columnDecimal', $metadata->fieldMappings);
+ $this->assertEquals(4, $metadata->fieldMappings['columnDecimal']['precision']);
+ $this->assertEquals(3, $metadata->fieldMappings['columnDecimal']['scale']);
- $this->assertTrue(!empty($metadata->table['indexes']['index1']['columns']));
- $this->assertEquals(array('column_index1','column_index2'),$metadata->table['indexes']['index1']['columns']);
+ $this->assertTrue( ! empty($metadata->table['indexes']['index1']['columns']));
+ $this->assertEquals(
+ array('column_index1','column_index2'),
+ $metadata->table['indexes']['index1']['columns']
+ );
- $this->assertTrue(!empty($metadata->table['uniqueConstraints']['unique_index1']['columns']));
- $this->assertEquals(array('column_unique_index1','column_unique_index2'),$metadata->table['uniqueConstraints']['unique_index1']['columns']);
+ $this->assertTrue( ! empty($metadata->table['uniqueConstraints']['unique_index1']['columns']));
+ $this->assertEquals(
+ array('column_unique_index1', 'column_unique_index2'),
+ $metadata->table['uniqueConstraints']['unique_index1']['columns']
+ );
}
}
From d685f592fe7afacd99840680a6f12404d5e2ac59 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Tue, 11 Jun 2013 13:44:08 -0400
Subject: [PATCH 158/332] Fix DDC-2494
---
.../Hydration/SimpleObjectHydrator.php | 82 +++----
.../ORM/Persisters/BasicEntityPersister.php | 12 +-
lib/Doctrine/ORM/Query/ResultSetMapping.php | 13 +-
.../ORM/Functional/Ticket/DDC2494Test.php | 211 ++++++++++++++++++
4 files changed, 273 insertions(+), 45 deletions(-)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
index 249b60462..85f3a0fad 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
@@ -114,9 +114,8 @@ class SimpleObjectHydrator extends AbstractHydrator
}
// Convert field to a valid PHP value
- if (isset($cache[$column]['field'])) {
- $type = Type::getType($cache[$column]['class']->fieldMappings[$cache[$column]['name']]['type']);
- $value = $type->convertToPHPValue($value, $this->_platform);
+ if (isset($cache[$column]['type'])) {
+ $value = Type::getType($cache[$column]['type'])->convertToPHPValue($value, $this->_platform);
}
// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
@@ -145,44 +144,51 @@ class SimpleObjectHydrator extends AbstractHydrator
*/
protected function hydrateColumnInfo($entityName, $column)
{
- switch (true) {
- case (isset($this->_rsm->fieldMappings[$column])):
- $class = isset($this->declaringClasses[$column])
- ? $this->declaringClasses[$column]
- : $this->class;
- // If class is not part of the inheritance, ignore
- if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
- return null;
- }
+ if (isset($this->_rsm->fieldMappings[$column])) {
+ $name = $this->_rsm->fieldMappings[$column];
+ $class = isset($this->declaringClasses[$column])
+ ? $this->declaringClasses[$column]
+ : $this->class;
- return array(
- 'class' => $class,
- 'name' => $this->_rsm->fieldMappings[$column],
- 'field' => true,
- );
-
- case (isset($this->_rsm->relationMap[$column])):
- $class = isset($this->_rsm->relationMap[$column])
- ? $this->_rsm->relationMap[$column]
- : $this->class;
-
- // If class is not self referencing, ignore
- if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
- return null;
- }
-
- // TODO: Decide what to do with associations. It seems original code is incomplete.
- // One solution is to load the association, but it might require extra efforts.
- return array('name' => $column);
-
- case (isset($this->_rsm->metaMappings[$column])):
- return array(
- 'name' => $this->_rsm->metaMappings[$column]
- );
-
- default:
+ // If class is not part of the inheritance, ignore
+ if ( ! ($class->name === $entityName || is_subclass_of($entityName, $class->name))) {
return null;
+ }
+
+ return array(
+ 'name' => $name,
+ 'type' => $class->fieldMappings[$name]['type']
+ );
}
+
+ if (isset($this->_rsm->relationMap[$column])) {
+ $class = isset($this->_rsm->relationMap[$column])
+ ? $this->_rsm->relationMap[$column]
+ : $this->class;
+
+ // If class is not self referencing, ignore
+ if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
+ return null;
+ }
+
+ // TODO: Decide what to do with associations. It seems original code is incomplete.
+ // One solution is to load the association, but it might require extra efforts.
+ return array('name' => $column);
+ }
+
+ if (isset($this->_rsm->metaMappings[$column])) {
+ $name = $this->_rsm->metaMappings[$column];
+ $type = isset($this->_rsm->typeMappings[$column])
+ ? $this->_rsm->typeMappings[$column]
+ : null;
+
+ return array(
+ 'name' => $name,
+ 'type' => $type
+ );
+ }
+
+ return null;
}
}
diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
index f101fda13..66e949ca8 100644
--- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
+++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php
@@ -1334,16 +1334,22 @@ class BasicEntityPersister
return '';
}
- $columnList = array();
+ $columnList = array();
+ $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
foreach ($assoc['joinColumns'] as $joinColumn) {
-
+ $type = null;
+ $isIdentifier = isset($assoc['id']) && $assoc['id'] === true;
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
$columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
- $this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, isset($assoc['id']) && $assoc['id'] === true);
+ if (isset($targetClass->fieldNames[$joinColumn['referencedColumnName']])) {
+ $type = $targetClass->fieldMappings[$targetClass->fieldNames[$joinColumn['referencedColumnName']]]['type'];
+ }
+
+ $this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type);
}
return implode(', ', $columnList);
diff --git a/lib/Doctrine/ORM/Query/ResultSetMapping.php b/lib/Doctrine/ORM/Query/ResultSetMapping.php
index 2f1727383..f4d11cf44 100644
--- a/lib/Doctrine/ORM/Query/ResultSetMapping.php
+++ b/lib/Doctrine/ORM/Query/ResultSetMapping.php
@@ -543,14 +543,15 @@ class ResultSetMapping
/**
* Adds a meta column (foreign key or discriminator column) to the result set.
*
- * @param string $alias
- * @param string $columnName
- * @param string $fieldName
+ * @param string $alias The result alias with which the meta result should be placed in the result structure.
+ * @param string $columnName The name of the column in the SQL result set.
+ * @param string $fieldName The name of the field on the declaring class.
* @param bool $isIdentifierColumn
+ * @param string $type The column type
*
* @return ResultSetMapping This ResultSetMapping instance.
*/
- public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false)
+ public function addMetaResult($alias, $columnName, $fieldName, $isIdentifierColumn = false, $type = null)
{
$this->metaMappings[$columnName] = $fieldName;
$this->columnOwnerMap[$columnName] = $alias;
@@ -559,6 +560,10 @@ class ResultSetMapping
$this->isIdentifierColumn[$alias][$columnName] = true;
}
+ if ($type) {
+ $this->typeMappings[$columnName] = $type;
+ }
+
return $this;
}
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
new file mode 100644
index 000000000..4c27fb777
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
@@ -0,0 +1,211 @@
+_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(DDC2494Currency::CLASSNAME),
+ $this->_em->getClassMetadata(DDC2494Campaign::CLASSNAME),
+ ));
+ }
+
+ public function testIssue()
+ {
+ $currency = new DDC2494Currency(1, 2);
+
+ $this->_em->persist($currency);
+ $this->_em->flush();
+
+ $campaign = new DDC2494Campaign($currency);
+
+ $this->_em->persist($campaign);
+ $this->_em->flush();
+ $this->_em->close();
+
+ $this->assertArrayHasKey('convertToDatabaseValue', DDC2494TinyIntType::$calls);
+ $this->assertCount(3, DDC2494TinyIntType::$calls['convertToDatabaseValue']);
+
+ $item = $this->_em->find(DDC2494Campaign::CLASSNAME, $campaign->getId());
+
+ $this->assertInstanceOf(DDC2494Campaign::CLASSNAME, $item);
+ $this->assertInstanceOf(DDC2494Currency::CLASSNAME, $item->getCurrency());
+
+ $queryCount = $this->getCurrentQueryCount();
+
+ $this->assertInstanceOf('\Doctrine\Common\Proxy\Proxy', $item->getCurrency());
+ $this->assertFalse($item->getCurrency()->__isInitialized());
+
+ $this->assertArrayHasKey('convertToPHPValue', DDC2494TinyIntType::$calls);
+ $this->assertCount(1, DDC2494TinyIntType::$calls['convertToPHPValue']);
+
+ $this->assertInternalType('integer', $item->getCurrency()->getId());
+ $this->assertCount(1, DDC2494TinyIntType::$calls['convertToPHPValue']);
+ $this->assertFalse($item->getCurrency()->__isInitialized());
+
+ $this->assertEquals($queryCount, $this->getCurrentQueryCount());
+
+ $this->assertInternalType('integer', $item->getCurrency()->getTemp());
+ $this->assertCount(3, DDC2494TinyIntType::$calls['convertToPHPValue']);
+ $this->assertTrue($item->getCurrency()->__isInitialized());
+
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ }
+}
+
+/**
+ * @Table(name="ddc2494_currency")
+ * @Entity
+ */
+class DDC2494Currency
+{
+ const CLASSNAME = __CLASS__;
+
+ /**
+ * @Id
+ * @Column(type="integer", type="ddc2494_tinyint")
+ */
+ protected $id;
+
+ /**
+ * @Column(name="temp", type="ddc2494_tinyint", nullable=false)
+ */
+ protected $temp;
+
+ /**
+ * @var \Doctrine\Common\Collections\Collection
+ *
+ * @OneToMany(targetEntity="DDC2494Campaign", mappedBy="currency")
+ */
+ protected $campaigns;
+
+ public function __construct($id, $temp)
+ {
+ $this->id = $id;
+ $this->temp = $temp;
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ public function getTemp()
+ {
+ return $this->temp;
+ }
+
+ public function getCampaigns()
+ {
+ return $this->campaigns;
+ }
+}
+
+/**
+ * @Table(name="ddc2494_campaign")
+ * @Entity
+ */
+class DDC2494Campaign
+{
+ const CLASSNAME = __CLASS__;
+
+ /**
+ * @Id
+ * @GeneratedValue
+ * @Column(type="integer")
+ */
+ protected $id;
+
+ /**
+ * @var \Doctrine\Tests\ORM\Functional\Ticket\DDC2494Currency
+ *
+ * @ManyToOne(targetEntity="DDC2494Currency", inversedBy="campaigns")
+ * @JoinColumn(name="currency_id", referencedColumnName="id", nullable=false)
+ */
+ protected $currency;
+
+ public function __construct(DDC2494Currency $currency)
+ {
+ $this->currency = $currency;
+ }
+
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * @return \Doctrine\Tests\ORM\Functional\Ticket\DDC2494Currency
+ */
+ public function getCurrency()
+ {
+ return $this->currency;
+ }
+}
+
+class DDC2494TinyIntType extends Type
+{
+ public static $calls = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+ {
+ return $platform->getSmallIntTypeDeclarationSQL($fieldDeclaration);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function convertToDatabaseValue($value, AbstractPlatform $platform)
+ {
+ $return = (string) $value;
+
+ self::$calls[__FUNCTION__][] = array(
+ 'value' => $value,
+ 'return' => $return,
+ 'platform' => $platform,
+ );
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function convertToPHPValue($value, AbstractPlatform $platform)
+ {
+ $return = (integer) $value;
+
+ self::$calls[__FUNCTION__][] = array(
+ 'value' => $value,
+ 'return' => $return,
+ 'platform' => $platform,
+ );
+
+ return $return;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'ddc2494_tinyint';
+ }
+}
\ No newline at end of file
From d961028b1443799a580bdc60437445a49c31b863 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Tue, 11 Jun 2013 14:23:50 -0400
Subject: [PATCH 159/332] small optimization
---
.../ORM/Internal/Hydration/SimpleObjectHydrator.php | 9 ++-------
.../Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php | 2 +-
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
index 85f3a0fad..412ad41e2 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
@@ -178,14 +178,9 @@ class SimpleObjectHydrator extends AbstractHydrator
}
if (isset($this->_rsm->metaMappings[$column])) {
- $name = $this->_rsm->metaMappings[$column];
- $type = isset($this->_rsm->typeMappings[$column])
- ? $this->_rsm->typeMappings[$column]
- : null;
-
return array(
- 'name' => $name,
- 'type' => $type
+ 'name' => $this->_rsm->metaMappings[$column],
+ 'type' => (isset($this->_rsm->typeMappings[$column]) ? $this->_rsm->typeMappings[$column] : null)
);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
index 4c27fb777..1b2ca881e 100644
--- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2494Test.php
@@ -208,4 +208,4 @@ class DDC2494TinyIntType extends Type
{
return 'ddc2494_tinyint';
}
-}
\ No newline at end of file
+}
From c1e688fc812f68d0f68c2135d46303fdb22ea23a Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Wed, 12 Jun 2013 10:29:17 -0400
Subject: [PATCH 160/332] drop useless support for associations
---
.../Hydration/SimpleObjectHydrator.php | 24 ++++++-------------
1 file changed, 7 insertions(+), 17 deletions(-)
diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
index 412ad41e2..eb0982c7d 100644
--- a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
+++ b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
@@ -146,8 +146,8 @@ class SimpleObjectHydrator extends AbstractHydrator
{
if (isset($this->_rsm->fieldMappings[$column])) {
- $name = $this->_rsm->fieldMappings[$column];
- $class = isset($this->declaringClasses[$column])
+ $name = $this->_rsm->fieldMappings[$column];
+ $class = isset($this->declaringClasses[$column])
? $this->declaringClasses[$column]
: $this->class;
@@ -162,21 +162,6 @@ class SimpleObjectHydrator extends AbstractHydrator
);
}
- if (isset($this->_rsm->relationMap[$column])) {
- $class = isset($this->_rsm->relationMap[$column])
- ? $this->_rsm->relationMap[$column]
- : $this->class;
-
- // If class is not self referencing, ignore
- if ( ! ($class === $entityName || is_subclass_of($entityName, $class))) {
- return null;
- }
-
- // TODO: Decide what to do with associations. It seems original code is incomplete.
- // One solution is to load the association, but it might require extra efforts.
- return array('name' => $column);
- }
-
if (isset($this->_rsm->metaMappings[$column])) {
return array(
'name' => $this->_rsm->metaMappings[$column],
@@ -184,6 +169,11 @@ class SimpleObjectHydrator extends AbstractHydrator
);
}
+ // An ObjectHydrator should be used instead of SimpleObjectHydrator
+ if (isset($this->_rsm->relationMap[$column])) {
+ throw new \Exception(sprintf('Unable to retrieve association information for column "%s"', $column));
+ }
+
return null;
}
}
From a1355d0bb9ed502d10ed8d7d333544e7089ce34c Mon Sep 17 00:00:00 2001
From: Marco Pivetta
Date: Wed, 12 Jun 2013 19:53:43 +0200
Subject: [PATCH 161/332] Adding failing test for DDC-2214
Parameters being bound to an SQL query should have the same type as
the identifier of the objects being bound to the placeholders of a
DQL query - this is currently broken with proxies, as this test
demonstrates.
---
.../ORM/Functional/Ticket/DDC2214Test.php | 71 +++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php
new file mode 100644
index 000000000..060b6ba33
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2214Test.php
@@ -0,0 +1,71 @@
+
+ *
+ * @group DDC-2214
+ */
+class DDC2214Test extends \Doctrine\Tests\OrmFunctionalTestCase
+{
+ protected function setUp()
+ {
+ parent::setUp();
+
+ $this->_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2214Foo'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2214Bar'),
+ ));
+ }
+
+ public function testIssue()
+ {
+ $foo = new DDC2214Foo();
+ $bar = new DDC2214Bar();
+
+ $foo->bar = $bar;
+
+ $this->_em->persist($foo);
+ $this->_em->persist($bar);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ /* @var $foo \Doctrine\Tests\ORM\Functional\Ticket\DDC2214Foo */
+ $foo = $this->_em->find(__NAMESPACE__ . '\\DDC2214Foo', $foo->id);
+ $bar = $foo->bar;
+
+ $logger = $this->_em->getConnection()->getConfiguration()->getSQLLogger();
+
+ $related = $this
+ ->_em
+ ->createQuery('SELECT b FROM '.__NAMESPACE__ . '\DDC2214Bar b WHERE b.id IN(:ids)')
+ ->setParameter('ids', array($bar))
+ ->getResult();
+
+ $query = end($logger->queries);
+
+ $this->assertEquals(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY, $query['types'][0]);
+ }
+}
+
+/** @Entity */
+class DDC2214Foo
+{
+ /** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
+ public $id;
+
+ /** @ManyToOne(targetEntity="DDC2214Bar") */
+ public $bar;
+}
+
+/** @Entity */
+class DDC2214Bar
+{
+ /** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */
+ public $id;
+}
From f16c8e3efe0cf4d75f2b6009ecec0a7d5743118f Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Thu, 13 Jun 2013 16:21:26 -0400
Subject: [PATCH 162/332] Fix DDC-2478
---
.../ORM/Persisters/SqlExpressionVisitor.php | 1 +
.../ORM/Functional/EntityRepositoryTest.php | 29 +++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php b/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
index b06358a20..7736943c6 100644
--- a/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
+++ b/lib/Doctrine/ORM/Persisters/SqlExpressionVisitor.php
@@ -66,6 +66,7 @@ class SqlExpressionVisitor extends ExpressionVisitor
$value = $comparison->getValue()->getValue(); // shortcut for walkValue()
if (isset($this->classMetadata->associationMappings[$field]) &&
+ $value !== null &&
! is_object($value) &&
! in_array($comparison->getOperator(), array(Comparison::IN, Comparison::NIN))) {
diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
index 517ff3d97..6432c3072 100644
--- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php
@@ -842,6 +842,35 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(2, count($users));
}
+ /**
+ * @group DDC-2478
+ */
+ public function testMatchingCriteriaNullAssocComparison()
+ {
+ $fixtures = $this->loadFixtureUserEmail();
+ $user = $this->_em->merge($fixtures[0]);
+ $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser');
+ $criteriaIsNull = Criteria::create()->where(Criteria::expr()->isNull('email'));
+ $criteriaEqNull = Criteria::create()->where(Criteria::expr()->eq('email', null));
+
+ $user->setEmail(null);
+ $this->_em->persist($user);
+ $this->_em->flush();
+ $this->_em->clear();
+
+ $usersIsNull = $repository->matching($criteriaIsNull);
+ $usersEqNull = $repository->matching($criteriaEqNull);
+
+ $this->assertCount(1, $usersIsNull);
+ $this->assertCount(1, $usersEqNull);
+
+ $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $usersIsNull[0]);
+ $this->assertInstanceOf('Doctrine\Tests\Models\CMS\CmsUser', $usersEqNull[0]);
+
+ $this->assertNull($usersIsNull[0]->getEmail());
+ $this->assertNull($usersEqNull[0]->getEmail());
+ }
+
/**
* @group DDC-2055
*/
From 7eb744126ba5081ea51441a893dd950046777383 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Thu, 13 Jun 2013 21:47:40 -0400
Subject: [PATCH 163/332] Implemented support for RepositoryFactory.
---
lib/Doctrine/ORM/Configuration.php | 50 ++++++++---
lib/Doctrine/ORM/EntityManager.php | 46 ++++------
.../Repository/DefaultRepositoryFactory.php | 89 +++++++++++++++++++
.../ORM/Repository/RepositoryFactory.php | 47 ++++++++++
.../ORM/Functional/Ticket/DDC2359Test.php | 5 +-
5 files changed, 195 insertions(+), 42 deletions(-)
create mode 100644 lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
create mode 100644 lib/Doctrine/ORM/Repository/RepositoryFactory.php
diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php
index 959a206dd..a1535de85 100644
--- a/lib/Doctrine/ORM/Configuration.php
+++ b/lib/Doctrine/ORM/Configuration.php
@@ -19,20 +19,22 @@
namespace Doctrine\ORM;
-use Doctrine\Common\Cache\Cache;
-use Doctrine\Common\Cache\ArrayCache;
-use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\AnnotationReader;
-use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
-use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
-use Doctrine\ORM\Mapping\QuoteStrategy;
-use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
-use Doctrine\ORM\Mapping\NamingStrategy;
-use Doctrine\ORM\Mapping\DefaultNamingStrategy;
-use Doctrine\ORM\Mapping\EntityListenerResolver;
-use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
-use Doctrine\Common\Annotations\SimpleAnnotationReader;
+use Doctrine\Common\Annotations\AnnotationRegistry;
use Doctrine\Common\Annotations\CachedReader;
+use Doctrine\Common\Annotations\SimpleAnnotationReader;
+use Doctrine\Common\Cache\ArrayCache;
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
+use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
+use Doctrine\ORM\Mapping\DefaultNamingStrategy;
+use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
+use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
+use Doctrine\ORM\Mapping\EntityListenerResolver;
+use Doctrine\ORM\Mapping\NamingStrategy;
+use Doctrine\ORM\Mapping\QuoteStrategy;
+use Doctrine\ORM\Repository\DefaultRepositoryFactory;
+use Doctrine\ORM\Repository\RepositoryFactoryInterface;
/**
* Configuration container for all configuration options of Doctrine.
@@ -779,4 +781,28 @@ class Configuration extends \Doctrine\DBAL\Configuration
return $this->_attributes['entityListenerResolver'];
}
+
+ /**
+ * Set the entity repository factory.
+ *
+ * @since 2.5
+ * @param \Doctrine\ORM\Repository\RepositoryFactoryInterface $repositoryFactory
+ */
+ public function setRepositoryFactory(RepositoryFactoryInterface $repositoryFactory)
+ {
+ $this->_attributes['repositoryFactory'] = $repositoryFactory;
+ }
+
+ /**
+ * Get the entity repository factory.
+ *
+ * @since 2.5
+ * @return \Doctrine\ORM\Repository\RepositoryFactoryInterface
+ */
+ public function getRepositoryFactory()
+ {
+ return isset($this->_attributes['repositoryFactory'])
+ ? $this->_attributes['repositoryFactory']
+ : new DefaultRepositoryFactory();
+ }
}
diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php
index bc0d4ef18..8ee39cf06 100644
--- a/lib/Doctrine/ORM/EntityManager.php
+++ b/lib/Doctrine/ORM/EntityManager.php
@@ -85,13 +85,6 @@ use Doctrine\Common\Util\ClassUtils;
*/
private $metadataFactory;
- /**
- * The EntityRepository instances.
- *
- * @var array
- */
- private $repositories = array();
-
/**
* The UnitOfWork used to coordinate object-level transactions.
*
@@ -120,6 +113,13 @@ use Doctrine\Common\Util\ClassUtils;
*/
private $proxyFactory;
+ /**
+ * The repository factory used to create dynamic repositories.
+ *
+ * @var \Doctrine\ORM\Repository\RepositoryFactory
+ */
+ private $repositoryFactory;
+
/**
* The expression builder instance used to generate query expressions.
*
@@ -151,9 +151,9 @@ use Doctrine\Common\Util\ClassUtils;
*/
protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
{
- $this->conn = $conn;
- $this->config = $config;
- $this->eventManager = $eventManager;
+ $this->conn = $conn;
+ $this->config = $config;
+ $this->eventManager = $eventManager;
$metadataFactoryClassName = $config->getClassMetadataFactoryName();
@@ -161,6 +161,11 @@ use Doctrine\Common\Util\ClassUtils;
$this->metadataFactory->setEntityManager($this);
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
+ $repositoryFactory = $config->getRepositoryFactory();
+
+ $this->repositoryFactory = $repositoryFactory;
+ $this->repositoryFactory->setEntityManager($this);
+
$this->unitOfWork = new UnitOfWork($this);
$this->proxyFactory = new ProxyFactory(
$this,
@@ -758,28 +763,11 @@ use Doctrine\Common\Util\ClassUtils;
*
* @param string $entityName The name of the entity.
*
- * @return EntityRepository The repository class.
+ * @return \Doctrine\ORM\EntityRepository The repository class.
*/
public function getRepository($entityName)
{
- $entityName = ltrim($entityName, '\\');
-
- if (isset($this->repositories[$entityName])) {
- return $this->repositories[$entityName];
- }
-
- $metadata = $this->getClassMetadata($entityName);
- $repositoryClassName = $metadata->customRepositoryClassName;
-
- if ($repositoryClassName === null) {
- $repositoryClassName = $this->config->getDefaultRepositoryClassName();
- }
-
- $repository = new $repositoryClassName($this, $metadata);
-
- $this->repositories[$entityName] = $repository;
-
- return $repository;
+ return $this->repositoryFactory->getRepository($entityName);
}
/**
diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
new file mode 100644
index 000000000..b97424810
--- /dev/null
+++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
@@ -0,0 +1,89 @@
+.
+ */
+
+namespace Doctrine\ORM\Repository;
+
+use Doctrine\ORM\EntityManagerInterface;
+
+/**
+ * This factory is used to create default repository objects for entities at runtime.
+ *
+ * @author Guilherme Blanco
+ * @since 2.5
+ */
+class DefaultRepositoryFactory implements RepositoryFactory
+{
+ /**
+ * The list of EntityRepository instances.
+ *
+ * @var array<\Doctrine\ORM\EntityRepository>
+ */
+ private $repositoryList = array();
+
+ /**
+ * @var \Doctrine\ORM\EntityManagerInterface
+ */
+ protected $entityManager;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setEntityManager(EntityManagerInterface $entityManager)
+ {
+ $this->entityManager = $entityManager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRepository($entityName)
+ {
+ $entityName = ltrim($entityName, '\\');
+
+ if (isset($this->repositoryList[$entityName])) {
+ return $this->repositoryList[$entityName];
+ }
+
+ $repository = $this->createRepository($entityName);
+
+ $this->repositoryList[$entityName] = $repository;
+
+ return $repository;
+ }
+
+ /**
+ * Create a new repository instance for an entity class.
+ *
+ * @param string $entityName The name of the entity.
+ *
+ * @return \Doctrine\ORM\EntityRepository
+ */
+ protected function createRepository($entityName)
+ {
+ $metadata = $this->entityManager->getClassMetadata($entityName);
+ $repositoryClassName = $metadata->customRepositoryClassName;
+
+ if ($repositoryClassName === null) {
+ $configuration = $this->entityManager->getConfiguration();
+ $repositoryClassName = $configuration->getDefaultRepositoryClassName();
+ }
+
+ return new $repositoryClassName($this->entityManager, $metadata);
+ }
+}
\ No newline at end of file
diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
new file mode 100644
index 000000000..cd3e20a26
--- /dev/null
+++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
@@ -0,0 +1,47 @@
+.
+ */
+
+namespace Doctrine\ORM\Repository;
+
+use Doctrine\ORM\EntityManagerInterface;
+
+/**
+ * Interface for entity repository factory.
+ *
+ * @author Guilherme Blanco
+ * @since 2.5
+ */
+interface RepositoryFactory
+{
+ /**
+ * Set the entity manager.
+ *
+ * @param \Doctrine\ORM\EntityManagerInterface $entityManager
+ */
+ public function setEntityManager(EntityManagerInterface $entityManager);
+
+ /**
+ * Gets the repository for an entity class.
+ *
+ * @param string $entityName The name of the entity.
+ *
+ * @return \Doctrine\ORM\EntityRepository
+ */
+ public function getRepository($entityName);
+}
\ No newline at end of file
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
index b9670d27a..c1189d797 100644
--- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2359Test.php
@@ -19,18 +19,21 @@ class DDC2359Test extends \PHPUnit_Framework_TestCase
$mockDriver = $this->getMock('Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriver');
$mockMetadata = $this->getMock('Doctrine\\ORM\\Mapping\\ClassMetadata', array(), array(), '', false);
$entityManager = $this->getMock('Doctrine\\ORM\\EntityManager', array(), array(), '', false);
+
/* @var $metadataFactory \Doctrine\ORM\Mapping\ClassMetadataFactory|\PHPUnit_Framework_MockObject_MockObject */
$metadataFactory = $this->getMock(
'Doctrine\\ORM\\Mapping\\ClassMetadataFactory',
array('newClassMetadataInstance', 'wakeupReflection')
);
- $configuration = $this->getMock('Doctrine\\ORM\\Configuration');
+
+ $configuration = $this->getMock('Doctrine\\ORM\\Configuration', array('getMetadataDriverImpl'));
$connection = $this->getMock('Doctrine\\DBAL\\Connection', array(), array(), '', false);
$configuration
->expects($this->any())
->method('getMetadataDriverImpl')
->will($this->returnValue($mockDriver));
+
$entityManager->expects($this->any())->method('getConfiguration')->will($this->returnValue($configuration));
$entityManager->expects($this->any())->method('getConnection')->will($this->returnValue($connection));
$entityManager
From 37e7e841c350ac6920ef5dc80b242659963b0868 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Thu, 13 Jun 2013 23:31:18 -0400
Subject: [PATCH 164/332] Fixed wrong interface.
---
lib/Doctrine/ORM/Configuration.php | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php
index a1535de85..073543ed9 100644
--- a/lib/Doctrine/ORM/Configuration.php
+++ b/lib/Doctrine/ORM/Configuration.php
@@ -34,7 +34,7 @@ use Doctrine\ORM\Mapping\EntityListenerResolver;
use Doctrine\ORM\Mapping\NamingStrategy;
use Doctrine\ORM\Mapping\QuoteStrategy;
use Doctrine\ORM\Repository\DefaultRepositoryFactory;
-use Doctrine\ORM\Repository\RepositoryFactoryInterface;
+use Doctrine\ORM\Repository\RepositoryFactory;
/**
* Configuration container for all configuration options of Doctrine.
@@ -786,9 +786,9 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Set the entity repository factory.
*
* @since 2.5
- * @param \Doctrine\ORM\Repository\RepositoryFactoryInterface $repositoryFactory
+ * @param \Doctrine\ORM\Repository\RepositoryFactory $repositoryFactory
*/
- public function setRepositoryFactory(RepositoryFactoryInterface $repositoryFactory)
+ public function setRepositoryFactory(RepositoryFactory $repositoryFactory)
{
$this->_attributes['repositoryFactory'] = $repositoryFactory;
}
@@ -797,7 +797,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Get the entity repository factory.
*
* @since 2.5
- * @return \Doctrine\ORM\Repository\RepositoryFactoryInterface
+ * @return \Doctrine\ORM\Repository\RepositoryFactory
*/
public function getRepositoryFactory()
{
From a66fc03441cff3f9ad2047852d1dcbfed9f48683 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Thu, 13 Jun 2013 23:53:53 -0400
Subject: [PATCH 165/332] Reducing dependency on RepositoryFactory by providing
EntityManager as a getRepository argument.
---
lib/Doctrine/ORM/EntityManager.php | 12 +++-----
.../Repository/DefaultRepositoryFactory.php | 28 ++++++-------------
.../ORM/Repository/RepositoryFactory.php | 12 ++------
3 files changed, 15 insertions(+), 37 deletions(-)
diff --git a/lib/Doctrine/ORM/EntityManager.php b/lib/Doctrine/ORM/EntityManager.php
index 8ee39cf06..acaec984d 100644
--- a/lib/Doctrine/ORM/EntityManager.php
+++ b/lib/Doctrine/ORM/EntityManager.php
@@ -161,13 +161,9 @@ use Doctrine\Common\Util\ClassUtils;
$this->metadataFactory->setEntityManager($this);
$this->metadataFactory->setCacheDriver($this->config->getMetadataCacheImpl());
- $repositoryFactory = $config->getRepositoryFactory();
-
- $this->repositoryFactory = $repositoryFactory;
- $this->repositoryFactory->setEntityManager($this);
-
- $this->unitOfWork = new UnitOfWork($this);
- $this->proxyFactory = new ProxyFactory(
+ $this->repositoryFactory = $config->getRepositoryFactory();
+ $this->unitOfWork = new UnitOfWork($this);
+ $this->proxyFactory = new ProxyFactory(
$this,
$config->getProxyDir(),
$config->getProxyNamespace(),
@@ -767,7 +763,7 @@ use Doctrine\Common\Util\ClassUtils;
*/
public function getRepository($entityName)
{
- return $this->repositoryFactory->getRepository($entityName);
+ return $this->repositoryFactory->getRepository($this, $entityName);
}
/**
diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
index b97424810..0caab1b63 100644
--- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
@@ -36,23 +36,10 @@ class DefaultRepositoryFactory implements RepositoryFactory
*/
private $repositoryList = array();
- /**
- * @var \Doctrine\ORM\EntityManagerInterface
- */
- protected $entityManager;
-
/**
* {@inheritdoc}
*/
- public function setEntityManager(EntityManagerInterface $entityManager)
- {
- $this->entityManager = $entityManager;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getRepository($entityName)
+ public function getRepository(EntityManagerInterface $entityManager, $entityName)
{
$entityName = ltrim($entityName, '\\');
@@ -60,7 +47,7 @@ class DefaultRepositoryFactory implements RepositoryFactory
return $this->repositoryList[$entityName];
}
- $repository = $this->createRepository($entityName);
+ $repository = $this->createRepository($entityManager, $entityName);
$this->repositoryList[$entityName] = $repository;
@@ -70,20 +57,21 @@ class DefaultRepositoryFactory implements RepositoryFactory
/**
* Create a new repository instance for an entity class.
*
- * @param string $entityName The name of the entity.
+ * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
+ * @param string $entityName The name of the entity.
*
* @return \Doctrine\ORM\EntityRepository
*/
- protected function createRepository($entityName)
+ protected function createRepository(EntityManagerInterface $entityManager, $entityName)
{
- $metadata = $this->entityManager->getClassMetadata($entityName);
+ $metadata = $entityManager->getClassMetadata($entityName);
$repositoryClassName = $metadata->customRepositoryClassName;
if ($repositoryClassName === null) {
- $configuration = $this->entityManager->getConfiguration();
+ $configuration = $entityManager->getConfiguration();
$repositoryClassName = $configuration->getDefaultRepositoryClassName();
}
- return new $repositoryClassName($this->entityManager, $metadata);
+ return new $repositoryClassName($entityManager, $metadata);
}
}
\ No newline at end of file
diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
index cd3e20a26..faf7d6c81 100644
--- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
@@ -29,19 +29,13 @@ use Doctrine\ORM\EntityManagerInterface;
*/
interface RepositoryFactory
{
- /**
- * Set the entity manager.
- *
- * @param \Doctrine\ORM\EntityManagerInterface $entityManager
- */
- public function setEntityManager(EntityManagerInterface $entityManager);
-
/**
* Gets the repository for an entity class.
*
- * @param string $entityName The name of the entity.
+ * @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
+ * @param string $entityName The name of the entity.
*
* @return \Doctrine\ORM\EntityRepository
*/
- public function getRepository($entityName);
+ public function getRepository(EntityManagerInterface $entityManager, $entityName);
}
\ No newline at end of file
From 3488049c18849a0cb942f4fea00501fa11727a83 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Thu, 13 Jun 2013 23:59:08 -0400
Subject: [PATCH 166/332] Reduced granularity of DefaultRepositoryFactory
reference to ObjectRepository instances, in cases where consumers are
completely rewrote EntityRepository.
---
lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 4 ++--
lib/Doctrine/ORM/Repository/RepositoryFactory.php | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
index 0caab1b63..932a1108c 100644
--- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
@@ -32,7 +32,7 @@ class DefaultRepositoryFactory implements RepositoryFactory
/**
* The list of EntityRepository instances.
*
- * @var array<\Doctrine\ORM\EntityRepository>
+ * @var array<\Doctrine\Common\Persistence\ObjectRepository>
*/
private $repositoryList = array();
@@ -60,7 +60,7 @@ class DefaultRepositoryFactory implements RepositoryFactory
* @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
* @param string $entityName The name of the entity.
*
- * @return \Doctrine\ORM\EntityRepository
+ * @return \Doctrine\Common\Persistence\ObjectRepository
*/
protected function createRepository(EntityManagerInterface $entityManager, $entityName)
{
diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
index faf7d6c81..00efca2c7 100644
--- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
@@ -35,7 +35,7 @@ interface RepositoryFactory
* @param \Doctrine\ORM\EntityManagerInterface $entityManager The EntityManager instance.
* @param string $entityName The name of the entity.
*
- * @return \Doctrine\ORM\EntityRepository
+ * @return \Doctrine\Common\Persistence\ObjectRepository
*/
public function getRepository(EntityManagerInterface $entityManager, $entityName);
}
\ No newline at end of file
From 37d7df6ac4d4501370487705bd02906983470158 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Perrin?=
Date: Fri, 14 Jun 2013 11:00:17 +0300
Subject: [PATCH 167/332] Fix phpDoc syntax in ClassMetadataInfo.php
---
lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
index da2b1caa6..3d42b24e6 100644
--- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
+++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
@@ -358,7 +358,7 @@ class ClassMetadataInfo implements ClassMetadata
* - scale (integer, optional, schema-only)
* The scale of a decimal column. Only valid if the column type is decimal.
*
- [* - 'unique'] (string, optional, schema-only)
+ * - 'unique' (string, optional, schema-only)
* Whether a unique constraint should be generated for the column.
*
* @var array
From 73e2aa54ef72d8278e3a9f0a968b18b39d685a46 Mon Sep 17 00:00:00 2001
From: Adam Prager
Date: Fri, 14 Jun 2013 10:07:05 +0200
Subject: [PATCH 168/332] moved php version check
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 1c55eb1bc..42a6e85c9 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -759,14 +759,12 @@ public function __construct()
*/
protected function getTraits(ClassMetadataInfo $metadata)
{
- if ($metadata->reflClass !== null || class_exists($metadata->name)) {
+ if (PHP_VERSION_ID >= 50400 && ($metadata->reflClass !== null || class_exists($metadata->name))) {
$reflClass = $metadata->reflClass === null
? new \ReflectionClass($metadata->name)
: $metadata->reflClass;
- if (PHP_VERSION_ID >= 50400) {
- return $reflClass->getTraits();
- }
+ return $reflClass->getTraits();
}
return array();
From 52b3fc1fc3b1adfe17290126712916196f5b5345 Mon Sep 17 00:00:00 2001
From: Guilherme Blanco
Date: Fri, 14 Jun 2013 12:07:28 -0400
Subject: [PATCH 169/332] Updated since php doc tag.
---
lib/Doctrine/ORM/Configuration.php | 4 ++--
lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php | 2 +-
lib/Doctrine/ORM/Repository/RepositoryFactory.php | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/Configuration.php b/lib/Doctrine/ORM/Configuration.php
index 073543ed9..3a096ba21 100644
--- a/lib/Doctrine/ORM/Configuration.php
+++ b/lib/Doctrine/ORM/Configuration.php
@@ -785,7 +785,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Set the entity repository factory.
*
- * @since 2.5
+ * @since 2.4
* @param \Doctrine\ORM\Repository\RepositoryFactory $repositoryFactory
*/
public function setRepositoryFactory(RepositoryFactory $repositoryFactory)
@@ -796,7 +796,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Get the entity repository factory.
*
- * @since 2.5
+ * @since 2.4
* @return \Doctrine\ORM\Repository\RepositoryFactory
*/
public function getRepositoryFactory()
diff --git a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
index 932a1108c..2774dea68 100644
--- a/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php
@@ -25,7 +25,7 @@ use Doctrine\ORM\EntityManagerInterface;
* This factory is used to create default repository objects for entities at runtime.
*
* @author Guilherme Blanco
- * @since 2.5
+ * @since 2.4
*/
class DefaultRepositoryFactory implements RepositoryFactory
{
diff --git a/lib/Doctrine/ORM/Repository/RepositoryFactory.php b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
index 00efca2c7..f3af43ebe 100644
--- a/lib/Doctrine/ORM/Repository/RepositoryFactory.php
+++ b/lib/Doctrine/ORM/Repository/RepositoryFactory.php
@@ -25,7 +25,7 @@ use Doctrine\ORM\EntityManagerInterface;
* Interface for entity repository factory.
*
* @author Guilherme Blanco
- * @since 2.5
+ * @since 2.4
*/
interface RepositoryFactory
{
From 184e8eb26cc8b449e8bfdb9b365bbc5ae3e2d3fb Mon Sep 17 00:00:00 2001
From: Robert Broen
Date: Mon, 17 Jun 2013 10:31:06 +0200
Subject: [PATCH 170/332] Update getting-started.rst
The tutorial assumes Doctrine 2.4
---
docs/en/tutorials/getting-started.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/tutorials/getting-started.rst b/docs/en/tutorials/getting-started.rst
index 187029dfa..8c51b6480 100644
--- a/docs/en/tutorials/getting-started.rst
+++ b/docs/en/tutorials/getting-started.rst
@@ -25,7 +25,7 @@ The code of this tutorial is `available on Github
Date: Mon, 17 Jun 2013 11:36:09 +0200
Subject: [PATCH 171/332] list_bugs.php needs to call to getters for protected
vars
list_bugs.php needs to call to getters for protected vars. This was changed in the "getting-started" code repository, but not in the "getting-started" tutorial.
---
docs/en/tutorials/getting-started.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/en/tutorials/getting-started.rst b/docs/en/tutorials/getting-started.rst
index 8c51b6480..4f169cd94 100644
--- a/docs/en/tutorials/getting-started.rst
+++ b/docs/en/tutorials/getting-started.rst
@@ -1108,10 +1108,10 @@ the first read-only use-case:
foreach($bugs AS $bug) {
echo $bug->getDescription()." - ".$bug->getCreated()->format('d.m.Y')."\n";
- echo " Reported by: ".$bug->getReporter()->name."\n";
- echo " Assigned to: ".$bug->getEngineer()->name."\n";
+ echo " Reported by: ".$bug->getReporter()->getName()."\n";
+ echo " Assigned to: ".$bug->getEngineer()->getName()."\n";
foreach($bug->getProducts() AS $product) {
- echo " Platform: ".$product->name."\n";
+ echo " Platform: ".$product->getName()."\n";
}
echo "\n";
}
From 3340234785351ef4680421f5c07f5706bd1524e0 Mon Sep 17 00:00:00 2001
From: shulcsm
Date: Wed, 19 Jun 2013 16:34:44 +0300
Subject: [PATCH 172/332] Clear visitedCollections
Visited collections are cleared only in commit(). Commit clears up only if it actually has something to do. Processing large amounts of records without changing them cause visitedCollections to grow without any way of clearing.
---
lib/Doctrine/ORM/UnitOfWork.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 68fde5d2c..9a8363863 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -2356,6 +2356,7 @@ class UnitOfWork implements PropertyChangedListener
$this->collectionUpdates =
$this->extraUpdates =
$this->readOnlyObjects =
+ $this->visitedCollections =
$this->orphanRemovals = array();
if ($this->commitOrderCalculator !== null) {
From c743bb938b30efafefe4932b01b6f63f95fe2c87 Mon Sep 17 00:00:00 2001
From: Giulio De Donato
Date: Wed, 19 Jun 2013 16:40:57 +0200
Subject: [PATCH 173/332] added badges
---
README.markdown | 3 +++
1 file changed, 3 insertions(+)
diff --git a/README.markdown b/README.markdown
index 64f7189a3..39bde0285 100644
--- a/README.markdown
+++ b/README.markdown
@@ -5,6 +5,9 @@ Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?bra
2.2: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.2)](http://travis-ci.org/doctrine/doctrine2)
2.1: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
+[![Latest Stable Version](https://poser.pugx.org/doctrine/orm/v/stable.png)](https://packagist.org/packages/doctrine/orm) [![Total Downloads](https://poser.pugx.org/doctrine/orm/downloads.png)](https://packagist.org/packages/doctrine/orm)
+
+
Doctrine 2 is an object-relational mapper (ORM) for PHP 5.3.2+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
is the option to write database queries in a proprietary object oriented SQL dialect called Doctrine Query Language (DQL),
From 523697d0b663221bc91d39c93b4317d164726816 Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 09:29:56 +0200
Subject: [PATCH 174/332] [DDC-1398] Extra-lazy get for indexed associations
If an association is EXTRA_LAZY and has an indexBy, then
you can call get() without loading the entire collection.
---
lib/Doctrine/ORM/PersistentCollection.php | 8 ++++
.../ORM/Persisters/ManyToManyPersister.php | 18 ++++++++
.../ORM/Persisters/OneToManyPersister.php | 18 ++++++++
.../Functional/ExtraLazyCollectionTest.php | 41 ++++++++++++++++++-
4 files changed, 83 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index 53ba1c1f2..d5a922aaf 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -517,6 +517,14 @@ final class PersistentCollection implements Collection, Selectable
*/
public function get($key)
{
+ if ( ! $this->initialized
+ && $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY
+ && isset($this->association['indexBy'])
+ ) {
+ $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
+ return $persister->get($this, $key);
+ }
+
$this->initialize();
return $this->coll->get($key);
diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
index d9f7e30ca..4ad32e8d8 100644
--- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
@@ -33,6 +33,24 @@ use Doctrine\ORM\UnitOfWork;
*/
class ManyToManyPersister extends AbstractCollectionPersister
{
+ /**
+ * {@inheritdoc}
+ *
+ * @override
+ */
+ public function get(PersistentCollection $coll, $index)
+ {
+ $mapping = $coll->getMapping();
+ $uow = $this->em->getUnitOfWork();
+ $persister = $uow->getEntityPersister($mapping['targetEntity']);
+
+ if (!isset($mapping['indexBy'])) {
+ throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
+ }
+
+ return current($persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1));
+ }
+
/**
* {@inheritdoc}
*
diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
index 911d699f6..041dfe5e2 100644
--- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
@@ -32,6 +32,24 @@ use Doctrine\ORM\UnitOfWork;
*/
class OneToManyPersister extends AbstractCollectionPersister
{
+ /**
+ * {@inheritdoc}
+ *
+ * @override
+ */
+ public function get(PersistentCollection $coll, $index)
+ {
+ $mapping = $coll->getMapping();
+ $uow = $this->em->getUnitOfWork();
+ $persister = $uow->getEntityPersister($mapping['targetEntity']);
+
+ if (!isset($mapping['indexBy'])) {
+ throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
+ }
+
+ return current($persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1));
+ }
+
/**
* Generates the SQL UPDATE that updates a particular row's foreign
* key to null.
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index b6c7a0f1e..aa6adb13a 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -24,7 +24,9 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
+ $class->associationMappings['groups']['indexBy'] = 'id';
$class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
+ $class->associationMappings['articles']['indexBy'] = 'id';
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
$class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
@@ -40,6 +42,9 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
$class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
+ unset($class->associationMappings['groups']['indexBy']);
+ unset($class->associationMappings['articles']['indexBy']);
+
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
$class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
}
@@ -174,8 +179,8 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertEquals(2, count($someGroups));
- $this->assertTrue($user->groups->contains($someGroups[0]));
- $this->assertTrue($user->groups->contains($someGroups[1]));
+ $this->assertTrue($user->groups->contains(array_shift($someGroups)));
+ $this->assertTrue($user->groups->contains(array_shift($someGroups)));
}
/**
@@ -512,6 +517,38 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($qc + 1, $this->getCurrentQueryCount());
}
+ /**
+ * @group DDC-1398
+ */
+ public function testGetIndexByOneToMany()
+ {
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
+ /* @var $user CmsUser */
+
+ $queryCount = $this->getCurrentQueryCount();
+
+ $user->articles->get($this->articleId);
+
+ $this->assertFalse($user->articles->isInitialized());
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ }
+
+ /**
+ * @group DDC-1398
+ */
+ public function testGetIndexByManyToMany()
+ {
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
+ /* @var $user CmsUser */
+
+ $queryCount = $this->getCurrentQueryCount();
+
+ $user->groups->get($this->groupId);
+
+ $this->assertFalse($user->groups->isInitialized());
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ }
+
private function loadFixture()
{
$user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
From 3555007f08c94435921d3c1ca2ad46e38a82ba2b Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 10:09:52 +0200
Subject: [PATCH 175/332] Return NULL for non-existent keys
The load() function already returns just one entity or NULL, so
the current() is not needed and the result can be returned directly.
---
lib/Doctrine/ORM/Persisters/ManyToManyPersister.php | 2 +-
lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 2 +-
.../Tests/ORM/Functional/ExtraLazyCollectionTest.php | 12 ++++++++++++
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
index 4ad32e8d8..df46aa30a 100644
--- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
@@ -48,7 +48,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
}
- return current($persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1));
+ return $persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1);
}
/**
diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
index 041dfe5e2..120ad548d 100644
--- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
@@ -47,7 +47,7 @@ class OneToManyPersister extends AbstractCollectionPersister
throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
}
- return current($persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1));
+ return $persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1);
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index aa6adb13a..fe642ac1b 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -549,6 +549,18 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
}
+ /**
+ * @group DDC-1398
+ */
+ public function testGetNonExistentIndexBy()
+ {
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
+ /* @var $user CmsUser */
+
+ $this->assertNull($user->articles->get(-1));
+ $this->assertNull($user->groups->get(-1));
+ }
+
private function loadFixture()
{
$user1 = new \Doctrine\Tests\Models\CMS\CmsUser();
From 647c5e2cad135abb9158a538b4e3f7758f8b71ed Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 10:18:08 +0200
Subject: [PATCH 176/332] Test actual data returned by get()
---
.../Tests/ORM/Functional/ExtraLazyCollectionTest.php | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index fe642ac1b..b1a2f7fd4 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -527,10 +527,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$queryCount = $this->getCurrentQueryCount();
- $user->articles->get($this->articleId);
+ $article = $user->articles->get($this->articleId);
$this->assertFalse($user->articles->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ $this->assertSame($article, $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId));
}
/**
@@ -543,10 +544,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$queryCount = $this->getCurrentQueryCount();
- $user->groups->get($this->groupId);
+ $group = $user->groups->get($this->groupId);
$this->assertFalse($user->groups->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ $this->assertSame($group, $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId));
}
/**
From 53c9ffda302af24e137607b244591b79419e6116 Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 10:20:16 +0200
Subject: [PATCH 177/332] Get rid of variable
---
lib/Doctrine/ORM/PersistentCollection.php | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index d5a922aaf..dd5a90d18 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -521,8 +521,7 @@ final class PersistentCollection implements Collection, Selectable
&& $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY
&& isset($this->association['indexBy'])
) {
- $persister = $this->em->getUnitOfWork()->getCollectionPersister($this->association);
- return $persister->get($this, $key);
+ return $this->em->getUnitOfWork()->getCollectionPersister($this->association)->get($this, $key);
}
$this->initialize();
From 3b92cfac5a7ae7fdc853b819f3d12505f2fe1c2f Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 13:45:38 +0200
Subject: [PATCH 178/332] Use find() if the indexBy field is the identifier
---
lib/Doctrine/ORM/PersistentCollection.php | 6 ++++++
.../Tests/ORM/Functional/ExtraLazyCollectionTest.php | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index dd5a90d18..4e64acb26 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -521,6 +521,12 @@ final class PersistentCollection implements Collection, Selectable
&& $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY
&& isset($this->association['indexBy'])
) {
+ $class = $this->em->getClassMetadata($this->association['targetEntity']);
+
+ if (!$class->isIdentifierComposite && $class->isIdentifier($this->association['indexBy'])) {
+ return $this->em->find($class->name, $key);
+ }
+
return $this->em->getUnitOfWork()->getCollectionPersister($this->association)->get($this, $key);
}
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index b1a2f7fd4..cbafd1132 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -532,6 +532,9 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertFalse($user->articles->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertSame($article, $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId));
+
+ $article = $user->articles->get($this->articleId);
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Getting the same entity should not cause an extra query to be executed");
}
/**
@@ -549,6 +552,9 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertFalse($user->groups->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertSame($group, $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId));
+
+ $group = $user->groups->get($this->groupId);
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Getting the same entity should not cause an extra query to be executed");
}
/**
From 28791620157c413e9dce23663a064eeb012061e3 Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 14:00:58 +0200
Subject: [PATCH 179/332] No need to lookup metadata
---
lib/Doctrine/ORM/PersistentCollection.php | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index 4e64acb26..a50cd8343 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -521,10 +521,8 @@ final class PersistentCollection implements Collection, Selectable
&& $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY
&& isset($this->association['indexBy'])
) {
- $class = $this->em->getClassMetadata($this->association['targetEntity']);
-
- if (!$class->isIdentifierComposite && $class->isIdentifier($this->association['indexBy'])) {
- return $this->em->find($class->name, $key);
+ if (!$this->typeClass->isIdentifierComposite && $this->typeClass->isIdentifier($this->association['indexBy'])) {
+ return $this->em->find($this->typeClass->name, $key);
}
return $this->em->getUnitOfWork()->getCollectionPersister($this->association)->get($this, $key);
From 70427871ce73090441ea8c0ed635efe6782a48c3 Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 20 Jun 2013 14:20:00 +0200
Subject: [PATCH 180/332] Extra test for indexBy identifier versus indexBy
other fields
---
.../Functional/ExtraLazyCollectionTest.php | 63 ++++++++++++++-----
1 file changed, 49 insertions(+), 14 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index cbafd1132..5d8fa0f2a 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -17,6 +17,10 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
private $groupId;
private $articleId;
+ private $groupname;
+ private $topic;
+ private $phonenumber;
+
public function setUp()
{
$this->useModelSet('cms');
@@ -24,9 +28,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
- $class->associationMappings['groups']['indexBy'] = 'id';
+ $class->associationMappings['groups']['indexBy'] = 'name';
$class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
- $class->associationMappings['articles']['indexBy'] = 'id';
+ $class->associationMappings['articles']['indexBy'] = 'topic';
+ $class->associationMappings['phonenumbers']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
+ $class->associationMappings['phonenumbers']['indexBy'] = 'phonenumber';
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
$class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_EXTRA_LAZY;
@@ -41,9 +47,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$class->associationMappings['groups']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
$class->associationMappings['articles']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
+ $class->associationMappings['phonenumbers']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
unset($class->associationMappings['groups']['indexBy']);
unset($class->associationMappings['articles']['indexBy']);
+ unset($class->associationMappings['phonenumbers']['indexBy']);
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsGroup');
$class->associationMappings['users']['fetch'] = ClassMetadataInfo::FETCH_LAZY;
@@ -517,6 +525,26 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($qc + 1, $this->getCurrentQueryCount());
}
+ /**
+ * @group DDC-1398
+ */
+ public function testGetIndexByIdentifier()
+ {
+ $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
+ /* @var $user CmsUser */
+
+ $queryCount = $this->getCurrentQueryCount();
+
+ $phonenumber = $user->phonenumbers->get($this->phonenumber);
+
+ $this->assertFalse($user->phonenumbers->isInitialized());
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
+ $this->assertSame($phonenumber, $this->_em->find('Doctrine\Tests\Models\CMS\CmsPhonenumber', $this->phonenumber));
+
+ $article = $user->phonenumbers->get($this->phonenumber);
+ $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Getting the same entity should not cause an extra query to be executed");
+ }
+
/**
* @group DDC-1398
*/
@@ -527,14 +555,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$queryCount = $this->getCurrentQueryCount();
- $article = $user->articles->get($this->articleId);
+ $article = $user->articles->get($this->topic);
$this->assertFalse($user->articles->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertSame($article, $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId));
-
- $article = $user->articles->get($this->articleId);
- $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Getting the same entity should not cause an extra query to be executed");
}
/**
@@ -547,14 +572,11 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$queryCount = $this->getCurrentQueryCount();
- $group = $user->groups->get($this->groupId);
+ $group = $user->groups->get($this->groupname);
$this->assertFalse($user->groups->isInitialized());
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
$this->assertSame($group, $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId));
-
- $group = $user->groups->get($this->groupId);
- $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Getting the same entity should not cause an extra query to be executed");
}
/**
@@ -618,23 +640,36 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->persist($group3);
$article1 = new \Doctrine\Tests\Models\CMS\CmsArticle();
- $article1->topic = "Test";
- $article1->text = "Test";
+ $article1->topic = "Test1";
+ $article1->text = "Test1";
$article1->setAuthor($user1);
$article2 = new \Doctrine\Tests\Models\CMS\CmsArticle();
- $article2->topic = "Test";
- $article2->text = "Test";
+ $article2->topic = "Test2";
+ $article2->text = "Test2";
$article2->setAuthor($user1);
$this->_em->persist($article1);
$this->_em->persist($article2);
+ $phonenumber1 = new \Doctrine\Tests\Models\CMS\CmsPhonenumber();
+ $phonenumber1->phonenumber = '12345';
+
+ $phonenumber2 = new \Doctrine\Tests\Models\CMS\CmsPhonenumber();
+ $phonenumber2->phonenumber = '67890';
+
+ $this->_em->persist($phonenumber1);
+ $this->_em->persist($phonenumber2);
+
$this->_em->flush();
$this->_em->clear();
$this->articleId = $article1->id;
$this->userId = $user1->getId();
$this->groupId = $group1->id;
+
+ $this->groupname = $group1->name;
+ $this->topic = $article1->topic;
+ $this->phonenumber = $phonenumber1->phonenumber;
}
}
\ No newline at end of file
From a165f63c8c44bbf1375f9b2aa7ae8a0551ba3622 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Sun, 16 Jun 2013 14:55:01 -0400
Subject: [PATCH 181/332] ANSI compliant quote strategy
---
.../ORM/Mapping/AnsiQuoteStrategy.php | 97 ++++++++++++
.../ORM/Mapping/AnsiQuoteStrategyTest.php | 148 ++++++++++++++++++
2 files changed, 245 insertions(+)
create mode 100644 lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php
create mode 100644 tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php
diff --git a/lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php b/lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php
new file mode 100644
index 000000000..440c3909f
--- /dev/null
+++ b/lib/Doctrine/ORM/Mapping/AnsiQuoteStrategy.php
@@ -0,0 +1,97 @@
+.
+ */
+
+namespace Doctrine\ORM\Mapping;
+
+use Doctrine\ORM\Mapping\ClassMetadata;
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+/**
+ * ANSI compliant quote strategy, this strategy does not apply any quote.
+ * To use this strategy all mapped tables and columns should be ANSI compliant.
+ *
+ * @since 2.5
+ * @author Fabio B. Silva
+ */
+class AnsiQuoteStrategy implements QuoteStrategy
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function getColumnName($fieldName, ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $class->fieldMappings[$fieldName]['columnName'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTableName(ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $class->table['name'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $definition['sequenceName'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $joinColumn['name'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getReferencedJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $joinColumn['referencedColumnName'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getJoinTableName(array $association, ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $association['joinTable']['name'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform)
+ {
+ return $class->identifier;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
+ {
+ return $platform->getSQLResultCasing($columnName . $counter);
+ }
+}
diff --git a/tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php b/tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php
new file mode 100644
index 000000000..5c51eb034
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Mapping/AnsiQuoteStrategyTest.php
@@ -0,0 +1,148 @@
+_getTestEntityManager();
+ $this->platform = $em->getConnection()->getDatabasePlatform();
+ $this->strategy = new AnsiQuoteStrategy();
+ }
+
+ /**
+ * @param string $className
+ * @return \Doctrine\ORM\Mapping\ClassMetadata
+ */
+ private function createClassMetadata($className)
+ {
+ $class = new ClassMetadata($className);
+ $class->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
+
+ return $class;
+ }
+
+ public function testGetColumnName()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
+ $class->mapField(array('fieldName' => 'name', 'columnName' => 'name'));
+ $class->mapField(array('fieldName' => 'id', 'columnName' => 'id', 'id' => true));
+
+ $this->assertEquals('id' ,$this->strategy->getColumnName('id', $class, $this->platform));
+ $this->assertEquals('name' ,$this->strategy->getColumnName('name', $class, $this->platform));
+ }
+
+ public function testGetTableName()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
+
+ $class->setPrimaryTable(array('name'=>'cms_user'));
+ $this->assertEquals('cms_user' ,$this->strategy->getTableName($class, $this->platform));
+ }
+
+ public function testJoinTableName()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
+
+ $class->mapManyToMany(array(
+ 'fieldName' => 'user',
+ 'targetEntity' => 'CmsUser',
+ 'inversedBy' => 'users',
+ 'joinTable' => array(
+ 'name' => 'cmsaddress_cmsuser'
+ )
+ ));
+
+ $this->assertEquals('cmsaddress_cmsuser', $this->strategy->getJoinTableName($class->associationMappings['user'], $class, $this->platform));
+
+ }
+
+ public function testIdentifierColumnNames()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
+
+ $class->mapField(array(
+ 'id' => true,
+ 'fieldName' => 'id',
+ 'columnName' => 'id',
+ ));
+
+ $this->assertEquals(array('id'), $this->strategy->getIdentifierColumnNames($class, $this->platform));
+ }
+
+
+ public function testColumnAlias()
+ {
+ $this->assertEquals('columnName1', $this->strategy->getColumnAlias('columnName', 1, $this->platform));
+ }
+
+ public function testJoinColumnName()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
+
+ $class->mapOneToOne(array(
+ 'id' => true,
+ 'fieldName' => 'article',
+ 'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
+ 'joinColumns' => array(array(
+ 'name' => 'article'
+ )),
+ ));
+
+ $joinColumn = $class->associationMappings['article']['joinColumns'][0];
+ $this->assertEquals('article',$this->strategy->getJoinColumnName($joinColumn, $class, $this->platform));
+ }
+
+ public function testReferencedJoinColumnName()
+ {
+ $cm = $this->createClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
+
+ $cm->mapOneToOne(array(
+ 'id' => true,
+ 'fieldName' => 'article',
+ 'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
+ 'joinColumns' => array(array(
+ 'name' => 'article'
+ )),
+ ));
+
+ $joinColumn = $cm->associationMappings['article']['joinColumns'][0];
+ $this->assertEquals('id',$this->strategy->getReferencedJoinColumnName($joinColumn, $cm, $this->platform));
+ }
+
+ public function testGetSequenceName()
+ {
+ $class = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
+ $definition = array(
+ 'sequenceName' => 'user_id_seq',
+ 'allocationSize' => 1,
+ 'initialValue' => 2
+ );
+
+ $class->setSequenceGeneratorDefinition($definition);
+
+ $this->assertEquals('user_id_seq',$this->strategy->getSequenceName($definition, $class, $this->platform));
+ }
+}
\ No newline at end of file
From 1cff8b4d98bc97c40b059342370f31613032b266 Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Thu, 20 Jun 2013 00:05:49 -0400
Subject: [PATCH 182/332] Fix DDC-2519
---
lib/Doctrine/ORM/Query/Parser.php | 6 ++
.../ORM/Functional/Ticket/DDC2519Test.php | 85 +++++++++++++++++++
.../ORM/Query/SelectSqlGenerationTest.php | 16 ++++
3 files changed, 107 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php
diff --git a/lib/Doctrine/ORM/Query/Parser.php b/lib/Doctrine/ORM/Query/Parser.php
index 67ee0729d..a82d9d82f 100644
--- a/lib/Doctrine/ORM/Query/Parser.php
+++ b/lib/Doctrine/ORM/Query/Parser.php
@@ -670,6 +670,12 @@ class Parser
continue;
}
+ if (isset($class->associationMappings[$field]) &&
+ $class->associationMappings[$field]['isOwningSide'] &&
+ $class->associationMappings[$field]['type'] & ClassMetadata::TO_ONE) {
+ continue;
+ }
+
$this->semanticalError(
"There is no mapped field named '$field' on class " . $class->name . ".", $deferredItem['token']
);
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php
new file mode 100644
index 000000000..d6ea115b5
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2519Test.php
@@ -0,0 +1,85 @@
+useModelSet('legacy');
+ parent::setUp();
+
+ $this->loadFixture();
+ }
+
+ /**
+ * @group DDC-2519
+ */
+ public function testIssue()
+ {
+ $dql = 'SELECT PARTIAL l.{_source, _target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l';
+ $result = $this->_em->createQuery($dql)->getResult();
+
+ $this->assertCount(2, $result);
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUserReference', $result[0]);
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUserReference', $result[1]);
+
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUser', $result[0]->source());
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUser', $result[0]->target());
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUser', $result[1]->source());
+ $this->assertInstanceOf('Doctrine\Tests\Models\Legacy\LegacyUser', $result[1]->target());
+
+ $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $result[0]->source());
+ $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $result[0]->target());
+ $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $result[1]->source());
+ $this->assertInstanceOf('Doctrine\ORM\Proxy\Proxy', $result[1]->target());
+
+ $this->assertFalse($result[0]->target()->__isInitialized());
+ $this->assertFalse($result[0]->source()->__isInitialized());
+ $this->assertFalse($result[1]->target()->__isInitialized());
+ $this->assertFalse($result[1]->source()->__isInitialized());
+
+ $this->assertNotNull($result[0]->source()->getId());
+ $this->assertNotNull($result[0]->target()->getId());
+ $this->assertNotNull($result[1]->source()->getId());
+ $this->assertNotNull($result[1]->target()->getId());
+ }
+
+ public function loadFixture()
+ {
+ $user1 = new LegacyUser();
+ $user1->_username = 'FabioBatSilva';
+ $user1->_name = 'Fabio B. Silva';
+ $user1->_status = 'active';
+
+ $user2 = new LegacyUser();
+ $user2->_username = 'doctrinebot';
+ $user2->_name = 'Doctrine Bot';
+ $user2->_status = 'active';
+
+ $user3 = new LegacyUser();
+ $user3->_username = 'test';
+ $user3->_name = 'Tester';
+ $user3->_status = 'active';
+
+ $this->_em->persist($user1);
+ $this->_em->persist($user2);
+ $this->_em->persist($user3);
+
+ $this->_em->flush();
+
+ $this->_em->persist(new LegacyUserReference($user1, $user2, 'foo'));
+ $this->_em->persist(new LegacyUserReference($user1, $user3, 'bar'));
+
+ $this->_em->flush();
+ $this->_em->clear();
+ }
+}
diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
index 785e25850..dbb303323 100644
--- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -1292,6 +1292,22 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
+ /**
+ * @group DDC-2519
+ */
+ public function testPartialWithAssociationIdentifier()
+ {
+ $this->assertSqlGeneration(
+ "SELECT PARTIAL l.{_source, _target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l",
+ 'SELECT l0_.iUserIdSource AS iUserIdSource0, l0_.iUserIdTarget AS iUserIdTarget1 FROM legacy_users_reference l0_'
+ );
+
+ $this->assertSqlGeneration(
+ "SELECT PARTIAL l.{_description, _source, _target} FROM Doctrine\Tests\Models\Legacy\LegacyUserReference l",
+ 'SELECT l0_.description AS description0, l0_.iUserIdSource AS iUserIdSource1, l0_.iUserIdTarget AS iUserIdTarget2 FROM legacy_users_reference l0_'
+ );
+ }
+
/**
* @group DDC-1339
*/
From 2f6e914d642e91a70053aa66e02f0a214130194d Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Mon, 24 Jun 2013 08:42:05 +0200
Subject: [PATCH 183/332] Dont allow failures in 5.5 anymore
---
.travis.yml | 3 ---
1 file changed, 3 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index a97513344..d6c3f027a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,9 +5,6 @@ php:
- 5.4
- 5.5
-matrix:
- allow_failures:
- - php: 5.5
env:
- DB=mysql
- DB=pgsql
From a91050e7f4eb40b35fd8f90b16359c754e05a8ee Mon Sep 17 00:00:00 2001
From: Benjamin Eberlei
Date: Tue, 25 Jun 2013 19:34:12 +0200
Subject: [PATCH 184/332] [DDC-2350] Eager Collections are not marked as
initialized, leading to multiple queries being executed.
---
lib/Doctrine/ORM/UnitOfWork.php | 2 +
.../ORM/Functional/Ticket/DDC2350Test.php | 68 +++++++++++++++++++
2 files changed, 70 insertions(+)
create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php
diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
index 68fde5d2c..62bce139d 100644
--- a/lib/Doctrine/ORM/UnitOfWork.php
+++ b/lib/Doctrine/ORM/UnitOfWork.php
@@ -2773,6 +2773,8 @@ class UnitOfWork implements PropertyChangedListener
$persister->loadManyToManyCollection($assoc, $collection->getOwner(), $collection);
break;
}
+
+ $collection->setInitialized(true);
}
/**
diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php
new file mode 100644
index 000000000..229bbff52
--- /dev/null
+++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2350Test.php
@@ -0,0 +1,68 @@
+_schemaTool->createSchema(array(
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2350User'),
+ $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2350Bug'),
+ ));
+ }
+
+ public function testEagerCollectionsAreOnlyRetrievedOnce()
+ {
+ $user = new DDC2350User();
+ $bug1 = new DDC2350Bug();
+ $bug1->user = $user;
+ $bug2 = new DDC2350Bug();
+ $bug2->user = $user;
+
+ $this->_em->persist($user);
+ $this->_em->persist($bug1);
+ $this->_em->persist($bug2);
+ $this->_em->flush();
+
+ $this->_em->clear();
+
+ $cnt = $this->getCurrentQueryCount();
+ $user = $this->_em->find(__NAMESPACE__ . '\DDC2350User', $user->id);
+
+ $this->assertEquals($cnt + 2, $this->getCurrentQueryCount());
+
+ $this->assertEquals(2, count($user->reportedBugs));
+
+ $this->assertEquals($cnt + 2, $this->getCurrentQueryCount());
+ }
+}
+
+/**
+ * @Entity
+ */
+class DDC2350User
+{
+ /** @Id @Column(type="integer") @GeneratedValue */
+ public $id;
+ /** @OneToMany(targetEntity="DDC2350Bug", mappedBy="user", fetch="EAGER") */
+ public $reportedBugs;
+}
+
+/**
+ * @Entity
+ */
+class DDC2350Bug
+{
+ /** @Id @Column(type="integer") @GeneratedValue */
+ public $id;
+ /** @ManyToOne(targetEntity="DDC2350User", inversedBy="reportedBugs") */
+ public $user;
+}
From 5635fa60a4bea0580b969a5cd9235e2ae6e18a78 Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 27 Jun 2013 14:17:41 +0200
Subject: [PATCH 185/332] Check owning entitiy on extra lazy get with OneToMany
relation
---
lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
index 120ad548d..2915fd2ed 100644
--- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php
@@ -47,7 +47,7 @@ class OneToManyPersister extends AbstractCollectionPersister
throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
}
- return $persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1);
+ return $persister->load(array($mapping['mappedBy'] => $coll->getOwner(), $mapping['indexBy'] => $index), null, null, array(), 0, 1);
}
/**
From 06ed21e88303b41381d7b7488033bcef983277dd Mon Sep 17 00:00:00 2001
From: Sander Marechal
Date: Thu, 27 Jun 2013 14:19:39 +0200
Subject: [PATCH 186/332] Remove extra-lazy-get for ManyToMany relation
---
lib/Doctrine/ORM/PersistentCollection.php | 1 +
.../ORM/Persisters/ManyToManyPersister.php | 18 --------------
.../Functional/ExtraLazyCollectionTest.php | 24 +------------------
3 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php
index a50cd8343..947774542 100644
--- a/lib/Doctrine/ORM/PersistentCollection.php
+++ b/lib/Doctrine/ORM/PersistentCollection.php
@@ -518,6 +518,7 @@ final class PersistentCollection implements Collection, Selectable
public function get($key)
{
if ( ! $this->initialized
+ && $this->association['type'] === Mapping\ClassMetadataInfo::ONE_TO_MANY
&& $this->association['fetch'] === Mapping\ClassMetadataInfo::FETCH_EXTRA_LAZY
&& isset($this->association['indexBy'])
) {
diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
index df46aa30a..d9f7e30ca 100644
--- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
+++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php
@@ -33,24 +33,6 @@ use Doctrine\ORM\UnitOfWork;
*/
class ManyToManyPersister extends AbstractCollectionPersister
{
- /**
- * {@inheritdoc}
- *
- * @override
- */
- public function get(PersistentCollection $coll, $index)
- {
- $mapping = $coll->getMapping();
- $uow = $this->em->getUnitOfWork();
- $persister = $uow->getEntityPersister($mapping['targetEntity']);
-
- if (!isset($mapping['indexBy'])) {
- throw new \BadMethodCallException("Selecting a collection by index is only supported on indexed collections.");
- }
-
- return $persister->load(array($mapping['indexBy'] => $index), null, null, array(), 0, 1);
- }
-
/**
* {@inheritdoc}
*
diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
index 5d8fa0f2a..eb4dbe4d8 100644
--- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php
@@ -17,7 +17,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
private $groupId;
private $articleId;
- private $groupname;
private $topic;
private $phonenumber;
@@ -562,33 +561,13 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertSame($article, $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId));
}
- /**
- * @group DDC-1398
- */
- public function testGetIndexByManyToMany()
- {
- $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
- /* @var $user CmsUser */
-
- $queryCount = $this->getCurrentQueryCount();
-
- $group = $user->groups->get($this->groupname);
-
- $this->assertFalse($user->groups->isInitialized());
- $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
- $this->assertSame($group, $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId));
- }
-
/**
* @group DDC-1398
*/
public function testGetNonExistentIndexBy()
{
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
- /* @var $user CmsUser */
-
$this->assertNull($user->articles->get(-1));
- $this->assertNull($user->groups->get(-1));
}
private function loadFixture()
@@ -668,8 +647,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->userId = $user1->getId();
$this->groupId = $group1->id;
- $this->groupname = $group1->name;
$this->topic = $article1->topic;
$this->phonenumber = $phonenumber1->phonenumber;
}
-}
\ No newline at end of file
+}
From e4bccdc7b3e40b5f017675e289272b952ae721bf Mon Sep 17 00:00:00 2001
From: "Fabio B. Silva"
Date: Thu, 27 Jun 2013 20:18:21 -0400
Subject: [PATCH 187/332] coveralls code coverage
---
.coveralls.yml | 4 ++++
.travis.yml | 3 +++
README.markdown | 2 ++
composer.json | 3 ++-
tests/travis/mysql.travis.xml | 4 ++++
tests/travis/pgsql.travis.xml | 5 +++++
tests/travis/sqlite.travis.xml | 6 ++++++
7 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 .coveralls.yml
diff --git a/.coveralls.yml b/.coveralls.yml
new file mode 100644
index 000000000..0c0823360
--- /dev/null
+++ b/.coveralls.yml
@@ -0,0 +1,4 @@
+# for php-coveralls
+service_name: travis-ci
+src_dir: lib
+coverage_clover: build/logs/clover.xml
diff --git a/.travis.yml b/.travis.yml
index d6c3f027a..92b97851f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,3 +19,6 @@ before_script:
- composer install --prefer-source --dev
script: phpunit --configuration tests/travis/$DB.travis.xml
+
+after_script:
+ - php vendor/bin/coveralls -v
diff --git a/README.markdown b/README.markdown
index 39bde0285..b6b60ac16 100644
--- a/README.markdown
+++ b/README.markdown
@@ -5,6 +5,8 @@ Master: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?bra
2.2: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.2)](http://travis-ci.org/doctrine/doctrine2)
2.1: [![Build Status](https://secure.travis-ci.org/doctrine/doctrine2.png?branch=2.1.x)](http://travis-ci.org/doctrine/doctrine2)
+Master: [![Coverage Status](https://coveralls.io/repos/doctrine/doctrine2/badge.png?branch=master)](https://coveralls.io/r/doctrine/doctrine2?branch=master)
+
[![Latest Stable Version](https://poser.pugx.org/doctrine/orm/v/stable.png)](https://packagist.org/packages/doctrine/orm) [![Total Downloads](https://poser.pugx.org/doctrine/orm/downloads.png)](https://packagist.org/packages/doctrine/orm)
diff --git a/composer.json b/composer.json
index f74058bac..8805d54a3 100644
--- a/composer.json
+++ b/composer.json
@@ -20,7 +20,8 @@
"symfony/console": "2.*"
},
"require-dev": {
- "symfony/yaml": "2.1"
+ "symfony/yaml": "2.1",
+ "satooshi/php-coveralls": "dev-master"
},
"suggest": {
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
diff --git a/tests/travis/mysql.travis.xml b/tests/travis/mysql.travis.xml
index f17a4b87d..82559afdf 100644
--- a/tests/travis/mysql.travis.xml
+++ b/tests/travis/mysql.travis.xml
@@ -16,6 +16,10 @@
+
+
+
+
./../Doctrine/Tests/ORM
diff --git a/tests/travis/pgsql.travis.xml b/tests/travis/pgsql.travis.xml
index fa0581acb..b92f775aa 100644
--- a/tests/travis/pgsql.travis.xml
+++ b/tests/travis/pgsql.travis.xml
@@ -18,6 +18,11 @@
+
+
+
+
+
./../Doctrine/Tests/ORM
diff --git a/tests/travis/sqlite.travis.xml b/tests/travis/sqlite.travis.xml
index 5d310c327..a4c400caa 100644
--- a/tests/travis/sqlite.travis.xml
+++ b/tests/travis/sqlite.travis.xml
@@ -1,10 +1,16 @@
+
+
+
+
+
./../Doctrine/Tests/ORM
+
performance
From c57f2c39f622b7fc4bfd705d1561706039bf89f1 Mon Sep 17 00:00:00 2001
From: Dave Hulbert
Date: Tue, 2 Jul 2013 16:28:58 +0100
Subject: [PATCH 188/332] Fix grammar in DropCommand
---
.../ORM/Tools/Console/Command/SchemaTool/DropCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
index ac003b991..247bca1e4 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
@@ -50,7 +50,7 @@ class DropCommand extends AbstractCommand
->setDefinition(array(
new InputOption(
'dump-sql', null, InputOption::VALUE_NONE,
- 'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
+ 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.'
),
new InputOption(
'force', null, InputOption::VALUE_NONE,
From 5e700db6d38aded206f19586789e9d68981fc9bf Mon Sep 17 00:00:00 2001
From: Dave Hulbert
Date: Tue, 2 Jul 2013 16:29:36 +0100
Subject: [PATCH 189/332] Fix grammar in CreateCommand
---
.../ORM/Tools/Console/Command/SchemaTool/CreateCommand.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
index 610f25c95..9a49c698d 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/CreateCommand.php
@@ -50,7 +50,7 @@ class CreateCommand extends AbstractCommand
->setDefinition(array(
new InputOption(
'dump-sql', null, InputOption::VALUE_NONE,
- 'Instead of try to apply generated SQLs into EntityManager Storage Connection, output them.'
+ 'Instead of trying to apply generated SQLs into EntityManager Storage Connection, output them.'
)
))
->setHelp(<<
Date: Wed, 3 Jul 2013 12:14:16 +0200
Subject: [PATCH 190/332] Appending the Paginator tree walker hint, instead of
removing all the other hints.
---
lib/Doctrine/ORM/Tools/Pagination/Paginator.php | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
mode change 100644 => 100755 lib/Doctrine/ORM/Tools/Pagination/Paginator.php
diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
old mode 100644
new mode 100755
index 115eb590e..d5eda5107
--- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
@@ -134,7 +134,7 @@ class Paginator implements \Countable, \IteratorAggregate
$countQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\CountOutputWalker');
$countQuery->setResultSetMapping($rsm);
} else {
- $countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\CountWalker'));
+ $this->appendTreeWalker($countQuery, 'Doctrine\ORM\Tools\Pagination\CountWalker');
}
$countQuery->setFirstResult(null)->setMaxResults(null);
@@ -165,7 +165,7 @@ class Paginator implements \Countable, \IteratorAggregate
if ($this->useOutputWalker($subQuery)) {
$subQuery->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryOutputWalker');
} else {
- $subQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker'));
+ $this->appendTreeWalker($subQuery, 'Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker');
}
$subQuery->setFirstResult($offset)->setMaxResults($length);
@@ -231,4 +231,16 @@ class Paginator implements \Countable, \IteratorAggregate
return $this->useOutputWalkers;
}
+
+ private function appendTreeWalker(Query $query, $walkerClass)
+ {
+ $hints = $query->getHint(Query::HINT_CUSTOM_TREE_WALKERS);
+
+ if ($hints === false) {
+ $hints = array();
+ }
+
+ $hints[] = $walkerClass;
+ $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, $hints);
+ }
}
From 981fcb2c21a0c3a8f624681283c4bec1263d53ca Mon Sep 17 00:00:00 2001
From: Roger Llopart Pla
Date: Wed, 3 Jul 2013 12:24:57 +0200
Subject: [PATCH 191/332] Added docblock.
---
lib/Doctrine/ORM/Tools/Pagination/Paginator.php | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
index d5eda5107..80438e03c 100755
--- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
@@ -232,6 +232,12 @@ class Paginator implements \Countable, \IteratorAggregate
return $this->useOutputWalkers;
}
+ /**
+ * Appends a custom tree walker to the tree walkers hint.
+ *
+ * @param Query $query
+ * @param string $walkerClass
+ */
private function appendTreeWalker(Query $query, $walkerClass)
{
$hints = $query->getHint(Query::HINT_CUSTOM_TREE_WALKERS);
From 91638aadcfe9675e8c3d3f85dbfd5ba3cad56b53 Mon Sep 17 00:00:00 2001
From: Roger Llopart Pla
Date: Wed, 3 Jul 2013 11:18:19 +0000
Subject: [PATCH 192/332] Added a test which verifies that the tree walkers are
kept.
---
.../Tests/ORM/Functional/PaginationTest.php | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
index 0a2845582..15c043d84 100644
--- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
@@ -139,6 +139,18 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($query->getParameters()->isEmpty());
}
+ public function testQueryWalkerIsKept()
+ {
+ $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u";
+ $query = $this->_em->createQuery($dql);
+ $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker'));
+
+ $paginator = new Paginator($query, true);
+ $paginator->setUseOutputWalkers(false);
+ $this->assertCount(1, $paginator->getIterator());
+ $this->assertEquals(1, $paginator->count());
+ }
+
public function populate()
{
for ($i = 0; $i < 3; $i++) {
@@ -166,3 +178,22 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
);
}
}
+
+class CustomTreeWalker extends Query\TreeWalkerAdapter
+{
+ public function walkSelectStatement(Query\AST\SelectStatement $selectStatement)
+ {
+ $condition = new Query\AST\ConditionalPrimary();
+
+ $path = new Query\AST\PathExpression(Query\AST\PathExpression::TYPE_STATE_FIELD, 'u', 'name');
+ $path->type = Query\AST\PathExpression::TYPE_STATE_FIELD;
+
+ $condition->simpleConditionalExpression = new Query\AST\ComparisonExpression(
+ $path,
+ '=',
+ new Query\AST\Literal(Query\AST\Literal::STRING, 'Name1')
+ );
+
+ $selectStatement->whereClause = new Query\AST\WhereClause($condition);
+ }
+}
From 6aa58d9939018f1960106f03b5d440e916e01867 Mon Sep 17 00:00:00 2001
From: Paul
Date: Thu, 4 Jul 2013 10:12:36 +0200
Subject: [PATCH 193/332] Allow query parameters starting with an underscore
---
lib/Doctrine/ORM/Query/Lexer.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/Query/Lexer.php b/lib/Doctrine/ORM/Query/Lexer.php
index bf0b5f6db..d5721a735 100644
--- a/lib/Doctrine/ORM/Query/Lexer.php
+++ b/lib/Doctrine/ORM/Query/Lexer.php
@@ -129,7 +129,7 @@ class Lexer extends \Doctrine\Common\Lexer
'[a-z_\\\][a-z0-9_\:\\\]*[a-z0-9_]{1}',
'(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?',
"'(?:[^']|'')*'",
- '\?[0-9]*|:[a-z]{1}[a-z0-9_]{0,}'
+ '\?[0-9]*|:[a-z_][a-z0-9_]*'
);
}
From 9f2994f4629d0a6a1b666b56ec8941e39067f177 Mon Sep 17 00:00:00 2001
From: Roger Llopart Pla
Date: Thu, 4 Jul 2013 08:29:46 +0000
Subject: [PATCH 194/332] Fixed name colision.
---
tests/Doctrine/Tests/ORM/Functional/PaginationTest.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
index 15c043d84..bf9e4a685 100644
--- a/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
+++ b/tests/Doctrine/Tests/ORM/Functional/PaginationTest.php
@@ -143,7 +143,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
$dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u";
$query = $this->_em->createQuery($dql);
- $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomTreeWalker'));
+ $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('Doctrine\Tests\ORM\Functional\CustomPaginationTestTreeWalker'));
$paginator = new Paginator($query, true);
$paginator->setUseOutputWalkers(false);
@@ -179,7 +179,7 @@ class PaginationTest extends \Doctrine\Tests\OrmFunctionalTestCase
}
}
-class CustomTreeWalker extends Query\TreeWalkerAdapter
+class CustomPaginationTestTreeWalker extends Query\TreeWalkerAdapter
{
public function walkSelectStatement(Query\AST\SelectStatement $selectStatement)
{
From b5394fc5a0303401a69fdfc5ae020f3ff1a2a792 Mon Sep 17 00:00:00 2001
From: Paul Hooijenga
Date: Fri, 5 Jul 2013 09:21:24 +0200
Subject: [PATCH 195/332] Add test for query paremeters starting with
underscore
---
tests/Doctrine/Tests/ORM/Query/LexerTest.php | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/tests/Doctrine/Tests/ORM/Query/LexerTest.php b/tests/Doctrine/Tests/ORM/Query/LexerTest.php
index 29bba4bae..1798cc1ed 100644
--- a/tests/Doctrine/Tests/ORM/Query/LexerTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/LexerTest.php
@@ -158,6 +158,15 @@ class LexerTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(':name', $token['value']);
}
+ public function testScannerRecognizesNamedInputParameterStartingWithUnderscore()
+ {
+ $lexer = new Lexer(':_name');
+ $lexer->moveNext();
+ $token = $lexer->lookahead;
+ $this->assertEquals(Lexer::T_INPUT_PARAMETER, $token['type']);
+ $this->assertEquals(':_name', $token['value']);
+ }
+
public function testScannerTokenizesASimpleQueryCorrectly()
{
$dql = "SELECT u FROM My\Namespace\User u WHERE u.name = 'Jack O''Neil'";
From 641774630bcb2398aa2e2a89f1babf31690a7240 Mon Sep 17 00:00:00 2001
From: Tristan Lins
Date: Fri, 5 Jul 2013 13:40:57 +0200
Subject: [PATCH 196/332] Access properties via static:: instead of self::.
The properties of EntityGenerator are now protected instead of private.
But this does not make sense until they are accessed with static::.
Otherwise the templates cannot be overwritten within a sub class.
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 5a55f0fc9..d9a5a2858 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -390,7 +390,7 @@ public function __construct()
$this->generateEntityBody($metadata)
);
- $code = str_replace($placeHolders, $replacements, self::$classTemplate);
+ $code = str_replace($placeHolders, $replacements, static::$classTemplate);
return str_replace('', $this->spaces, $code);
}
@@ -474,7 +474,7 @@ public function __construct()
*/
public function setFieldVisibility($visibility)
{
- if ($visibility !== self::FIELD_VISIBLE_PRIVATE && $visibility !== self::FIELD_VISIBLE_PROTECTED) {
+ if ($visibility !== static::FIELD_VISIBLE_PRIVATE && $visibility !== static::FIELD_VISIBLE_PROTECTED) {
throw new \InvalidArgumentException('Invalid provided visibility (only private and protected are allowed): ' . $visibility);
}
@@ -633,7 +633,7 @@ public function __construct()
}
if ($collections) {
- return $this->prefixCodeWithSpaces(str_replace("", implode("\n".$this->spaces, $collections), self::$constructorMethodTemplate));
+ return $this->prefixCodeWithSpaces(str_replace("", implode("\n".$this->spaces, $collections), static::$constructorMethodTemplate));
}
return '';
@@ -1102,7 +1102,7 @@ public function __construct()
$this->staticReflection[$metadata->name]['methods'][] = $methodName;
$var = sprintf('%sMethodTemplate', $type);
- $template = self::$$var;
+ $template = static::$$var;
$methodTypeHint = null;
$types = Type::getTypesMap();
@@ -1155,7 +1155,7 @@ public function __construct()
$method = str_replace(
array_keys($replacements),
array_values($replacements),
- self::$lifecycleCallbackMethodTemplate
+ static::$lifecycleCallbackMethodTemplate
);
return $this->prefixCodeWithSpaces($method);
@@ -1463,11 +1463,11 @@ public function __construct()
*/
protected function getInheritanceTypeString($type)
{
- if ( ! isset(self::$inheritanceTypeMap[$type])) {
+ if ( ! isset(static::$inheritanceTypeMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided InheritanceType: %s', $type));
}
- return self::$inheritanceTypeMap[$type];
+ return static::$inheritanceTypeMap[$type];
}
/**
@@ -1479,11 +1479,11 @@ public function __construct()
*/
protected function getChangeTrackingPolicyString($type)
{
- if ( ! isset(self::$changeTrackingPolicyMap[$type])) {
+ if ( ! isset(static::$changeTrackingPolicyMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided ChangeTrackingPolicy: %s', $type));
}
- return self::$changeTrackingPolicyMap[$type];
+ return static::$changeTrackingPolicyMap[$type];
}
/**
@@ -1495,10 +1495,10 @@ public function __construct()
*/
protected function getIdGeneratorTypeString($type)
{
- if ( ! isset(self::$generatorStrategyMap[$type])) {
+ if ( ! isset(static::$generatorStrategyMap[$type])) {
throw new \InvalidArgumentException(sprintf('Invalid provided IdGeneratorType: %s', $type));
}
- return self::$generatorStrategyMap[$type];
+ return static::$generatorStrategyMap[$type];
}
}
From 3f112db7256994fc2284f011b4063d36b8614016 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Gallego?=
Date: Tue, 9 Jul 2013 17:31:30 +0200
Subject: [PATCH 197/332] Allow to have non-distinct queries
---
lib/Doctrine/ORM/AbstractQuery.php | 12 ++++++++++++
lib/Doctrine/ORM/Tools/Pagination/Paginator.php | 2 +-
tests/Doctrine/Tests/ORM/Query/QueryTest.php | 2 ++
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php
index b32310512..583969944 100644
--- a/lib/Doctrine/ORM/AbstractQuery.php
+++ b/lib/Doctrine/ORM/AbstractQuery.php
@@ -701,6 +701,18 @@ abstract class AbstractQuery
return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
}
+ /**
+ * Check if the query has a hint
+ *
+ * @param string $name The name of the hint
+ *
+ * @return bool False if the query does not have any hint
+ */
+ public function hasHint($name)
+ {
+ return isset($this->_hints[$name]);
+ }
+
/**
* Return the key value map of query hints that are currently set.
*
diff --git a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
index 115eb590e..2d45df95a 100644
--- a/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
+++ b/lib/Doctrine/ORM/Tools/Pagination/Paginator.php
@@ -121,7 +121,7 @@ class Paginator implements \Countable, \IteratorAggregate
/* @var $countQuery Query */
$countQuery = $this->cloneQuery($this->query);
- if ( ! $countQuery->getHint(CountWalker::HINT_DISTINCT)) {
+ if ( ! $countQuery->hasHint(CountWalker::HINT_DISTINCT)) {
$countQuery->setHint(CountWalker::HINT_DISTINCT, true);
}
diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php
index 9617fa873..adef91d4a 100644
--- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php
+++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php
@@ -105,6 +105,8 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('bar', $q->getHint('foo'));
$this->assertEquals('baz', $q->getHint('bar'));
$this->assertEquals(array('foo' => 'bar', 'bar' => 'baz'), $q->getHints());
+ $this->assertTrue($q->hasHint('foo'));
+ $this->assertFalse($q->hasHint('barFooBaz'));
}
/**
From d249a22f74c105925fe2de80d4c29d7c965e5fd6 Mon Sep 17 00:00:00 2001
From: Alessandro Tagliapietra
Date: Thu, 11 Jul 2013 11:52:26 +0200
Subject: [PATCH 198/332] Updated batch-processing link extension
I've changed the batch processing link adding .html else the link is broken
---
docs/en/reference/dql-doctrine-query-language.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/en/reference/dql-doctrine-query-language.rst b/docs/en/reference/dql-doctrine-query-language.rst
index 856a4b077..f9ac299e3 100644
--- a/docs/en/reference/dql-doctrine-query-language.rst
+++ b/docs/en/reference/dql-doctrine-query-language.rst
@@ -1189,7 +1189,7 @@ There are situations when a query you want to execute returns a
very large result-set that needs to be processed. All the
previously described hydration modes completely load a result-set
into memory which might not be feasible with large result sets. See
-the `Batch Processing `_ section on details how
+the `Batch Processing `_ section on details how
to iterate large result sets.
Functions
From 0a151f247410287d81ff893f1d9a362a73beef1b Mon Sep 17 00:00:00 2001
From: Eugene Morgan
Date: Mon, 15 Jul 2013 15:01:33 -0500
Subject: [PATCH 199/332] Remove extra semicolon before ->setParameter() calls
---
docs/en/reference/query-builder.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/en/reference/query-builder.rst b/docs/en/reference/query-builder.rst
index 8029822b5..b96e2dfe2 100644
--- a/docs/en/reference/query-builder.rst
+++ b/docs/en/reference/query-builder.rst
@@ -208,7 +208,7 @@ allowed. Binding parameters can simply be achieved as follows:
$qb->select('u')
->from('User u')
->where('u.id = ?1')
- ->orderBy('u.name', 'ASC');
+ ->orderBy('u.name', 'ASC')
->setParameter(1, 100); // Sets ?1 to 100, and thus we will fetch a user with u.id = 100
You are not forced to enumerate your placeholders as the
@@ -222,7 +222,7 @@ alternative syntax is available:
$qb->select('u')
->from('User u')
->where('u.id = :identifier')
- ->orderBy('u.name', 'ASC');
+ ->orderBy('u.name', 'ASC')
->setParameter('identifier', 100); // Sets :identifier to 100, and thus we will fetch a user with u.id = 100
Note that numeric placeholders start with a ? followed by a number
From 0c3581a1f8343bb4ebeb683c018a2c1d175e01a8 Mon Sep 17 00:00:00 2001
From: Thomas Tourlourat
Date: Fri, 19 Jul 2013 11:33:35 +0200
Subject: [PATCH 200/332] Color message like the update tools
---
.../ORM/Tools/Console/Command/SchemaTool/DropCommand.php | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
index 247bca1e4..a852194bc 100644
--- a/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
+++ b/lib/Doctrine/ORM/Tools/Console/Command/SchemaTool/DropCommand.php
@@ -115,8 +115,11 @@ EOT
}
if (count($sqls)) {
- $output->writeln('Schema-Tool would execute ' . count($sqls) . ' queries to drop the database.');
- $output->writeln('Please run the operation with --force to execute these queries or use --dump-sql to see them.');
+ $output->writeln(sprintf('The Schema-Tool would execute "%s" queries to update the database.', count($sqls)));
+ $output->writeln('Please run the operation by passing one - or both - of the following options:');
+
+ $output->writeln(sprintf(' %s --force to execute the command', $this->getName()));
+ $output->writeln(sprintf(' %s --dump-sql to dump the SQL statements to the screen', $this->getName()));
return 1;
}
From b4e9dafd10f2f962cf9000f6fe9e167804aa4fc9 Mon Sep 17 00:00:00 2001
From: David Buchmann
Date: Mon, 22 Jul 2013 10:23:47 +0200
Subject: [PATCH 201/332] add missing hint about lifecycle callback
---
docs/en/reference/events.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/en/reference/events.rst b/docs/en/reference/events.rst
index 517f2ec5b..1d5351563 100644
--- a/docs/en/reference/events.rst
+++ b/docs/en/reference/events.rst
@@ -173,7 +173,7 @@ the life-time of their registered entities.
database or after the refresh operation has been applied to it.
- loadClassMetadata - The loadClassMetadata event occurs after the
mapping metadata for a class has been loaded from a mapping source
- (annotations/xml/yaml).
+ (annotations/xml/yaml). This event is not a lifecycle callback.
- preFlush - The preFlush event occurs at the very beginning of a flush
operation. This event is not a lifecycle callback.
- onFlush - The onFlush event occurs after the change-sets of all
@@ -183,7 +183,7 @@ the life-time of their registered entities.
event is not a lifecycle callback.
- onClear - The onClear event occurs when the EntityManager#clear() operation is
invoked, after all references to entities have been removed from the unit of
- work.
+ work. This event is not a lifecycle callback.
.. warning::
From eba933bb478a4a1d2d8bd5bd1ef48e6efad87d0c Mon Sep 17 00:00:00 2001
From: Nicolas Nutten
Date: Mon, 22 Jul 2013 10:56:18 +0200
Subject: [PATCH 202/332] To avoid "SpacingAfterParams" error with PHPCS
Symfony2 coding standard
Hello,
I added two blank lines in comments two avoid the following error with PHPCS Symfony2 coding standard :
Error Code: SpacingAfterParams
Error Description: Last parameter comment requires a blank new line after it.
---
lib/Doctrine/ORM/Tools/EntityGenerator.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/Doctrine/ORM/Tools/EntityGenerator.php b/lib/Doctrine/ORM/Tools/EntityGenerator.php
index 94c1a2eac..c1e1c771e 100644
--- a/lib/Doctrine/ORM/Tools/EntityGenerator.php
+++ b/lib/Doctrine/ORM/Tools/EntityGenerator.php
@@ -234,6 +234,7 @@ public function ()
*
*
* @param $
+ *
* @return
*/
public function ($)
@@ -251,6 +252,7 @@ public function ($)
*
*
* @param $
+ *
* @return
*/
public function (