From 076663fe3ae09667e1b7b0edf76ad3def9f367b9 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 27 Jun 2012 00:14:29 -0300 Subject: [PATCH 1/4] fix DDC-1885 in persisters --- .../ORM/Persisters/BasicEntityPersister.php | 63 +++++++------ .../ORM/Persisters/ManyToManyPersister.php | 10 +- tests/Doctrine/Tests/Models/Quote/User.php | 2 +- .../ORM/Functional/Ticket/DDC1885Test.php | 92 +++++++++++++++++++ 4 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 7ccc7e663..eeeb89dd8 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -846,7 +846,11 @@ class BasicEntityPersister if ($assoc['isOwningSide']) { $quotedJoinTable = $this->quoteStrategy->getJoinTableName($assoc, $sourceClass, $this->_platform); - foreach ($assoc['relationToSourceKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) { + foreach ($assoc['joinTable']['joinColumns'] as $joinColumn) { + $relationKeyColumn = $joinColumn['name']; + $sourceKeyColumn = $joinColumn['referencedColumnName']; + $quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $sourceClass, $this->_platform); + if ($sourceClass->containsForeignIdentifier) { $field = $sourceClass->getFieldForColumn($sourceKeyColumn); $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); @@ -856,9 +860,9 @@ class BasicEntityPersister $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]]; } - $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value; + $criteria[$quotedJoinTable . "." . $quotedKeyColumn] = $value; } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) { - $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + $criteria[$quotedJoinTable . "." . $quotedKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); } else { throw MappingException::joinColumnMustPointToMappedField( $sourceClass->name, $sourceKeyColumn @@ -870,7 +874,11 @@ class BasicEntityPersister $quotedJoinTable = $this->quoteStrategy->getJoinTableName($owningAssoc, $sourceClass, $this->_platform); // TRICKY: since the association is inverted source and target are flipped - foreach ($owningAssoc['relationToTargetKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) { + foreach ($owningAssoc['joinTable']['inverseJoinColumns'] as $joinColumn) { + $relationKeyColumn = $joinColumn['name']; + $sourceKeyColumn = $joinColumn['referencedColumnName']; + $quotedKeyColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $sourceClass, $this->_platform); + if ($sourceClass->containsForeignIdentifier) { $field = $sourceClass->getFieldForColumn($sourceKeyColumn); $value = $sourceClass->reflFields[$field]->getValue($sourceEntity); @@ -880,9 +888,9 @@ class BasicEntityPersister $value = $value[$this->_em->getClassMetadata($sourceClass->associationMappings[$field]['targetEntity'])->identifier[0]]; } - $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $value; + $criteria[$quotedJoinTable . "." . $quotedKeyColumn] = $value; } else if (isset($sourceClass->fieldNames[$sourceKeyColumn])) { - $criteria[$quotedJoinTable . "." . $relationKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); + $criteria[$quotedJoinTable . "." . $quotedKeyColumn] = $sourceClass->reflFields[$sourceClass->fieldNames[$sourceKeyColumn]]->getValue($sourceEntity); } else { throw MappingException::joinColumnMustPointToMappedField( $sourceClass->name, $sourceKeyColumn @@ -1132,31 +1140,28 @@ class BasicEntityPersister */ protected function _getSelectManyToManyJoinSQL(array $manyToMany) { - if ($manyToMany['isOwningSide']) { - $owningAssoc = $manyToMany; - $joinClauses = $manyToMany['relationToTargetKeyColumns']; - } else { - $owningAssoc = $this->_em->getClassMetadata($manyToMany['targetEntity'])->associationMappings[$manyToMany['mappedBy']]; - $joinClauses = $owningAssoc['relationToSourceKeyColumns']; + + $conditions = array(); + $sourceTableAlias = $this->_getSQLTableAlias($this->_class->name); + + $association = ($manyToMany['isOwningSide']) + ? $manyToMany + : $this->_em->getClassMetadata($manyToMany['targetEntity']) + ->associationMappings[$manyToMany['mappedBy']]; + + $relationColumns = ($manyToMany['isOwningSide']) + ? $association['joinTable']['inverseJoinColumns'] + : $association['joinTable']['joinColumns']; + + $joinTableName = $this->quoteStrategy->getJoinTableName($association, $this->_class, $this->_platform); + foreach ($relationColumns as $joinColumn) { + $quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform); + $quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $this->_class, $this->_platform); + + $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableName . '.' . $quotedSourceColumn; } - $joinTableName = $this->quoteStrategy->getJoinTableName($owningAssoc, $this->_class, $this->_platform); - $joinSql = ''; - - foreach ($joinClauses as $joinTableColumn => $sourceColumn) { - if ($joinSql != '') $joinSql .= ' AND '; - - if ($this->_class->containsForeignIdentifier && ! isset($this->_class->fieldNames[$sourceColumn])) { - $quotedColumn = $sourceColumn; // join columns cannot be quoted - } else { - $quotedColumn = $this->quoteStrategy->getColumnName($this->_class->fieldNames[$sourceColumn], $this->_class, $this->_platform); - } - - $joinSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $quotedColumn . ' = ' - . $joinTableName . '.' . $joinTableColumn; - } - - return ' INNER JOIN ' . $joinTableName . ' ON ' . $joinSql; + return ' INNER JOIN ' . $joinTableName . ' ON ' . implode(' AND ', $conditions); } /** diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php index 153482693..7e017f530 100644 --- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php @@ -76,11 +76,19 @@ class ManyToManyPersister extends AbstractCollectionPersister */ protected function _getInsertRowSQL(PersistentCollection $coll) { + $columns = array(); $mapping = $coll->getMapping(); - $columns = $mapping['joinTableColumns']; $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); $joinTable = $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform); + foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) { + $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + } + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) { + $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + } + return 'INSERT INTO ' . $joinTable . ' (' . implode(', ', $columns) . ')' . ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')'; } diff --git a/tests/Doctrine/Tests/Models/Quote/User.php b/tests/Doctrine/Tests/Models/Quote/User.php index 72715d783..fe700c09c 100644 --- a/tests/Doctrine/Tests/Models/Quote/User.php +++ b/tests/Doctrine/Tests/Models/Quote/User.php @@ -34,7 +34,7 @@ class User public $address; /** - * @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"persist"}) + * @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"all"}) * @JoinTable(name="`quote-users-groups`", * joinColumns={ * @JoinColumn( diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php new file mode 100644 index 000000000..8818e2776 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php @@ -0,0 +1,92 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\User'), + $this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Group'), + $this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Address'), + )); + } catch(\Exception $e) { + } + } + + public function testCreateRetreaveUpdateDelete() + { + + $g1 = new Group('G 1'); + $g2 = new Group('G 2'); + $user = new User(); + + $user->name = "FabioBatSilva"; + $user->email = "fabio.bat.silva@gmail.com"; + $user->groups[] = $g1; + $user->groups[] = $g2; + + // Create + $this->_em->persist($user); + $this->_em->flush(); + $this->_em->clear(); + + $u1Id = $user->id; + $g1Id = $g1->id; + $g2Id = $g2->id; + + // Retreave + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(2, $user->groups); + + $g1 = $user->getGroups()->get(0); + $g2 = $user->getGroups()->get(1); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $g1); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $g2); + + $g1->name = 'Bar 11'; + $g2->name = 'Foo 22'; + + // Update + $this->_em->persist($user); + $this->_em->flush(); + $this->_em->clear(); + + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + // Delete + $this->_em->remove($user); + + $this->_em->flush(); + $this->_em->clear(); + + $this->assertNull($this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id)); + $this->assertNull($this->_em->find('Doctrine\Tests\Models\Quote\Group', $g1Id)); + $this->assertNull($this->_em->find('Doctrine\Tests\Models\Quote\Group', $g2Id)); + } + +} \ No newline at end of file From 63580dfe262c22a0cc4964770df1e457b3695d50 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 27 Jun 2012 00:24:53 -0300 Subject: [PATCH 2/4] Fix CS --- .../ORM/Persisters/BasicEntityPersister.php | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index eeeb89dd8..8b54271c9 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -1140,28 +1140,27 @@ class BasicEntityPersister */ protected function _getSelectManyToManyJoinSQL(array $manyToMany) { + $conditions = array(); + $association = $manyToMany; + $sourceTableAlias = $this->_getSQLTableAlias($this->_class->name); - $conditions = array(); - $sourceTableAlias = $this->_getSQLTableAlias($this->_class->name); + if ( ! $manyToMany['isOwningSide']) { + $targetEntity = $this->_em->getClassMetadata($manyToMany['targetEntity']); + $association = $targetEntity->associationMappings[$manyToMany['mappedBy']]; + } - $association = ($manyToMany['isOwningSide']) - ? $manyToMany - : $this->_em->getClassMetadata($manyToMany['targetEntity']) - ->associationMappings[$manyToMany['mappedBy']]; - - $relationColumns = ($manyToMany['isOwningSide']) + $joinTableName = $this->quoteStrategy->getJoinTableName($association, $this->_class, $this->_platform); + $joinColumns = ($manyToMany['isOwningSide']) ? $association['joinTable']['inverseJoinColumns'] : $association['joinTable']['joinColumns']; - $joinTableName = $this->quoteStrategy->getJoinTableName($association, $this->_class, $this->_platform); - foreach ($relationColumns as $joinColumn) { + foreach ($joinColumns as $joinColumn) { $quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform); $quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $this->_class, $this->_platform); - - $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableName . '.' . $quotedSourceColumn; + $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableName . '.' . $quotedSourceColumn; } - return ' INNER JOIN ' . $joinTableName . ' ON ' . implode(' AND ', $conditions); + return ' INNER JOIN ' . $joinTableName . ' ON ' . implode(' AND ', $conditions); } /** From fe11831bd728a281f63f84003e031bea7be74218 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 27 Jun 2012 12:37:09 -0300 Subject: [PATCH 3/4] test remove item and clear collection --- .../ORM/Persisters/ManyToManyPersister.php | 20 +++- tests/Doctrine/Tests/Models/Quote/User.php | 19 ++++ .../ORM/Functional/Ticket/DDC1885Test.php | 92 ++++++++++++++++--- 3 files changed, 115 insertions(+), 16 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php index 7e017f530..db2792152 100644 --- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php @@ -40,11 +40,20 @@ class ManyToManyPersister extends AbstractCollectionPersister */ protected function _getDeleteRowSQL(PersistentCollection $coll) { + $columns = array(); $mapping = $coll->getMapping(); $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); + foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) { + $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + } + + foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) { + $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + } + return 'DELETE FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform) - . ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?'; + . ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?'; } /** @@ -155,12 +164,17 @@ class ManyToManyPersister extends AbstractCollectionPersister */ protected function _getDeleteSQL(PersistentCollection $coll) { - $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); + $columns = array(); $mapping = $coll->getMapping(); + $class = $this->_em->getClassMetadata(get_class($coll->getOwner())); $joinTable = $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform); + foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) { + $columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + } + return 'DELETE FROM ' . $joinTable - . ' WHERE ' . implode(' = ? AND ', array_keys($mapping['relationToSourceKeyColumns'])) . ' = ?'; + . ' WHERE ' . implode(' = ? AND ', $columns) . ' = ?'; } /** diff --git a/tests/Doctrine/Tests/Models/Quote/User.php b/tests/Doctrine/Tests/Models/Quote/User.php index fe700c09c..d034f598d 100644 --- a/tests/Doctrine/Tests/Models/Quote/User.php +++ b/tests/Doctrine/Tests/Models/Quote/User.php @@ -52,6 +52,25 @@ class User */ public $groups; + /** + * @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"all"}, fetch="EXTRA_LAZY") + * @JoinTable(name="`quote-extra-lazy-users-groups`", + * joinColumns={ + * @JoinColumn( + * name="`user-id`", + * referencedColumnName="`user-id`" + * ) + * }, + * inverseJoinColumns={ + * @JoinColumn( + * name="`group-id`", + * referencedColumnName="`group-id`" + * ) + * } + * ) + */ + public $extraLazyGroups; + public function __construct() { $this->phones = new ArrayCollection; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php index 8818e2776..09b55fbc4 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php @@ -14,6 +14,11 @@ require_once __DIR__ . '/../../../TestInit.php'; class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase { + /** + * @var \Doctrine\Tests\Models\Quote\User + */ + private $user; + protected function setUp() { parent::setUp(); @@ -26,28 +31,30 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase )); } catch(\Exception $e) { } - } - - public function testCreateRetreaveUpdateDelete() - { - - $g1 = new Group('G 1'); - $g2 = new Group('G 2'); - $user = new User(); + $user = new User(); $user->name = "FabioBatSilva"; $user->email = "fabio.bat.silva@gmail.com"; - $user->groups[] = $g1; - $user->groups[] = $g2; + $user->groups[] = new Group('G 1'); + $user->groups[] = new Group('G 2'); + $this->user = $user; // Create $this->_em->persist($user); $this->_em->flush(); $this->_em->clear(); + + } - $u1Id = $user->id; - $g1Id = $g1->id; - $g2Id = $g2->id; + public function testCreateRetreaveUpdateDelete() + { + $user = $this->user; + $g1 = $user->getGroups()->get(0); + $g2 = $user->getGroups()->get(1); + + $u1Id = $user->id; + $g1Id = $g1->id; + $g2Id = $g2->id; // Retreave $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); @@ -89,4 +96,63 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertNull($this->_em->find('Doctrine\Tests\Models\Quote\Group', $g2Id)); } + public function testRemoveItem() + { + $user = $this->user; + $u1Id = $user->id; + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(2, $user->groups); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0)); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1)); + + $user->getGroups()->remove(0); + + // Update + $this->_em->persist($user); + $this->_em->flush(); + $this->_em->clear(); + + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(1, $user->getGroups()); + } + + public function testClearAll() + { + $user = $this->user; + $u1Id = $user->id; + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(2, $user->groups); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0)); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1)); + + $user->getGroups()->clear(); + + // Update + $this->_em->persist($user); + $this->_em->flush(); + $this->_em->clear(); + + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(0, $user->getGroups()); + } } \ No newline at end of file From 632d13ba0c8f909cdb44c3890244b41c9f047ff2 Mon Sep 17 00:00:00 2001 From: "Fabio B. Silva" Date: Wed, 27 Jun 2012 14:15:06 -0300 Subject: [PATCH 4/4] fix extra lazy count --- .../ORM/Persisters/BasicEntityPersister.php | 2 +- .../ORM/Persisters/ManyToManyPersister.php | 49 ++++++++++--------- .../ORM/Functional/Ticket/DDC1885Test.php | 17 ++++++- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 8b54271c9..2d9b1f45c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -1160,7 +1160,7 @@ class BasicEntityPersister $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableName . '.' . $quotedSourceColumn; } - return ' INNER JOIN ' . $joinTableName . ' ON ' . implode(' AND ', $conditions); + return ' INNER JOIN ' . $joinTableName . ' ON ' . implode(' AND ', $conditions); } /** diff --git a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php index db2792152..23e41786c 100644 --- a/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/ManyToManyPersister.php @@ -212,41 +212,42 @@ class ManyToManyPersister extends AbstractCollectionPersister */ public function count(PersistentCollection $coll) { - $mapping = $filterMapping = $coll->getMapping(); - $class = $this->_em->getClassMetadata($mapping['sourceEntity']); - $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner()); + $conditions = array(); + $params = array(); + $mapping = $coll->getMapping(); + $association = $mapping; + $class = $this->_em->getClassMetadata($mapping['sourceEntity']); + $id = $this->_em->getUnitOfWork()->getEntityIdentifier($coll->getOwner()); - if ($mapping['isOwningSide']) { - $joinColumns = $mapping['relationToSourceKeyColumns']; - } else { - $mapping = $this->_em->getClassMetadata($mapping['targetEntity'])->associationMappings[$mapping['mappedBy']]; - $joinColumns = $mapping['relationToTargetKeyColumns']; + if ( ! $mapping['isOwningSide']) { + $targetEntity = $this->_em->getClassMetadata($mapping['targetEntity']); + $association = $targetEntity->associationMappings[$mapping['mappedBy']]; } - $whereClauses = array(); - $params = array(); + $joinColumns = ( ! $mapping['isOwningSide']) + ? $association['joinTable']['inverseJoinColumns'] + : $association['joinTable']['joinColumns']; - foreach ($mapping['joinTableColumns'] as $joinTableColumn) { - if ( ! isset($joinColumns[$joinTableColumn])) { - continue; - } - - $whereClauses[] = $joinTableColumn . ' = ?'; - - $params[] = ($class->containsForeignIdentifier) - ? $id[$class->getFieldForColumn($joinColumns[$joinTableColumn])] - : $id[$class->fieldNames[$joinColumns[$joinTableColumn]]]; + foreach ($joinColumns as $joinColumn) { + $columnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); + $referencedName = $joinColumn['referencedColumnName']; + $conditions[] = $columnName . ' = ?'; + $params[] = ($class->containsForeignIdentifier) + ? $id[$class->getFieldForColumn($referencedName)] + : $id[$class->fieldNames[$referencedName]]; } - list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($filterMapping); + $joinTableName = $this->quoteStrategy->getJoinTableName($association, $class, $this->platform); + list($joinTargetEntitySQL, $filterSql) = $this->getFilterSql($mapping); + if ($filterSql) { - $whereClauses[] = $filterSql; + $conditions[] = $filterSql; } $sql = 'SELECT COUNT(*)' - . ' FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform) . ' t' + . ' FROM ' . $joinTableName . ' t' . $joinTargetEntitySQL - . ' WHERE ' . implode(' AND ', $whereClauses); + . ' WHERE ' . implode(' AND ', $conditions); return $this->_conn->fetchColumn($sql, $params); } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php index 09b55fbc4..8fbb19ad0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1885Test.php @@ -126,7 +126,7 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertCount(1, $user->getGroups()); } - public function testClearAll() + public function testClearAll() { $user = $this->user; $u1Id = $user->id; @@ -155,4 +155,19 @@ class DDC1885Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertCount(0, $user->getGroups()); } + + public function testCountExtraLazy() + { + $user = $this->user; + $u1Id = $user->id; + $user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $u1Id); + + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user); + $this->assertEquals('FabioBatSilva', $user->name); + $this->assertEquals($u1Id, $user->id); + + $this->assertCount(0, $user->extraLazyGroups); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(0)); + $this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $user->getGroups()->get(1)); + } } \ No newline at end of file