From 9ad13c473068c70a59612225b73c5bd9f5e0dac0 Mon Sep 17 00:00:00 2001 From: guilhermeblanco Date: Wed, 6 Jan 2010 13:23:56 +0000 Subject: [PATCH] [2.0][DDC-236] Enhanced unique constraints to support names. Fixed general issues on XML and YAML exporters. Fixed issues on XML, YAML, Doctrine 1.X and Annotation drivers. --- .../DBAL/Platforms/AbstractPlatform.php | 38 ++++++++++++++----- lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 4 +- lib/Doctrine/DBAL/Schema/Table.php | 8 ++-- .../ORM/Mapping/Driver/AnnotationDriver.php | 8 +++- lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php | 6 ++- .../ORM/Mapping/Driver/YamlDriver.php | 15 ++++++-- .../ORM/Tools/ConvertDoctrine1Schema.php | 9 ++--- .../ORM/Tools/Export/Driver/XmlExporter.php | 9 +++-- .../ORM/Tools/Export/Driver/YamlExporter.php | 4 +- lib/Doctrine/ORM/Tools/SchemaTool.php | 13 ++++--- .../ORM/Tools/ConvertDoctrine1SchemaTest.php | 2 +- 11 files changed, 76 insertions(+), 40 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index ef30a2601..58632c4c1 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -617,8 +617,8 @@ abstract class AbstractPlatform $columnListSql = $this->getColumnDeclarationListSql($columns); if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { - foreach ($options['uniqueConstraints'] as $uniqueConstraint) { - $columnListSql .= ', UNIQUE(' . implode(', ', array_values($uniqueConstraint)) . ')'; + foreach ($options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSql($name, $definition); } } @@ -1035,32 +1035,50 @@ abstract class AbstractPlatform return implode(', ', $constraints); } + + /** + * Obtain DBMS specific SQL code portion needed to set a unique + * constraint declaration to be used in statements like CREATE TABLE. + * + * @param string $name name of the unique constraint + * @param Index $index index definition + * @return string DBMS specific SQL code portion needed + * to set a constraint + */ + public function getUniqueConstraintDeclarationSql($name, Index $index) + { + if (count($index->getColumns()) == 0) { + throw \InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return 'CONSTRAINT' . $name . ' UNIQUE (' + . $this->getIndexFieldDeclarationListSql($index->getColumns()) + . ')'; + } /** * Obtain DBMS specific SQL code portion needed to set an index * declaration to be used in statements like CREATE TABLE. * * @param string $name name of the index - * @param Index $index index definition + * @param Index $index index definition * @return string DBMS specific SQL code portion needed to set an index */ public function getIndexDeclarationSql($name, Index $index) { - $type = ''; + $type = ''; if($index->isUnique()) { - $type = "UNIQUE"; + $type = 'UNIQUE '; } if (count($index->getColumns()) == 0) { throw \InvalidArgumentException("Incomplete definition. 'columns' required."); } - $query = $type . ' INDEX ' . $name; - - $query .= ' (' . $this->getIndexFieldDeclarationListSql($index->getColumns()) . ')'; - - return $query; + return $type . 'INDEX ' . $name . ' (' + . $this->getIndexFieldDeclarationListSql($index->getColumns()) + . ')'; } /** diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index d95ecac02..a54e51440 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -446,8 +446,8 @@ class MySqlPlatform extends AbstractPlatform $queryFields = $this->getColumnDeclarationListSql($columns); if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { - foreach ($options['uniqueConstraints'] as $uniqueConstraint) { - $queryFields .= ', UNIQUE(' . implode(', ', array_values($uniqueConstraint)) . ')'; + foreach ($options['uniqueConstraints'] as $index => $definition) { + $queryFields .= ', ' . $this->getUniqueIndexDeclarationSql($index, $definition); } } diff --git a/lib/Doctrine/DBAL/Schema/Table.php b/lib/Doctrine/DBAL/Schema/Table.php index b71867814..eff785a2a 100644 --- a/lib/Doctrine/DBAL/Schema/Table.php +++ b/lib/Doctrine/DBAL/Schema/Table.php @@ -146,9 +146,9 @@ class Table extends AbstractAsset * @param string $indexName * @return Table */ - public function setPrimaryKey(array $columns, $indexName=false) + public function setPrimaryKey(array $columns, $indexName = false) { - return $this->_createIndex($columns, $indexName?:"primary", true, true); + return $this->_createIndex($columns, $indexName ?: "primary", true, true); } /** @@ -166,7 +166,7 @@ class Table extends AbstractAsset * @param string $indexName * @return Table */ - public function addIndex(array $columnNames, $indexName=null) + public function addIndex(array $columnNames, $indexName = null) { if($indexName == null) { $indexName = $this->_generateIdentifierName( @@ -183,7 +183,7 @@ class Table extends AbstractAsset * @param string $indexName * @return Table */ - public function addUniqueIndex(array $columnNames, $indexName=null) + public function addUniqueIndex(array $columnNames, $indexName = null) { if ($indexName == null) { $indexName = $this->_generateIdentifierName( diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index ff4729ec7..249ffa2f0 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -92,13 +92,17 @@ class AnnotationDriver implements Driver if ($tableAnnot->indexes !== null) { foreach ($tableAnnot->indexes as $indexAnnot) { - $primaryTable['indexes'][$indexAnnot->name] = array('columns' => $indexAnnot->columns); + $primaryTable['indexes'][$indexAnnot->name] = array( + 'columns' => $indexAnnot->columns + ); } } if ($tableAnnot->uniqueConstraints !== null) { foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) { - $primaryTable['uniqueConstraints'][] = $uniqueConstraint->columns; + $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array( + 'columns' => $uniqueConstraint->columns + ); } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php index 88f96cf76..df340d838 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php @@ -101,6 +101,7 @@ class XmlDriver extends AbstractFileDriver } else { $columns = $index['columns']; } + $metadata->primaryTable['indexes'][$index['name']] = array( 'columns' => $columns ); @@ -115,7 +116,10 @@ class XmlDriver extends AbstractFileDriver } else { $columns = $unique['columns']; } - $metadata->primaryTable['uniqueConstraints'][] = $columns; + + $metadata->primaryTable['uniqueConstraints'][$unique['name']] = array( + 'columns' => $columns + ); } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php index d9b12f172..6ae95dd12 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php @@ -101,11 +101,13 @@ class YamlDriver extends AbstractFileDriver if ( ! isset($index['name'])) { $index['name'] = $name; } + if (is_string($index['columns'])) { $columns = explode(',', $index['columns']); } else { $columns = $index['columns']; } + $metadata->primaryTable['indexes'][$index['name']] = array( 'columns' => $columns ); @@ -114,13 +116,20 @@ class YamlDriver extends AbstractFileDriver // Evaluate uniqueConstraints if (isset($element['uniqueConstraints'])) { - foreach ($element['uniqueConstraints'] as $unique) { - if (is_string($index['columns'])) { + foreach ($element['uniqueConstraints'] as $name => $unique) { + if ( ! isset($unique['name'])) { + $unique['name'] = $name; + } + + if (is_string($unique['columns'])) { $columns = explode(',', $unique['columns']); } else { $columns = $unique['columns']; } - $metadata->primaryTable['uniqueConstraints'][] = $columns; + + $metadata->primaryTable['uniqueConstraints'][$unique['name']] = array( + 'columns' => $columns + ); } } diff --git a/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php b/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php index 83bb5d8f8..4487d8905 100644 --- a/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php +++ b/lib/Doctrine/ORM/Tools/ConvertDoctrine1Schema.php @@ -213,13 +213,12 @@ class ConvertDoctrine1Schema { if (isset($model['indexes']) && $model['indexes']) { foreach ($model['indexes'] as $name => $index) { - $metadata->primaryTable['indexes'][$name] = array( + $type = (isset($index['type']) && $index['type'] == 'unique') + ? 'uniqueConstraints' : 'indexes'; + + $metadata->primaryTable[$type][$name] = array( 'columns' => $index['fields'] ); - - if (isset($index['type']) && $index['type'] == 'unique') { - $metadata->primaryTable['uniqueConstraints'][] = $index['fields']; - } } } } diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php index 29464a4f8..62263d772 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/XmlExporter.php @@ -99,8 +99,9 @@ class XmlExporter extends AbstractExporter if (isset($metadata->primaryTable['indexes'])) { $indexesXml = $root->addChild('indexes'); + foreach ($metadata->primaryTable['indexes'] as $name => $index) { - $indexXml = $root->addChild('index'); + $indexXml = $indexesXml->addChild('index'); $indexXml->addAttribute('name', $name); $indexXml->addAttribute('columns', implode(',', $index['columns'])); } @@ -108,9 +109,11 @@ class XmlExporter extends AbstractExporter if (isset($metadata->primaryTable['uniqueConstraints'])) { $uniqueConstraintsXml = $root->addChild('unique-constraints'); - foreach ($metadata->primaryTable['uniqueConstraints'] as $uniqueConstraint) { + + foreach ($metadata->primaryTable['uniqueConstraints'] as $unique) { $uniqueConstraintXml = $uniqueConstraintsXml->addChild('unique-constraint'); - $uniqueConstraintXml->addAttribute('columns', $uniqueConstraint['columns']); + $uniqueConstraintXml->addAttribute('name', $name); + $uniqueConstraintXml->addAttribute('columns', implode(',', $unique['columns'])); } } diff --git a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php index 78b6eeffe..b64982dff 100644 --- a/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php +++ b/lib/Doctrine/ORM/Tools/Export/Driver/YamlExporter.php @@ -92,9 +92,7 @@ class YamlExporter extends AbstractExporter } if (isset($metadata->primaryTable['uniqueConstraints'])) { - foreach ($metadata->primaryTable['uniqueConstraints'] as $uniqueConstraint) { - $array['uniqueConstraints'][]['columns'] = $uniqueConstraint; - } + $array['uniqueConstraints'] = $metadata->primaryTable['uniqueConstraints']; } $fieldMappings = $metadata->fieldMappings; diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index ea9421b5e..f3f1aeb30 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -201,7 +201,7 @@ class SchemaTool if (isset($class->primaryTable['uniqueConstraints'])) { foreach ($class->primaryTable['uniqueConstraints'] AS $indexName => $indexData) { - $table->addUniqueIndex($indexData, $indexName); + $table->addUniqueIndex($indexData['columns'], $indexName); } } @@ -354,8 +354,7 @@ class SchemaTool $theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform)); - $primaryKeyColumns = array(); - $uniqueConstraints = array(); + $primaryKeyColumns = $uniqueConstraints = array(); // Build first FK constraint (relation table => source table) $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints); @@ -363,8 +362,10 @@ class SchemaTool // Build second FK constraint (relation table => target table) $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); - foreach($uniqueConstraints AS $unique) { - $theJoinTable->addUniqueIndex($unique); + foreach($uniqueConstraints AS $indexName => $unique) { + $theJoinTable->addUniqueIndex( + $unique['columns'], is_numeric($indexName) ? null : $indexName + ); } $theJoinTable->setPrimaryKey($primaryKeyColumns); @@ -413,7 +414,7 @@ class SchemaTool } if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) { - $uniqueConstraints[] = array($columnName); + $uniqueConstraints[] = array('columns' => $columnName); } if (isset($joinColumn['onUpdate'])) { diff --git a/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php b/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php index 614d395f8..508b1096c 100644 --- a/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php +++ b/tests/Doctrine/Tests/ORM/Tools/ConvertDoctrine1SchemaTest.php @@ -65,7 +65,7 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('Profile', $metadatas['Profile']->associationMappings['User']->sourceEntityName); $this->assertEquals('User', $metadatas['Profile']->associationMappings['User']->targetEntityName); - $this->assertEquals('username', $metadatas['User']->primaryTable['indexes']['username']['columns'][0]); + $this->assertEquals('username', $metadatas['User']->primaryTable['uniqueConstraints']['username']['columns'][0]); unlink(__DIR__ . '/convert/User.dcm.yml'); unlink(__DIR__ . '/convert/Profile.dcm.yml');