[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:
parent
d8c8078302
commit
3d17cb0d60
@ -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(',')) {
|
||||
|
@ -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);
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 ' .
|
||||
|
@ -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
|
||||
|
@ -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 {}
|
||||
|
@ -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 : '');
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1689,7 +1689,7 @@ class Parser
|
||||
/**
|
||||
* ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")"
|
||||
*
|
||||
* @return \Doctrine\ORM\Query\AST\ConditionalPrimary
|
||||
* @return Doctrine\ORM\Query\AST\ConditionalPrimary
|
||||
*/
|
||||
public function ConditionalPrimary()
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -5,7 +5,6 @@ namespace Doctrine\Tests\Models\Company;
|
||||
/**
|
||||
* @Entity
|
||||
* @Table(name="company_managers")
|
||||
* @DiscriminatorValue("manager")
|
||||
*/
|
||||
class CompanyManager extends CompanyEmployee
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 {
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user