1
0
mirror of synced 2025-01-18 06:21:40 +03:00

Merge pull request #372 from FabioBatSilva/DDC-1845

[DDC-1845] QuoteStrategy
This commit is contained in:
Guilherme Blanco 2012-06-24 20:36:54 -07:00
commit cb72219b11
30 changed files with 1817 additions and 465 deletions

View File

@ -25,6 +25,8 @@ use Doctrine\Common\Cache\Cache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\ORM\Mapping\Driver\Driver,
Doctrine\ORM\Mapping\Driver\AnnotationDriver,
Doctrine\ORM\Mapping\QuoteStrategy,
Doctrine\ORM\Mapping\DefaultQuoteStrategy,
Doctrine\ORM\Mapping\NamingStrategy,
Doctrine\ORM\Mapping\DefaultNamingStrategy;
@ -629,4 +631,30 @@ class Configuration extends \Doctrine\DBAL\Configuration
return $this->_attributes['namingStrategy'];
}
/**
* Set quote strategy.
*
* @since 2.3
* @param Doctrine\ORM\Mapping\QuoteStrategy $quoteStrategy
*/
public function setQuoteStrategy(QuoteStrategy $quoteStrategy)
{
$this->_attributes['quoteStrategy'] = $quoteStrategy;
}
/**
* Get quote strategy.
*
* @since 2.3
* @return Doctrine\ORM\Mapping\QuoteStrategy
*/
public function getQuoteStrategy()
{
if ( ! isset($this->_attributes['quoteStrategy'])) {
$this->_attributes['quoteStrategy'] = new DefaultQuoteStrategy();
}
return $this->_attributes['quoteStrategy'];
}
}

View File

@ -385,12 +385,12 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
$class->validateLifecycleCallbacks($this->getReflectionService());
// verify inheritance
if (!$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if (!$parent) {
if ( ! $class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if ( ! $parent) {
if (count($class->discriminatorMap) == 0) {
throw MappingException::missingDiscriminatorMap($class->name);
}
if (!$class->discriminatorColumn) {
if ( ! $class->discriminatorColumn) {
throw MappingException::missingDiscriminatorColumn($class->name);
}
} else if ($parent && !$class->reflClass->isAbstract() && !in_array($class->name, array_values($class->discriminatorMap))) {
@ -562,7 +562,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private function addInheritedNamedQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedQueries as $name => $query) {
if (!isset ($subClass->namedQueries[$name])) {
if ( ! isset ($subClass->namedQueries[$name])) {
$subClass->addNamedQuery(array(
'name' => $query['name'],
'query' => $query['query']
@ -581,7 +581,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private function addInheritedNamedNativeQueries(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->namedNativeQueries as $name => $query) {
if (!isset ($subClass->namedNativeQueries[$name])) {
if ( ! isset ($subClass->namedNativeQueries[$name])) {
$subClass->addNamedNativeQuery(array(
'name' => $query['name'],
'query' => $query['query'],
@ -603,7 +603,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
private function addInheritedSqlResultSetMappings(ClassMetadata $subClass, ClassMetadata $parentClass)
{
foreach ($parentClass->sqlResultSetMappings as $name => $mapping) {
if (!isset ($subClass->sqlResultSetMappings[$name])) {
if ( ! isset ($subClass->sqlResultSetMappings[$name])) {
$entities = array();
foreach ($mapping['entities'] as $entity) {
$entities[] = array(
@ -648,44 +648,77 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
// For PostgreSQL IDENTITY (SERIAL) we need a sequence name. It defaults to
// <table>_<column>_seq in PostgreSQL for SERIAL columns.
// Not pretty but necessary and the simplest solution that currently works.
$seqName = $this->targetPlatform instanceof Platforms\PostgreSQLPlatform ?
$class->getTableName() . '_' . $class->columnNames[$class->identifier[0]] . '_seq' :
null;
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($seqName));
$sequenceName = null;
if ($this->targetPlatform instanceof Platforms\PostgreSQLPlatform) {
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName)
);
if ($quoted) {
$definition['quoted'] = true;
}
$sequenceName = $this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform);
}
$class->setIdGenerator(new \Doctrine\ORM\Id\IdentityGenerator($sequenceName));
break;
case ClassMetadata::GENERATOR_TYPE_SEQUENCE:
// If there is no sequence definition yet, create a default definition
$definition = $class->sequenceGeneratorDefinition;
if ( ! $definition) {
$sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq';
$definition['sequenceName'] = $this->targetPlatform->fixSchemaElementName($sequenceName);
$definition['allocationSize'] = 1;
$definition['initialValue'] = 1;
$fieldName = $class->getSingleIdentifierFieldName();
$columnName = $class->getSingleIdentifierColumnName();
$quoted = isset($class->fieldMappings[$fieldName]['quoted']) || isset($class->table['quoted']);
$sequenceName = $class->getTableName() . '_' . $columnName . '_seq';
$definition = array(
'sequenceName' => $this->targetPlatform->fixSchemaElementName($sequenceName),
'allocationSize' => 1,
'initialValue' => 1,
);
if ($quoted) {
$definition['quoted'] = true;
}
$class->setSequenceGeneratorDefinition($definition);
}
$sequenceGenerator = new \Doctrine\ORM\Id\SequenceGenerator(
$definition['sequenceName'],
$this->em->getConfiguration()->getQuoteStrategy()->getSequenceName($definition, $class, $this->targetPlatform),
$definition['allocationSize']
);
$class->setIdGenerator($sequenceGenerator);
break;
case ClassMetadata::GENERATOR_TYPE_NONE:
$class->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_UUID:
$class->setIdGenerator(new \Doctrine\ORM\Id\UuidGenerator());
break;
case ClassMetadata::GENERATOR_TYPE_TABLE:
throw new ORMException("TableGenerator not yet implemented.");
break;
case ClassMetadata::GENERATOR_TYPE_CUSTOM:
$definition = $class->customGeneratorDefinition;
if (!class_exists($definition['class'])) {
if ( ! class_exists($definition['class'])) {
throw new ORMException("Can't instantiate custom generator : " .
$definition['class']);
}
$class->setIdGenerator(new $definition['class']);
break;
default:
throw new ORMException("Unknown generator type: " . $class->generatorType);
}

View File

@ -1181,11 +1181,11 @@ class ClassMetadataInfo implements ClassMetadata
// Complete fieldName and columnName mapping
if ( ! isset($mapping['columnName'])) {
$mapping['columnName'] = $this->namingStrategy->propertyToColumnName($mapping['fieldName']);
} else {
if ($mapping['columnName'][0] == '`') {
$mapping['columnName'] = trim($mapping['columnName'], '`');
$mapping['quoted'] = true;
}
}
if ($mapping['columnName'][0] === '`') {
$mapping['columnName'] = trim($mapping['columnName'], '`');
$mapping['quoted'] = true;
}
$this->columnNames[$mapping['fieldName']] = $mapping['columnName'];
@ -1295,8 +1295,8 @@ class ClassMetadataInfo implements ClassMetadata
// Mandatory and optional attributes for either side
if ( ! $mapping['mappedBy']) {
if (isset($mapping['joinTable']) && $mapping['joinTable']) {
if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] == '`') {
$mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`');
if (isset($mapping['joinTable']['name']) && $mapping['joinTable']['name'][0] === '`') {
$mapping['joinTable']['name'] = trim($mapping['joinTable']['name'], '`');
$mapping['joinTable']['quoted'] = true;
}
}
@ -1373,12 +1373,25 @@ class ClassMetadataInfo implements ClassMetadata
$uniqueContraintColumns[] = $joinColumn['name'];
}
}
if (empty($joinColumn['name'])) {
$joinColumn['name'] = $this->namingStrategy->joinColumnName($mapping['fieldName']);
}
if (empty($joinColumn['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
}
if ($joinColumn['name'][0] === '`') {
$joinColumn['name'] = trim($joinColumn['name'], '`');
$joinColumn['quoted'] = true;
}
if ($joinColumn['referencedColumnName'][0] === '`') {
$joinColumn['referencedColumnName'] = trim($joinColumn['referencedColumnName'], '`');
$joinColumn['quoted'] = true;
}
$mapping['sourceToTargetKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
$mapping['joinColumnFieldNames'][$joinColumn['name']] = isset($joinColumn['fieldName'])
? $joinColumn['fieldName'] : $joinColumn['name'];
@ -1459,12 +1472,25 @@ class ClassMetadataInfo implements ClassMetadata
if (empty($joinColumn['name'])) {
$joinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['sourceEntity'], $joinColumn['referencedColumnName']);
}
if (empty($joinColumn['referencedColumnName'])) {
$joinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
}
if ($joinColumn['name'][0] === '`') {
$joinColumn['name'] = trim($joinColumn['name'], '`');
$joinColumn['quoted'] = true;
}
if ($joinColumn['referencedColumnName'][0] === '`') {
$joinColumn['referencedColumnName'] = trim($joinColumn['referencedColumnName'], '`');
$joinColumn['quoted'] = true;
}
if (isset($joinColumn['onDelete']) && strtolower($joinColumn['onDelete']) == 'cascade') {
$mapping['isOnDeleteCascade'] = true;
}
$mapping['relationToSourceKeyColumns'][$joinColumn['name']] = $joinColumn['referencedColumnName'];
$mapping['joinTableColumns'][] = $joinColumn['name'];
}
@ -1473,12 +1499,25 @@ class ClassMetadataInfo implements ClassMetadata
if (empty($inverseJoinColumn['name'])) {
$inverseJoinColumn['name'] = $this->namingStrategy->joinKeyColumnName($mapping['targetEntity'], $inverseJoinColumn['referencedColumnName']);
}
if (empty($inverseJoinColumn['referencedColumnName'])) {
$inverseJoinColumn['referencedColumnName'] = $this->namingStrategy->referenceColumnName();
}
if ($inverseJoinColumn['name'][0] === '`') {
$inverseJoinColumn['name'] = trim($inverseJoinColumn['name'], '`');
$inverseJoinColumn['quoted'] = true;
}
if ($inverseJoinColumn['referencedColumnName'][0] === '`') {
$inverseJoinColumn['referencedColumnName'] = trim($inverseJoinColumn['referencedColumnName'], '`');
$inverseJoinColumn['quoted'] = true;
}
if (isset($inverseJoinColumn['onDelete']) && strtolower($inverseJoinColumn['onDelete']) == 'cascade') {
$mapping['isOnDeleteCascade'] = true;
}
$mapping['relationToTargetKeyColumns'][$inverseJoinColumn['name']] = $inverseJoinColumn['referencedColumnName'];
$mapping['joinTableColumns'][] = $inverseJoinColumn['name'];
}
@ -1945,12 +1984,12 @@ class ClassMetadataInfo implements ClassMetadata
public function setPrimaryTable(array $table)
{
if (isset($table['name'])) {
if ($table['name'][0] == '`') {
$this->table['name'] = str_replace("`", "", $table['name']);
$this->table['quoted'] = true;
} else {
$this->table['name'] = $table['name'];
if ($table['name'][0] === '`') {
$table['name'] = trim($table['name'], '`');
$this->table['quoted'] = true;
}
$this->table['name'] = $table['name'];
}
if (isset($table['indexes'])) {
@ -2528,9 +2567,10 @@ class ClassMetadataInfo implements ClassMetadata
* The definition must have the following structure:
* <code>
* array(
* 'sequenceName' => 'name',
* 'sequenceName' => 'name',
* 'allocationSize' => 20,
* 'initialValue' => 1
* 'initialValue' => 1
* 'quoted' => 1
* )
* </code>
*
@ -2538,6 +2578,11 @@ class ClassMetadataInfo implements ClassMetadata
*/
public function setSequenceGeneratorDefinition(array $definition)
{
if (isset($definition['name']) && $definition['name'] == '`') {
$definition['name'] = trim($definition['name'], '`');
$definition['quoted'] = true;
}
$this->sequenceGeneratorDefinition = $definition;
}
@ -2646,6 +2691,8 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
*
* @deprecated Deprecated since version 2.3 in favor of \Doctrine\ORM\Mapping\QuoteStrategy
*
* @param AbstractPlatform $platform
* @return array
*/
@ -2680,8 +2727,9 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
* Gets the (possibly quoted) column name of a mapped field for safe use
* in an SQL statement.
* Gets the (possibly quoted) column name of a mapped field for safe use in an SQL statement.
*
* @deprecated Deprecated since version 2.3 in favor of \Doctrine\ORM\Mapping\QuoteStrategy
*
* @param string $field
* @param AbstractPlatform $platform
@ -2695,8 +2743,9 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
* Gets the (possibly quoted) primary table name of this class for safe use
* in an SQL statement.
* Gets the (possibly quoted) primary table name of this class for safe use in an SQL statement.
*
* @deprecated Deprecated since version 2.3 in favor of \Doctrine\ORM\Mapping\QuoteStrategy
*
* @param AbstractPlatform $platform
* @return string
@ -2709,6 +2758,8 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets the (possibly quoted) name of the join table.
*
* @deprecated Deprecated since version 2.3 in favor of \Doctrine\ORM\Mapping\QuoteStrategy
*
* @param AbstractPlatform $platform
* @return string
*/

View File

@ -0,0 +1,140 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* A set of rules for determining the physical column, alias and table quotes
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
class DefaultQuoteStrategy implements QuoteStrategy
{
/**
* {@inheritdoc}
*/
public function getColumnName($fieldName, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($class->fieldMappings[$fieldName]['quoted'])
? $platform->quoteIdentifier($class->fieldMappings[$fieldName]['columnName'])
: $class->fieldMappings[$fieldName]['columnName'];
}
/**
* {@inheritdoc}
*/
public function getTableName(ClassMetadata $class, AbstractPlatform $platform)
{
return isset($class->table['quoted'])
? $platform->quoteIdentifier($class->table['name'])
: $class->table['name'];
}
/**
* {@inheritdoc}
*/
public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($definition['quoted'])
? $platform->quoteIdentifier($definition['sequenceName'])
: $definition['sequenceName'];
}
/**
* {@inheritdoc}
*/
public function getJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];
}
/**
* {@inheritdoc}
*/
public function getReferencedJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['referencedColumnName'])
: $joinColumn['referencedColumnName'];
}
/**
* {@inheritdoc}
*/
public function getJoinTableName(array $association, ClassMetadata $class, AbstractPlatform $platform)
{
return isset($association['joinTable']['quoted'])
? $platform->quoteIdentifier($association['joinTable']['name'])
: $association['joinTable']['name'];
}
/**
* {@inheritdoc}
*/
public function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform)
{
$quotedColumnNames = array();
foreach ($class->identifier as $fieldName) {
if (isset($class->fieldMappings[$fieldName])) {
$quotedColumnNames[] = $this->getColumnName($fieldName, $class, $platform);
continue;
}
// Association defined as Id field
$joinColumns = $class->associationMappings[$fieldName]['joinColumns'];
$assocQuotedColumnNames = array_map(
function ($joinColumn) use ($platform)
{
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];
},
$joinColumns
);
$quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames);
}
return $quotedColumnNames;
}
/**
* {@inheritdoc}
*/
public function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null)
{
// Trim the column alias to the maximum identifier length of the platform.
// If the alias is to long, characters are cut off from the beginning.
// And strip non alphanumeric characters
$columnName = $columnName . $counter;
$columnName = substr($columnName, -$platform->getMaxIdentifierLength());
$columnName = preg_replace('/[^A-Za-z0-9_]/', '', $columnName);
return $platform->getSQLResultCasing($columnName);
}
}

View File

@ -0,0 +1,112 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Mapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* A set of rules for determining the column, alias and table quotes
*
* @since 2.3
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
*/
interface QuoteStrategy
{
/**
* Gets the (possibly quoted) column name for safe use in an SQL statement.
*
* @param string $fieldName
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getColumnName($fieldName, ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) primary table name for safe use in an SQL statement.
*
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getTableName(ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) sequence name for safe use in an SQL statement.
*
* @param array $definition
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) name of the join table.
*
* @param array $association
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getJoinTableName(array $association, ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) join column name.
*
* @param array $joinColumn
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) join column name.
*
* @param array $joinColumn
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return string
*/
function getReferencedJoinColumnName(array $joinColumn, ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
*
* @param ClassMetadata $class
* @param AbstractPlatform $platform
* @return array
*/
function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform);
/**
* Gets the column alias.
*
* @param string $columnName
* @param integer $counter
* @param AbstractPlatform $platform
* @param ClassMetadata $class
* @return string
*/
function getColumnAlias($columnName, $counter, AbstractPlatform $platform, ClassMetadata $class = null);
}

View File

@ -45,6 +45,20 @@ abstract class AbstractCollectionPersister
*/
protected $_uow;
/**
* The database platform.
*
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
protected $platform;
/**
* The quote strategy.
*
* @var \Doctrine\ORM\Mapping\QuoteStrategy
*/
protected $quoteStrategy;
/**
* Initializes a new instance of a class derived from AbstractCollectionPersister.
*
@ -52,9 +66,11 @@ abstract class AbstractCollectionPersister
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->_uow = $em->getUnitOfWork();
$this->_conn = $em->getConnection();
$this->_em = $em;
$this->_uow = $em->getUnitOfWork();
$this->_conn = $em->getConnection();
$this->platform = $this->_conn->getDatabasePlatform();
$this->quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
}
/**

View File

@ -61,7 +61,7 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
{
$columnName = $class->columnNames[$field];
$sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) . '.' . $class->getQuotedColumnName($field, $this->_platform);
$sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias) . '.' . $this->quoteStrategy->getColumnName($field, $class, $this->_platform);
$columnAlias = $this->getSQLColumnAlias($columnName);
$this->_rsm->addFieldResult($alias, $columnAlias, $field, $class->name);

View File

@ -132,6 +132,15 @@ class BasicEntityPersister
*/
protected $_columnTypes = array();
/**
* The map of quoted column names.
*
* @var array
* @see _prepareInsertData($entity)
* @see _prepareUpdateData($entity)
*/
protected $quotedColumns = array();
/**
* The INSERT SQL statement used for entities handled by this persister.
* This SQL is only generated once per request, if at all.
@ -170,6 +179,13 @@ class BasicEntityPersister
*/
protected $_sqlTableAliases = array();
/**
* The quote strategy.
*
* @var \Doctrine\ORM\Mapping\QuoteStrategy
*/
protected $quoteStrategy;
/**
* Initializes a new <tt>BasicEntityPersister</tt> that uses the given EntityManager
* and persists instances of the class described by the given ClassMetadata descriptor.
@ -179,10 +195,11 @@ class BasicEntityPersister
*/
public function __construct(EntityManager $em, ClassMetadata $class)
{
$this->_em = $em;
$this->_class = $class;
$this->_conn = $em->getConnection();
$this->_platform = $this->_conn->getDatabasePlatform();
$this->_em = $em;
$this->_class = $class;
$this->_conn = $em->getConnection();
$this->_platform = $this->_conn->getDatabasePlatform();
$this->quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
}
/**
@ -281,13 +298,13 @@ class BasicEntityPersister
protected function fetchVersionValue($versionedClass, $id)
{
$versionField = $versionedClass->versionField;
$identifier = $versionedClass->getIdentifierColumnNames();
$identifier = $this->quoteStrategy->getIdentifierColumnNames($versionedClass, $this->_platform);
$versionFieldColumnName = $versionedClass->getQuotedColumnName($versionField, $this->_platform);
$versionFieldColumnName = $this->quoteStrategy->getColumnName($versionField, $versionedClass, $this->_platform);
//FIXME: Order with composite keys might not be correct
$sql = 'SELECT ' . $versionFieldColumnName
. ' FROM ' . $versionedClass->getQuotedTableName($this->_platform)
. ' FROM ' . $this->quoteStrategy->getTableName($versionedClass, $this->_platform)
. ' WHERE ' . implode(' = ? AND ', $identifier) . ' = ?';
$value = $this->_conn->fetchColumn($sql, array_values((array)$id));
@ -315,7 +332,7 @@ class BasicEntityPersister
if (isset($updateData[$tableName]) && $updateData[$tableName]) {
$this->_updateTable(
$entity, $this->_class->getQuotedTableName($this->_platform),
$entity, $this->quoteStrategy->getTableName($this->_class, $this->_platform),
$updateData[$tableName], $this->_class->isVersioned
);
@ -344,12 +361,14 @@ class BasicEntityPersister
$placeholder = '?';
if (isset($this->_class->fieldNames[$columnName])) {
$column = $this->_class->getQuotedColumnName($this->_class->fieldNames[$columnName], $this->_platform);
$column = $this->quoteStrategy->getColumnName($this->_class->fieldNames[$columnName], $this->_class, $this->_platform);
if (isset($this->_class->fieldMappings[$this->_class->fieldNames[$columnName]]['requireSQLConversion'])) {
$type = Type::getType($this->_columnTypes[$columnName]);
$placeholder = $type->convertToDatabaseValueSQL('?', $this->_platform);
}
} else if (isset($this->quotedColumns[$columnName])) {
$column = $this->quotedColumns[$columnName];
}
$set[] = $column . ' = ' . $placeholder;
@ -367,7 +386,7 @@ class BasicEntityPersister
$params[] = $id[$idField];
$types[] = $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type'];
} else {
$where[] = $this->_class->getQuotedColumnName($idField, $this->_platform);
$where[] = $this->quoteStrategy->getColumnName($idField, $this->_class, $this->_platform);
$params[] = $id[$idField];
$types[] = $this->_class->fieldMappings[$idField]['type'];
}
@ -376,7 +395,7 @@ class BasicEntityPersister
if ($versioned) {
$versionField = $this->_class->versionField;
$versionFieldType = $this->_class->fieldMappings[$versionField]['type'];
$versionColumn = $this->_class->getQuotedColumnName($versionField, $this->_platform);
$versionColumn = $this->quoteStrategy->getColumnName($versionField, $this->_class, $this->_platform);
if ($versionFieldType == Type::INTEGER) {
$set[] = $versionColumn . ' = ' . $versionColumn . ' + 1';
@ -412,34 +431,43 @@ class BasicEntityPersister
// @Todo this only covers scenarios with no inheritance or of the same level. Is there something
// like self-referential relationship between different levels of an inheritance hierachy? I hope not!
$selfReferential = ($mapping['targetEntity'] == $mapping['sourceEntity']);
$otherKeys = array();
$keys = array();
if ( ! $mapping['isOwningSide']) {
$relatedClass = $this->_em->getClassMetadata($mapping['targetEntity']);
$mapping = $relatedClass->associationMappings[$mapping['mappedBy']];
$keys = array_keys($mapping['relationToTargetKeyColumns']);
$relatedClass = $this->_em->getClassMetadata($mapping['targetEntity']);
$mapping = $relatedClass->associationMappings[$mapping['mappedBy']];
foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
$keys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $relatedClass, $this->_platform);
}
if ($selfReferential) {
$otherKeys = array_keys($mapping['relationToSourceKeyColumns']);
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
$otherKeys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $relatedClass, $this->_platform);
}
}
} else {
$keys = array_keys($mapping['relationToSourceKeyColumns']);
foreach ($mapping['joinTable']['joinColumns'] as $joinColumn) {
$keys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
}
if ($selfReferential) {
$otherKeys = array_keys($mapping['relationToTargetKeyColumns']);
foreach ($mapping['joinTable']['inverseJoinColumns'] as $joinColumn) {
$otherKeys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
}
}
}
if ( ! isset($mapping['isOnDeleteCascade'])) {
$this->_conn->delete(
$this->_class->getQuotedJoinTableName($mapping, $this->_platform),
array_combine($keys, $identifier)
);
$joinTableName = $this->quoteStrategy->getJoinTableName($mapping, $this->_class, $this->_platform);
$this->_conn->delete($joinTableName, array_combine($keys, $identifier));
if ($selfReferential) {
$this->_conn->delete(
$this->_class->getQuotedJoinTableName($mapping, $this->_platform),
array_combine($otherKeys, $identifier)
);
$this->_conn->delete($joinTableName, array_combine($otherKeys, $identifier));
}
}
}
@ -459,10 +487,12 @@ class BasicEntityPersister
public function delete($entity)
{
$identifier = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->deleteJoinTableRecords($identifier);
$id = array_combine($this->_class->getIdentifierColumnNames(), $identifier);
$this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id);
$id = array_combine($this->quoteStrategy->getIdentifierColumnNames($this->_class, $this->_platform), $identifier);
$this->_conn->delete($this->quoteStrategy->getTableName($this->_class, $this->_platform), $id);
}
/**
@ -530,7 +560,13 @@ class BasicEntityPersister
$targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
$owningTable = $this->getOwningTable($field);
foreach ($assoc['sourceToTargetKeyColumns'] as $sourceColumn => $targetColumn) {
foreach ($assoc['joinColumns'] as $joinColumn) {
$sourceColumn = $joinColumn['name'];
$targetColumn = $joinColumn['referencedColumnName'];
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
$this->quotedColumns[$sourceColumn] = $quotedColumn;
if ($newVal === null) {
$result[$owningTable][$sourceColumn] = null;
} else if ($targetClass->containsForeignIdentifier) {
@ -808,7 +844,7 @@ class BasicEntityPersister
$sourceClass = $this->_em->getClassMetadata($assoc['sourceEntity']);
if ($assoc['isOwningSide']) {
$quotedJoinTable = $sourceClass->getQuotedJoinTableName($assoc, $this->_platform);
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($assoc, $sourceClass, $this->_platform);
foreach ($assoc['relationToSourceKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) {
if ($sourceClass->containsForeignIdentifier) {
@ -831,7 +867,7 @@ class BasicEntityPersister
}
} else {
$owningAssoc = $this->_em->getClassMetadata($assoc['targetEntity'])->associationMappings[$assoc['mappedBy']];
$quotedJoinTable = $sourceClass->getQuotedJoinTableName($owningAssoc, $this->_platform);
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($owningAssoc, $sourceClass, $this->_platform);
// TRICKY: since the association is inverted source and target are flipped
foreach ($owningAssoc['relationToTargetKeyColumns'] as $relationKeyColumn => $sourceKeyColumn) {
@ -901,7 +937,7 @@ class BasicEntityPersister
}
return $this->_platform->modifyLimitQuery('SELECT ' . $this->_getSelectColumnListSQL()
. $this->_platform->appendLockHint(' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' '
. $this->_platform->appendLockHint(' FROM ' . $this->quoteStrategy->getTableName($this->_class, $this->_platform) . ' '
. $alias, $lockMode)
. $this->_selectJoinSql . $joinSql
. ($conditionSql ? ' WHERE ' . $conditionSql : '')
@ -934,7 +970,7 @@ class BasicEntityPersister
$this->_getSQLTableAlias($this->_class->fieldMappings[$fieldName]['inherited'])
: $baseTableAlias;
$columnName = $this->_class->getQuotedColumnName($fieldName, $this->_platform);
$columnName = $this->quoteStrategy->getColumnName($fieldName, $this->_class, $this->_platform);
$orderBySql .= $orderBySql ? ', ' : ' ORDER BY ';
$orderBySql .= $tableAlias . '.' . $columnName . ' ' . $orientation;
@ -1012,10 +1048,13 @@ class BasicEntityPersister
if ($assoc['isOwningSide']) {
$this->_selectJoinSql .= ' ' . $this->getJoinSQLForJoinColumns($assoc['joinColumns']);
$this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' ' . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) .' ON ';
$this->_selectJoinSql .= ' ' . $this->quoteStrategy->getTableName($eagerEntity, $this->_platform) . ' ' . $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) .' ON ';
$tableAlias = $this->_getSQLTableAlias($assoc['targetEntity'], $assocAlias);
foreach ($assoc['sourceToTargetKeyColumns'] as $sourceCol => $targetCol) {
foreach ($assoc['joinColumns'] as $joinColumn) {
$sourceCol = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
$targetCol = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $this->_class, $this->_platform);
if ( ! $first) {
$this->_selectJoinSql .= ' AND ';
}
@ -1033,7 +1072,7 @@ class BasicEntityPersister
$owningAssoc = $eagerEntity->getAssociationMapping($assoc['mappedBy']);
$this->_selectJoinSql .= ' LEFT JOIN';
$this->_selectJoinSql .= ' ' . $eagerEntity->getQuotedTableName($this->_platform) . ' '
$this->_selectJoinSql .= ' ' . $this->quoteStrategy->getTableName($eagerEntity, $this->_platform) . ' '
. $this->_getSQLTableAlias($eagerEntity->name, $assocAlias) . ' ON ';
foreach ($owningAssoc['sourceToTargetKeyColumns'] as $sourceCol => $targetCol) {
@ -1066,20 +1105,22 @@ class BasicEntityPersister
*/
protected function _getSelectColumnAssociationSQL($field, $assoc, ClassMetadata $class, $alias = 'r')
{
$columnList = '';
$columnList = array();
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
if ($columnList) $columnList .= ', ';
$resultColumnName = $this->getSQLColumnAlias($srcColumn);
$columnList .= $this->_getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
. '.' . $srcColumn . ' AS ' . $resultColumnName;
$this->_rsm->addMetaResult($alias, $resultColumnName, $srcColumn, isset($assoc['id']) && $assoc['id'] === true);
foreach ($assoc['joinColumns'] as $joinColumn) {
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
$columnList[] = $this->_getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
$this->_rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, isset($assoc['id']) && $assoc['id'] === true);
}
}
return $columnList;
return implode(', ', $columnList);
}
/**
@ -1099,7 +1140,7 @@ class BasicEntityPersister
$joinClauses = $owningAssoc['relationToSourceKeyColumns'];
}
$joinTableName = $this->_class->getQuotedJoinTableName($owningAssoc, $this->_platform);
$joinTableName = $this->quoteStrategy->getJoinTableName($owningAssoc, $this->_class, $this->_platform);
$joinSql = '';
foreach ($joinClauses as $joinTableColumn => $sourceColumn) {
@ -1108,7 +1149,7 @@ class BasicEntityPersister
if ($this->_class->containsForeignIdentifier && ! isset($this->_class->fieldNames[$sourceColumn])) {
$quotedColumn = $sourceColumn; // join columns cannot be quoted
} else {
$quotedColumn = $this->_class->getQuotedColumnName($this->_class->fieldNames[$sourceColumn], $this->_platform);
$quotedColumn = $this->quoteStrategy->getColumnName($this->_class->fieldNames[$sourceColumn], $this->_class, $this->_platform);
}
$joinSql .= $this->_getSQLTableAlias($this->_class->name) . '.' . $quotedColumn . ' = '
@ -1131,8 +1172,8 @@ class BasicEntityPersister
if (empty($columns)) {
$insertSql = $this->_platform->getEmptyIdentityInsertSQL(
$this->_class->getQuotedTableName($this->_platform),
$this->_class->getQuotedColumnName($this->_class->identifier[0], $this->_platform)
$this->quoteStrategy->getTableName($this->_class, $this->_platform),
$this->quoteStrategy->getColumnName($this->_class->identifier[0], $this->_class, $this->_platform)
);
} else {
$columns = array_unique($columns);
@ -1151,7 +1192,7 @@ class BasicEntityPersister
$values[] = $placeholder;
}
$insertSql = 'INSERT INTO ' . $this->_class->getQuotedTableName($this->_platform)
$insertSql = 'INSERT INTO ' . $this->quoteStrategy->getTableName($this->_class, $this->_platform)
. ' (' . implode(', ', $columns) . ') VALUES (' . implode(', ', $values) . ')';
}
@ -1180,14 +1221,13 @@ class BasicEntityPersister
if (isset($this->_class->associationMappings[$name])) {
$assoc = $this->_class->associationMappings[$name];
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
foreach ($assoc['targetToSourceKeyColumns'] as $sourceCol) {
$columns[] = $sourceCol;
foreach ($assoc['joinColumns'] as $joinColumn) {
$columns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->_class, $this->_platform);
}
}
} else if ($this->_class->generatorType != ClassMetadata::GENERATOR_TYPE_IDENTITY || $this->_class->identifier[0] != $name) {
$columns[] = $this->_class->getQuotedColumnName($name, $this->_platform);
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
$this->_columnTypes[$name] = $this->_class->fieldMappings[$name]['type'];
}
}
@ -1206,7 +1246,7 @@ class BasicEntityPersister
protected function _getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r')
{
$sql = $this->_getSQLTableAlias($class->name, $alias == 'r' ? '' : $alias)
. '.' . $class->getQuotedColumnName($field, $this->_platform);
. '.' . $this->quoteStrategy->getColumnName($field, $class, $this->_platform);
$columnAlias = $this->getSQLColumnAlias($class->columnNames[$field]);
$this->_rsm->addFieldResult($alias, $columnAlias, $field);
@ -1276,7 +1316,7 @@ class BasicEntityPersister
*/
protected function getLockTablesSql()
{
return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' '
return 'FROM ' . $this->quoteStrategy->getTableName($this->_class, $this->_platform) . ' '
. $this->_getSQLTableAlias($this->_class->name);
}
@ -1305,7 +1345,7 @@ class BasicEntityPersister
? $this->_class->fieldMappings[$field]['inherited']
: $this->_class->name;
$conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->_class->getQuotedColumnName($field, $this->_platform);
$conditionSql .= $this->_getSQLTableAlias($className) . '.' . $this->quoteStrategy->getColumnName($field, $this->_class, $this->_platform);
if (isset($this->_class->fieldMappings[$field]['requireSQLConversion'])) {
$type = Type::getType($this->_class->getTypeOfField($field));
@ -1557,7 +1597,7 @@ class BasicEntityPersister
{
// if one of the join columns is nullable, return left join
foreach ($joinColumns as $joinColumn) {
if (!isset($joinColumn['nullable']) || $joinColumn['nullable']) {
if ( ! isset($joinColumn['nullable']) || $joinColumn['nullable']) {
return 'LEFT JOIN';
}
}
@ -1573,11 +1613,7 @@ class BasicEntityPersister
*/
public function getSQLColumnAlias($columnName)
{
// Trim the column alias to the maximum identifier length of the platform.
// If the alias is to long, characters are cut off from the beginning.
return $this->_platform->getSQLResultCasing(
substr($columnName . $this->_sqlAliasCounter++, -$this->_platform->getMaxIdentifierLength())
);
return $this->quoteStrategy->getColumnAlias($columnName, $this->_sqlAliasCounter++, $this->_platform);
}
/**

View File

@ -105,7 +105,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
$tableName = $cm->getTableName();
$this->_owningTableMap[$fieldName] = $tableName;
$this->_quotedTableMap[$tableName] = $cm->getQuotedTableName($this->_platform);
$this->_quotedTableMap[$tableName] = $this->quoteStrategy->getTableName($cm, $this->_platform);
return $tableName;
}
@ -225,7 +225,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// Make sure the table with the version column is updated even if no columns on that
// table were affected.
if ($isVersioned && ! isset($updateData[$versionedTable])) {
$this->_updateTable($entity, $versionedClass->getQuotedTableName($this->_platform), array(), true);
$this->_updateTable($entity, $this->quoteStrategy->getTableName($versionedClass, $this->_platform), array(), true);
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->assignDefaultVersionValue($entity, $id);
@ -247,15 +247,15 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
// delete the row from the root table. Cascades do the rest.
if ($this->_platform->supportsForeignKeyConstraints()) {
$this->_conn->delete(
$this->_em->getClassMetadata($this->_class->rootEntityName)->getQuotedTableName($this->_platform), $id
$this->quoteStrategy->getTableName($this->_em->getClassMetadata($this->_class->rootEntityName), $this->_platform), $id
);
} else {
// Delete from all tables individually, starting from this class' table up to the root table.
$this->_conn->delete($this->_class->getQuotedTableName($this->_platform), $id);
$this->_conn->delete($this->quoteStrategy->getTableName($this->_class, $this->_platform), $id);
foreach ($this->_class->parentClasses as $parentClass) {
$this->_conn->delete(
$this->_em->getClassMetadata($parentClass)->getQuotedTableName($this->_platform), $id
$this->quoteStrategy->getTableName($this->_em->getClassMetadata($parentClass), $this->_platform), $id
);
}
}
@ -321,7 +321,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName);
$tableAlias = $this->_getSQLTableAlias($parentClassName);
$joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
@ -361,7 +361,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
// Add LEFT JOIN
$joinSql .= ' LEFT JOIN ' . $subClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$joinSql .= ' LEFT JOIN ' . $this->quoteStrategy->getTableName($subClass, $this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
@ -400,7 +400,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
return $this->_platform->modifyLimitQuery('SELECT ' . $this->_selectColumnListSql
. ' FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias
. ' FROM ' . $this->quoteStrategy->getTableName($this->_class, $this->_platform) . ' ' . $baseTableAlias
. $joinSql
. ($conditionSql != '' ? ' WHERE ' . $conditionSql : '') . $orderBySql, $limit, $offset)
. $lockSql;
@ -422,7 +422,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
foreach ($this->_class->parentClasses as $parentClassName) {
$parentClass = $this->_em->getClassMetadata($parentClassName);
$tableAlias = $this->_getSQLTableAlias($parentClassName);
$joinSql .= ' INNER JOIN ' . $parentClass->getQuotedTableName($this->_platform) . ' ' . $tableAlias . ' ON ';
$joinSql .= ' INNER JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->_platform) . ' ' . $tableAlias . ' ON ';
$first = true;
foreach ($idColumns as $idColumn) {
@ -432,7 +432,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
}
return 'FROM ' . $this->_class->getQuotedTableName($this->_platform) . ' ' . $baseTableAlias . $joinSql;
return 'FROM ' .$this->quoteStrategy->getTableName($this->_class, $this->_platform) . ' ' . $baseTableAlias . $joinSql;
}
/* Ensure this method is never called. This persister overrides _getSelectEntitiesSQL directly. */
@ -463,7 +463,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
}
} else if ($this->_class->name != $this->_class->rootEntityName ||
! $this->_class->isIdGeneratorIdentity() || $this->_class->identifier[0] != $name) {
$columns[] = $this->_class->getQuotedColumnName($name, $this->_platform);
$columns[] = $this->quoteStrategy->getColumnName($name, $this->_class, $this->_platform);
}
}

View File

@ -43,7 +43,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$mapping = $coll->getMapping();
$class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
return 'DELETE FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform)
. ' WHERE ' . implode(' = ? AND ', $mapping['joinTableColumns']) . ' = ?';
}
@ -76,11 +76,10 @@ class ManyToManyPersister extends AbstractCollectionPersister
*/
protected function _getInsertRowSQL(PersistentCollection $coll)
{
$mapping = $coll->getMapping();
$columns = $mapping['joinTableColumns'];
$class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$joinTable = $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform());
$mapping = $coll->getMapping();
$columns = $mapping['joinTableColumns'];
$class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$joinTable = $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform);
return 'INSERT INTO ' . $joinTable . ' (' . implode(', ', $columns) . ')'
. ' VALUES (' . implode(', ', array_fill(0, count($columns), '?')) . ')';
@ -148,10 +147,11 @@ class ManyToManyPersister extends AbstractCollectionPersister
*/
protected function _getDeleteSQL(PersistentCollection $coll)
{
$class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$mapping = $coll->getMapping();
$class = $this->_em->getClassMetadata(get_class($coll->getOwner()));
$mapping = $coll->getMapping();
$joinTable = $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform);
return 'DELETE FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform())
return 'DELETE FROM ' . $joinTable
. ' WHERE ' . implode(' = ? AND ', array_keys($mapping['relationToSourceKeyColumns'])) . ' = ?';
}
@ -222,7 +222,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
}
$sql = 'SELECT COUNT(*)'
. ' FROM ' . $class->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform()) . ' t'
. ' FROM ' . $this->quoteStrategy->getJoinTableName($mapping, $class, $this->platform) . ' t'
. $joinTargetEntitySQL
. ' WHERE ' . implode(' AND ', $whereClauses);
@ -324,7 +324,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$targetId = $uow->getEntityIdentifier($element);
}
$quotedJoinTable = $sourceClass->getQuotedJoinTableName($mapping, $this->_conn->getDatabasePlatform());
$quotedJoinTable = $this->quoteStrategy->getJoinTableName($mapping, $sourceClass, $this->platform);
$whereClauses = array();
$params = array();
@ -385,7 +385,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
$joinTargetEntitySQL = '';
if ($filterSql = $this->generateFilterConditionSQL($targetClass, 'te')) {
$joinTargetEntitySQL = ' JOIN '
. $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' te'
. $this->quoteStrategy->getTableName($targetClass, $this->platform) . ' te'
. ' ON';
$joinTargetEntitySQLClauses = array();

View File

@ -45,7 +45,7 @@ class OneToManyPersister extends AbstractCollectionPersister
$mapping = $coll->getMapping();
$class = $this->_em->getClassMetadata($mapping['targetEntity']);
return 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform())
return 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform)
. ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?';
}
@ -127,7 +127,7 @@ class OneToManyPersister extends AbstractCollectionPersister
}
$sql = 'SELECT count(*)'
. ' FROM ' . $targetClass->getQuotedTableName($this->_conn->getDatabasePlatform()) . ' t'
. ' FROM ' . $this->quoteStrategy->getTableName($targetClass, $this->platform) . ' t'
. ' WHERE ' . implode(' AND ', $whereClauses);
return $this->_conn->fetchColumn($sql, $params);
@ -204,7 +204,7 @@ class OneToManyPersister extends AbstractCollectionPersister
$mapping = $coll->getMapping();
$class = $this->_em->getClassMetadata($mapping['targetEntity']);
$sql = 'DELETE FROM ' . $class->getQuotedTableName($this->_conn->getDatabasePlatform())
$sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform)
. ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?';
return (bool) $this->_conn->executeUpdate($sql, $this->_getDeleteRowSQLParameters($coll, $element));

View File

@ -42,21 +42,22 @@ class SizeFunction extends FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
$dqlAlias = $this->collectionPathExpression->identificationVariable;
$assocField = $this->collectionPathExpression->field;
$platform = $sqlWalker->getEntityManager()->getConnection()->getDatabasePlatform();
$quoteStrategy = $sqlWalker->getEntityManager()->getConfiguration()->getQuoteStrategy();
$dqlAlias = $this->collectionPathExpression->identificationVariable;
$assocField = $this->collectionPathExpression->field;
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
$class = $qComp['metadata'];
$assoc = $class->associationMappings[$assocField];
$sql = 'SELECT COUNT(*) FROM ';
$qComp = $sqlWalker->getQueryComponent($dqlAlias);
$class = $qComp['metadata'];
$assoc = $class->associationMappings[$assocField];
$sql = 'SELECT COUNT(*) FROM ';
if ($assoc['type'] == \Doctrine\ORM\Mapping\ClassMetadata::ONE_TO_MANY) {
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
$targetTableAlias = $sqlWalker->getSQLTableAlias($targetClass->getTableName());
$sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
$targetTableAlias = $sqlWalker->getSQLTableAlias($targetClass->getTableName());
$sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
$sql .= $targetClass->getQuotedTableName($platform) . ' ' . $targetTableAlias . ' WHERE ';
$sql .= $quoteStrategy->getTableName($targetClass, $platform) . ' ' . $targetTableAlias . ' WHERE ';
$owningAssoc = $targetClass->associationMappings[$assoc['mappedBy']];
@ -67,7 +68,7 @@ class SizeFunction extends FunctionNode
$sql .= $targetTableAlias . '.' . $sourceColumn
. ' = '
. $sourceTableAlias . '.' . $class->getQuotedColumnName($class->fieldNames[$targetColumn], $platform);
. $sourceTableAlias . '.' . $quoteStrategy->getColumnName($class->fieldNames[$targetColumn], $class, $platform);
}
} else { // many-to-many
$targetClass = $sqlWalker->getEntityManager()->getClassMetadata($assoc['targetEntity']);
@ -80,7 +81,7 @@ class SizeFunction extends FunctionNode
$sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias);
// join to target table
$sql .= $targetClass->getQuotedJoinTableName($owningAssoc, $platform) . ' ' . $joinTableAlias . ' WHERE ';
$sql .= $quoteStrategy->getJoinTableName($owningAssoc, $targetClass, $platform) . ' ' . $joinTableAlias . ' WHERE ';
$joinColumns = $assoc['isOwningSide']
? $joinTable['joinColumns']
@ -91,8 +92,8 @@ class SizeFunction extends FunctionNode
foreach ($joinColumns as $joinColumn) {
if ($first) $first = false; else $sql .= ' AND ';
$sourceColumnName = $class->getQuotedColumnName(
$class->fieldNames[$joinColumn['referencedColumnName']], $platform
$sourceColumnName = $quoteStrategy->getColumnName(
$class->fieldNames[$joinColumn['referencedColumnName']], $class, $platform
);
$sql .= $joinTableAlias . '.' . $joinColumn['name']

View File

@ -47,17 +47,18 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
*/
public function __construct(AST\Node $AST, $sqlWalker)
{
$em = $sqlWalker->getEntityManager();
$conn = $em->getConnection();
$platform = $conn->getDatabasePlatform();
$em = $sqlWalker->getEntityManager();
$conn = $em->getConnection();
$platform = $conn->getDatabasePlatform();
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
$tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
$idColumnNames = $rootClass->getIdentifierColumnNames();
$idColumnList = implode(', ', $idColumnNames);
$tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
$idColumnNames = $rootClass->getIdentifierColumnNames();
$idColumnList = implode(', ', $idColumnNames);
// 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
$sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias);
@ -80,7 +81,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
// 3. Create and store DELETE statements
$classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses);
foreach (array_reverse($classNames) as $className) {
$tableName = $em->getClassMetadata($className)->getQuotedTableName($platform);
$tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform);
$this->_sqlStatements[] = 'DELETE FROM ' . $tableName
. ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
}

View File

@ -50,20 +50,20 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
*/
public function __construct(AST\Node $AST, $sqlWalker)
{
$em = $sqlWalker->getEntityManager();
$conn = $em->getConnection();
$platform = $conn->getDatabasePlatform();
$em = $sqlWalker->getEntityManager();
$conn = $em->getConnection();
$platform = $conn->getDatabasePlatform();
$quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
$updateClause = $AST->updateClause;
$updateClause = $AST->updateClause;
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
$updateItems = $updateClause->updateItems;
$updateItems = $updateClause->updateItems;
$tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
$idColumnNames = $rootClass->getIdentifierColumnNames();
$idColumnList = implode(', ', $idColumnNames);
$tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName());
$idColumnNames = $rootClass->getIdentifierColumnNames();
$idColumnList = implode(', ', $idColumnNames);
// 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause()
$sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable);
@ -86,7 +86,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
foreach (array_reverse($classNames) as $className) {
$affected = false;
$class = $em->getClassMetadata($className);
$updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET ';
$updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class, $platform) . ' SET ';
foreach ($updateItems as $updateItem) {
$field = $updateItem->pathExpression->field;

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,6 @@ use Doctrine\ORM\ORMException,
*
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @author Jonathan Wage <jonwage@gmail.com>
* @author Roman Borschel <roman@code-factory.org>
@ -47,12 +46,19 @@ class SchemaTool
/**
* @var \Doctrine\ORM\EntityManager
*/
private $_em;
private $em;
/**
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $_platform;
private $platform;
/**
* The quote strategy.
*
* @var \Doctrine\ORM\Mapping\QuoteStrategy
*/
private $quoteStrategy;
/**
* Initializes a new SchemaTool instance that uses the connection of the
@ -62,8 +68,9 @@ class SchemaTool
*/
public function __construct(EntityManager $em)
{
$this->_em = $em;
$this->_platform = $em->getConnection()->getDatabasePlatform();
$this->em = $em;
$this->platform = $em->getConnection()->getDatabasePlatform();
$this->quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
}
/**
@ -76,7 +83,7 @@ class SchemaTool
public function createSchema(array $classes)
{
$createSchemaSql = $this->getCreateSchemaSql($classes);
$conn = $this->_em->getConnection();
$conn = $this->em->getConnection();
foreach ($createSchemaSql as $sql) {
try {
@ -97,7 +104,7 @@ class SchemaTool
public function getCreateSchemaSql(array $classes)
{
$schema = $this->getSchemaFromMetadata($classes);
return $schema->toSql($this->_platform);
return $schema->toSql($this->platform);
}
/**
@ -124,23 +131,22 @@ class SchemaTool
*/
public function getSchemaFromMetadata(array $classes)
{
$processedClasses = array(); // Reminder for processed classes, used for hierarchies
// Reminder for processed classes, used for hierarchies
$processedClasses = array();
$eventManager = $this->em->getEventManager();
$schemaManager = $this->em->getConnection()->getSchemaManager();
$metadataSchemaConfig = $schemaManager->createSchemaConfig();
$sm = $this->_em->getConnection()->getSchemaManager();
$metadataSchemaConfig = $sm->createSchemaConfig();
$metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
$schema = new Schema(array(), array(), $metadataSchemaConfig);
$evm = $this->_em->getEventManager();
foreach ($classes as $class) {
if ($this->processingNotRequired($class, $processedClasses)) {
continue;
}
$table = $schema->createTable($class->getQuotedTableName($this->_platform));
$columns = array(); // table columns
$table = $schema->createTable($this->quoteStrategy->getTableName($class, $this->platform));
$columns = array(); // table columns
if ($class->isInheritanceTypeSingleTable()) {
$columns = $this->_gatherColumns($class, $table);
@ -156,7 +162,7 @@ class SchemaTool
}
foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName);
$subClass = $this->em->getClassMetadata($subClassName);
$this->_gatherColumns($subClass, $table);
$this->_gatherRelationsSql($subClass, $table, $schema);
$processedClasses[$subClassName] = true;
@ -166,7 +172,7 @@ class SchemaTool
$pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) {
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
$columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
$this->_gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($fieldName)) {
@ -185,7 +191,7 @@ class SchemaTool
/* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
$idMapping = $class->fieldMappings[$class->identifier[0]];
$this->_gatherColumn($class, $idMapping, $table);
$columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
$columnName = $this->quoteStrategy->getColumnName($class->identifier[0], $class, $this->platform);
// TODO: This seems rather hackish, can we optimize it?
$table->getColumn($columnName)->setAutoincrement(false);
@ -193,7 +199,7 @@ class SchemaTool
// Add a FK constraint on the ID column
$table->addUnnamedForeignKeyConstraint(
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
$this->quoteStrategy->getTableName($this->em->getClassMetadata($class->rootEntityName), $this->platform),
array($columnName), array($columnName), array('onDelete' => 'CASCADE')
);
}
@ -210,16 +216,17 @@ class SchemaTool
$pkColumns = array();
foreach ($class->identifier as $identifierField) {
if (isset($class->fieldMappings[$identifierField])) {
$pkColumns[] = $class->getQuotedColumnName($identifierField, $this->_platform);
$pkColumns[] = $this->quoteStrategy->getColumnName($identifierField, $class, $this->platform);
} else if (isset($class->associationMappings[$identifierField])) {
/* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
$assoc = $class->associationMappings[$identifierField];
foreach ($assoc['joinColumns'] as $joinColumn) {
$pkColumns[] = $joinColumn['name'];
$pkColumns[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
}
}
}
if (!$table->hasIndex('primary')) {
if ( ! $table->hasIndex('primary')) {
$table->setPrimaryKey($pkColumns);
}
@ -244,28 +251,28 @@ class SchemaTool
$processedClasses[$class->name] = true;
if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) {
$seqDef = $class->sequenceGeneratorDefinition;
if (!$schema->hasSequence($seqDef['sequenceName'])) {
$seqDef = $class->sequenceGeneratorDefinition;
$quotedName = $this->quoteStrategy->getSequenceName($seqDef, $class, $this->platform);
if ( ! $schema->hasSequence($quotedName)) {
$schema->createSequence(
$seqDef['sequenceName'],
$quotedName,
$seqDef['allocationSize'],
$seqDef['initialValue']
);
}
}
if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) {
$evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
if ($eventManager->hasListeners(ToolEvents::postGenerateSchemaTable)) {
$eventManager->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table));
}
}
if ( ! $this->_platform->supportsSchemas() && ! $this->_platform->canEmulateSchemas() ) {
if ( ! $this->platform->supportsSchemas() && ! $this->platform->canEmulateSchemas() ) {
$schema->visit(new RemoveNamespacedAssets());
}
if ($evm->hasListeners(ToolEvents::postGenerateSchema)) {
$evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema));
if ($eventManager->hasListeners(ToolEvents::postGenerateSchema)) {
$eventManager->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->em, $schema));
}
return $schema;
@ -283,7 +290,7 @@ class SchemaTool
{
$discrColumn = $class->discriminatorColumn;
if (!isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) {
if ( ! isset($discrColumn['type']) || (strtolower($discrColumn['type']) == 'string' && $discrColumn['length'] === null)) {
$discrColumn['type'] = 'string';
$discrColumn['length'] = 255;
}
@ -321,7 +328,7 @@ class SchemaTool
$column = $this->_gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($mapping['fieldName'])) {
$pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
$pkColumns[] = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
}
}
@ -344,7 +351,7 @@ class SchemaTool
*/
private function _gatherColumn($class, array $mapping, $table)
{
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform);
$columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class, $this->platform);
$columnType = $mapping['type'];
$options = array();
@ -417,7 +424,7 @@ class SchemaTool
continue;
}
$foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']);
$foreignClass = $this->em->getClassMetadata($mapping['targetEntity']);
if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
$primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type
@ -434,7 +441,7 @@ class SchemaTool
// create join table
$joinTable = $mapping['joinTable'];
$theJoinTable = $schema->createTable($foreignClass->getQuotedJoinTableName($mapping, $this->_platform));
$theJoinTable = $schema->createTable($this->quoteStrategy->getJoinTableName($mapping, $foreignClass, $this->platform));
$primaryKeyColumns = $uniqueConstraints = array();
@ -477,7 +484,7 @@ class SchemaTool
foreach ($class->getIdentifierFieldNames() as $fieldName) {
if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
return $this->getDefiningClass(
$this->_em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
$this->em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
$class->getSingleAssociationReferencedJoinColumnName($fieldName)
);
}
@ -499,27 +506,30 @@ class SchemaTool
*/
private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints)
{
$localColumns = array();
$foreignColumns = array();
$fkOptions = array();
$foreignTableName = $class->getQuotedTableName($this->_platform);
$localColumns = array();
$foreignColumns = array();
$fkOptions = array();
$foreignTableName = $this->quoteStrategy->getTableName($class, $this->platform);
foreach ($joinColumns as $joinColumn) {
$columnName = $joinColumn['name'];
list($definingClass, $referencedFieldName) = $this->getDefiningClass($class, $joinColumn['referencedColumnName']);
if (!$definingClass) {
if ( ! $definingClass) {
throw new \Doctrine\ORM\ORMException(
"Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ".
$mapping['sourceEntity'] . " towards ". $mapping['targetEntity'] . " does not exist."
);
}
$primaryKeyColumns[] = $columnName;
$localColumns[] = $columnName;
$foreignColumns[] = $joinColumn['referencedColumnName'];
$quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform);
$quotedRefColumnName = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $class, $this->platform);
if ( ! $theJoinTable->hasColumn($joinColumn['name'])) {
$primaryKeyColumns[] = $quotedColumnName;
$localColumns[] = $quotedColumnName;
$foreignColumns[] = $quotedRefColumnName;
if ( ! $theJoinTable->hasColumn($quotedColumnName)) {
// Only add the column to the table if it does not exist already.
// It might exist already if the foreign key is mapped into a regular
// property as well.
@ -543,11 +553,11 @@ class SchemaTool
$columnOptions['precision'] = $fieldMapping['precision'];
}
$theJoinTable->addColumn($columnName, $fieldMapping['type'], $columnOptions);
$theJoinTable->addColumn($quotedColumnName, $fieldMapping['type'], $columnOptions);
}
if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) {
$uniqueConstraints[] = array('columns' => array($columnName));
$uniqueConstraints[] = array('columns' => array($quotedColumnName));
}
if (isset($joinColumn['onDelete'])) {
@ -572,7 +582,7 @@ class SchemaTool
public function dropSchema(array $classes)
{
$dropSchemaSql = $this->getDropSchemaSQL($classes);
$conn = $this->_em->getConnection();
$conn = $this->em->getConnection();
foreach ($dropSchemaSql as $sql) {
try {
@ -591,7 +601,7 @@ class SchemaTool
public function dropDatabase()
{
$dropSchemaSql = $this->getDropDatabaseSQL();
$conn = $this->_em->getConnection();
$conn = $this->em->getConnection();
foreach ($dropSchemaSql as $sql) {
$conn->executeQuery($sql);
@ -605,10 +615,10 @@ class SchemaTool
*/
public function getDropDatabaseSQL()
{
$sm = $this->_em->getConnection()->getSchemaManager();
$sm = $this->em->getConnection()->getSchemaManager();
$schema = $sm->createSchema();
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->platform);
/* @var $schema \Doctrine\DBAL\Schema\Schema */
$schema->visit($visitor);
return $visitor->getQueries();
@ -622,13 +632,13 @@ class SchemaTool
*/
public function getDropSchemaSQL(array $classes)
{
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->platform);
$schema = $this->getSchemaFromMetadata($classes);
$sm = $this->_em->getConnection()->getSchemaManager();
$sm = $this->em->getConnection()->getSchemaManager();
$fullSchema = $sm->createSchema();
foreach ($fullSchema->getTables() as $table) {
if (!$schema->hasTable($table->getName())) {
if ( ! $schema->hasTable($table->getName())) {
foreach ($table->getForeignKeys() as $foreignKey) {
/* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */
if ($schema->hasTable($foreignKey->getForeignTableName())) {
@ -643,7 +653,7 @@ class SchemaTool
}
}
if ($this->_platform->supportsSequences()) {
if ($this->platform->supportsSequences()) {
foreach ($schema->getSequences() as $sequence) {
$visitor->acceptSequence($sequence);
}
@ -676,7 +686,7 @@ class SchemaTool
public function updateSchema(array $classes, $saveMode=false)
{
$updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
$conn = $this->_em->getConnection();
$conn = $this->em->getConnection();
foreach ($updateSchemaSql as $sql) {
$conn->executeQuery($sql);
@ -695,7 +705,7 @@ class SchemaTool
*/
public function getUpdateSchemaSql(array $classes, $saveMode=false)
{
$sm = $this->_em->getConnection()->getSchemaManager();
$sm = $this->em->getConnection()->getSchemaManager();
$fromSchema = $sm->createSchema();
$toSchema = $this->getSchemaFromMetadata($classes);
@ -704,9 +714,9 @@ class SchemaTool
$schemaDiff = $comparator->compare($fromSchema, $toSchema);
if ($saveMode) {
return $schemaDiff->toSaveSql($this->_platform);
return $schemaDiff->toSaveSql($this->platform);
} else {
return $schemaDiff->toSql($this->_platform);
return $schemaDiff->toSql($this->platform);
}
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
* @Table(name="`quote-address`")
*/
class Address
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer", name="`address-id`")
*/
public $id;
/**
* @Column(name="`address-zip`")
*/
public $zip;
/**
* @OneToOne(targetEntity="User", inversedBy="address")
* @JoinColumn(name="`user-id`", referencedColumnName="`user-id`")
*/
public $user;
public function setUser(User $user) {
if ($this->user !== $user) {
$this->user = $user;
$user->setAddress($this);
}
}
public function getId()
{
return $this->id;
}
public function getZip()
{
return $this->zip;
}
public function getUser()
{
return $this->user;
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
* @Table(name="`quote-group`")
*/
class Group
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer", name="`group-id`")
*/
public $id;
/**
* @Column(name="`group-name`")
*/
public $name;
/**
* @var Group
*
* @ManyToOne(targetEntity="Group", cascade={"persist"})
* @JoinColumn(name="`parent-id`", referencedColumnName="`group-id`")
*/
public $parent;
/**
* @ManyToMany(targetEntity="User", mappedBy="groups")
*/
public $users;
public function __construct($name = null, Group $parent = null)
{
$this->name = $name;
$this->parent = $parent;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
* @Table(name="`quote-phone`")
*/
class Phone
{
/**
* @Id
* @Column(name="`phone-number`")
*/
public $number;
/**
* @ManyToOne(targetEntity="User", inversedBy="phones")
* @JoinColumn(name="`user-id`", referencedColumnName="`user-id`")
*/
public $user;
}

View File

@ -0,0 +1,32 @@
<?php
namespace Doctrine\Tests\Models\Quote;
/**
* @Entity
* @Table(name="`ddc-1719-simple-entity`")
*/
class SimpleEntity
{
/**
* @Id
* @Column(type="integer", name="`simple-entity-id`")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
/**
* @Column(type="string", name="`simple-entity-value`")
*/
public $value;
/**
* @param string $value
*/
public function __construct($value)
{
$this->value = $value;
}
}

View File

@ -0,0 +1,83 @@
<?php
namespace Doctrine\Tests\Models\Quote;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="`quote-user`")
*/
class User
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer", name="`user-id`")
*/
public $id;
/**
* @Column(type="string", name="`user-name`")
*/
public $name;
/**
* @OneToMany(targetEntity="Phone", mappedBy="user", cascade={"persist"})
*/
public $phones;
/**
* @JoinColumn(name="`address-id`", referencedColumnName="`address-id`")
* @OneToOne(targetEntity="Address", mappedBy="user", cascade={"persist"}, fetch="EAGER")
*/
public $address;
/**
* @ManyToMany(targetEntity="Group", inversedBy="users", cascade={"persist"})
* @JoinTable(name="`quote-users-groups`",
* joinColumns={
* @JoinColumn(
* name="`user-id`",
* referencedColumnName="`user-id`"
* )
* },
* inverseJoinColumns={
* @JoinColumn(
* name="`group-id`",
* referencedColumnName="`group-id`"
* )
* }
* )
*/
public $groups;
public function __construct()
{
$this->phones = new ArrayCollection;
$this->groups = new ArrayCollection;
}
public function getPhones()
{
return $this->phones;
}
public function getAddress()
{
return $this->address;
}
public function getGroups()
{
return $this->groups;
}
public function setAddress(Address $address) {
if ($this->address !== $address) {
$this->address = $address;
$address->setUser($this);
}
}
}

View File

@ -25,8 +25,8 @@ class DDC1151Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals("CREATE INDEX IDX_88A3259AC5AD08A ON ddc1151user_ddc1151group (ddc1151user_id)", $sql[2]);
$this->assertEquals("CREATE INDEX IDX_88A32597357E0B1 ON ddc1151user_ddc1151group (ddc1151group_id)", $sql[3]);
$this->assertEquals("CREATE TABLE \"Group\" (id INT NOT NULL, PRIMARY KEY(id))", $sql[4]);
$this->assertEquals("CREATE SEQUENCE User_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[5]);
$this->assertEquals("CREATE SEQUENCE Group_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[6]);
$this->assertEquals("CREATE SEQUENCE \"User_id_seq\" INCREMENT BY 1 MINVALUE 1 START 1", $sql[5]);
$this->assertEquals("CREATE SEQUENCE \"Group_id_seq\" INCREMENT BY 1 MINVALUE 1 START 1", $sql[6]);
$this->assertEquals("ALTER TABLE ddc1151user_ddc1151group ADD CONSTRAINT FK_88A3259AC5AD08A FOREIGN KEY (ddc1151user_id) REFERENCES \"User\" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[7]);
$this->assertEquals("ALTER TABLE ddc1151user_ddc1151group ADD CONSTRAINT FK_88A32597357E0B1 FOREIGN KEY (ddc1151group_id) REFERENCES \"Group\" (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[8]);
}

View File

@ -21,7 +21,7 @@ class DDC1360Test extends OrmFunctionalTestCase
$this->assertEquals(array(
'CREATE TABLE "user"."user" (id INT NOT NULL, PRIMARY KEY(id))',
'CREATE SEQUENCE "user".user_id_seq INCREMENT BY 1 MINVALUE 1 START 1',
'CREATE SEQUENCE "user"."user_id_seq" INCREMENT BY 1 MINVALUE 1 START 1',
), $sql);
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Quote\User;
use Doctrine\Tests\Models\Quote\Address;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1845
* @group DDC-142
*/
class DDC142Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\User'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Group'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Phone'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Address'),
));
} catch(\Exception $e) {
}
}
public function testCreateRetreaveUpdateDelete()
{
$user = new User;
$user->name = 'FabioBatSilva';
$this->_em->persist($user);
$address = new Address;
$address->zip = '12345';
$this->_em->persist($address);
$this->_em->flush();
$addressRef = $this->_em->getReference('Doctrine\Tests\Models\Quote\Address', $address->getId());
$user->setAddress($addressRef);
$this->_em->flush();
$this->_em->clear();
$id = $user->id;
$this->assertNotNull($id);
$user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $id);
$address = $user->getAddress();
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Address', $user->getAddress());
$this->assertEquals('FabioBatSilva', $user->name);
$this->assertEquals('12345', $address->zip);
$user->name = 'FabioBatSilva1';
$user->address = null;
$this->_em->persist($user);
$this->_em->remove($address);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find('Doctrine\Tests\Models\Quote\User', $id);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\User', $user);
$this->assertNull($user->getAddress());
$this->assertEquals('FabioBatSilva1', $user->name);
$this->_em->remove($user);
$this->_em->flush();
$this->_em->clear();
$this->assertNull($this->_em->find('Doctrine\Tests\Models\Quote\User', $id));
}
}

View File

@ -0,0 +1,88 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Quote\SimpleEntity;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1719
*/
class DDC1719Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
const CLASS_NAME = '\Doctrine\Tests\Models\Quote\SimpleEntity';
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(self::CLASS_NAME),
));
} catch(\Exception $e) {
}
}
public function testCreateRetreaveUpdateDelete()
{
$e1 = new SimpleEntity('Bar 1');
$e2 = new SimpleEntity('Foo 1');
// Create
$this->_em->persist($e1);
$this->_em->persist($e2);
$this->_em->flush();
$this->_em->clear();
$e1Id = $e1->id;
$e2Id = $e2->id;
// Retreave
$e1 = $this->_em->find(self::CLASS_NAME, $e1Id);
$e2 = $this->_em->find(self::CLASS_NAME, $e2Id);
$this->assertInstanceOf(self::CLASS_NAME, $e1);
$this->assertInstanceOf(self::CLASS_NAME, $e2);
$this->assertEquals($e1Id, $e1->id);
$this->assertEquals($e2Id, $e2->id);
$this->assertEquals('Bar 1', $e1->value);
$this->assertEquals('Foo 1', $e2->value);
$e1->value = 'Bar 2';
$e2->value = 'Foo 2';
// Update
$this->_em->persist($e1);
$this->_em->persist($e2);
$this->_em->flush();
$this->assertEquals('Bar 2', $e1->value);
$this->assertEquals('Foo 2', $e2->value);
$this->assertInstanceOf(self::CLASS_NAME, $e1);
$this->assertInstanceOf(self::CLASS_NAME, $e2);
$this->assertEquals($e1Id, $e1->id);
$this->assertEquals($e2Id, $e2->id);
$this->assertEquals('Bar 2', $e1->value);
$this->assertEquals('Foo 2', $e2->value);
// Delete
$this->_em->remove($e1);
$this->_em->remove($e2);
$this->_em->flush();
$e1 = $this->_em->find(self::CLASS_NAME, $e1Id);
$e2 = $this->_em->find(self::CLASS_NAME, $e2Id);
$this->assertNull($e1);
$this->assertNull($e2);
}
}

View File

@ -0,0 +1,136 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Tests\Models\Quote\Group;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1845
* @group DDC-1843
*/
class DDC1843Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\User'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Group'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Phone'),
$this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\Address'),
));
} catch(\Exception $e) {
}
}
public function testCreateRetreaveUpdateDelete()
{
$e1 = new Group('Parent Bar 1');
$e2 = new Group('Parent Foo 2');
$this->_em->persist($e1);
$this->_em->persist($e2);
$this->_em->flush();
$e3 = new Group('Bar 3', $e1);
$e4 = new Group('Foo 4', $e2);
// Create
$this->_em->persist($e3);
$this->_em->persist($e4);
$this->_em->flush();
$this->_em->clear();
$e1Id = $e1->id;
$e2Id = $e2->id;
$e3Id = $e3->id;
$e4Id = $e4->id;
// Retreave
$e1 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e1Id);
$e2 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e2Id);
$e3 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e3Id);
$e4 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e4Id);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e1);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e2);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e3);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e4);
$this->assertEquals($e1Id, $e1->id);
$this->assertEquals($e2Id, $e2->id);
$this->assertEquals($e3Id, $e3->id);
$this->assertEquals($e4Id, $e4->id);
$this->assertEquals('Parent Bar 1', $e1->name);
$this->assertEquals('Parent Foo 2', $e2->name);
$this->assertEquals('Bar 3', $e3->name);
$this->assertEquals('Foo 4', $e4->name);
$e1->name = 'Parent Bar 11';
$e2->name = 'Parent Foo 22';
$e3->name = 'Bar 33';
$e4->name = 'Foo 44';
// Update
$this->_em->persist($e1);
$this->_em->persist($e2);
$this->_em->persist($e3);
$this->_em->persist($e4);
$this->_em->flush();
$this->assertEquals('Parent Bar 11', $e1->name);
$this->assertEquals('Parent Foo 22', $e2->name);
$this->assertEquals('Bar 33', $e3->name);
$this->assertEquals('Foo 44', $e4->name);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e1);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e2);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e3);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e4);
$this->assertEquals($e1Id, $e1->id);
$this->assertEquals($e2Id, $e2->id);
$this->assertEquals($e3Id, $e3->id);
$this->assertEquals($e4Id, $e4->id);
$this->assertEquals('Parent Bar 11', $e1->name);
$this->assertEquals('Parent Foo 22', $e2->name);
$this->assertEquals('Bar 33', $e3->name);
$this->assertEquals('Foo 44', $e4->name);
// Delete
$this->_em->remove($e4);
$this->_em->remove($e3);
$this->_em->remove($e2);
$this->_em->remove($e1);
$this->_em->flush();
$this->_em->clear();
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e1);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e2);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e3);
$this->assertInstanceOf('Doctrine\Tests\Models\Quote\Group', $e4);
// Retreave
$e1 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e1Id);
$e2 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e2Id);
$e3 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e3Id);
$e4 = $this->_em->find('Doctrine\Tests\Models\Quote\Group', $e4Id);
$this->assertNull($e1);
$this->assertNull($e2);
$this->assertNull($e3);
$this->assertNull($e4);
}
}

View File

@ -243,6 +243,86 @@ class ClassMetadataFactoryTest extends \Doctrine\Tests\OrmTestCase
$cm1->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_AUTO);
return $cm1;
}
/**
* @group DDC-1845
*/
public function testQuoteMetadata()
{
$cmf = new ClassMetadataFactory();
$driver = $this->createAnnotationDriver(array(__DIR__ . '/../../Models/Quote/'));
$em = $this->_createEntityManager($driver);
$cmf->setEntityManager($em);
$userMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\User');
$phoneMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Phone');
$groupMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Group');
$addressMetadata = $cmf->getMetadataFor('Doctrine\Tests\Models\Quote\Address');
// Phone Class Metadata
$this->assertTrue($phoneMetadata->fieldMappings['number']['quoted']);
$this->assertEquals('phone-number', $phoneMetadata->fieldMappings['number']['columnName']);
$user = $phoneMetadata->associationMappings['user'];
$this->assertTrue($user['joinColumns'][0]['quoted']);
$this->assertEquals('user-id', $user['joinColumns'][0]['name']);
$this->assertEquals('user-id', $user['joinColumns'][0]['referencedColumnName']);
// User Group Metadata
$this->assertTrue($groupMetadata->fieldMappings['id']['quoted']);
$this->assertTrue($groupMetadata->fieldMappings['name']['quoted']);
$this->assertEquals('user-id', $userMetadata->fieldMappings['id']['columnName']);
$this->assertEquals('user-name', $userMetadata->fieldMappings['name']['columnName']);
$user = $groupMetadata->associationMappings['parent'];
$this->assertTrue($user['joinColumns'][0]['quoted']);
$this->assertEquals('parent-id', $user['joinColumns'][0]['name']);
$this->assertEquals('group-id', $user['joinColumns'][0]['referencedColumnName']);
// Address Class Metadata
$this->assertTrue($addressMetadata->fieldMappings['id']['quoted']);
$this->assertTrue($addressMetadata->fieldMappings['zip']['quoted']);
$this->assertEquals('address-id', $addressMetadata->fieldMappings['id']['columnName']);
$this->assertEquals('address-zip', $addressMetadata->fieldMappings['zip']['columnName']);
$user = $addressMetadata->associationMappings['user'];
$this->assertTrue($user['joinColumns'][0]['quoted']);
$this->assertEquals('user-id', $user['joinColumns'][0]['name']);
$this->assertEquals('user-id', $user['joinColumns'][0]['referencedColumnName']);
// User Class Metadata
$this->assertTrue($userMetadata->fieldMappings['id']['quoted']);
$this->assertTrue($userMetadata->fieldMappings['name']['quoted']);
$this->assertEquals('user-id', $userMetadata->fieldMappings['id']['columnName']);
$this->assertEquals('user-name', $userMetadata->fieldMappings['name']['columnName']);
$address = $userMetadata->associationMappings['address'];
$this->assertTrue($address['joinColumns'][0]['quoted']);
$this->assertEquals('address-id', $address['joinColumns'][0]['name']);
$this->assertEquals('address-id', $address['joinColumns'][0]['referencedColumnName']);
$groups = $userMetadata->associationMappings['groups'];
$this->assertTrue($groups['joinTable']['quoted']);
$this->assertTrue($groups['joinTable']['joinColumns'][0]['quoted']);
$this->assertEquals('quote-users-groups', $groups['joinTable']['name']);
$this->assertEquals('user-id', $groups['joinTable']['joinColumns'][0]['name']);
$this->assertEquals('user-id', $groups['joinTable']['joinColumns'][0]['referencedColumnName']);
$this->assertTrue($groups['joinTable']['inverseJoinColumns'][0]['quoted']);
$this->assertEquals('group-id', $groups['joinTable']['inverseJoinColumns'][0]['name']);
$this->assertEquals('group-id', $groups['joinTable']['inverseJoinColumns'][0]['referencedColumnName']);
}
}
/* Test subject class with overriden factory method for mocking purposes */

View File

@ -0,0 +1,197 @@
<?php
namespace Doctrine\Tests\ORM\Mapping;
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
use Doctrine\ORM\Mapping\QuoteStrategy;
use Doctrine\ORM\Mapping\ClassMetadata;
require_once __DIR__ . '/../../TestInit.php';
/**
* @group DDC-1845
*/
class QuoteStrategyTest extends \Doctrine\Tests\OrmTestCase
{
/**
* @var \Doctrine\ORM\Mapping\DefaultQuoteStrategy
*/
private $strategy;
/**
* @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/
private $platform;
protected function setUp()
{
parent::setUp();
$em = $this->_getTestEntityManager();
$this->platform = $em->getConnection()->getDatabasePlatform();
$this->strategy = new DefaultQuoteStrategy();
}
/**
* @param string $className
* @return \Doctrine\ORM\Mapping\ClassMetadata
*/
private function createClassMetadata($className)
{
$cm = new ClassMetadata($className);
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
return $cm;
}
public function testConfiguration()
{
$em = $this->_getTestEntityManager();
$config = $em->getConfiguration();
$this->assertInstanceOf('Doctrine\ORM\Mapping\QuoteStrategy', $config->getQuoteStrategy());
$this->assertInstanceOf('Doctrine\ORM\Mapping\DefaultQuoteStrategy', $config->getQuoteStrategy());
$config->setQuoteStrategy(new MyQuoteStrategy());
$this->assertInstanceOf('Doctrine\ORM\Mapping\QuoteStrategy', $config->getQuoteStrategy());
$this->assertInstanceOf('Doctrine\Tests\ORM\Mapping\MyQuoteStrategy', $config->getQuoteStrategy());
}
public function testGetColumnName()
{
$cm = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$cm->mapField(array('fieldName' => 'name', 'columnName' => '`name`'));
$cm->mapField(array('fieldName' => 'id', 'columnName' => 'id'));
$this->assertEquals('id' ,$this->strategy->getColumnName('id', $cm, $this->platform));
$this->assertEquals('"name"' ,$this->strategy->getColumnName('name', $cm, $this->platform));
}
public function testGetTableName()
{
$cm = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$cm->setPrimaryTable(array('name'=>'`cms_user`'));
$this->assertEquals('"cms_user"' ,$this->strategy->getTableName($cm, $this->platform));
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$cm->initializeReflection(new \Doctrine\Common\Persistence\Mapping\RuntimeReflectionService);
$cm->setPrimaryTable(array('name'=>'cms_user'));
$this->assertEquals('cms_user' ,$this->strategy->getTableName($cm, $this->platform));
}
public function testJoinTableName()
{
$cm1 = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$cm2 = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$cm1->mapManyToMany(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'inversedBy' => 'users',
'joinTable' => array(
'name' => '`cmsaddress_cmsuser`'
)
));
$cm2->mapManyToMany(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'inversedBy' => 'users',
'joinTable' => array(
'name' => 'cmsaddress_cmsuser'
)
)
);
$this->assertEquals('"cmsaddress_cmsuser"', $this->strategy->getJoinTableName($cm1->associationMappings['user'], $cm1, $this->platform));
$this->assertEquals('cmsaddress_cmsuser', $this->strategy->getJoinTableName($cm2->associationMappings['user'], $cm2, $this->platform));
}
public function testIdentifierColumnNames()
{
$cm1 = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$cm2 = $this->createClassMetadata('Doctrine\Tests\Models\CMS\CmsAddress');
$cm1->mapField(array(
'id' => true,
'fieldName' => 'id',
'columnName' => '`id`',
));
$cm2->mapField(array(
'id' => true,
'fieldName' => 'id',
'columnName' => 'id',
));
$this->assertEquals(array('"id"'), $this->strategy->getIdentifierColumnNames($cm1, $this->platform));
$this->assertEquals(array('id'), $this->strategy->getIdentifierColumnNames($cm2, $this->platform));
}
public function testColumnAlias()
{
$i = 0;
$this->assertEquals('columnName0', $this->strategy->getColumnAlias('columnName', $i++, $this->platform));
$this->assertEquals('column_name1', $this->strategy->getColumnAlias('column_name', $i++, $this->platform));
$this->assertEquals('COLUMN_NAME2', $this->strategy->getColumnAlias('COLUMN_NAME', $i++, $this->platform));
$this->assertEquals('COLUMNNAME3', $this->strategy->getColumnAlias('COLUMN-NAME-', $i++, $this->platform));
}
public function testQuoteIdentifierJoinColumns()
{
$cm = $this->createClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
$cm->mapOneToOne(array(
'id' => true,
'fieldName' => 'article',
'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
'joinColumns' => array(array(
'name' => '`article`'
)),
));
$this->assertEquals(array('"article"'), $this->strategy->getIdentifierColumnNames($cm, $this->platform));
}
public function testJoinColumnName()
{
$cm = $this->createClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
$cm->mapOneToOne(array(
'id' => true,
'fieldName' => 'article',
'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
'joinColumns' => array(array(
'name' => '`article`'
)),
));
$joinColumn = $cm->associationMappings['article']['joinColumns'][0];
$this->assertEquals('"article"',$this->strategy->getJoinColumnName($joinColumn, $cm, $this->platform));
}
public function testReferencedJoinColumnName()
{
$cm = $this->createClassMetadata('Doctrine\Tests\Models\DDC117\DDC117ArticleDetails');
$cm->mapOneToOne(array(
'id' => true,
'fieldName' => 'article',
'targetEntity' => 'Doctrine\Tests\Models\DDC117\DDC117Article',
'joinColumns' => array(array(
'name' => '`article`'
)),
));
$joinColumn = $cm->associationMappings['article']['joinColumns'][0];
$this->assertEquals('"id"',$this->strategy->getReferencedJoinColumnName($joinColumn, $cm, $this->platform));
}
}
class MyQuoteStrategy extends \Doctrine\ORM\Mapping\DefaultQuoteStrategy
{
}

View File

@ -76,4 +76,16 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('t0.customInteger = ABS(?) AND t0.child_id = ?', $sql);
}
/**
* @group DDC-1719
*/
public function testStripNonAlphanumericCharactersFromSelectColumnListSQL()
{
$persister = new BasicEntityPersister($this->_em, $this->_em->getClassMetadata('Doctrine\Tests\Models\Quote\SimpleEntity'));
$method = new \ReflectionMethod($persister, '_getSelectColumnListSQL');
$method->setAccessible(true);
$this->assertEquals('t0."simple-entity-id" AS simpleentityid1, t0."simple-entity-value" AS simpleentityvalue2', $method->invoke($persister));
}
}

View File

@ -1641,8 +1641,63 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
}
/**
* @group DDC-1719
*/
public function testStripNonAlphanumericCharactersFromAlias()
{
$this->assertSqlGeneration(
'SELECT e FROM Doctrine\Tests\Models\Quote\SimpleEntity e',
'SELECT d0_."simple-entity-id" AS simpleentityid0, d0_."simple-entity-value" AS simpleentityvalue1 FROM "ddc-1719-simple-entity" d0_'
);
$this->assertSqlGeneration(
'SELECT e.value FROM Doctrine\Tests\Models\Quote\SimpleEntity e ORDER BY e.value',
'SELECT d0_."simple-entity-value" AS simpleentityvalue0 FROM "ddc-1719-simple-entity" d0_ ORDER BY d0_."simple-entity-value" ASC'
);
$this->assertSqlGeneration(
'SELECT TRIM(e.value) FROM Doctrine\Tests\Models\Quote\SimpleEntity e ORDER BY e.value',
'SELECT TRIM(d0_."simple-entity-value") AS sclr0 FROM "ddc-1719-simple-entity" d0_ ORDER BY d0_."simple-entity-value" ASC'
);
}
/**
* @group DDC-1845
*/
public function testQuotedWalkJoinVariableDeclaration()
{
$this->assertSqlGeneration(
'SELECT u, a FROM Doctrine\Tests\Models\Quote\User u JOIN u.address a',
'SELECT q0_."user-id" AS userid0, q0_."user-name" AS username1, q1_."address-id" AS addressid2, q1_."address-zip" AS addresszip3 FROM "quote-user" q0_ INNER JOIN "quote-address" q1_ ON q0_."address-id" = q1_."address-id"'
);
$this->assertSqlGeneration(
'SELECT u, p FROM Doctrine\Tests\Models\Quote\User u JOIN u.phones p',
'SELECT q0_."user-id" AS userid0, q0_."user-name" AS username1, q1_."phone-number" AS phonenumber2 FROM "quote-user" q0_ INNER JOIN "quote-phone" q1_ ON q0_."user-id" = q1_."user-id"'
);
$this->assertSqlGeneration(
'SELECT u, g FROM Doctrine\Tests\Models\Quote\User u JOIN u.groups g',
'SELECT q0_."user-id" AS userid0, q0_."user-name" AS username1, q1_."group-id" AS groupid2, q1_."group-name" AS groupname3 FROM "quote-user" q0_ INNER JOIN "quote-users-groups" q2_ ON q0_."user-id" = q2_."user-id" INNER JOIN "quote-group" q1_ ON q1_."group-id" = q2_."group-id"'
);
$this->assertSqlGeneration(
'SELECT a, u FROM Doctrine\Tests\Models\Quote\Address a JOIN a.user u',
'SELECT q0_."address-id" AS addressid0, q0_."address-zip" AS addresszip1, q1_."user-id" AS userid2, q1_."user-name" AS username3 FROM "quote-address" q0_ INNER JOIN "quote-user" q1_ ON q0_."user-id" = q1_."user-id"'
);
$this->assertSqlGeneration(
'SELECT g, u FROM Doctrine\Tests\Models\Quote\Group g JOIN g.users u',
'SELECT q0_."group-id" AS groupid0, q0_."group-name" AS groupname1, q1_."user-id" AS userid2, q1_."user-name" AS username3 FROM "quote-group" q0_ INNER JOIN "quote-users-groups" q2_ ON q0_."group-id" = q2_."group-id" INNER JOIN "quote-user" q1_ ON q1_."user-id" = q2_."user-id"'
);
$this->assertSqlGeneration(
'SELECT g, p FROM Doctrine\Tests\Models\Quote\Group g JOIN g.parent p',
'SELECT q0_."group-id" AS groupid0, q0_."group-name" AS groupname1, q1_."group-id" AS groupid2, q1_."group-name" AS groupname3 FROM "quote-group" q0_ INNER JOIN "quote-group" q1_ ON q0_."parent-id" = q1_."group-id"'
);
}
}
class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
{