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;
*/
abstract class AbstractHydrator
{
const TYPES_JOINCOLUMN = 'join_column';
/** The ResultSetMapping. */
protected $_rsm;
......@@ -186,23 +184,19 @@ abstract class AbstractHydrator
} else if (isset($this->_rsm->fieldMappings[$key])) {
$classMetadata = $this->_em->getClassMetadata($this->_rsm->getOwningClass($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);
}
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['isScalar'] = false;
if (isset($classMetadata->fieldMappings[$fieldName])) {
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
} else {
$cache[$key]['type'] = self::TYPES_JOINCOLUMN;
}
$cache[$key]['type'] = Type::getType($classMetadata->fieldMappings[$fieldName]['type']);
$cache[$key]['isIdentifier'] = $classMetadata->isIdentifier($fieldName);
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
} else {
// Discriminator column
$cache[$key]['isDiscriminator'] = true;
// Meta column (has meaning in relational schema only, i.e. foreign keys or discriminator columns).
$cache[$key]['isMetaColumn'] = true;
$cache[$key]['isScalar'] = false;
$cache[$key]['fieldName'] = $key;
$cache[$key]['fieldName'] = $this->_rsm->metaMappings[$key];
$cache[$key]['dqlAlias'] = $this->_rsm->columnOwnerMap[$key];
}
}
......@@ -214,7 +208,7 @@ abstract class AbstractHydrator
$dqlAlias = $cache[$key]['dqlAlias'];
if (isset($cache[$key]['isDiscriminator'])) {
if (isset($cache[$key]['isMetaColumn'])) {
$rowData[$dqlAlias][$cache[$key]['fieldName']] = $value;
continue;
}
......@@ -223,11 +217,7 @@ abstract class AbstractHydrator
$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) {
$nonemptyComponents[$dqlAlias] = true;
......
......@@ -230,25 +230,22 @@ class ObjectHydrator extends AbstractHydrator
{
$className = $this->_rsm->aliasMap[$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]];
unset($data[$discrColumn]);
}
$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.
if ( ! $this->_allowPartialObjects) {
foreach ($this->_ce[$className]->associationMappings as $field => $assoc) {
if ( ! isset($this->_fetchedAssociations[$className][$field])) {
if ($assoc->isOneToOne()) {
if ($assoc->isLazilyFetched()) {
$joinColumnsValues = array();
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$joinColumnsValues[$srcColumn] = $data[$assoc->joinColumnFieldNames[$srcColumn]];
}
// Inject proxy
$proxy = $this->_em->getProxyFactory()->getAssociationProxy($entity, $assoc, $joinColumnsValues);
$this->_ce[$className]->reflFields[$field]->setValue($entity, $proxy);
......
......@@ -254,12 +254,6 @@ final class ClassMetadata
*/
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.
*
......@@ -499,11 +493,6 @@ final class ClassMetadata
$this->reflFields[$propName] = $property;
}
public function addJoinColumn($name)
{
$this->joinColumnNames[] = $name;
}
/**
* Gets a ReflectionProperty for a specific field of the mapped class.
*
......@@ -1337,11 +1326,6 @@ final class ClassMetadata
if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false) {
$mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
}
if (isset($mapping['joinColumns'])) {
foreach ($mapping['joinColumns'] as $columns) {
$this->addJoinColumn($columns['name']);
}
}
return $mapping;
}
......@@ -1582,6 +1566,9 @@ final class ClassMetadata
public function setDiscriminatorColumn($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 {
final class InheritanceType extends \Doctrine\Common\Annotations\Annotation {}
final class DiscriminatorColumn extends \Doctrine\Common\Annotations\Annotation {
public $name;
//public $fieldName; // field name used in non-object hydration (array/scalar)
public $type;
public $length;
}
......@@ -42,6 +43,7 @@ final class GeneratedValue extends \Doctrine\Common\Annotations\Annotation {
final class Version extends \Doctrine\Common\Annotations\Annotation {}
final class JoinColumn extends \Doctrine\Common\Annotations\Annotation {
public $name;
//public $fieldName; // field name used in non-object hydration (array/scalar)
public $referencedColumnName;
public $unique = false;
public $nullable = true;
......
......@@ -67,6 +67,8 @@ class OneToOneMapping extends AssociationMapping
*/
public $joinColumns = array();
public $joinColumnFieldNames = array();
/**
* Creates a new OneToOneMapping.
*
......@@ -99,6 +101,8 @@ class OneToOneMapping extends AssociationMapping
$this->joinColumns = $mapping['joinColumns'];
foreach ($mapping['joinColumns'] as $joinColumn) {
$this->sourceToTargetKeyColumns[$joinColumn['name']] = $joinColumn['referencedColumnName'];
$this->joinColumnFieldNames[$joinColumn['name']] = isset($joinColumn['fieldName'])
? $joinColumn['fieldName'] : $joinColumn['name'];
}
$this->targetToSourceKeyColumns = array_flip($this->sourceToTargetKeyColumns);
}
......
......@@ -21,6 +21,7 @@
namespace Doctrine\ORM\Persisters;
use Doctrine\Common\DoctrineException;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
......@@ -477,9 +478,16 @@ class StandardEntityPersister
if ($columnList != '') $columnList .= ', ';
$columnList .= $this->_conn->quoteIdentifier($column);
}
if (!$this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($this->_class->joinColumnNames as $column) {
$columnList .= ', ' . $this->_conn->quoteIdentifier($column);
$joinColumnNames = array();
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
if ($conditionSql != '') $conditionSql .= ' AND ';
if (isset($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;
} else {
throw new Exception("Unrecognized field: $field");
throw DoctrineException::unrecognizedField($field);
}
$conditionSql .= $this->_conn->quoteIdentifier($columnName) . ' = ?';
}
......
......@@ -45,6 +45,8 @@ class ResultSetMapping
public $fieldMappings = array();
/** Maps column names in the result set to the alias to use in the mapped result. */
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. */
public $columnOwnerMap = array();
/** List of columns in the result set that are used as discriminator columns. */
......@@ -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
*/
......@@ -293,6 +299,19 @@ class ResultSetMapping
{
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.
......
......@@ -171,6 +171,7 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSqlColumnAlias($discrColumn['name']);
$sql .= ", $tblAlias." . $discrColumn['name'] . ' AS ' . $columnAlias;
$this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']);
}
//}
}
......@@ -470,13 +471,19 @@ class SqlWalker implements TreeWalker
$sql .= $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($mapping['columnName']) . ' AS ' . $columnAlias;
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
}
if (!$this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($class->joinColumnNames as $name) {
$columnAlias = $this->getSqlColumnAlias($name);
$sql .= ', ' . $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($name) . ' AS ' . $columnAlias;
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $name);
if ( ! $this->_em->getConfiguration()->getAllowPartialObjects()) {
foreach ($class->associationMappings as $assoc) {
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$columnAlias = $this->getSqlColumnAlias($srcColumn);
$sql .= ', ' . $sqlTableAlias . '.' . $this->_conn->quoteIdentifier($srcColumn) . ' AS ' . $columnAlias;
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn);
}
}
}
}
}
}
......
......@@ -21,6 +21,8 @@ class StandardEntityPersisterTest extends \Doctrine\Tests\OrmFunctionalTestCase
}
public function testAcceptsForeignKeysAsCriteria() {
$this->_em->getConfiguration()->setAllowPartialObjects(false);
$customer = new ECommerceCustomer();
$customer->setName('John Doe');
$cart = new ECommerceCart();
......
......@@ -109,7 +109,7 @@ class ObjectHydratorTest extends HydrationTestCase
$rsm->addEntityResult('Doctrine\Tests\Models\ECommerce\ECommerceProduct', 'p');
$rsm->addFieldResult('p', 'p__id', 'id');
$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
$resultSet = array(
......
......@@ -60,7 +60,6 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
$cm1 = $cmf->getMetadataFor('Doctrine\Tests\ORM\Mapping\TestEntity1');
$this->assertEquals(array(), $cm1->parentClasses);
$this->assertEquals(array('other_id'), $cm1->joinColumnNames);
$this->assertTrue($cm1->hasField('name'));
$this->assertEquals(ClassMetadata::GENERATOR_TYPE_SEQUENCE, $cm1->generatorType);
}
......
......@@ -41,7 +41,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals(array('One', 'Two', 'Three'), $cm->subClasses);
$this->assertEquals(array('UserParent'), $cm->parentClasses);
$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->assertEquals(1, count($cm->associationMappings));
$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