[2.0] More small internal perf. improvements.
This commit is contained in:
parent
eea4391598
commit
96ef7eca13
@ -39,7 +39,7 @@ use \PDO;
|
||||
abstract class AbstractHydrator
|
||||
{
|
||||
/** The ResultSetMapping. */
|
||||
protected $_resultSetMapping;
|
||||
protected $_rsm;
|
||||
|
||||
/** @var EntityManager The EntityManager instance. */
|
||||
protected $_em;
|
||||
@ -74,7 +74,7 @@ abstract class AbstractHydrator
|
||||
public function iterate($stmt, $resultSetMapping)
|
||||
{
|
||||
$this->_stmt = $stmt;
|
||||
$this->_resultSetMapping = $resultSetMapping;
|
||||
$this->_rsm = $resultSetMapping;
|
||||
$this->_prepare();
|
||||
return new IterableResult($this);
|
||||
}
|
||||
@ -89,7 +89,7 @@ abstract class AbstractHydrator
|
||||
public function hydrateAll($stmt, $resultSetMapping)
|
||||
{
|
||||
$this->_stmt = $stmt;
|
||||
$this->_resultSetMapping = $resultSetMapping;
|
||||
$this->_rsm = $resultSetMapping;
|
||||
$this->_prepare();
|
||||
$result = $this->_hydrateAll();
|
||||
$this->_cleanup();
|
||||
@ -127,7 +127,7 @@ abstract class AbstractHydrator
|
||||
*/
|
||||
protected function _cleanup()
|
||||
{
|
||||
$this->_resultSetMapping = null;
|
||||
$this->_rsm = null;
|
||||
$this->_stmt->closeCursor();
|
||||
$this->_stmt = null;
|
||||
}
|
||||
@ -174,26 +174,26 @@ abstract class AbstractHydrator
|
||||
foreach ($data as $key => $value) {
|
||||
// Parse each column name only once. Cache the results.
|
||||
if ( ! isset($cache[$key])) {
|
||||
if (isset($this->_resultSetMapping->ignoredColumns[$key])) {
|
||||
if (isset($this->_rsm->ignoredColumns[$key])) {
|
||||
$cache[$key] = false;
|
||||
} else if (isset($this->_resultSetMapping->scalarMappings[$key])) {
|
||||
$cache[$key]['fieldName'] = $this->_resultSetMapping->getScalarAlias($key);
|
||||
} else if (isset($this->_rsm->scalarMappings[$key])) {
|
||||
$cache[$key]['fieldName'] = $this->_rsm->getScalarAlias($key);
|
||||
$cache[$key]['isScalar'] = true;
|
||||
} else if (isset($this->_resultSetMapping->fieldMappings[$key])) {
|
||||
$classMetadata = $this->_resultSetMapping->getOwningClass($key);
|
||||
$fieldName = $this->_resultSetMapping->fieldMappings[$key];
|
||||
} else if (isset($this->_rsm->fieldMappings[$key])) {
|
||||
$classMetadata = $this->_rsm->getOwningClass($key);
|
||||
$fieldName = $this->_rsm->fieldMappings[$key];
|
||||
$classMetadata = $this->_lookupDeclaringClass($classMetadata, $fieldName);
|
||||
$cache[$key]['fieldName'] = $fieldName;
|
||||
$cache[$key]['isScalar'] = false;
|
||||
$cache[$key]['type'] = Type::getType($classMetadata->getTypeOfField($fieldName));
|
||||
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
|
||||
$cache[$key]['dqlAlias'] = $this->_resultSetMapping->columnOwnerMap[$key];
|
||||
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
|
||||
} else {
|
||||
// Discriminator column
|
||||
$cache[$key]['isDiscriminator'] = true;
|
||||
$cache[$key]['isScalar'] = false;
|
||||
$cache[$key]['fieldName'] = $key;
|
||||
$cache[$key]['dqlAlias'] = $this->_resultSetMapping->columnOwnerMap[$key];
|
||||
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,20 +245,20 @@ abstract class AbstractHydrator
|
||||
foreach ($data as $key => $value) {
|
||||
// Parse each column name only once. Cache the results.
|
||||
if ( ! isset($cache[$key])) {
|
||||
if (isset($this->_resultSetMapping->ignoredColumns[$key])) {
|
||||
if (isset($this->_rsm->ignoredColumns[$key])) {
|
||||
$cache[$key] = false;
|
||||
continue;
|
||||
} else if (isset($this->_resultSetMapping->scalarMappings[$key])) {
|
||||
$cache[$key]['fieldName'] = $this->_resultSetMapping->scalarMappings[$key];
|
||||
} else if (isset($this->_rsm->scalarMappings[$key])) {
|
||||
$cache[$key]['fieldName'] = $this->_rsm->scalarMappings[$key];
|
||||
$cache[$key]['isScalar'] = true;
|
||||
} else {
|
||||
$classMetadata = $this->_resultSetMapping->getOwningClass($key);
|
||||
$fieldName = $this->_resultSetMapping->fieldMappings[$key];
|
||||
$classMetadata = $this->_rsm->getOwningClass($key);
|
||||
$fieldName = $this->_rsm->fieldMappings[$key];
|
||||
$classMetadata = $this->_lookupDeclaringClass($classMetadata, $fieldName);
|
||||
$cache[$key]['fieldName'] = $fieldName;
|
||||
$cache[$key]['isScalar'] = false;
|
||||
$cache[$key]['type'] = Type::getType($classMetadata->getTypeOfField($fieldName));
|
||||
$cache[$key]['dqlAlias'] = $this->_resultSetMapping->columnOwnerMap[$key];
|
||||
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,8 +283,8 @@ abstract class AbstractHydrator
|
||||
*/
|
||||
protected function _getCustomIndexField($alias)
|
||||
{
|
||||
return isset($this->_resultSetMapping->indexByMap[$alias]) ?
|
||||
$this->_resultSetMapping->indexByMap[$alias] : null;
|
||||
return isset($this->_rsm->indexByMap[$alias]) ?
|
||||
$this->_rsm->indexByMap[$alias] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,12 +40,12 @@ class ArrayHydrator extends AbstractHydrator
|
||||
/** @override */
|
||||
protected function _prepare()
|
||||
{
|
||||
$this->_isSimpleQuery = $this->_resultSetMapping->getEntityResultCount() <= 1;
|
||||
$this->_isSimpleQuery = $this->_rsm->getEntityResultCount() <= 1;
|
||||
$this->_identifierMap = array();
|
||||
$this->_resultPointers = array();
|
||||
$this->_idTemplate = array();
|
||||
$this->_resultCounter = 0;
|
||||
foreach ($this->_resultSetMapping->getAliasMap() as $dqlAlias => $class) {
|
||||
foreach ($this->_rsm->getAliasMap() as $dqlAlias => $class) {
|
||||
$this->_identifierMap[$dqlAlias] = array();
|
||||
$this->_resultPointers[$dqlAlias] = array();
|
||||
$this->_idTemplate[$dqlAlias] = '';
|
||||
@ -88,17 +88,17 @@ class ArrayHydrator extends AbstractHydrator
|
||||
foreach ($rowData as $dqlAlias => $data) {
|
||||
$index = false;
|
||||
|
||||
if (isset($this->_resultSetMapping->parentAliasMap[$dqlAlias])) {
|
||||
if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
|
||||
// It's a joined result
|
||||
|
||||
$parent = $this->_resultSetMapping->parentAliasMap[$dqlAlias];
|
||||
$relation = $this->_resultSetMapping->relationMap[$dqlAlias];
|
||||
$parent = $this->_rsm->parentAliasMap[$dqlAlias];
|
||||
$relation = $this->_rsm->relationMap[$dqlAlias];
|
||||
$relationAlias = $relation->getSourceFieldName();
|
||||
$path = $parent . '.' . $dqlAlias;
|
||||
|
||||
// Get a reference to the right element in the result tree.
|
||||
// This element will get the associated element attached.
|
||||
if ($this->_resultSetMapping->isMixed && isset($this->_rootAliases[$parent])) {
|
||||
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) {
|
||||
$key = key(reset($this->_resultPointers));
|
||||
// TODO: Exception if $key === null ?
|
||||
$baseElement =& $this->_resultPointers[$parent][$key];
|
||||
@ -155,14 +155,14 @@ class ArrayHydrator extends AbstractHydrator
|
||||
if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
|
||||
$element = $rowData[$dqlAlias];
|
||||
if ($field = $this->_getCustomIndexField($dqlAlias)) {
|
||||
if ($this->_resultSetMapping->isMixed) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result[] = array($element[$field] => $element);
|
||||
++$this->_resultCounter;
|
||||
} else {
|
||||
$result[$element[$field]] = $element;
|
||||
}
|
||||
} else {
|
||||
if ($this->_resultSetMapping->isMixed) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result[] = array($element);
|
||||
++$this->_resultCounter;
|
||||
} else {
|
||||
|
@ -33,55 +33,69 @@ use Doctrine\Common\Collections\Collection;
|
||||
*/
|
||||
class ObjectHydrator extends AbstractHydrator
|
||||
{
|
||||
/* TODO: Consider unifying _collections and _initializedRelations */
|
||||
/** Collections initialized by the hydrator */
|
||||
private $_collections = array();
|
||||
/** Memory for initialized relations */
|
||||
private $_initializedRelations = array();
|
||||
|
||||
/*
|
||||
* These two properties maintain their values between hydration runs.
|
||||
*/
|
||||
private $_classMetadatas = array();
|
||||
private $_rootAliases = array();
|
||||
private $_discriminatorMap = array();
|
||||
|
||||
/*
|
||||
* The following parts are reinitialized on every hydration run.
|
||||
*/
|
||||
private $_isSimpleQuery = false;
|
||||
private $_allowPartialObjects = false;
|
||||
private $_identifierMap = array();
|
||||
private $_resultPointers = array();
|
||||
private $_idTemplate = array();
|
||||
private $_resultCounter = 0;
|
||||
private $_discriminatorMap = array();
|
||||
private $_rootAliases = array();
|
||||
private $_fetchedAssociations = array();
|
||||
/* TODO: Consider unifying _collections and _initializedRelations */
|
||||
/** Collections initialized by the hydrator */
|
||||
private $_collections = array();
|
||||
/** Memory for initialized relations */
|
||||
private $_initializedRelations = array();
|
||||
|
||||
/** @override */
|
||||
protected function _prepare()
|
||||
{
|
||||
$this->_isSimpleQuery = count($this->_resultSetMapping->aliasMap) <= 1;
|
||||
$this->_isSimpleQuery = count($this->_rsm->aliasMap) <= 1;
|
||||
$this->_allowPartialObjects = $this->_em->getConfiguration()->getAllowPartialObjects();
|
||||
$this->_identifierMap = array();
|
||||
$this->_resultPointers = array();
|
||||
$this->_idTemplate = array();
|
||||
$this->_resultCounter = 0;
|
||||
foreach ($this->_resultSetMapping->aliasMap as $dqlAlias => $class) {
|
||||
$this->_fetchedAssociations = array();
|
||||
|
||||
foreach ($this->_rsm->aliasMap as $dqlAlias => $class) {
|
||||
$this->_identifierMap[$dqlAlias] = array();
|
||||
$this->_resultPointers[$dqlAlias] = array();
|
||||
$this->_idTemplate[$dqlAlias] = '';
|
||||
$this->_classMetadatas[$class->name] = $class;
|
||||
if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
|
||||
$this->_discriminatorMap[$class->name][$class->discriminatorValue] = $class->name;
|
||||
foreach (array_merge($class->parentClasses, $class->subClasses) as $className) {
|
||||
$otherClass = $this->_em->getClassMetadata($className);
|
||||
$value = $otherClass->discriminatorValue;
|
||||
$this->_classMetadatas[$className] = $otherClass;
|
||||
$this->_discriminatorMap[$class->name][$value] = $className;
|
||||
|
||||
if ( ! isset($this->_classMetadatas[$class->name])) {
|
||||
$this->_classMetadatas[$class->name] = $class;
|
||||
// Gather class descriptors and discriminator values of subclasses, if necessary
|
||||
if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
|
||||
$this->_discriminatorMap[$class->name][$class->discriminatorValue] = $class->name;
|
||||
foreach (array_merge($class->parentClasses, $class->subClasses) as $className) {
|
||||
$otherClass = $this->_em->getClassMetadata($className);
|
||||
$value = $otherClass->discriminatorValue;
|
||||
$this->_classMetadatas[$className] = $otherClass;
|
||||
$this->_discriminatorMap[$class->name][$value] = $className;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->_resultSetMapping->relationMap[$dqlAlias])) {
|
||||
$assoc = $this->_resultSetMapping->relationMap[$dqlAlias];
|
||||
$this->_fetchedAssociations[$assoc->getSourceEntityName()][$assoc->getSourceFieldName()] = true;
|
||||
if ($mappedByField = $assoc->getMappedByFieldName()) {
|
||||
$this->_fetchedAssociations[$assoc->getTargetEntityName()][$mappedByField] = true;
|
||||
} else if ($inverseAssoc = $this->_em->getClassMetadata($assoc->getTargetEntityName())
|
||||
->inverseMappings[$assoc->getSourceFieldName()]) {
|
||||
$this->_fetchedAssociations[$assoc->getTargetEntityName()][
|
||||
$inverseAssoc->getSourceFieldName()
|
||||
|
||||
// Remember which classes are "fetch joined"
|
||||
if (isset($this->_rsm->relationMap[$dqlAlias])) {
|
||||
$assoc = $this->_rsm->relationMap[$dqlAlias];
|
||||
$this->_fetchedAssociations[$assoc->getSourceEntityName()][$assoc->sourceFieldName] = true;
|
||||
if ($mappedByField = $assoc->mappedByFieldName) {
|
||||
$this->_fetchedAssociations[$assoc->targetEntityName][$mappedByField] = true;
|
||||
} else if ($inverseAssoc = $this->_em->getClassMetadata($assoc->targetEntityName)
|
||||
->inverseMappings[$assoc->sourceFieldName]) {
|
||||
$this->_fetchedAssociations[$assoc->targetEntityName][
|
||||
$inverseAssoc->sourceFieldName
|
||||
] = true;
|
||||
}
|
||||
}
|
||||
@ -97,7 +111,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
{
|
||||
$s = microtime(true);
|
||||
|
||||
if ($this->_resultSetMapping->isMixed) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result = array();
|
||||
} else {
|
||||
$result = new Collection;
|
||||
@ -184,7 +198,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$classMetadata = $this->_classMetadatas[get_class($entity)];
|
||||
|
||||
$relation = $classMetadata->getAssociationMapping($name);
|
||||
$relatedClass = $this->_em->getClassMetadata($relation->getTargetEntityName());
|
||||
$relatedClass = $this->_em->getClassMetadata($relation->targetEntityName);
|
||||
$coll = $this->getCollection($relatedClass);
|
||||
$coll->setOwner($entity, $relation);
|
||||
|
||||
@ -226,8 +240,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
private function getEntity(array $data, $className)
|
||||
{
|
||||
if (isset($this->_resultSetMapping->discriminatorColumns[$className])) {
|
||||
$discrColumn = $this->_resultSetMapping->discriminatorColumns[$className];
|
||||
if (isset($this->_rsm->discriminatorColumns[$className])) {
|
||||
$discrColumn = $this->_rsm->discriminatorColumns[$className];
|
||||
$className = $this->_discriminatorMap[$className][$data[$discrColumn]];
|
||||
unset($data[$discrColumn]);
|
||||
}
|
||||
@ -241,15 +255,16 @@ class ObjectHydrator extends AbstractHydrator
|
||||
if ($assoc->isLazilyFetched()) {
|
||||
// Inject proxy
|
||||
$proxy = $this->_em->getProxyGenerator()->getAssociationProxy($entity, $assoc);
|
||||
$this->_classMetadatas[$className]->setFieldValue($entity, $field, $proxy);
|
||||
$this->_classMetadatas[$className]->reflFields[$field]->setValue($entity, $proxy);
|
||||
} else {
|
||||
//TODO: Schedule for eager fetching?
|
||||
}
|
||||
} else {
|
||||
// Inject collection
|
||||
$this->_classMetadatas[$className]->reflFields[$field]
|
||||
->setValue($entity, new PersistentCollection($this->_em,
|
||||
$this->_em->getClassMetadata($assoc->getTargetEntityName())
|
||||
->setValue($entity, new PersistentCollection(
|
||||
$this->_em,
|
||||
$this->_em->getClassMetadata($assoc->targetEntityName)
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -287,16 +302,16 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$this->_uow->setOriginalEntityProperty(spl_object_hash($entity1), $property, $entity2);
|
||||
$relation = $classMetadata1->getAssociationMapping($property);
|
||||
if ($relation->isOneToOne()) {
|
||||
$targetClass = $this->_classMetadatas[$relation->getTargetEntityName()];
|
||||
$targetClass = $this->_classMetadatas[$relation->targetEntityName];
|
||||
if ($relation->isOwningSide()) {
|
||||
// If there is an inverse mapping on the target class its bidirectional
|
||||
if ($targetClass->hasInverseAssociationMapping($property)) {
|
||||
$sourceProp = $targetClass->inverseMappings[$fieldName]->getSourceFieldName();
|
||||
if (isset($targetClass->inverseMappings[$property])) {
|
||||
$sourceProp = $targetClass->inverseMappings[$fieldName]->sourceFieldName;
|
||||
$targetClass->reflFields[$sourceProp]->setValue($entity2, $entity1);
|
||||
}
|
||||
} else {
|
||||
// For sure bidirectional, as there is no inverse side in unidirectional
|
||||
$targetClass->reflFields[$relation->getMappedByFieldName()]->setValue($entity2, $entity1);
|
||||
$targetClass->reflFields[$relation->mappedByFieldName]->setValue($entity2, $entity1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -322,18 +337,18 @@ class ObjectHydrator extends AbstractHydrator
|
||||
// Hydrate the entity data found in the current row.
|
||||
foreach ($rowData as $dqlAlias => $data) {
|
||||
$index = false;
|
||||
$entityName = $this->_resultSetMapping->aliasMap[$dqlAlias]->name;
|
||||
$entityName = $this->_rsm->aliasMap[$dqlAlias]->name;
|
||||
|
||||
if (isset($this->_resultSetMapping->parentAliasMap[$dqlAlias])) {
|
||||
if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
|
||||
// It's a joined result
|
||||
|
||||
$parent = $this->_resultSetMapping->parentAliasMap[$dqlAlias];
|
||||
$relation = $this->_resultSetMapping->relationMap[$dqlAlias];
|
||||
$relationAlias = $relation->getSourceFieldName();
|
||||
$parent = $this->_rsm->parentAliasMap[$dqlAlias];
|
||||
$relation = $this->_rsm->relationMap[$dqlAlias];
|
||||
$relationAlias = $relation->sourceFieldName;
|
||||
|
||||
// Get a reference to the right element in the result tree.
|
||||
// This element will get the associated element attached.
|
||||
if ($this->_resultSetMapping->isMixed && isset($this->_rootAliases[$parent])) {
|
||||
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parent])) {
|
||||
$key = key(reset($this->_resultPointers));
|
||||
// TODO: Exception if $key === null ?
|
||||
$baseElement =& $this->_resultPointers[$parent][$key];
|
||||
@ -363,12 +378,11 @@ class ObjectHydrator extends AbstractHydrator
|
||||
// If it's a bi-directional many-to-many, also initialize the reverse collection.
|
||||
if ($relation->isManyToMany()) {
|
||||
if ($relation->isOwningSide()) {
|
||||
$reverseAssoc = $this->_classMetadatas[$entityName]
|
||||
->inverseMappings[$relationAlias];
|
||||
$reverseAssoc = $this->_classMetadatas[$entityName]->inverseMappings[$relationAlias];
|
||||
if ($reverseAssoc) {
|
||||
$this->initRelatedCollection($element, $reverseAssoc->getSourceFieldName());
|
||||
$this->initRelatedCollection($element, $reverseAssoc->sourceFieldName);
|
||||
}
|
||||
} else if ($mappedByField = $relation->getMappedByFieldName()) {
|
||||
} else if ($mappedByField = $relation->mappedByFieldName) {
|
||||
$this->initRelatedCollection($element, $mappedByField);
|
||||
}
|
||||
}
|
||||
@ -421,7 +435,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
if ($this->_isSimpleQuery || ! isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]])) {
|
||||
$element = $this->getEntity($rowData[$dqlAlias], $entityName);
|
||||
if ($field = $this->_getCustomIndexField($dqlAlias)) {
|
||||
if ($this->_resultSetMapping->isMixed) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result[] = array(
|
||||
$this->_classMetadatas[$entityName]
|
||||
->reflFields[$field]
|
||||
@ -434,7 +448,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
->getValue($element));
|
||||
}
|
||||
} else {
|
||||
if ($this->_resultSetMapping->isMixed) {
|
||||
if ($this->_rsm->isMixed) {
|
||||
$result[] = array($element);
|
||||
++$this->_resultCounter;
|
||||
} else {
|
||||
|
@ -1,7 +1,22 @@
|
||||
<?php
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Internal\Hydration;
|
||||
@ -11,7 +26,7 @@ use \PDO;
|
||||
/**
|
||||
* Description of SingleScalarHydrator
|
||||
*
|
||||
* @author robo
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
class SingleScalarHydrator extends AbstractHydrator
|
||||
{
|
||||
|
@ -24,6 +24,14 @@ namespace Doctrine\ORM\Mapping;
|
||||
/**
|
||||
* Base class for association mappings.
|
||||
*
|
||||
* <b>IMPORTANT NOTE:</b>
|
||||
*
|
||||
* The fields of this class are only public for 2 reasons:
|
||||
* 1) To allow fast, internal READ access.
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
@ -47,18 +55,18 @@ abstract class AssociationMapping
|
||||
'merge'
|
||||
);
|
||||
|
||||
protected $_cascades = array();
|
||||
protected $_isCascadeDelete;
|
||||
protected $_isCascadeSave;
|
||||
protected $_isCascadeRefresh;
|
||||
protected $_isCascadeMerge;
|
||||
public $cascades = array();
|
||||
public $isCascadeDelete;
|
||||
public $isCascadeSave;
|
||||
public $isCascadeRefresh;
|
||||
public $isCascadeMerge;
|
||||
|
||||
/**
|
||||
* The fetch mode used for the association.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_fetchMode = self::FETCH_MANUAL;
|
||||
public $fetchMode = self::FETCH_MANUAL;
|
||||
|
||||
/**
|
||||
* Flag that indicates whether the class that defines this mapping is
|
||||
@ -66,7 +74,7 @@ abstract class AssociationMapping
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_isOwningSide = true;
|
||||
public $isOwningSide = true;
|
||||
|
||||
/**
|
||||
* Whether the association is optional (0..X) or not (1..X).
|
||||
@ -74,14 +82,14 @@ abstract class AssociationMapping
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_isOptional = true;
|
||||
public $isOptional = true;
|
||||
|
||||
/**
|
||||
* The name of the source Entity (the Entity that defines this mapping).
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_sourceEntityName;
|
||||
public $sourceEntityName;
|
||||
|
||||
/**
|
||||
* The name of the target Entity (the Enitity that is the target of the
|
||||
@ -89,7 +97,7 @@ abstract class AssociationMapping
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_targetEntityName;
|
||||
public $targetEntityName;
|
||||
|
||||
/**
|
||||
* Identifies the field on the source class (the class this AssociationMapping
|
||||
@ -98,7 +106,7 @@ abstract class AssociationMapping
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_sourceFieldName;
|
||||
public $sourceFieldName;
|
||||
|
||||
/**
|
||||
* Identifies the field on the owning side that controls the mapping for the
|
||||
@ -106,14 +114,14 @@ abstract class AssociationMapping
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_mappedByFieldName;
|
||||
public $mappedByFieldName;
|
||||
|
||||
/**
|
||||
* The join table definition, if any.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_joinTable = array();
|
||||
public $joinTable = array();
|
||||
|
||||
//protected $_joinTableInsertSql;
|
||||
|
||||
@ -138,34 +146,38 @@ abstract class AssociationMapping
|
||||
if ( ! isset($mapping['fieldName'])) {
|
||||
throw MappingException::missingFieldName();
|
||||
}
|
||||
$this->_sourceFieldName = $mapping['fieldName'];
|
||||
$this->sourceFieldName = $mapping['fieldName'];
|
||||
|
||||
if ( ! isset($mapping['sourceEntity'])) {
|
||||
throw MappingException::missingSourceEntity($mapping['fieldName']);
|
||||
}
|
||||
$this->_sourceEntityName = $mapping['sourceEntity'];
|
||||
$this->sourceEntityName = $mapping['sourceEntity'];
|
||||
|
||||
if ( ! isset($mapping['targetEntity'])) {
|
||||
throw MappingException::missingTargetEntity($mapping['fieldName']);
|
||||
}
|
||||
$this->_targetEntityName = $mapping['targetEntity'];
|
||||
$this->targetEntityName = $mapping['targetEntity'];
|
||||
|
||||
// Mandatory and optional attributes for either side
|
||||
if ( ! isset($mapping['mappedBy'])) {
|
||||
// Optional
|
||||
if (isset($mapping['joinTable'])) {
|
||||
$this->_joinTable = $mapping['joinTable'];
|
||||
$this->joinTable = $mapping['joinTable'];
|
||||
}
|
||||
} else {
|
||||
$this->_isOwningSide = false;
|
||||
$this->_mappedByFieldName = $mapping['mappedBy'];
|
||||
$this->isOwningSide = false;
|
||||
$this->mappedByFieldName = $mapping['mappedBy'];
|
||||
}
|
||||
|
||||
// Optional attributes for both sides
|
||||
$this->_isOptional = isset($mapping['optional']) ?
|
||||
$this->isOptional = isset($mapping['optional']) ?
|
||||
(bool)$mapping['optional'] : true;
|
||||
$this->_cascades = isset($mapping['cascade']) ?
|
||||
$this->cascades = isset($mapping['cascade']) ?
|
||||
(array)$mapping['cascade'] : array();
|
||||
$this->isCascadeDelete = in_array('delete', $this->cascades);
|
||||
$this->isCascadeSave = in_array('save', $this->cascades);
|
||||
$this->isCascadeRefresh = in_array('refresh', $this->cascades);
|
||||
$this->isCascadeMerge = in_array('merge', $this->cascades);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,10 +188,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isCascadeDelete()
|
||||
{
|
||||
if ($this->_isCascadeDelete === null) {
|
||||
$this->_isCascadeDelete = in_array('delete', $this->_cascades);
|
||||
}
|
||||
return $this->_isCascadeDelete;
|
||||
return $this->isCascadeDelete;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,10 +199,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isCascadeSave()
|
||||
{
|
||||
if ($this->_isCascadeSave === null) {
|
||||
$this->_isCascadeSave = in_array('save', $this->_cascades);
|
||||
}
|
||||
return $this->_isCascadeSave;
|
||||
return $this->isCascadeSave;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,10 +210,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isCascadeRefresh()
|
||||
{
|
||||
if ($this->_isCascadeRefresh === null) {
|
||||
$this->_isCascadeRefresh = in_array('refresh', $this->_cascades);
|
||||
}
|
||||
return $this->_isCascadeRefresh;
|
||||
return $this->isCascadeRefresh;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,10 +221,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isCascadeMerge()
|
||||
{
|
||||
if ($this->_isCascadeMerge === null) {
|
||||
$this->_isCascadeMerge = in_array('merge', $this->_cascades);
|
||||
}
|
||||
return $this->_isCascadeMerge;
|
||||
return $this->isCascadeMerge;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +231,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isEagerlyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_EAGER;
|
||||
return $this->fetchMode == self::FETCH_EAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -241,7 +241,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isLazilyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_LAZY;
|
||||
return $this->fetchMode == self::FETCH_LAZY;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -251,7 +251,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isManuallyFetched()
|
||||
{
|
||||
return $this->_fetchMode == self::FETCH_MANUAL;
|
||||
return $this->fetchMode == self::FETCH_MANUAL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -261,7 +261,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isOwningSide()
|
||||
{
|
||||
return $this->_isOwningSide;
|
||||
return $this->isOwningSide;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,7 +271,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isInverseSide()
|
||||
{
|
||||
return ! $this->_isOwningSide;
|
||||
return ! $this->isOwningSide;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,7 +282,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function isOptional()
|
||||
{
|
||||
return $this->_isOptional;
|
||||
return $this->isOptional;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,7 +292,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function getSourceEntityName()
|
||||
{
|
||||
return $this->_sourceEntityName;
|
||||
return $this->sourceEntityName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,7 +302,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function getTargetEntityName()
|
||||
{
|
||||
return $this->_targetEntityName;
|
||||
return $this->targetEntityName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,7 +312,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function getJoinTable()
|
||||
{
|
||||
return $this->_joinTable;
|
||||
return $this->joinTable;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -322,7 +322,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function getSourceFieldName()
|
||||
{
|
||||
return $this->_sourceFieldName;
|
||||
return $this->sourceFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,7 +334,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function getMappedByFieldName()
|
||||
{
|
||||
return $this->_mappedByFieldName;
|
||||
return $this->mappedByFieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,7 +374,7 @@ abstract class AssociationMapping
|
||||
*/
|
||||
public function usesJoinTable()
|
||||
{
|
||||
return (bool)$this->_joinTable;
|
||||
return (bool)$this->joinTable;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,8 +36,6 @@ use Doctrine\Common\DoctrineException;
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* !! Do NOT write/modify the public properties directly. Go through the public API. !!
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
|
@ -25,6 +25,14 @@ namespace Doctrine\ORM\Mapping;
|
||||
* A many-to-many mapping describes the mapping between two collections of
|
||||
* entities.
|
||||
*
|
||||
* <b>IMPORTANT NOTE:</b>
|
||||
*
|
||||
* The fields of this class are only public for 2 reasons:
|
||||
* 1) To allow fast, internal READ access.
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
@ -33,27 +41,27 @@ class ManyToManyMapping extends AssociationMapping
|
||||
/**
|
||||
* The key columns of the source table.
|
||||
*/
|
||||
private $_sourceKeyColumns = array();
|
||||
public $sourceKeyColumns = array();
|
||||
|
||||
/**
|
||||
* The key columns of the target table.
|
||||
*/
|
||||
private $_targetKeyColumns = array();
|
||||
public $targetKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Maps the columns in the source table to the columns in the relation table.
|
||||
*/
|
||||
private $_sourceToRelationKeyColumns = array();
|
||||
public $sourceToRelationKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Maps the columns in the target table to the columns in the relation table.
|
||||
*/
|
||||
private $_targetToRelationKeyColumns = array();
|
||||
public $targetToRelationKeyColumns = array();
|
||||
|
||||
/**
|
||||
* The columns on the join table.
|
||||
*/
|
||||
private $_joinTableColumns = array();
|
||||
public $joinTableColumns = array();
|
||||
|
||||
/**
|
||||
* Initializes a new ManyToManyMapping.
|
||||
@ -85,46 +93,46 @@ class ManyToManyMapping extends AssociationMapping
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
|
||||
$this->_sourceToRelationKeyColumns[$joinColumn['referencedColumnName']] = $joinColumn['name'];
|
||||
$this->_joinTableColumns[] = $joinColumn['name'];
|
||||
$this->sourceToRelationKeyColumns[$joinColumn['referencedColumnName']] = $joinColumn['name'];
|
||||
$this->joinTableColumns[] = $joinColumn['name'];
|
||||
}
|
||||
$this->_sourceKeyColumns = array_keys($this->_sourceToRelationKeyColumns);
|
||||
$this->sourceKeyColumns = array_keys($this->sourceToRelationKeyColumns);
|
||||
|
||||
// owning side MUST specify inverseJoinColumns
|
||||
if ( ! isset($mapping['joinTable']['inverseJoinColumns'])) {
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
foreach ($mapping['joinTable']['inverseJoinColumns'] as $inverseJoinColumn) {
|
||||
$this->_targetToRelationKeyColumns[$inverseJoinColumn['referencedColumnName']] = $inverseJoinColumn['name'];
|
||||
$this->_joinTableColumns[] = $inverseJoinColumn['name'];
|
||||
$this->targetToRelationKeyColumns[$inverseJoinColumn['referencedColumnName']] = $inverseJoinColumn['name'];
|
||||
$this->joinTableColumns[] = $inverseJoinColumn['name'];
|
||||
}
|
||||
$this->_targetKeyColumns = array_keys($this->_targetToRelationKeyColumns);
|
||||
$this->targetKeyColumns = array_keys($this->targetToRelationKeyColumns);
|
||||
}
|
||||
}
|
||||
|
||||
public function getJoinTableColumns()
|
||||
{
|
||||
return $this->_joinTableColumns;
|
||||
return $this->joinTableColumns;
|
||||
}
|
||||
|
||||
public function getSourceToRelationKeyColumns()
|
||||
{
|
||||
return $this->_sourceToRelationKeyColumns;
|
||||
return $this->sourceToRelationKeyColumns;
|
||||
}
|
||||
|
||||
public function getTargetToRelationKeyColumns()
|
||||
{
|
||||
return $this->_targetToRelationKeyColumns;
|
||||
return $this->targetToRelationKeyColumns;
|
||||
}
|
||||
|
||||
public function getSourceKeyColumns()
|
||||
{
|
||||
return $this->_sourceKeyColumns;
|
||||
return $this->sourceKeyColumns;
|
||||
}
|
||||
|
||||
public function getTargetKeyColumns()
|
||||
{
|
||||
return $this->_targetKeyColumns;
|
||||
return $this->targetKeyColumns;
|
||||
}
|
||||
|
||||
public function lazyLoadFor($entity, $entityManager)
|
||||
|
@ -29,6 +29,14 @@ namespace Doctrine\ORM\Mapping;
|
||||
* In other words, the many-side MUST be the owning side and the one-side MUST be
|
||||
* the inverse side.
|
||||
*
|
||||
* <b>IMPORTANT NOTE:</b>
|
||||
*
|
||||
* The fields of this class are only public for 2 reasons:
|
||||
* 1) To allow fast, internal READ access.
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
@ -51,7 +59,7 @@ class OneToManyMapping extends AssociationMapping
|
||||
//protected $_sourceKeysToTargetForeignKeys;
|
||||
|
||||
/** Whether to delete orphaned elements (removed from the collection) */
|
||||
private $_deleteOrphans = false;
|
||||
public $deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* Initializes a new OneToManyMapping.
|
||||
@ -79,7 +87,7 @@ class OneToManyMapping extends AssociationMapping
|
||||
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
|
||||
}
|
||||
|
||||
$this->_deleteOrphans = isset($mapping['deleteOrphans']) ?
|
||||
$this->deleteOrphans = isset($mapping['deleteOrphans']) ?
|
||||
(bool)$mapping['deleteOrphans'] : false;
|
||||
}
|
||||
|
||||
@ -90,7 +98,7 @@ class OneToManyMapping extends AssociationMapping
|
||||
*/
|
||||
public function shouldDeleteOrphans()
|
||||
{
|
||||
return $this->_deleteOrphans;
|
||||
return $this->deleteOrphans;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,14 @@ namespace Doctrine\ORM\Mapping;
|
||||
* A one-to-one mapping describes a uni-directional mapping from one entity
|
||||
* to another entity.
|
||||
*
|
||||
* <b>IMPORTANT NOTE:</b>
|
||||
*
|
||||
* The fields of this class are only public for 2 reasons:
|
||||
* 1) To allow fast, internal READ access.
|
||||
* 2) To drastically reduce the size of a serialized instance (private/protected members
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* @since 2.0
|
||||
* @author Roman Borschel <roman@code-factory.org>
|
||||
*/
|
||||
@ -35,28 +43,28 @@ class OneToOneMapping extends AssociationMapping
|
||||
* i.e. source.id (pk) => target.user_id (fk).
|
||||
* Reverse mapping of _targetToSourceKeyColumns.
|
||||
*/
|
||||
private $_sourceToTargetKeyColumns = array();
|
||||
public $sourceToTargetKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Maps the target primary/foreign key columns to the source foreign/primary key columns.
|
||||
* i.e. target.user_id (fk) => source.id (pk).
|
||||
* Reverse mapping of _sourceToTargetKeyColumns.
|
||||
*/
|
||||
private $_targetToSourceKeyColumns = array();
|
||||
public $targetToSourceKeyColumns = array();
|
||||
|
||||
/**
|
||||
* Whether to delete orphaned elements (when nulled out, i.e. $foo->other = null)
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $_deleteOrphans = false;
|
||||
public $deleteOrphans = false;
|
||||
|
||||
/**
|
||||
* The join column definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_joinColumns = array();
|
||||
public $joinColumns = array();
|
||||
|
||||
/**
|
||||
* Creates a new OneToOneMapping.
|
||||
@ -83,14 +91,14 @@ class OneToOneMapping extends AssociationMapping
|
||||
if ( ! isset($mapping['joinColumns'])) {
|
||||
throw MappingException::invalidMapping($this->_sourceFieldName);
|
||||
}
|
||||
$this->_joinColumns = $mapping['joinColumns'];
|
||||
$this->joinColumns = $mapping['joinColumns'];
|
||||
foreach ($mapping['joinColumns'] as $joinColumn) {
|
||||
$this->_sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||
$this->sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
|
||||
}
|
||||
$this->_targetToSourceKeyColumns = array_flip($this->_sourceToTargetKeyColumns);
|
||||
$this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns);
|
||||
}
|
||||
|
||||
$this->_deleteOrphans = isset($mapping['deleteOrphans']) ?
|
||||
$this->deleteOrphans = isset($mapping['deleteOrphans']) ?
|
||||
(bool)$mapping['deleteOrphans'] : false;
|
||||
|
||||
return $mapping;
|
||||
@ -103,7 +111,7 @@ class OneToOneMapping extends AssociationMapping
|
||||
*/
|
||||
public function getJoinColumns()
|
||||
{
|
||||
return $this->_joinColumns;
|
||||
return $this->joinColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,7 +121,7 @@ class OneToOneMapping extends AssociationMapping
|
||||
*/
|
||||
public function getSourceToTargetKeyColumns()
|
||||
{
|
||||
return $this->_sourceToTargetKeyColumns;
|
||||
return $this->sourceToTargetKeyColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +131,7 @@ class OneToOneMapping extends AssociationMapping
|
||||
*/
|
||||
public function getTargetToSourceKeyColumns()
|
||||
{
|
||||
return $this->_targetToSourceKeyColumns;
|
||||
return $this->targetToSourceKeyColumns;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,31 +154,31 @@ class OneToOneMapping extends AssociationMapping
|
||||
*/
|
||||
public function load($owningEntity, $targetEntity, $em)
|
||||
{
|
||||
$sourceClass = $em->getClassMetadata($this->_sourceEntityName);
|
||||
$targetClass = $em->getClassMetadata($this->_targetEntityName);
|
||||
$sourceClass = $em->getClassMetadata($this->sourceEntityName);
|
||||
$targetClass = $em->getClassMetadata($this->targetEntityName);
|
||||
|
||||
$conditions = array();
|
||||
|
||||
if ($this->_isOwningSide) {
|
||||
foreach ($this->_sourceToTargetKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
|
||||
if ($this->isOwningSide) {
|
||||
foreach ($this->sourceToTargetKeyColumns as $sourceKeyColumn => $targetKeyColumn) {
|
||||
$conditions[$targetKeyColumn] = $sourceClass->getReflectionProperty(
|
||||
$sourceClass->getFieldName($sourceKeyColumn))->getValue($owningEntity);
|
||||
}
|
||||
if ($targetClass->hasInverseAssociation($this->_sourceFieldName)) {
|
||||
if ($targetClass->hasInverseAssociation($this->sourceFieldName)) {
|
||||
$targetClass->setFieldValue(
|
||||
$targetEntity,
|
||||
$targetClass->inverseMappings[$this->_sourceFieldName]->getSourceFieldName(),
|
||||
$owningEntity);
|
||||
}
|
||||
} else {
|
||||
$owningAssoc = $em->getClassMetadata($this->_targetEntityName)->getAssociationMapping($this->_mappedByFieldName);
|
||||
$owningAssoc = $em->getClassMetadata($this->targetEntityName)->getAssociationMapping($this->mappedByFieldName);
|
||||
foreach ($owningAssoc->getTargetToSourceKeyColumns() as $targetKeyColumn => $sourceKeyColumn) {
|
||||
$conditions[$sourceKeyColumn] = $sourceClass->getReflectionProperty(
|
||||
$sourceClass->getFieldName($targetKeyColumn))->getValue($owningEntity);
|
||||
}
|
||||
$targetClass->setFieldValue($targetEntity, $this->_mappedByFieldName, $owningEntity);
|
||||
$targetClass->setFieldValue($targetEntity, $this->mappedByFieldName, $owningEntity);
|
||||
}
|
||||
|
||||
$em->getUnitOfWork()->getEntityPersister($this->_targetEntityName)->load($conditions, $targetEntity);
|
||||
$em->getUnitOfWork()->getEntityPersister($this->targetEntityName)->load($conditions, $targetEntity);
|
||||
}
|
||||
}
|
@ -272,12 +272,11 @@ abstract class AbstractEntityPersister
|
||||
$entity = $this->_em->getUnitOfWork()->createEntity($this->_entityName, $data);
|
||||
} else {
|
||||
foreach ($data as $field => $value) {
|
||||
$this->_class->setFieldValue($entity, $field, $value);
|
||||
$this->_class->reflFields[$field]->setValue($entity, $value);
|
||||
}
|
||||
$id = array();
|
||||
if ($this->_class->isIdentifierComposite()) {
|
||||
$identifierFieldNames = $this->_class->identifier;
|
||||
foreach ($identifierFieldNames as $fieldName) {
|
||||
foreach ($this->_class->identifier as $fieldName) {
|
||||
$id[] = $data[$fieldName];
|
||||
}
|
||||
} else {
|
||||
@ -292,15 +291,15 @@ abstract class AbstractEntityPersister
|
||||
if ($assoc->isLazilyFetched()) {
|
||||
// Inject proxy
|
||||
$proxy = $this->_em->getProxyGenerator()->getAssociationProxy($entity, $assoc);
|
||||
$this->_class->setFieldValue($entity, $field, $proxy);
|
||||
$this->_class->reflFields[$field]->setValue($entity, $proxy);
|
||||
} else {
|
||||
//TODO: Eager fetch?
|
||||
}
|
||||
} else {
|
||||
// Inject collection
|
||||
$this->_class->getReflectionProperty($field)
|
||||
->setValue($entity, new PersistentCollection($this->_em,
|
||||
$this->_em->getClassMetadata($assoc->getTargetEntityName())
|
||||
$this->_class->reflFields[$field]->setValue(
|
||||
$entity, new PersistentCollection($this->_em,
|
||||
$this->_em->getClassMetadata($assoc->targetEntityName)
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -318,8 +317,7 @@ abstract class AbstractEntityPersister
|
||||
protected function _getSelectSingleEntitySql(array $criteria)
|
||||
{
|
||||
$columnList = '';
|
||||
$columnNames = $this->_class->getColumnNames();
|
||||
foreach ($columnNames as $column) {
|
||||
foreach ($this->_class->columnNames as $column) {
|
||||
if ($columnList != '') $columnList .= ', ';
|
||||
$columnList .= $column;
|
||||
}
|
||||
@ -327,7 +325,7 @@ abstract class AbstractEntityPersister
|
||||
$conditionSql = '';
|
||||
foreach ($criteria as $field => $value) {
|
||||
if ($conditionSql != '') $conditionSql .= ' AND ';
|
||||
$conditionSql .= $this->_class->getColumnName($field) . ' = ?';
|
||||
$conditionSql .= $this->_class->columnNames[$field] . ' = ?';
|
||||
}
|
||||
|
||||
return 'SELECT ' . $columnList . ' FROM ' . $this->_class->getTableName()
|
||||
|
@ -65,38 +65,75 @@ class ResultSetMapping
|
||||
$this->aliasMap[$alias] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $className
|
||||
* @param <type> $alias
|
||||
* @param <type> $discrColumn
|
||||
*/
|
||||
public function setDiscriminatorColumn($className, $alias, $discrColumn)
|
||||
{
|
||||
$this->discriminatorColumns[$className] = $discrColumn;
|
||||
$this->columnOwnerMap[$discrColumn] = $alias;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $className
|
||||
* @return string
|
||||
*/
|
||||
public function getDiscriminatorColumn($className)
|
||||
{
|
||||
return isset($this->discriminatorColumns[$className]) ?
|
||||
$this->discriminatorColumns[$className] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @param string $fieldName
|
||||
*/
|
||||
public function addIndexBy($alias, $fieldName)
|
||||
{
|
||||
$this->indexByMap[$alias] = $fieldName;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasIndexBy($alias)
|
||||
{
|
||||
return isset($this->indexByMap[$alias]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return string
|
||||
*/
|
||||
public function getIndexByField($alias)
|
||||
{
|
||||
return $this->indexByMap[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return boolean
|
||||
*/
|
||||
public function isFieldResult($columnName)
|
||||
{
|
||||
return isset($this->fieldMappings[$columnName]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $alias
|
||||
* @param <type> $columnName
|
||||
* @param <type> $fieldName
|
||||
*/
|
||||
public function addFieldResult($alias, $columnName, $fieldName)
|
||||
{
|
||||
$this->fieldMappings[$columnName] = $fieldName;
|
||||
@ -106,6 +143,13 @@ class ResultSetMapping
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $class
|
||||
* @param <type> $alias
|
||||
* @param <type> $parentAlias
|
||||
* @param <type> $relation
|
||||
*/
|
||||
public function addJoinedEntityResult($class, $alias, $parentAlias, $relation)
|
||||
{
|
||||
$this->aliasMap[$alias] = $class;
|
||||
@ -164,11 +208,21 @@ class ResultSetMapping
|
||||
return $this->aliasMap[$this->columnOwnerMap[$columnName]];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return AssociationMapping
|
||||
*/
|
||||
public function getRelation($alias)
|
||||
{
|
||||
return $this->relationMap[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return boolean
|
||||
*/
|
||||
public function isRelation($alias)
|
||||
{
|
||||
return isset($this->relationMap[$alias]);
|
||||
@ -186,50 +240,77 @@ class ResultSetMapping
|
||||
|
||||
/**
|
||||
*
|
||||
* @param <type> $alias
|
||||
* @return <type>
|
||||
* @param string $alias
|
||||
* @return string
|
||||
*/
|
||||
public function getParentAlias($alias)
|
||||
{
|
||||
return $this->parentAliasMap[$alias];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $alias
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasParentAlias($alias)
|
||||
{
|
||||
return isset($this->parentAliasMap[$alias]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the field name for a column name.
|
||||
*
|
||||
* @param <type> $className
|
||||
* @param <type> $columnName
|
||||
* @return <type>
|
||||
* @param string $columnName
|
||||
* @return string
|
||||
*/
|
||||
public function getFieldName($columnName)
|
||||
{
|
||||
return $this->fieldMappings[$columnName];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAliasMap()
|
||||
{
|
||||
return $this->aliasMap;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getEntityResultCount()
|
||||
{
|
||||
return count($this->aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isMixedResult()
|
||||
{
|
||||
return $this->isMixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a column name that will be ignored during hydration.
|
||||
*
|
||||
* @param string $columnName
|
||||
*/
|
||||
public function addIgnoredColumn($columnName)
|
||||
{
|
||||
$this->ignoredColumns[$columnName] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return boolean
|
||||
*/
|
||||
public function isIgnoredColumn($columnName)
|
||||
{
|
||||
return isset($this->ignoredColumns[$columnName]);
|
||||
|
@ -144,9 +144,9 @@ class HydrationPerformanceTest extends \Doctrine\Tests\OrmPerformanceTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* [romanb: 10000 rows => 3.4 seconds]
|
||||
* [romanb: 10000 rows => 3.8 seconds]
|
||||
*
|
||||
* MAXIMUM TIME: 4 seconds
|
||||
* MAXIMUM TIME: 5 seconds
|
||||
*/
|
||||
public function testSimpleQueryObjectHydrationPerformance()
|
||||
{
|
||||
@ -192,7 +192,7 @@ class HydrationPerformanceTest extends \Doctrine\Tests\OrmPerformanceTestCase
|
||||
$stmt = new HydratorMockStatement($resultSet);
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
|
||||
|
||||
$this->setMaxRunningTime(4);
|
||||
$this->setMaxRunningTime(5);
|
||||
$result = $hydrator->hydrateAll($stmt, $rsm);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user