1
0
mirror of synced 2025-01-20 15:31:40 +03:00

use quote strategy in SizeFunction, MultiTableDeleteExecutor, MultiTableUpdateExecutor, and SchemaTool

This commit is contained in:
Fabio B. Silva 2012-06-04 14:26:05 -03:00
parent 851d17f940
commit 4ef3d99770
5 changed files with 125 additions and 81 deletions

View File

@ -2643,6 +2643,42 @@ class ClassMetadataInfo implements ClassMetadata
return $this->name; return $this->name;
} }
/**
* Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
*
* @param AbstractPlatform $platform
* @return array
*/
public function getQuotedIdentifierColumnNames($platform)
{
$quotedColumnNames = array();
foreach ($this->identifier as $idProperty) {
if (isset($this->fieldMappings[$idProperty])) {
$quotedColumnNames[] = isset($this->fieldMappings[$idProperty]['quoted'])
? $platform->quoteIdentifier($this->fieldMappings[$idProperty]['columnName'])
: $this->fieldMappings[$idProperty]['columnName'];
continue;
}
// Association defined as Id field
$joinColumns = $this->associationMappings[$idProperty]['joinColumns'];
$assocQuotedColumnNames = array_map(
function ($joinColumn) {
return isset($joinColumn['quoted'])
? $platform->quoteIdentifier($joinColumn['name'])
: $joinColumn['name'];
},
$joinColumns
);
$quotedColumnNames = array_merge($quotedColumnNames, $assocQuotedColumnNames);
}
return $quotedColumnNames;
}
/** /**
* Gets the (possibly quoted) column name of a mapped field for safe use * Gets the (possibly quoted) column name of a mapped field for safe use
* in an SQL statement. * in an SQL statement.

View File

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

View File

@ -50,6 +50,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
$em = $sqlWalker->getEntityManager(); $em = $sqlWalker->getEntityManager();
$conn = $em->getConnection(); $conn = $em->getConnection();
$platform = $conn->getDatabasePlatform(); $platform = $conn->getDatabasePlatform();
$quoteStrategy = $em->getQuoteStrategy();
$primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName); $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName);
$primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable;
@ -80,7 +81,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
// 3. Create and store DELETE statements // 3. Create and store DELETE statements
$classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses); $classNames = array_merge($primaryClass->parentClasses, array($primaryClass->name), $primaryClass->subClasses);
foreach (array_reverse($classNames) as $className) { foreach (array_reverse($classNames) as $className) {
$tableName = $em->getClassMetadata($className)->getQuotedTableName($platform); $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className));
$this->_sqlStatements[] = 'DELETE FROM ' . $tableName $this->_sqlStatements[] = 'DELETE FROM ' . $tableName
. ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')';
} }

View File

@ -53,9 +53,9 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
$em = $sqlWalker->getEntityManager(); $em = $sqlWalker->getEntityManager();
$conn = $em->getConnection(); $conn = $em->getConnection();
$platform = $conn->getDatabasePlatform(); $platform = $conn->getDatabasePlatform();
$quoteStrategy = $em->getQuoteStrategy();
$updateClause = $AST->updateClause; $updateClause = $AST->updateClause;
$primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName); $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName);
$rootClass = $em->getClassMetadata($primaryClass->rootEntityName); $rootClass = $em->getClassMetadata($primaryClass->rootEntityName);
@ -86,7 +86,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
foreach (array_reverse($classNames) as $className) { foreach (array_reverse($classNames) as $className) {
$affected = false; $affected = false;
$class = $em->getClassMetadata($className); $class = $em->getClassMetadata($className);
$updateSql = 'UPDATE ' . $class->getQuotedTableName($platform) . ' SET '; $updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class) . ' SET ';
foreach ($updateItems as $updateItem) { foreach ($updateItems as $updateItem) {
$field = $updateItem->pathExpression->field; $field = $updateItem->pathExpression->field;

View File

@ -47,12 +47,19 @@ class SchemaTool
/** /**
* @var \Doctrine\ORM\EntityManager * @var \Doctrine\ORM\EntityManager
*/ */
private $_em; private $em;
/** /**
* @var \Doctrine\DBAL\Platforms\AbstractPlatform * @var \Doctrine\DBAL\Platforms\AbstractPlatform
*/ */
private $_platform; private $platform;
/**
* The quote strategy.
*
* @var \Doctrine\ORM\Mapping\QuoteStrategy
*/
protected $quoteStrategy;
/** /**
* Initializes a new SchemaTool instance that uses the connection of the * Initializes a new SchemaTool instance that uses the connection of the
@ -62,8 +69,9 @@ class SchemaTool
*/ */
public function __construct(EntityManager $em) public function __construct(EntityManager $em)
{ {
$this->_em = $em; $this->em = $em;
$this->_platform = $em->getConnection()->getDatabasePlatform(); $this->quoteStrategy = $em->getQuoteStrategy();
$this->platform = $em->getConnection()->getDatabasePlatform();
} }
/** /**
@ -76,7 +84,7 @@ class SchemaTool
public function createSchema(array $classes) public function createSchema(array $classes)
{ {
$createSchemaSql = $this->getCreateSchemaSql($classes); $createSchemaSql = $this->getCreateSchemaSql($classes);
$conn = $this->_em->getConnection(); $conn = $this->em->getConnection();
foreach ($createSchemaSql as $sql) { foreach ($createSchemaSql as $sql) {
try { try {
@ -97,7 +105,7 @@ class SchemaTool
public function getCreateSchemaSql(array $classes) public function getCreateSchemaSql(array $classes)
{ {
$schema = $this->getSchemaFromMetadata($classes); $schema = $this->getSchemaFromMetadata($classes);
return $schema->toSql($this->_platform); return $schema->toSql($this->platform);
} }
/** /**
@ -124,22 +132,21 @@ class SchemaTool
*/ */
public function getSchemaFromMetadata(array $classes) 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); $metadataSchemaConfig->setExplicitForeignKeyIndexes(false);
$schema = new Schema(array(), array(), $metadataSchemaConfig); $schema = new Schema(array(), array(), $metadataSchemaConfig);
$evm = $this->_em->getEventManager();
foreach ($classes as $class) { foreach ($classes as $class) {
if ($this->processingNotRequired($class, $processedClasses)) { if ($this->processingNotRequired($class, $processedClasses)) {
continue; continue;
} }
$table = $schema->createTable($class->getQuotedTableName($this->_platform)); $table = $schema->createTable($this->quoteStrategy->getTableName($class));
$columns = array(); // table columns $columns = array(); // table columns
if ($class->isInheritanceTypeSingleTable()) { if ($class->isInheritanceTypeSingleTable()) {
@ -156,7 +163,7 @@ class SchemaTool
} }
foreach ($class->subClasses as $subClassName) { foreach ($class->subClasses as $subClassName) {
$subClass = $this->_em->getClassMetadata($subClassName); $subClass = $this->em->getClassMetadata($subClassName);
$this->_gatherColumns($subClass, $table); $this->_gatherColumns($subClass, $table);
$this->_gatherRelationsSql($subClass, $table, $schema); $this->_gatherRelationsSql($subClass, $table, $schema);
$processedClasses[$subClassName] = true; $processedClasses[$subClassName] = true;
@ -166,7 +173,7 @@ class SchemaTool
$pkColumns = array(); $pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) { foreach ($class->fieldMappings as $fieldName => $mapping) {
if ( ! isset($mapping['inherited'])) { if ( ! isset($mapping['inherited'])) {
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); $columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class);
$this->_gatherColumn($class, $mapping, $table); $this->_gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($fieldName)) { if ($class->isIdentifier($fieldName)) {
@ -185,7 +192,7 @@ class SchemaTool
/* @var \Doctrine\ORM\Mapping\ClassMetadata $class */ /* @var \Doctrine\ORM\Mapping\ClassMetadata $class */
$idMapping = $class->fieldMappings[$class->identifier[0]]; $idMapping = $class->fieldMappings[$class->identifier[0]];
$this->_gatherColumn($class, $idMapping, $table); $this->_gatherColumn($class, $idMapping, $table);
$columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform); $columnName = $this->quoteStrategy->getColumnName($class->identifier[0], $class);
// TODO: This seems rather hackish, can we optimize it? // TODO: This seems rather hackish, can we optimize it?
$table->getColumn($columnName)->setAutoincrement(false); $table->getColumn($columnName)->setAutoincrement(false);
@ -193,7 +200,7 @@ class SchemaTool
// Add a FK constraint on the ID column // Add a FK constraint on the ID column
$table->addUnnamedForeignKeyConstraint( $table->addUnnamedForeignKeyConstraint(
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform), $this->quoteStrategy->getTableName($this->em->getClassMetadata($class->rootEntityName)),
array($columnName), array($columnName), array('onDelete' => 'CASCADE') array($columnName), array($columnName), array('onDelete' => 'CASCADE')
); );
} }
@ -210,7 +217,7 @@ class SchemaTool
$pkColumns = array(); $pkColumns = array();
foreach ($class->identifier as $identifierField) { foreach ($class->identifier as $identifierField) {
if (isset($class->fieldMappings[$identifierField])) { if (isset($class->fieldMappings[$identifierField])) {
$pkColumns[] = $class->getQuotedColumnName($identifierField, $this->_platform); $pkColumns[] = $this->quoteStrategy->getColumnName($identifierField, $class);
} else if (isset($class->associationMappings[$identifierField])) { } else if (isset($class->associationMappings[$identifierField])) {
/* @var $assoc \Doctrine\ORM\Mapping\OneToOne */ /* @var $assoc \Doctrine\ORM\Mapping\OneToOne */
$assoc = $class->associationMappings[$identifierField]; $assoc = $class->associationMappings[$identifierField];
@ -255,17 +262,17 @@ class SchemaTool
} }
} }
if ($evm->hasListeners(ToolEvents::postGenerateSchemaTable)) { if ($eventManager->hasListeners(ToolEvents::postGenerateSchemaTable)) {
$evm->dispatchEvent(ToolEvents::postGenerateSchemaTable, new GenerateSchemaTableEventArgs($class, $schema, $table)); $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()); $schema->visit(new RemoveNamespacedAssets());
} }
if ($evm->hasListeners(ToolEvents::postGenerateSchema)) { if ($eventManager->hasListeners(ToolEvents::postGenerateSchema)) {
$evm->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->_em, $schema)); $eventManager->dispatchEvent(ToolEvents::postGenerateSchema, new GenerateSchemaEventArgs($this->em, $schema));
} }
return $schema; return $schema;
@ -321,7 +328,7 @@ class SchemaTool
$column = $this->_gatherColumn($class, $mapping, $table); $column = $this->_gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($mapping['fieldName'])) { if ($class->isIdentifier($mapping['fieldName'])) {
$pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); $pkColumns[] = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class);
} }
} }
@ -344,7 +351,7 @@ class SchemaTool
*/ */
private function _gatherColumn($class, array $mapping, $table) private function _gatherColumn($class, array $mapping, $table)
{ {
$columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); $columnName = $this->quoteStrategy->getColumnName($mapping['fieldName'], $class);
$columnType = $mapping['type']; $columnType = $mapping['type'];
$options = array(); $options = array();
@ -417,7 +424,7 @@ class SchemaTool
continue; continue;
} }
$foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']); $foreignClass = $this->em->getClassMetadata($mapping['targetEntity']);
if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) { if ($mapping['type'] & ClassMetadata::TO_ONE && $mapping['isOwningSide']) {
$primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type $primaryKeyColumns = $uniqueConstraints = array(); // PK is unnecessary for this relation-type
@ -434,7 +441,7 @@ class SchemaTool
// create join table // create join table
$joinTable = $mapping['joinTable']; $joinTable = $mapping['joinTable'];
$theJoinTable = $schema->createTable($foreignClass->getQuotedJoinTableName($mapping, $this->_platform)); $theJoinTable = $schema->createTable($this->quoteStrategy->getJoinTableName($mapping, $foreignClass));
$primaryKeyColumns = $uniqueConstraints = array(); $primaryKeyColumns = $uniqueConstraints = array();
@ -477,7 +484,7 @@ class SchemaTool
foreach ($class->getIdentifierFieldNames() as $fieldName) { foreach ($class->getIdentifierFieldNames() as $fieldName) {
if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) { if ($class->hasAssociation($fieldName) && $class->getSingleAssociationJoinColumnName($fieldName) == $referencedColumnName) {
return $this->getDefiningClass( return $this->getDefiningClass(
$this->_em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']), $this->em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']),
$class->getSingleAssociationReferencedJoinColumnName($fieldName) $class->getSingleAssociationReferencedJoinColumnName($fieldName)
); );
} }
@ -502,7 +509,7 @@ class SchemaTool
$localColumns = array(); $localColumns = array();
$foreignColumns = array(); $foreignColumns = array();
$fkOptions = array(); $fkOptions = array();
$foreignTableName = $class->getQuotedTableName($this->_platform); $foreignTableName = $this->quoteStrategy->getTableName($class);
foreach ($joinColumns as $joinColumn) { foreach ($joinColumns as $joinColumn) {
$columnName = $joinColumn['name']; $columnName = $joinColumn['name'];
@ -572,7 +579,7 @@ class SchemaTool
public function dropSchema(array $classes) public function dropSchema(array $classes)
{ {
$dropSchemaSql = $this->getDropSchemaSQL($classes); $dropSchemaSql = $this->getDropSchemaSQL($classes);
$conn = $this->_em->getConnection(); $conn = $this->em->getConnection();
foreach ($dropSchemaSql as $sql) { foreach ($dropSchemaSql as $sql) {
try { try {
@ -591,7 +598,7 @@ class SchemaTool
public function dropDatabase() public function dropDatabase()
{ {
$dropSchemaSql = $this->getDropDatabaseSQL(); $dropSchemaSql = $this->getDropDatabaseSQL();
$conn = $this->_em->getConnection(); $conn = $this->em->getConnection();
foreach ($dropSchemaSql as $sql) { foreach ($dropSchemaSql as $sql) {
$conn->executeQuery($sql); $conn->executeQuery($sql);
@ -605,10 +612,10 @@ class SchemaTool
*/ */
public function getDropDatabaseSQL() public function getDropDatabaseSQL()
{ {
$sm = $this->_em->getConnection()->getSchemaManager(); $sm = $this->em->getConnection()->getSchemaManager();
$schema = $sm->createSchema(); $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 */ /* @var $schema \Doctrine\DBAL\Schema\Schema */
$schema->visit($visitor); $schema->visit($visitor);
return $visitor->getQueries(); return $visitor->getQueries();
@ -622,10 +629,10 @@ class SchemaTool
*/ */
public function getDropSchemaSQL(array $classes) 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); $schema = $this->getSchemaFromMetadata($classes);
$sm = $this->_em->getConnection()->getSchemaManager(); $sm = $this->em->getConnection()->getSchemaManager();
$fullSchema = $sm->createSchema(); $fullSchema = $sm->createSchema();
foreach ($fullSchema->getTables() as $table) { foreach ($fullSchema->getTables() as $table) {
if (!$schema->hasTable($table->getName())) { if (!$schema->hasTable($table->getName())) {
@ -643,7 +650,7 @@ class SchemaTool
} }
} }
if ($this->_platform->supportsSequences()) { if ($this->platform->supportsSequences()) {
foreach ($schema->getSequences() as $sequence) { foreach ($schema->getSequences() as $sequence) {
$visitor->acceptSequence($sequence); $visitor->acceptSequence($sequence);
} }
@ -676,7 +683,7 @@ class SchemaTool
public function updateSchema(array $classes, $saveMode=false) public function updateSchema(array $classes, $saveMode=false)
{ {
$updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode); $updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode);
$conn = $this->_em->getConnection(); $conn = $this->em->getConnection();
foreach ($updateSchemaSql as $sql) { foreach ($updateSchemaSql as $sql) {
$conn->executeQuery($sql); $conn->executeQuery($sql);
@ -695,7 +702,7 @@ class SchemaTool
*/ */
public function getUpdateSchemaSql(array $classes, $saveMode=false) public function getUpdateSchemaSql(array $classes, $saveMode=false)
{ {
$sm = $this->_em->getConnection()->getSchemaManager(); $sm = $this->em->getConnection()->getSchemaManager();
$fromSchema = $sm->createSchema(); $fromSchema = $sm->createSchema();
$toSchema = $this->getSchemaFromMetadata($classes); $toSchema = $this->getSchemaFromMetadata($classes);
@ -704,9 +711,9 @@ class SchemaTool
$schemaDiff = $comparator->compare($fromSchema, $toSchema); $schemaDiff = $comparator->compare($fromSchema, $toSchema);
if ($saveMode) { if ($saveMode) {
return $schemaDiff->toSaveSql($this->_platform); return $schemaDiff->toSaveSql($this->platform);
} else { } else {
return $schemaDiff->toSql($this->_platform); return $schemaDiff->toSql($this->platform);
} }
} }
} }