Commit a3018340 authored by romanb's avatar romanb

[2.0] First part of cleanup for changeset 6120. More to follow.

parent 0c623fdb
...@@ -38,8 +38,6 @@ use Doctrine\Common\DoctrineException; ...@@ -38,8 +38,6 @@ use Doctrine\Common\DoctrineException;
*/ */
abstract class AbstractHydrator abstract class AbstractHydrator
{ {
const TYPES_JOINCOLUMN = 'join_column';
/** The ResultSetMapping. */ /** The ResultSetMapping. */
protected $_rsm; protected $_rsm;
...@@ -186,23 +184,19 @@ abstract class AbstractHydrator ...@@ -186,23 +184,19 @@ abstract class AbstractHydrator
} else if (isset($this->_rsm->fieldMappings[$key])) { } else if (isset($this->_rsm->fieldMappings[$key])) {
$classMetadata = $this->_em->getClassMetadata($this->_rsm->getOwningClass($key)); $classMetadata = $this->_em->getClassMetadata($this->_rsm->getOwningClass($key));
$fieldName = $this->_rsm->fieldMappings[$key]; $fieldName = $this->_rsm->fieldMappings[$key];
if ( ! isset($classMetadata->reflFields[$fieldName]) && ! in_array($fieldName, $classMetadata->joinColumnNames)) { if ( ! isset($classMetadata->reflFields[$fieldName])) {
$classMetadata = $this->_lookupDeclaringClass($classMetadata, $fieldName); $classMetadata = $this->_lookupDeclaringClass($classMetadata, $fieldName);
} }
$cache[$key]['fieldName'] = $fieldName; $cache[$key]['fieldName'] = $fieldName;
$cache[$key]['isScalar'] = false; $cache[$key]['isScalar'] = false;
if (isset($classMetadata->fieldMappings[$fieldName])) {
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']); $cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
} else {
$cache[$key]['type'] = self::TYPES_JOINCOLUMN;
}
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName); $cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else { } else {
// Discriminator column // Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isDiscriminator'] = true; $cache[$key]['isMetaColumn'] = true;
$cache[$key]['isScalar'] = false; $cache[$key]['isScalar'] = false;
$cache[$key]['fieldName'] = $key; $cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key]; $cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} }
} }
...@@ -214,7 +208,7 @@ abstract class AbstractHydrator ...@@ -214,7 +208,7 @@ abstract class AbstractHydrator
$dqlAlias = $cache[$key]['dqlAlias']; $dqlAlias = $cache[$key]['dqlAlias'];
if (isset($cache[$key]['isDiscriminator'])) { if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value; $rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
continue; continue;
} }
...@@ -223,11 +217,7 @@ abstract class AbstractHydrator ...@@ -223,11 +217,7 @@ abstract class AbstractHydrator
$id[$dqlAlias] .= '|' . $value; $id[$dqlAlias] .= '|' . $value;
} }
if ($cache[$key]['type'] == self::TYPES_JOINCOLUMN) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
} else {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform); $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
}
if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) { if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
$nonemptyComponents[$dqlAlias] = true; $nonemptyComponents[$dqlAlias] = true;
......
...@@ -230,25 +230,22 @@ class ObjectHydrator extends AbstractHydrator ...@@ -230,25 +230,22 @@ class ObjectHydrator extends AbstractHydrator
{ {
$className = $this->_rsm->aliasMap[$dqlAlias]; $className = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) { if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
$discrColumn = $this->_rsm->discriminatorColumns[$dqlAlias]; $discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
$className = $this->_discriminatorMap[$className][$data[$discrColumn]]; $className = $this->_discriminatorMap[$className][$data[$discrColumn]];
unset($data[$discrColumn]); unset($data[$discrColumn]);
} }
$entity = $this->_uow->createEntity($className, $data); $entity = $this->_uow->createEntity($className, $data);
$joinColumnsValues = array();
foreach ($this->_ce[$className]->joinColumnNames as $name) {
if (isset($data[$name])) {
$joinColumnsValues[$name] = $data[$name];
}
}
// Properly initialize any unfetched associations, if partial objects are not allowed. // Properly initialize any unfetched associations, if partial objects are not allowed.
if ( ! $this->_allowPartialObjects) { if ( ! $this->_allowPartialObjects) {
foreach ($this->_ce[$className]->associationMappings as $field => $assoc) { foreach ($this->_ce[$className]->associationMappings as $field => $assoc) {
if ( ! isset($this->_fetchedAssociations[$className][$field])) { if ( ! isset($this->_fetchedAssociations[$className][$field])) {
if ($assoc->isOneToOne()) { if ($assoc->isOneToOne()) {
if ($assoc->isLazilyFetched()) { if ($assoc->isLazilyFetched()) {
$joinColumnsValues = array();
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$joinColumnsValues[$srcColumn] = $data[$assoc->joinColumnFieldNames[$srcColumn]];
}
// Inject proxy // Inject proxy
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnsValues); $proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnsValues);
$this->_ce[$className]->reflFields[$field]->setValue($entity, $proxy); $this->_ce[$className]->reflFields[$field]->setValue($entity, $proxy);
......
...@@ -254,12 +254,6 @@ final class ClassMetadata ...@@ -254,12 +254,6 @@ final class ClassMetadata
*/ */
public $columnNames = array(); public $columnNames = array();
/**
* Array of all column names that does not map to a field.
* Foreign keys are here.
*/
public $joinColumnNames = array();
/** /**
* Whether to automatically OUTER JOIN subtypes when a basetype is queried. * Whether to automatically OUTER JOIN subtypes when a basetype is queried.
* *
...@@ -499,11 +493,6 @@ final class ClassMetadata ...@@ -499,11 +493,6 @@ final class ClassMetadata
$this->reflFields[$propName] = $property; $this->reflFields[$propName] = $property;
} }
public function addJoinColumn($name)
{
$this->joinColumnNames[] = $name;
}
/** /**
* Gets a ReflectionProperty for a specific field of the mapped class. * Gets a ReflectionProperty for a specific field of the mapped class.
* *
...@@ -1337,11 +1326,6 @@ final class ClassMetadata ...@@ -1337,11 +1326,6 @@ final class ClassMetadata
if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false) { if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false) {
$mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity']; $mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
} }
if (isset($mapping['joinColumns'])) {
foreach ($mapping['joinColumns'] as $columns) {
$this->addJoinColumn($columns['name']);
}
}
return $mapping; return $mapping;
} }
...@@ -1582,6 +1566,9 @@ final class ClassMetadata ...@@ -1582,6 +1566,9 @@ final class ClassMetadata
public function setDiscriminatorColumn($columnDef) public function setDiscriminatorColumn($columnDef)
{ {
$this->discriminatorColumn = $columnDef; $this->discriminatorColumn = $columnDef;
if ( ! isset($columnDef['fieldName'])) {
$this->discriminatorColumn['fieldName'] = $columnDef['name'];
}
} }
/** /**
......
...@@ -29,6 +29,7 @@ final class Entity extends \Doctrine\Common\Annotations\Annotation { ...@@ -29,6 +29,7 @@ final class Entity extends \Doctrine\Common\Annotations\Annotation {
final class InheritanceType extends \Doctrine\Common\Annotations\Annotation {} final class InheritanceType extends \Doctrine\Common\Annotations\Annotation {}
final class DiscriminatorColumn extends \Doctrine\Common\Annotations\Annotation { final class DiscriminatorColumn extends \Doctrine\Common\Annotations\Annotation {
public $name; public $name;
//public $fieldName; // field name used in non-object hydration (array/scalar)
public $type; public $type;
public $length; public $length;
} }
...@@ -42,6 +43,7 @@ final class GeneratedValue extends \Doctrine\Common\Annotations\Annotation { ...@@ -42,6 +43,7 @@ final class GeneratedValue extends \Doctrine\Common\Annotations\Annotation {
final class Version extends \Doctrine\Common\Annotations\Annotation {} final class Version extends \Doctrine\Common\Annotations\Annotation {}
final class JoinColumn extends \Doctrine\Common\Annotations\Annotation { final class JoinColumn extends \Doctrine\Common\Annotations\Annotation {
public $name; public $name;
//public $fieldName; // field name used in non-object hydration (array/scalar)
public $referencedColumnName; public $referencedColumnName;
public $unique = false; public $unique = false;
public $nullable = true; public $nullable = true;
......
...@@ -67,6 +67,8 @@ class OneToOneMapping extends AssociationMapping ...@@ -67,6 +67,8 @@ class OneToOneMapping extends AssociationMapping
*/ */
public $joinColumns = array(); public $joinColumns = array();
public $joinColumnFieldNames = array();
/** /**
* Creates a new OneToOneMapping. * Creates a new OneToOneMapping.
* *
...@@ -99,6 +101,8 @@ class OneToOneMapping extends AssociationMapping ...@@ -99,6 +101,8 @@ class OneToOneMapping extends AssociationMapping
$this->joinColumns = $mapping['joinColumns']; $this->joinColumns = $mapping['joinColumns'];
foreach ($mapping['joinColumns'] as $joinColumn) { foreach ($mapping['joinColumns'] as $joinColumn) {
$this->sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName']; $this->sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
$this->joinColumnFieldNames[$joinColumn['name']] = isset($joinColumn['fieldName'])
? $joinColumn['fieldName'] : $joinColumn['name'];
} }
$this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns); $this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns);
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
namespace Doctrine\ORM\Persisters; namespace Doctrine\ORM\Persisters;
use Doctrine\Common\DoctrineException;
use Doctrine\DBAL\Connection; use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
...@@ -477,9 +478,16 @@ class StandardEntityPersister ...@@ -477,9 +478,16 @@ class StandardEntityPersister
if ($columnList != '') $columnList .= ', '; if ($columnList != '') $columnList .= ', ';
$columnList .= $this->_conn->quoteIdentifier($column); $columnList .= $this->_conn->quoteIdentifier($column);
} }
if (!$this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($this->_class->joinColumnNames as $column) { $joinColumnNames = array();
$columnList .= ', ' . $this->_conn->quoteIdentifier($column); if ( ! $this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($this->_class->associationMappings as $assoc) {
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$joinColumnNames[] = $srcColumn;
$columnList .= ', ' . $this->_conn->quoteIdentifier($srcColumn);
}
}
} }
} }
...@@ -488,10 +496,10 @@ class StandardEntityPersister ...@@ -488,10 +496,10 @@ class StandardEntityPersister
if ($conditionSql != '') $conditionSql .= ' AND '; if ($conditionSql != '') $conditionSql .= ' AND ';
if (isset($this->_class->columnNames[$field])) { if (isset($this->_class->columnNames[$field])) {
$columnName = $this->_class->columnNames[$field]; $columnName = $this->_class->columnNames[$field];
} else if (in_array($field, $this->_class->joinColumnNames)) { } else if (in_array($field, $joinColumnNames)) {
$columnName = $field; $columnName = $field;
} else { } else {
throw new Exception("Unrecognized field: $field"); throw DoctrineException::unrecognizedField($field);
} }
$conditionSql .= $this->_conn->quoteIdentifier($columnName) . ' = ?'; $conditionSql .= $this->_conn->quoteIdentifier($columnName) . ' = ?';
} }
......
...@@ -45,6 +45,8 @@ class ResultSetMapping ...@@ -45,6 +45,8 @@ class ResultSetMapping
public $fieldMappings = array(); public $fieldMappings = array();
/** Maps column names in the result set to the alias to use in the mapped result. */ /** Maps column names in the result set to the alias to use in the mapped result. */
public $scalarMappings = array(); public $scalarMappings = array();
/** Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names. */
public $metaMappings = array();
/** Maps column names in the result set to the alias they belong to. */ /** Maps column names in the result set to the alias they belong to. */
public $columnOwnerMap = array(); public $columnOwnerMap = array();
/** List of columns in the result set that are used as discriminator columns. */ /** List of columns in the result set that are used as discriminator columns. */
...@@ -286,6 +288,10 @@ class ResultSetMapping ...@@ -286,6 +288,10 @@ class ResultSetMapping
} }
/** /**
* Checks whether this ResultSetMapping defines a mixed result.
* Mixed results can only occur in object and array (graph) hydration. In such a
* case a mixed result means that scalar values are mixed with objects/array in
* the result.
* *
* @return boolean * @return boolean
*/ */
...@@ -294,6 +300,19 @@ class ResultSetMapping ...@@ -294,6 +300,19 @@ class ResultSetMapping
return $this->isMixed; return $this->isMixed;
} }
/**
*
* @param $alias
* @param $columnName
* @param $fieldName
* @return unknown_type
*/
public function addMetaResult($alias, $columnName, $fieldName)
{
$this->metaMappings[$columnName] = $fieldName;
$this->columnOwnerMap[$columnName] = $alias;
}
/** /**
* Adds a column name that will be ignored during hydration. * Adds a column name that will be ignored during hydration.
* *
......
...@@ -171,6 +171,7 @@ class SqlWalker implements TreeWalker ...@@ -171,6 +171,7 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSqlColumnAlias($discrColumn['name']); $columnAlias = $this->getSqlColumnAlias($discrColumn['name']);
$sql .= ", $tblAlias." . $discrColumn['name'] . ' AS ' . $columnAlias; $sql .= ", $tblAlias." . $discrColumn['name'] . ' AS ' . $columnAlias;
$this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); $this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']);
} }
//} //}
} }
...@@ -470,14 +471,20 @@ class SqlWalker implements TreeWalker ...@@ -470,14 +471,20 @@ class SqlWalker implements TreeWalker
$sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) . ' AS ' . $columnAlias; $sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) . ' AS ' . $columnAlias;
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName); $this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
} }
if (!$this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($class->joinColumnNames as $name) { if ( ! $this->_em->getConfiguration()->getAllowPartialObjects()) {
$columnAlias = $this->getSqlColumnAlias($name); foreach ($class->associationMappings as $assoc) {
$sql .= ', ' . $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($name) . ' AS ' . $columnAlias; if ($assoc->isOwningSide && $assoc->isOneToOne()) {
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $name); foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$columnAlias = $this->getSqlColumnAlias($srcColumn);
$sql .= ', ' . $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($srcColumn) . ' AS ' . $columnAlias;
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn);
}
} }
} }
} }
}
} }
return $sql; return $sql;
......
...@@ -21,6 +21,8 @@ class StandardEntityPersisterTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -21,6 +21,8 @@ class StandardEntityPersisterTest extends \Doctrine\Tests\OrmFunctionalTestCase
} }
public function testAcceptsForeignKeysAsCriteria() { public function testAcceptsForeignKeysAsCriteria() {
$this->_em->getConfiguration()->setAllowPartialObjects(false);
$customer = new ECommerceCustomer(); $customer = new ECommerceCustomer();
$customer->setName('John Doe'); $customer->setName('John Doe');
$cart = new ECommerceCart(); $cart = new ECommerceCart();
......
...@@ -109,7 +109,7 @@ class ObjectHydratorTest extends HydrationTestCase ...@@ -109,7 +109,7 @@ class ObjectHydratorTest extends HydrationTestCase
$rsm->addEntityResult('Doctrine\Tests\Models\ECommerce\ECommerceProduct', 'p'); $rsm->addEntityResult('Doctrine\Tests\Models\ECommerce\ECommerceProduct', 'p');
$rsm->addFieldResult('p', 'p__id', 'id'); $rsm->addFieldResult('p', 'p__id', 'id');
$rsm->addFieldResult('p', 'p__name', 'name'); $rsm->addFieldResult('p', 'p__name', 'name');
$rsm->addFieldResult('p', 'p__shipping_id', 'shipping_id'); $rsm->addMetaResult('p', 'p__shipping_id', 'shipping_id');
// Faked result set // Faked result set
$resultSet = array( $resultSet = array(
......
...@@ -60,7 +60,6 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase ...@@ -60,7 +60,6 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
$cm1 = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\TestEntity1'); $cm1 = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\TestEntity1');
$this->assertEquals(array(), $cm1->parentClasses); $this->assertEquals(array(), $cm1->parentClasses);
$this->assertEquals(array('other_id'), $cm1->joinColumnNames);
$this->assertTrue($cm1->hasField('name')); $this->assertTrue($cm1->hasField('name'));
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType); $this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
} }
......
...@@ -41,7 +41,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase ...@@ -41,7 +41,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(array('One', 'Two', 'Three'), $cm->subClasses); $this->assertEquals(array('One', 'Two', 'Three'), $cm->subClasses);
$this->assertEquals(array('UserParent'), $cm->parentClasses); $this->assertEquals(array('UserParent'), $cm->parentClasses);
$this->assertEquals('UserRepository', $cm->getCustomRepositoryClass()); $this->assertEquals('UserRepository', $cm->getCustomRepositoryClass());
$this->assertEquals(array('name' => 'disc', 'type' => 'integer'), $cm->discriminatorColumn); $this->assertEquals(array('name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'), $cm->discriminatorColumn);
$this->assertTrue($cm->getAssociationMapping('phonenumbers') instanceof \Doctrine\ORM\Mapping\OneToOneMapping); $this->assertTrue($cm->getAssociationMapping('phonenumbers') instanceof \Doctrine\ORM\Mapping\OneToOneMapping);
$this->assertEquals(1, count($cm->associationMappings)); $this->assertEquals(1, count($cm->associationMappings));
$oneOneMapping = $cm->getAssociationMapping('phonenumbers'); $oneOneMapping = $cm->getAssociationMapping('phonenumbers');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment