[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.
This commit is contained in:
parent
1382d766b0
commit
523697d0b6
@ -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);
|
||||
|
@ -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}
|
||||
*
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user