1
0
mirror of synced 2024-12-12 22:36:02 +03:00

[2.0] Applied fixes for character casing issues. Simplified inheritance mapping and improved handling of outer joins in Class Table Inheritance.

This commit is contained in:
romanb 2009-08-17 17:58:16 +00:00
parent d8c8078302
commit 3d17cb0d60
20 changed files with 229 additions and 160 deletions

View File

@ -269,6 +269,13 @@ class Parser
public function Values()
{
$values = array();
// Handle the case of a single array as value, i.e. @Foo({....})
if ($this->_lexer->isNextToken('{')) {
$values['value'] = $this->Value();
return $values;
}
$values[] = $this->Value();
while ($this->_lexer->isNextToken(',')) {

View File

@ -34,7 +34,7 @@ class MySqlSchemaManager extends AbstractSchemaManager
{
protected function _getPortableViewDefinition($view)
{
return $view['table_name'];
return $view['TABLE_NAME'];
}
protected function _getPortableTableDefinition($table)
@ -45,8 +45,8 @@ class MySqlSchemaManager extends AbstractSchemaManager
protected function _getPortableUserDefinition($user)
{
return array(
'user' => $user['user'],
'password' => $user['password'],
'user' => $user['User'],
'password' => $user['Password'],
);
}
@ -83,12 +83,12 @@ class MySqlSchemaManager extends AbstractSchemaManager
protected function _getPortableDatabaseDefinition($database)
{
return $database['database'];
return $database['Database'];
}
protected function _getPortableTableColumnDefinition($tableColumn)
{
$dbType = strtolower($tableColumn['type']);
$dbType = strtolower($tableColumn['Type']);
$dbType = strtok($dbType, '(), ');
if ($dbType == 'national') {
$dbType = strtok('(), ');
@ -117,28 +117,28 @@ class MySqlSchemaManager extends AbstractSchemaManager
if (preg_match('/^(is|has)/', $tableColumn['name'])) {
$type = array_reverse($type);
}
$unsigned = preg_match('/ unsigned/i', $tableColumn['type']);
$unsigned = preg_match('/ unsigned/i', $tableColumn['Type']);
$length = 1;
break;
case 'smallint':
$type = 'integer';
$unsigned = preg_match('/ unsigned/i', $tableColumn['type']);
$unsigned = preg_match('/ unsigned/i', $tableColumn['Type']);
$length = 2;
break;
case 'mediumint':
$type = 'integer';
$unsigned = preg_match('/ unsigned/i', $tableColumn['type']);
$unsigned = preg_match('/ unsigned/i', $tableColumn['Type']);
$length = 3;
break;
case 'int':
case 'integer':
$type = 'integer';
$unsigned = preg_match('/ unsigned/i', $tableColumn['type']);
$unsigned = preg_match('/ unsigned/i', $tableColumn['Type']);
$length = 4;
break;
case 'bigint':
$type = 'integer';
$unsigned = preg_match('/ unsigned/i', $tableColumn['type']);
$unsigned = preg_match('/ unsigned/i', $tableColumn['Type']);
$length = 8;
break;
case 'tinytext':
@ -249,12 +249,12 @@ class MySqlSchemaManager extends AbstractSchemaManager
$values = isset($def['values']) ? $def['values'] : array();
$column = array(
'name' => $tableColumn['field'],
'name' => $tableColumn['Field'],
'values' => $values,
'primary' => (bool) (strtolower($tableColumn['key']) == 'pri'),
'default' => $tableColumn['default'],
'notnull' => (bool) ($tableColumn['null'] != 'YES'),
'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false),
'primary' => (bool) (strtolower($tableColumn['Key']) == 'pri'),
'default' => $tableColumn['Default'],
'notnull' => (bool) ($tableColumn['Null'] != 'YES'),
'autoincrement' => (bool) (strpos($tableColumn['Extra'], 'auto_increment') !== false),
);
$column = array_merge($column, $def);

View File

@ -40,7 +40,6 @@ class ObjectHydrator extends AbstractHydrator
*/
/* Local ClassMetadata cache to avoid going to the EntityManager all the time. */
private $_ce = array();
private $_discriminatorMap = array();
/*
* The following parts are reinitialized on every hydration run.
*/
@ -76,17 +75,6 @@ class ObjectHydrator extends AbstractHydrator
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $class;
// Gather class descriptors and discriminator values of subclasses, if necessary
if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) {
$this->_discriminatorMap[$className][$class->discriminatorValue] = $className;
foreach (array_merge($class->parentClasses, $class->subClasses) as $className) {
$otherClass = $this->_em->getClassMetadata($className);
$value = $otherClass->discriminatorValue;
$this->_ce[$className] = $otherClass;
$this->_discriminatorMap[$class->name][$value] = $className;
$this->_discriminatorMap[$className][$value] = $className;
}
}
}
// Remember which associations are "fetch joined"
@ -172,7 +160,7 @@ class ObjectHydrator extends AbstractHydrator
$className = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
$discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
$className = $this->_discriminatorMap[$className][$data[$discrColumn]];
$className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
unset($data[$discrColumn]);
}
@ -180,7 +168,7 @@ class ObjectHydrator extends AbstractHydrator
// Properly initialize any unfetched associations, if partial objects are not allowed.
if ( ! $this->_allowPartialObjects) {
foreach ($this->_ce[$className]->associationMappings as $field => $assoc) {
foreach ($this->_getClassMetadata($className)->associationMappings as $field => $assoc) {
// Check if the association is not among the fetch-joined associatons already.
if ( ! isset($this->_fetchedAssociations[$className][$field])) {
if ($assoc->isOneToOne()) {

View File

@ -254,13 +254,22 @@ final class ClassMetadata
public $fieldNames = array();
/**
* An array of column names. Keys are field names and values column names.
* A map of field names to column names. Keys are field names and values column names.
* Used to look up column names from field names.
* This is the reverse lookup map of $_fieldNames.
*
* @var array
*/
public $columnNames = array();
/**
* A map of column names as they appear in an SQL result set to column names as they
* are defined in the mapping. This includes the columns of all mapped fields as well
* as any join columns and discriminator columns.
*
* @var array
*/
public $resultColumnNames = array();
/**
* Whether to automatically OUTER JOIN subtypes when a basetype is queried.
@ -281,6 +290,17 @@ final class ClassMetadata
* @see _discriminatorColumn
*/
public $discriminatorValue;
/**
* The discriminator map of all mapped classes in the hierarchy.
*
* <b>This does only apply to the JOINED and SINGLE_TABLE inheritance mapping strategies
* where a discriminator column is used.</b>
*
* @var mixed
* @see _discriminatorColumn
*/
public $discriminatorMap = array();
/**
* The definition of the descriminator column used in JOINED and SINGLE_TABLE
@ -1139,16 +1159,19 @@ final class ClassMetadata
}
/**
* Sets the subclasses of the mapped class.
*
* <b>All entity classes that participate in a hierarchy and have subclasses
* need to declare them this way.</b>
* Sets the mapped subclasses of this class.
*
* @param array $subclasses The names of all subclasses.
* @param array $subclasses The names of all mapped subclasses.
*/
public function setSubclasses(array $subclasses)
{
$this->subClasses = $subclasses;
foreach ($subclasses as $subclass) {
if (strpos($subclass, '\\') === false) {
$this->subClasses[] = $this->namespace . '\\' . $subclass;
} else {
$this->subClasses[] = $subclass;
}
}
}
/**
@ -1572,14 +1595,24 @@ final class ClassMetadata
}
/**
* Sets the dsicriminator value used by this class.
* Sets the dsicriminator values used by this class.
* Used for JOINED and SINGLE_TABLE inheritance mapping strategies.
*
* @param array $map
*/
public function setDiscriminatorValue($value)
public function setDiscriminatorMap(array $map)
{
$this->discriminatorValue = $value;
foreach ($map as $value => $className) {
if (strpos($className, '\\') === false) {
$className = $this->namespace . '\\' . $className;
}
$this->discriminatorMap[$value] = $className;
if ($this->name == $className) {
$this->discriminatorValue = $value;
} else if (is_subclass_of($className, $this->name)) {
$this->subClasses[] = $className;
}
}
}
/**

View File

@ -177,6 +177,7 @@ class ClassMetadataFactory
$class->setIdentifier($parent->identifier);
$class->setVersioned($parent->isVersioned);
$class->setVersionField($parent->versionField);
$class->setDiscriminatorMap($parent->discriminatorMap);
}
// Invoke driver
@ -291,6 +292,11 @@ class ClassMetadataFactory
if (isset($class->fieldMappings[$name]['inherited']) && ! isset($class->fieldMappings[$name]['id'])
|| isset($class->inheritedAssociationFields[$name])
|| ($versioned && $versionField == $name)) {
if (isset($class->columnNames[$name])) {
// Add column mapping for SQL result sets
$columnName = $class->columnNames[$name];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
}
continue;
}
@ -300,11 +306,20 @@ class ClassMetadataFactory
foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
$columns[] = $assoc->getQuotedJoinColumnName($sourceCol, $this->_targetPlatform);
$values[] = '?';
// Add column mapping for SQL result sets
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($sourceCol)] = $sourceCol;
}
}
} else if ($class->name != $class->rootEntityName || ! $class->isIdGeneratorIdentity() || $class->identifier[0] != $name) {
$columns[] = $class->getQuotedColumnName($name, $this->_targetPlatform);
$values[] = '?';
// Add column mapping for SQL result sets
$columnName = $class->columnNames[$name];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
} else {
// Add column mapping for SQL result sets
$columnName = $class->columnNames[$name];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
}
}
} else {
@ -319,19 +334,34 @@ class ClassMetadataFactory
foreach ($assoc->targetToSourceKeyColumns as $sourceCol) {
$columns[] = $assoc->getQuotedJoinColumnName($sourceCol, $this->_targetPlatform);
$values[] = '?';
// Add column mapping for SQL result sets
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($sourceCol)] = $sourceCol;
}
}
} else if ($class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $class->identifier[0] != $name) {
$columns[] = $class->getQuotedColumnName($name, $this->_targetPlatform);
$values[] = '?';
// Add column mapping for SQL result sets
$columnName = $class->columnNames[$name];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
} else {
// Add column mapping for SQL result sets
$columnName = $class->columnNames[$name];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
}
}
}
// Add discriminator column to the INSERT SQL if necessary
if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined() && $class->name == $class->rootEntityName) {
$columns[] = $class->getQuotedDiscriminatorColumnName($this->_targetPlatform);
$values[] = '?';
if (isset($class->discriminatorColumn['name'])) {
if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()
&& $class->name == $class->rootEntityName) {
$columns[] = $class->getQuotedDiscriminatorColumnName($this->_targetPlatform);
$values[] = '?';
}
// Add column mapping for SQL result sets
$columnName = $class->discriminatorColumn['name'];
$class->resultColumnNames[$this->_targetPlatform->getSqlResultCasing($columnName)] = $columnName;
}
$class->insertSql = 'INSERT INTO ' .

View File

@ -95,10 +95,10 @@ class AnnotationDriver implements Driver
));
}
// Evaluate DiscriminatorValue annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorValue'])) {
$discrValueAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorValue'];
$metadata->setDiscriminatorValue($discrValueAnnot->value);
// Evaluate DiscriminatorMap annotation
if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) {
$discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'];
$metadata->setDiscriminatorMap($discrMapAnnot->value);
}
// Evaluate DoctrineSubClasses annotation

View File

@ -25,26 +25,25 @@ use \Doctrine\Common\Annotations\Annotation;
/* Annotations */
final class Entity extends \Doctrine\Common\Annotations\Annotation {
final class Entity extends Annotation {
public $repositoryClass;
}
final class MappedSuperclass extends Annotation {}
final class InheritanceType extends \Doctrine\Common\Annotations\Annotation {}
final class DiscriminatorColumn extends \Doctrine\Common\Annotations\Annotation {
final class InheritanceType extends Annotation {}
final class DiscriminatorColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $type;
public $length;
}
final class DiscriminatorValue extends \Doctrine\Common\Annotations\Annotation {}
final class SubClasses extends \Doctrine\Common\Annotations\Annotation {}
final class Id extends \Doctrine\Common\Annotations\Annotation {}
final class GeneratedValue extends \Doctrine\Common\Annotations\Annotation {
final class DiscriminatorMap extends Annotation {}
/*final class SubClasses extends Annotation {}*/
final class Id extends Annotation {}
final class GeneratedValue extends Annotation {
public $strategy;
//public $generator;
}
final class Version extends \Doctrine\Common\Annotations\Annotation {}
final class JoinColumn extends \Doctrine\Common\Annotations\Annotation {
final class Version extends Annotation {}
final class JoinColumn extends Annotation {
public $name;
public $fieldName; // field name used in non-object hydration (array/scalar)
public $referencedColumnName;
@ -53,8 +52,8 @@ final class JoinColumn extends \Doctrine\Common\Annotations\Annotation {
public $onDelete;
public $onUpdate;
}
final class JoinColumns extends \Doctrine\Common\Annotations\Annotation {}
final class Column extends \Doctrine\Common\Annotations\Annotation {
final class JoinColumns extends Annotation {}
final class Column extends Annotation {
public $type;
public $length;
public $unique = false;
@ -62,7 +61,7 @@ final class Column extends \Doctrine\Common\Annotations\Annotation {
public $default;
public $name;
}
final class OneToOne extends \Doctrine\Common\Annotations\Annotation {
final class OneToOne extends Annotation {
public $targetEntity;
public $mappedBy;
public $cascade;
@ -70,54 +69,54 @@ final class OneToOne extends \Doctrine\Common\Annotations\Annotation {
public $optional;
public $orphanRemoval = false;
}
final class OneToMany extends \Doctrine\Common\Annotations\Annotation {
final class OneToMany extends Annotation {
public $mappedBy;
public $targetEntity;
public $cascade;
public $fetch;
public $orphanRemoval = false;
}
final class ManyToOne extends \Doctrine\Common\Annotations\Annotation {
final class ManyToOne extends Annotation {
public $targetEntity;
public $cascade;
public $fetch;
public $optional;
}
final class ManyToMany extends \Doctrine\Common\Annotations\Annotation {
final class ManyToMany extends Annotation {
public $targetEntity;
public $mappedBy;
public $cascade;
public $fetch;
}
final class ElementCollection extends \Doctrine\Common\Annotations\Annotation {
final class ElementCollection extends Annotation {
public $tableName;
}
final class Table extends \Doctrine\Common\Annotations\Annotation {
final class Table extends Annotation {
public $name;
public $schema;
}
final class JoinTable extends \Doctrine\Common\Annotations\Annotation {
final class JoinTable extends Annotation {
public $name;
public $schema;
public $joinColumns;
public $inverseJoinColumns;
}
final class SequenceGenerator extends \Doctrine\Common\Annotations\Annotation {
final class SequenceGenerator extends Annotation {
public $sequenceName;
public $allocationSize = 10;
public $initialValue = 1;
}
final class ChangeTrackingPolicy extends \Doctrine\Common\Annotations\Annotation {}
final class ChangeTrackingPolicy extends Annotation {}
/* Annotations for lifecycle callbacks */
final class LifecycleListener extends \Doctrine\Common\Annotations\Annotation {}
final class PrePersist extends \Doctrine\Common\Annotations\Annotation {}
final class PostPersist extends \Doctrine\Common\Annotations\Annotation {}
final class PreUpdate extends \Doctrine\Common\Annotations\Annotation {}
final class PostUpdate extends \Doctrine\Common\Annotations\Annotation {}
final class PreRemove extends \Doctrine\Common\Annotations\Annotation {}
final class PostRemove extends \Doctrine\Common\Annotations\Annotation {}
final class PostLoad extends \Doctrine\Common\Annotations\Annotation {}
final class LifecycleListener extends Annotation {}
final class PrePersist extends Annotation {}
final class PostPersist extends Annotation {}
final class PreUpdate extends Annotation {}
final class PostUpdate extends Annotation {}
final class PreRemove extends Annotation {}
final class PostRemove extends Annotation {}
final class PostLoad extends Annotation {}
/* Generic annotation for Doctrine extensions */
final class DoctrineX extends \Doctrine\Common\Annotations\Annotation {}
final class DoctrineX extends Annotation {}

View File

@ -288,16 +288,25 @@ class JoinedSubclassPersister extends StandardEntityPersister
$tableAlias = isset($mapping['inherited']) ?
$tableAliases[$mapping['inherited']] : $baseTableAlias;
if ($columnList != '') $columnList .= ', ';
$columnList .= $tableAlias . '.' . $this->_class->columnNames[$fieldName];
$columnList .= $tableAlias . '.' . $this->_class->getQuotedColumnName($fieldName, $this->_platform);
}
// Add discriminator column
if ($this->_class->rootEntityName == $this->_class->name) {
$columnList .= ', ' . $baseTableAlias . '.' .
$this->_class->getQuotedDiscriminatorColumnName($this->_platform);
} else {
$columnList .= ', ' . $tableAliases[$this->_class->rootEntityName] . '.' .
$this->_class->getQuotedDiscriminatorColumnName($this->_platform);
}
$sql = 'SELECT ' . $columnList . ' FROM ' . $this->_class->primaryTable['name']. ' ' . $baseTableAlias;
$sql = 'SELECT ' . $columnList . ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias;
// INNER JOIN parent tables
foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName);
$tableAlias = $tableAliases[$parentClassName];
$sql .= ' INNER JOIN ' . $parentClass->primaryTable['name'] . ' ' . $tableAlias . ' ON ';
$sql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
if ($first) $first = false; else $sql .= ' AND ';
@ -309,7 +318,7 @@ class JoinedSubclassPersister extends StandardEntityPersister
foreach ($this->_class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
$tableAlias = $tableAliases[$subClassName];
$sql .= ' LEFT JOIN ' . $subClass->primaryTable['name'] . ' ' . $tableAlias . ' ON ';
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
if ($first) $first = false; else $sql .= ' AND ';
@ -323,6 +332,6 @@ class JoinedSubclassPersister extends StandardEntityPersister
$conditionSql .= $baseTableAlias . '.' . $this->_class->columnNames[$field] . ' = ?';
}
return $sql . ' WHERE ' . $conditionSql;
return $sql . ($conditionSql != '' ? ' WHERE ' . $conditionSql : '');
}
}

View File

@ -85,8 +85,6 @@ class StandardEntityPersister
* @var array
*/
protected $_queuedInserts = array();
//protected $_rsm;
/**
* Initializes a new instance of a class derived from AbstractEntityPersister
@ -483,36 +481,25 @@ class StandardEntityPersister
if ($result === false) {
return null;
}
$data = $joinColumnValues = array();
/*if ($this->_rsm === null) {
$this->_rsm = array();
foreach ($this->_class->columnNames as $column) {
$this->_rsm[$this->_platform->getSqlResultCasing($column)] = $column;
}
foreach ($this->_class->associationMappings as $assoc) {
if ($assoc->isOwningSide && $assoc->isOneToOne()) {
foreach ($assoc->targetToSourceKeyColumns as $keyColumn) {
$this->_rsm[$this->_platform->getSqlResultCasing($keyColumn)] = $keyColumn;
}
}
}
}*/
$entityName = $this->_entityName;
foreach ($result as $column => $value) {
//$column = $this->_rsm[$column];
$column = $this->_class->resultColumnNames[$column];
if (isset($this->_class->fieldNames[$column])) {
$fieldName = $this->_class->fieldNames[$column];
$data[$fieldName] = Type::getType($this->_class->fieldMappings[$fieldName]['type'])
->convertToPHPValue($value, $this->_platform);
} else if ($this->_class->discriminatorColumn !== null && $column == $this->_class->discriminatorColumn['name']) {
$entityName = $this->_class->discriminatorMap[$value];
} else {
$joinColumnValues[$column] = $value;
}
}
if ($entity === null) {
$entity = $this->_em->getUnitOfWork()->createEntity($this->_entityName, $data);
$entity = $this->_em->getUnitOfWork()->createEntity($entityName, $data);
} else {
foreach ($data as $field => $value) {
$this->_class->reflFields[$field]->setValue($entity, $value);

View File

@ -1689,7 +1689,7 @@ class Parser
/**
* ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
*
* @return \Doctrine\ORM\Query\AST\ConditionalPrimary
* @return Doctrine\ORM\Query\AST\ConditionalPrimary
*/
public function ConditionalPrimary()
{

View File

@ -248,21 +248,23 @@ class SqlWalker implements TreeWalker
}
}
// LEFT JOIN subclass tables
foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
$tableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
. ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($class->identifier as $idField) {
if ($first) $first = false; else $sql .= ' AND ';
$columnName = $class->getQuotedColumnName($idField, $this->_platform);
$sql .= $baseTableAlias . '.' . $columnName
. ' = '
. $tableAlias . '.' . $columnName;
// LEFT JOIN subclass tables, only if partial objects disallowed
if ( ! $this->_em->getConfiguration()->getAllowPartialObjects() && ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
$tableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
$sql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform)
. ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($class->identifier as $idField) {
if ($first) $first = false; else $sql .= ' AND ';
$columnName = $class->getQuotedColumnName($idField, $this->_platform);
$sql .= $baseTableAlias . '.' . $columnName
. ' = '
. $tableAlias . '.' . $columnName;
}
}
}
@ -471,7 +473,7 @@ class SqlWalker implements TreeWalker
$sql .= ", $tblAlias." . $rootClass->getQuotedDiscriminatorColumnName($this->_platform)
. ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn['fieldName']);
@ -490,7 +492,7 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSqlColumnAlias($srcColumn);
$sql .= ", $sqlTableAlias." . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform)
. ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn);
}
}
@ -506,7 +508,7 @@ class SqlWalker implements TreeWalker
foreach ($assoc->targetToSourceKeyColumns as $srcColumn) {
$columnAlias = $this->getSqlColumnAlias($srcColumn);
$sql .= ', ' . $sqlTableAlias . '.' . $assoc->getQuotedJoinColumnName($srcColumn, $this->_platform) . ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $columnAlias, $srcColumn);
}
}
@ -748,7 +750,7 @@ class SqlWalker implements TreeWalker
$columnAlias = $this->getSqlColumnAlias($class->columnNames[$fieldName]);
$sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
} else {
throw DoctrineException::updateMe(
@ -765,7 +767,7 @@ class SqlWalker implements TreeWalker
$columnAlias = 'sclr' . $this->_aliasCounter++;
$sql .= $this->walkAggregateExpression($expr) . ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
} else if ($expr instanceof AST\Subselect) {
$sql .= $this->walkSubselect($expr);
@ -779,7 +781,7 @@ class SqlWalker implements TreeWalker
$columnAlias = 'sclr' . $this->_aliasCounter++;
$sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
} else {
// IdentificationVariable
@ -807,28 +809,33 @@ class SqlWalker implements TreeWalker
$sql .= $sqlTableAlias . '.' . $class->getQuotedColumnName($fieldName, $this->_platform)
. ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
}
// Add any additional fields of subclasses (not inherited fields)
foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
foreach ($subClass->fieldMappings as $fieldName => $mapping) {
if (isset($mapping['inherited'])) {
continue;
// 1) on Single Table Inheritance: always, since its marginal overhead
// 2) on Class Table Inheritance only if partial objects are disallowed,
// since it requires outer joining subtables.
if ($class->isInheritanceTypeSingleTable() || ! $this->_em->getConfiguration()->getAllowPartialObjects()
&& ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD)) {
foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
foreach ($subClass->fieldMappings as $fieldName => $mapping) {
if (isset($mapping['inherited'])) {
continue;
}
if ($beginning) $beginning = false; else $sql .= ', ';
$sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
$columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
$sql .= $sqlTableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform)
. ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
}
if ($beginning) $beginning = false; else $sql .= ', ';
$sqlTableAlias = $this->getSqlTableAlias($subClass->primaryTable['name'], $dqlAlias);
$columnAlias = $this->getSqlColumnAlias($mapping['columnName']);
$sql .= $sqlTableAlias . '.' . $subClass->getQuotedColumnName($fieldName, $this->_platform)
. ' AS ' . $columnAlias;
//$columnAlias = $this->_platform->getSqlResultCasing($columnAlias);
$this->_rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName);
}
}
}

View File

@ -21,8 +21,8 @@
namespace Doctrine\ORM\Tools;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManager;
use Doctrine\DBAL\Types\Type,
Doctrine\ORM\EntityManager;
/**
* The SchemaTool is a tool to create and/or drop database schemas based on
@ -306,4 +306,14 @@ class SchemaTool
{
//TODO
}
public function updateSchema(array $classes)
{
//TODO
}
public function getUpdateSchemaSql(array $classes)
{
//TODO
}
}

View File

@ -5,8 +5,6 @@ namespace Doctrine\Tests\Models\Company;
/**
* @Entity
* @Table(name="company_employees")
* @DiscriminatorValue("employee")
* @SubClasses({"Doctrine\Tests\Models\Company\CompanyManager"})
*/
class CompanyEmployee extends CompanyPerson
{

View File

@ -5,7 +5,6 @@ namespace Doctrine\Tests\Models\Company;
/**
* @Entity
* @Table(name="company_managers")
* @DiscriminatorValue("manager")
*/
class CompanyManager extends CompanyEmployee
{

View File

@ -8,11 +8,12 @@ namespace Doctrine\Tests\Models\Company;
* @author robo
* @Entity
* @Table(name="company_persons")
* @DiscriminatorValue("person")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @SubClasses({"Doctrine\Tests\Models\Company\CompanyEmployee",
"Doctrine\Tests\Models\Company\CompanyManager"})
* @DiscriminatorMap({
* "person" = "CompanyPerson",
* "manager" = "CompanyManager",
* "employee" = "CompanyEmployee"})
*/
class CompanyPerson
{
@ -39,6 +40,10 @@ class CompanyPerson
inverseJoinColumns={@JoinColumn(name="friend_id", referencedColumnName="id")})
*/
private $friends;
public function __construct() {
$this->friends = new \Doctrine\Common\Collections\ArrayCollection;
}
public function getId() {
return $this->id;
@ -61,9 +66,6 @@ class CompanyPerson
}
public function addFriend(CompanyPerson $friend) {
if ( ! $this->friends) {
$this->friends = new \Doctrine\Common\Collections\ArrayCollection;
}
if ( ! $this->friends->contains($friend)) {
$this->friends->add($friend);
$friend->addFriend($this);

View File

@ -39,6 +39,7 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->clear();
$this->_em->getConfiguration()->setAllowPartialObjects(false);
$query = $this->_em->createQuery("select p from Doctrine\Tests\Models\Company\CompanyPerson p order by p.id asc");
$entities = $query->getResult();
@ -51,6 +52,7 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals('Roman S. Borschel', $entities[0]->getName());
$this->assertEquals('Guilherme Blanco', $entities[1]->getName());
$this->assertEquals(100000, $entities[1]->getSalary());
$this->_em->getConfiguration()->setAllowPartialObjects(true);
$this->_em->clear();
@ -99,6 +101,7 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$manager = $this->_em->find('Doctrine\Tests\Models\Company\CompanyManager', $manager->getId());
$this->assertTrue($manager instanceof CompanyManager);
$this->assertEquals('Roman B.', $manager->getName());
$this->assertEquals(119000, $manager->getSalary());
$this->assertEquals('CEO', $manager->getTitle());

View File

@ -124,10 +124,9 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase
/**
* @Entity
* @Table(name="optimistic_joined_parent")
* @DiscriminatorValue("parent")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @SubClasses({"Doctrine\Tests\ORM\Functional\Locking\OptimisticJoinedChild"})
* @DiscriminatorMap({"parent" = "OptimisticJoinedParent", "child" = "OptimisticJoinedChild"})
*/
class OptimisticJoinedParent
{
@ -151,7 +150,6 @@ class OptimisticJoinedParent
/**
* @Entity
* @Table(name="optimistic_joined_child")
* @DiscriminatorValue("child")
*/
class OptimisticJoinedChild extends OptimisticJoinedParent
{

View File

@ -101,8 +101,7 @@ class SingleTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @SubClasses({"Doctrine\Tests\ORM\Functional\ChildEntity"})
* @DiscriminatorValue("parent")
* @DiscriminatorMap({"parent"="ParentEntity", "child"="ChildEntity"})
*/
class ParentEntity {
/**
@ -132,7 +131,6 @@ class ParentEntity {
/**
* @Entity
* @DiscriminatorValue("child")
*/
class ChildEntity extends ParentEntity {
/**

View File

@ -38,7 +38,7 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue($cm->reflClass instanceof \ReflectionClass);
$this->assertEquals('Doctrine\Tests\Models\CMS\CmsUser', $cm->name);
$this->assertEquals('UserParent', $cm->rootEntityName);
$this->assertEquals(array('One', 'Two', 'Three'), $cm->subClasses);
$this->assertEquals(array('Doctrine\Tests\Models\CMS\One', 'Doctrine\Tests\Models\CMS\Two', 'Doctrine\Tests\Models\CMS\Three'), $cm->subClasses);
$this->assertEquals(array('UserParent'), $cm->parentClasses);
$this->assertEquals('UserRepository', $cm->getCustomRepositoryClass());
$this->assertEquals(array('name' => 'disc', 'type' => 'integer', 'fieldName' => 'disc'), $cm->discriminatorColumn);

View File

@ -296,15 +296,16 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
// "Get all persons who have $person as a friend."
// Tough one: Many-many self-referencing ("friends") with class table inheritance
$q3 = $this->_em->createQuery('SELECT p.id FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
$this->_em->getConfiguration()->setAllowPartialObjects(false);
$q3 = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
$person = new \Doctrine\Tests\Models\Company\CompanyPerson;
$this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, 101);
$q3->setParameter('param', $person);
$this->assertEquals(
'SELECT c0_.id AS id0, c0_.discr AS discr1 FROM company_persons c0_ LEFT JOIN company_employees c1_ ON c0_.id = c1_.id LEFT JOIN company_managers c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.person_id = c0_.id WHERE c3_.friend_id = c4_.id AND c4_.id = ?)',
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c0_.discr AS discr5, c0_.spouse_id AS spouse_id6 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.person_id = c0_.id WHERE c3_.friend_id = c4_.id AND c4_.id = ?)',
$q3->getSql()
);
$this->_em->getConfiguration()->setAllowPartialObjects(true);
}
public function testSupportsCurrentDateFunction()