diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 641ff405058..a0091788662 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -2349,25 +2349,31 @@ public function getCheckDeclarationSQL(array $definition) * Obtains DBMS specific SQL code portion needed to set a unique * constraint declaration to be used in statements like CREATE TABLE. * - * @param string $name The name of the unique constraint. - * @param \Doctrine\DBAL\Schema\Index $index The index definition. + * @param string $name The name of the unique constraint. + * @param \Doctrine\DBAL\Schema\UniqueConstraint $constraint The unique constraint definition. * * @return string DBMS specific SQL code portion needed to set a constraint. * * @throws \InvalidArgumentException */ - public function getUniqueConstraintDeclarationSQL($name, Index $index) + public function getUniqueConstraintDeclarationSQL($name, UniqueConstraint $constraint) { - $columns = $index->getQuotedColumns($this); - $name = new Identifier($name); + $columns = $constraint->getQuotedColumns($this); + $name = new Identifier($name); if (count($columns) === 0) { throw new \InvalidArgumentException("Incomplete definition. 'columns' required."); } - return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE (' + $flags = ''; + + if ($constraint->hasFlag('clustered')) { + $flags = 'CLUSTERED '; + } + + return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($columns) - . ')' . $this->getPartialIndexSQL($index); + . ')'; } /** diff --git a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php b/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php index 86e3ea070ec..0c6de1def8a 100644 --- a/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php @@ -199,8 +199,8 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options $queryFields = $this->getColumnDeclarationListSQL($columns); if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { - foreach ($options['uniqueConstraints'] as $index => $definition) { - $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + foreach ($options['uniqueConstraints'] as $name => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); } } diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 3dda34086e3..da532b24c84 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -414,8 +414,8 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options $queryFields = $this->getColumnDeclarationListSQL($columns); if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { - foreach ($options['uniqueConstraints'] as $index => $definition) { - $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + foreach ($options['uniqueConstraints'] as $name => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); } } diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 7e05af1b1e5..bb2e1a9e572 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -384,11 +384,11 @@ public function getListSequencesSQL($database) /** * {@inheritDoc} */ - protected function _getCreateTableSQL($table, array $columns, array $options = []) + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) { $indexes = isset($options['indexes']) ? $options['indexes'] : []; $options['indexes'] = []; - $sql = parent::_getCreateTableSQL($table, $columns, $options); + $sql = parent::_getCreateTableSQL($tableName, $columns, $options); foreach ($columns as $name => $column) { if (isset($column['sequence'])) { @@ -397,13 +397,13 @@ protected function _getCreateTableSQL($table, array $columns, array $options = [ if (isset($column['autoincrement']) && $column['autoincrement'] || (isset($column['autoinc']) && $column['autoinc'])) { - $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table)); + $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $tableName)); } } if (isset($indexes) && ! empty($indexes)) { foreach ($indexes as $index) { - $sql[] = $this->getCreateIndexSQL($index, $table); + $sql[] = $this->getCreateIndexSQL($index, $tableName); } } diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php index 9d6f152b446..6bf62ae443b 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -1140,27 +1140,6 @@ public function getTruncateTableSQL($tableName, $cascade = false) return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); } - /** - * {@inheritdoc} - */ - public function getUniqueConstraintDeclarationSQL($name, Index $index) - { - if ($index->isPrimary()) { - throw new \InvalidArgumentException( - 'Cannot create primary key constraint declarations with getUniqueConstraintDeclarationSQL().' - ); - } - - if ( ! $index->isUnique()) { - throw new \InvalidArgumentException( - 'Can only create unique constraint declarations, no common index declarations with ' . - 'getUniqueConstraintDeclarationSQL().' - ); - } - - return $this->getTableConstraintDeclarationSQL($index, $name); - } - /** * {@inheritdoc} */ diff --git a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php index 3a5a21076a9..03b01ea5a05 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -365,18 +365,6 @@ public function getDefaultConstraintDeclarationSQL($table, array $column) ' FOR ' . $columnName->getQuotedName($this); } - /** - * {@inheritDoc} - */ - public function getUniqueConstraintDeclarationSQL($name, Index $index) - { - $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index); - - $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); - - return $constraint; - } - /** * {@inheritDoc} */ diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index e8d88ad792a..f95486f69f6 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -316,9 +316,9 @@ public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) /** * {@inheritDoc} */ - protected function _getCreateTableSQL($name, array $columns, array $options = []) + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) { - $name = str_replace('.', '__', $name); + $tableName = str_replace('.', '__', $tableName); $queryFields = $this->getColumnDeclarationListSQL($columns); if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { @@ -338,7 +338,7 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] } } - $query[] = 'CREATE TABLE ' . $name . ' (' . $queryFields . ')'; + $query[] = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')'; if (isset($options['alter']) && true === $options['alter']) { return $query; @@ -346,13 +346,13 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] if (isset($options['indexes']) && ! empty($options['indexes'])) { foreach ($options['indexes'] as $indexDef) { - $query[] = $this->getCreateIndexSQL($indexDef, $name); + $query[] = $this->getCreateIndexSQL($indexDef, $tableName); } } if (isset($options['unique']) && ! empty($options['unique'])) { foreach ($options['unique'] as $indexDef) { - $query[] = $this->getCreateIndexSQL($indexDef, $name); + $query[] = $this->getCreateIndexSQL($indexDef, $tableName); } } @@ -364,8 +364,10 @@ protected function _getCreateTableSQL($name, array $columns, array $options = [] */ protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) { - return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') - : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); + return $fixed + ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT') + ; } /** diff --git a/lib/Doctrine/DBAL/Schema/Table.php b/lib/Doctrine/DBAL/Schema/Table.php index 20eae2270d2..c62a74de614 100644 --- a/lib/Doctrine/DBAL/Schema/Table.php +++ b/lib/Doctrine/DBAL/Schema/Table.php @@ -156,11 +156,12 @@ public function setPrimaryKey(array $columns, $indexName = false) /** * @param array $columnNames * @param string|null $indexName + * @param array $flags * @param array $options * * @return self */ - public function addUniqueConstraint(array $columnNames, $indexName = null, array $options = []) + public function addUniqueConstraint(array $columnNames, $indexName = null, array $flags = array(), array $options = []) { if ($indexName == null) { $indexName = $this->_generateIdentifierName( @@ -168,7 +169,7 @@ public function addUniqueConstraint(array $columnNames, $indexName = null, array ); } - return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $options)); + return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $flags, $options)); } /** @@ -901,11 +902,11 @@ protected function _addIndex(Index $indexCandidate) } /** - * @param UniqueConstraint $uniqueConstraint + * @param UniqueConstraint $constraint * * @return self */ - protected function _addUniqueConstraint(UniqueConstraint $uniqueConstraint) + protected function _addUniqueConstraint(UniqueConstraint $constraint) { $name = strlen($uniqueConstraint->getName()) ? $uniqueConstraint->getName() @@ -916,7 +917,7 @@ protected function _addUniqueConstraint(UniqueConstraint $uniqueConstraint) $name = $this->normalizeIdentifier($name); - $this->_uniqueConstraints[$name] = $uniqueConstraint; + $this->_uniqueConstraints[$name] = $constraint; // If there is already an index that fulfills this requirements drop the request. In the case of __construct // calling this method during hydration from schema-details all the explicitly added indexes lead to duplicates. @@ -997,13 +998,14 @@ private function normalizeIdentifier($identifier) /** * @param array $columnNames * @param string $indexName + * @param array $flags * @param array $options * * @return UniqueConstraint * * @throws SchemaException */ - private function _createUniqueConstraint(array $columnNames, $indexName, array $options = []) + private function _createUniqueConstraint(array $columnNames, $indexName, array $flags = array(), array $options = []) { if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) { throw SchemaException::indexNameInvalid($indexName); @@ -1019,7 +1021,7 @@ private function _createUniqueConstraint(array $columnNames, $indexName, array $ } } - return new UniqueConstraint($indexName, $columnNames, $options); + return new UniqueConstraint($indexName, $columnNames, $flags, $options); } /** diff --git a/lib/Doctrine/DBAL/Schema/UniqueConstraint.php b/lib/Doctrine/DBAL/Schema/UniqueConstraint.php index e35939948f2..e185bcd48f9 100644 --- a/lib/Doctrine/DBAL/Schema/UniqueConstraint.php +++ b/lib/Doctrine/DBAL/Schema/UniqueConstraint.php @@ -38,6 +38,14 @@ class UniqueConstraint extends AbstractAsset implements Constraint */ protected $columns = array(); + /** + * Platform specific flags + * array($flagName => true) + * + * @var array + */ + protected $flags = array(); + /** * Platform specific options * @@ -48,9 +56,10 @@ class UniqueConstraint extends AbstractAsset implements Constraint /** * @param string $indexName * @param string[] $columns + * @param array $flags * @param array $options */ - public function __construct($indexName, array $columns, array $options = array()) + public function __construct($indexName, array $columns, array $flags = array(), array $options = array()) { $this->_setName($indexName); @@ -59,6 +68,10 @@ public function __construct($indexName, array $columns, array $options = array() foreach ($columns as $column) { $this->_addColumn($column); } + + foreach ($flags as $flag) { + $this->addFlag($flag); + } } /** @@ -107,6 +120,56 @@ public function getUnquotedColumns() return array_map(array($this, 'trimQuotes'), $this->getColumns()); } + /** + * Returns platform specific flags for unique constraint. + * + * @return string[] + */ + public function getFlags() + { + return array_keys($this->flags); + } + + /** + * Adds flag for a unique constraint that translates to platform specific handling. + * + * @example $uniqueConstraint->addFlag('CLUSTERED') + * + * @param string $flag + * + * @return self + */ + public function addFlag($flag) + { + $this->flags[strtolower($flag)] = true; + + return $this; + } + + /** + * Does this unique constraint have a specific flag? + * + * @param string $flag + * + * @return boolean + */ + public function hasFlag($flag) + { + return isset($this->flags[strtolower($flag)]); + } + + /** + * Removes a flag. + * + * @param string $flag + * + * @return void + */ + public function removeFlag($flag) + { + unset($this->flags[strtolower($flag)]); + } + /** * @param string $name *