[DDC-250] Initial untested support for @ManyToMany(indexBy) and @OneToMany(indexBy) option.
This commit is contained in:
parent
266d85e917
commit
17c1ed948e
@ -377,6 +377,11 @@ class ClassMetadataInfo
|
|||||||
* through a join table by simply mapping the association as many-to-many with a unique
|
* through a join table by simply mapping the association as many-to-many with a unique
|
||||||
* constraint on the join table.
|
* constraint on the join table.
|
||||||
*
|
*
|
||||||
|
* - <b>indexBy</b> (string, optional, to-many only)
|
||||||
|
* Specification of a field on target-entity that is used to index the collection by.
|
||||||
|
* This field HAS to be either the primary key or a unique column. Otherwise the collection
|
||||||
|
* does not contain all the entities that are actually related.
|
||||||
|
*
|
||||||
* A join table definition has the following structure:
|
* A join table definition has the following structure:
|
||||||
* <pre>
|
* <pre>
|
||||||
* array(
|
* array(
|
||||||
@ -717,6 +722,11 @@ class ClassMetadataInfo
|
|||||||
}
|
}
|
||||||
$mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
|
$mapping['isOwningSide'] = true; // assume owning side until we hit mappedBy
|
||||||
|
|
||||||
|
// unset optional indexBy attribute if its empty
|
||||||
|
if (isset($mapping['indexBy']) && !$mapping['indexBy']) {
|
||||||
|
unset($mapping['indexBy']);
|
||||||
|
}
|
||||||
|
|
||||||
// If targetEntity is unqualified, assume it is in the same namespace as
|
// If targetEntity is unqualified, assume it is in the same namespace as
|
||||||
// the sourceEntity.
|
// the sourceEntity.
|
||||||
$mapping['sourceEntity'] = $this->name;
|
$mapping['sourceEntity'] = $this->name;
|
||||||
|
@ -304,6 +304,7 @@ class AnnotationDriver implements Driver
|
|||||||
$mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
|
$mapping['mappedBy'] = $oneToManyAnnot->mappedBy;
|
||||||
$mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
|
$mapping['targetEntity'] = $oneToManyAnnot->targetEntity;
|
||||||
$mapping['cascade'] = $oneToManyAnnot->cascade;
|
$mapping['cascade'] = $oneToManyAnnot->cascade;
|
||||||
|
$mapping['indexBy'] = $oneToManyAnnot->indexBy;
|
||||||
$mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
|
$mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval;
|
||||||
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyAnnot->fetch);
|
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $oneToManyAnnot->fetch);
|
||||||
|
|
||||||
@ -362,6 +363,7 @@ class AnnotationDriver implements Driver
|
|||||||
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
|
$mapping['mappedBy'] = $manyToManyAnnot->mappedBy;
|
||||||
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
|
$mapping['inversedBy'] = $manyToManyAnnot->inversedBy;
|
||||||
$mapping['cascade'] = $manyToManyAnnot->cascade;
|
$mapping['cascade'] = $manyToManyAnnot->cascade;
|
||||||
|
$mapping['indexBy'] = $manyToManyAnnot->indexBy;
|
||||||
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyAnnot->fetch);
|
$mapping['fetch'] = constant('Doctrine\ORM\Mapping\ClassMetadata::FETCH_' . $manyToManyAnnot->fetch);
|
||||||
|
|
||||||
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
|
if ($orderByAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OrderBy')) {
|
||||||
|
@ -80,6 +80,7 @@ final class OneToMany extends Annotation {
|
|||||||
public $cascade;
|
public $cascade;
|
||||||
public $fetch = 'LAZY';
|
public $fetch = 'LAZY';
|
||||||
public $orphanRemoval = false;
|
public $orphanRemoval = false;
|
||||||
|
public $indexBy;
|
||||||
}
|
}
|
||||||
final class ManyToOne extends Annotation {
|
final class ManyToOne extends Annotation {
|
||||||
public $targetEntity;
|
public $targetEntity;
|
||||||
@ -93,6 +94,7 @@ final class ManyToMany extends Annotation {
|
|||||||
public $inversedBy;
|
public $inversedBy;
|
||||||
public $cascade;
|
public $cascade;
|
||||||
public $fetch = 'LAZY';
|
public $fetch = 'LAZY';
|
||||||
|
public $indexBy;
|
||||||
}
|
}
|
||||||
final class ElementCollection extends Annotation {
|
final class ElementCollection extends Annotation {
|
||||||
public $tableName;
|
public $tableName;
|
||||||
|
@ -309,6 +309,10 @@ class XmlDriver extends AbstractFileDriver
|
|||||||
$mapping['orderBy'] = $orderBy;
|
$mapping['orderBy'] = $orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($oneToManyElement->{'index-by'})) {
|
||||||
|
$mapping['indexBy'] = (string)$oneToManyElement->{'index-by'};
|
||||||
|
}
|
||||||
|
|
||||||
$metadata->mapOneToMany($mapping);
|
$metadata->mapOneToMany($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,6 +419,10 @@ class XmlDriver extends AbstractFileDriver
|
|||||||
$mapping['orderBy'] = $orderBy;
|
$mapping['orderBy'] = $orderBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($manyToManyElement->{'index-by'})) {
|
||||||
|
$mapping['indexBy'] = (string)$manyToManyElement->{'index-by'};
|
||||||
|
}
|
||||||
|
|
||||||
$metadata->mapManyToMany($mapping);
|
$metadata->mapManyToMany($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,6 +301,10 @@ class YamlDriver extends AbstractFileDriver
|
|||||||
$mapping['orderBy'] = $oneToManyElement['orderBy'];
|
$mapping['orderBy'] = $oneToManyElement['orderBy'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($oneToManyElement['indexBy'])) {
|
||||||
|
$mapping['indexBy'] = $oneToManyElement['indexBy'];
|
||||||
|
}
|
||||||
|
|
||||||
$metadata->mapOneToMany($mapping);
|
$metadata->mapOneToMany($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,6 +408,10 @@ class YamlDriver extends AbstractFileDriver
|
|||||||
$mapping['orderBy'] = $manyToManyElement['orderBy'];
|
$mapping['orderBy'] = $manyToManyElement['orderBy'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($manyToManyElement['indexBy'])) {
|
||||||
|
$mapping['indexBy'] = $manyToManyElement['indexBy'];
|
||||||
|
}
|
||||||
|
|
||||||
$metadata->mapManyToMany($mapping);
|
$metadata->mapManyToMany($mapping);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -750,15 +750,55 @@ class BasicEntityPersister
|
|||||||
public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
||||||
{
|
{
|
||||||
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity, $offset, $limit);
|
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity, $offset, $limit);
|
||||||
|
return $this->loadArrayFromStatement($assoc, $stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load an array of entities from a given dbal statement.
|
||||||
|
*
|
||||||
|
* @param array $assoc
|
||||||
|
* @param Doctrine\DBAL\Statement $stmt
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function loadArrayFromStatement($assoc, $stmt)
|
||||||
|
{
|
||||||
$entities = array();
|
$entities = array();
|
||||||
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
if ($assoc['indexBy']) {
|
||||||
$entities[] = $this->_createEntity($result);
|
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$entity = $this->_createEntity($result);
|
||||||
|
$entities[$this->_class->reflFields[$assoc['indexBy']]->getValue($entity)] = $entity;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$entities[] = $this->_createEntity($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$stmt->closeCursor();
|
$stmt->closeCursor();
|
||||||
return $entities;
|
return $entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hydrate a collection from a given dbal statement.
|
||||||
|
*
|
||||||
|
* @param array $assoc
|
||||||
|
* @param Doctrine\DBAL\Statement $stmt
|
||||||
|
* @param PersistentCollection $coll
|
||||||
|
*/
|
||||||
|
private function loadCollectionFromStatement($assoc, $stmt, $coll)
|
||||||
|
{
|
||||||
|
if ($assoc['indexBy']) {
|
||||||
|
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$entity = $this->_createEntity($result);
|
||||||
|
$coll->hydrateSet($this->_class->reflFields[$assoc['indexBy']]->getValue($entity), $entity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
|
$coll->hydrateAdd($this->_createEntity($result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$stmt->closeCursor();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a collection of entities of a many-to-many association.
|
* Loads a collection of entities of a many-to-many association.
|
||||||
*
|
*
|
||||||
@ -772,11 +812,7 @@ class BasicEntityPersister
|
|||||||
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||||
{
|
{
|
||||||
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity);
|
$stmt = $this->getManyToManyStatement($assoc, $sourceEntity);
|
||||||
|
return $this->loadCollectionFromStatement($assoc, $stmt, $coll);
|
||||||
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
$coll->hydrateAdd($this->_createEntity($result));
|
|
||||||
}
|
|
||||||
$stmt->closeCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
private function getManyToManyStatement(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
||||||
@ -1238,13 +1274,7 @@ class BasicEntityPersister
|
|||||||
public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
|
||||||
{
|
{
|
||||||
$stmt = $this->getOneToManyStatement($assoc, $sourceEntity, $offset, $limit);
|
$stmt = $this->getOneToManyStatement($assoc, $sourceEntity, $offset, $limit);
|
||||||
|
return $this->loadArrayFromStatement($assoc, $stmt);
|
||||||
$entities = array();
|
|
||||||
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
$entities[] = $this->_createEntity($result);
|
|
||||||
}
|
|
||||||
$stmt->closeCursor();
|
|
||||||
return $entities;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1259,11 +1289,7 @@ class BasicEntityPersister
|
|||||||
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
|
||||||
{
|
{
|
||||||
$stmt = $this->getOneToManyStatement($assoc, $sourceEntity);
|
$stmt = $this->getOneToManyStatement($assoc, $sourceEntity);
|
||||||
|
$this->loadCollectionFromStatement($assoc, $stmt, $coll);
|
||||||
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
$coll->hydrateAdd($this->_createEntity($result));
|
|
||||||
}
|
|
||||||
$stmt->closeCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user