Unverified Commit fe067f20 authored by Guilherme Blanco's avatar Guilherme Blanco Committed by Sergei Morozov

Added flag support to unique constraint

parent 36522aa4
...@@ -2372,24 +2372,30 @@ abstract class AbstractPlatform ...@@ -2372,24 +2372,30 @@ abstract class AbstractPlatform
* constraint declaration to be used in statements like CREATE TABLE. * constraint declaration to be used in statements like CREATE TABLE.
* *
* @param string $name The name of the unique constraint. * @param string $name The name of the unique constraint.
* @param Index $index The index definition. * @param UniqueConstraint $constraint The unique constraint definition.
* *
* @return string DBMS specific SQL code portion needed to set a constraint. * @return string DBMS specific SQL code portion needed to set a constraint.
* *
* @throws InvalidArgumentException * @throws InvalidArgumentException
*/ */
public function getUniqueConstraintDeclarationSQL($name, Index $index) public function getUniqueConstraintDeclarationSQL($name, UniqueConstraint $constraint)
{ {
$columns = $index->getColumns(); $columns = $constraint->getColumns();
$name = new Identifier($name); $name = new Identifier($name);
if (count($columns) === 0) { if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required."); 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($index) . $this->getIndexFieldDeclarationListSQL($index)
. ')' . $this->getPartialIndexSQL($index); . ')';
} }
/** /**
......
...@@ -191,8 +191,8 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -191,8 +191,8 @@ class DrizzlePlatform extends AbstractPlatform
$queryFields = $this->getColumnDeclarationListSQL($columns); $queryFields = $this->getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $index => $definition) { foreach ($options['uniqueConstraints'] as $name => $definition) {
$queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
} }
} }
......
...@@ -418,8 +418,8 @@ SQL ...@@ -418,8 +418,8 @@ SQL
$queryFields = $this->getColumnDeclarationListSQL($columns); $queryFields = $this->getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
foreach ($options['uniqueConstraints'] as $index => $definition) { foreach ($options['uniqueConstraints'] as $name => $definition) {
$queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition);
} }
} }
......
...@@ -376,11 +376,11 @@ class OraclePlatform extends AbstractPlatform ...@@ -376,11 +376,11 @@ class OraclePlatform extends AbstractPlatform
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
protected function _getCreateTableSQL($table, array $columns, array $options = []) protected function _getCreateTableSQL($tableName, array $columns, array $options = [])
{ {
$indexes = $options['indexes'] ?? []; $indexes = $options['indexes'] ?? [];
$options['indexes'] = []; $options['indexes'] = [];
$sql = parent::_getCreateTableSQL($table, $columns, $options); $sql = parent::_getCreateTableSQL($tableName, $columns, $options);
foreach ($columns as $name => $column) { foreach ($columns as $name => $column) {
if (isset($column['sequence'])) { if (isset($column['sequence'])) {
...@@ -392,12 +392,12 @@ class OraclePlatform extends AbstractPlatform ...@@ -392,12 +392,12 @@ class OraclePlatform extends AbstractPlatform
continue; continue;
} }
$sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table)); $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $tableName));
} }
if (isset($indexes) && ! empty($indexes)) { if (isset($indexes) && ! empty($indexes)) {
foreach ($indexes as $index) { foreach ($indexes as $index) {
$sql[] = $this->getCreateIndexSQL($index, $table); $sql[] = $this->getCreateIndexSQL($index, $tableName);
} }
} }
......
...@@ -1160,27 +1160,6 @@ SQL ...@@ -1160,27 +1160,6 @@ SQL
return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); 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} * {@inheritdoc}
*/ */
......
...@@ -397,18 +397,6 @@ SQL ...@@ -397,18 +397,6 @@ SQL
' FOR ' . $columnName->getQuotedName($this); ' FOR ' . $columnName->getQuotedName($this);
} }
/**
* {@inheritDoc}
*/
public function getUniqueConstraintDeclarationSQL($name, Index $index)
{
$constraint = parent::getUniqueConstraintDeclarationSQL($name, $index);
$constraint = $this->_appendUniqueConstraintDefinition($constraint, $index);
return $constraint;
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
......
...@@ -314,9 +314,9 @@ class SqlitePlatform extends AbstractPlatform ...@@ -314,9 +314,9 @@ class SqlitePlatform extends AbstractPlatform
/** /**
* {@inheritDoc} * {@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); $queryFields = $this->getColumnDeclarationListSQL($columns);
if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) {
...@@ -340,7 +340,7 @@ class SqlitePlatform extends AbstractPlatform ...@@ -340,7 +340,7 @@ class SqlitePlatform extends AbstractPlatform
$tableComment = $this->getInlineTableCommentSQL($comment); $tableComment = $this->getInlineTableCommentSQL($comment);
} }
$query = ['CREATE TABLE ' . $name . ' ' . $tableComment . '(' . $queryFields . ')']; $query = ['CREATE TABLE ' . $tableName . ' ' . $tableComment . '(' . $queryFields . ')'];
if (isset($options['alter']) && $options['alter'] === true) { if (isset($options['alter']) && $options['alter'] === true) {
return $query; return $query;
...@@ -348,13 +348,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -348,13 +348,13 @@ class SqlitePlatform extends AbstractPlatform
if (isset($options['indexes']) && ! empty($options['indexes'])) { if (isset($options['indexes']) && ! empty($options['indexes'])) {
foreach ($options['indexes'] as $indexDef) { foreach ($options['indexes'] as $indexDef) {
$query[] = $this->getCreateIndexSQL($indexDef, $name); $query[] = $this->getCreateIndexSQL($indexDef, $tableName);
} }
} }
if (isset($options['unique']) && ! empty($options['unique'])) { if (isset($options['unique']) && ! empty($options['unique'])) {
foreach ($options['unique'] as $indexDef) { foreach ($options['unique'] as $indexDef) {
$query[] = $this->getCreateIndexSQL($indexDef, $name); $query[] = $this->getCreateIndexSQL($indexDef, $tableName);
} }
} }
...@@ -389,8 +389,10 @@ class SqlitePlatform extends AbstractPlatform ...@@ -389,8 +389,10 @@ class SqlitePlatform extends AbstractPlatform
*/ */
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{ {
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') return $fixed
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT')
;
} }
/** /**
......
...@@ -123,11 +123,12 @@ class Table extends AbstractAsset ...@@ -123,11 +123,12 @@ class Table extends AbstractAsset
/** /**
* @param mixed[] $columnNames * @param mixed[] $columnNames
* @param string|null $indexName * @param string|null $indexName
* @param array $flags
* @param mixed[] $options * @param mixed[] $options
* *
* @return self * @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) { if ($indexName === null) {
$indexName = $this->_generateIdentifierName( $indexName = $this->_generateIdentifierName(
...@@ -137,7 +138,7 @@ class Table extends AbstractAsset ...@@ -137,7 +138,7 @@ class Table extends AbstractAsset
); );
} }
return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $options)); return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $flags, $options));
} }
/** /**
...@@ -866,7 +867,7 @@ class Table extends AbstractAsset ...@@ -866,7 +867,7 @@ class Table extends AbstractAsset
/** /**
* @return self * @return self
*/ */
protected function _addUniqueConstraint(UniqueConstraint $uniqueConstraint) protected function _addUniqueConstraint(UniqueConstraint $constraint)
{ {
$name = strlen($uniqueConstraint->getName()) $name = strlen($uniqueConstraint->getName())
? $uniqueConstraint->getName() ? $uniqueConstraint->getName()
...@@ -878,7 +879,7 @@ class Table extends AbstractAsset ...@@ -878,7 +879,7 @@ class Table extends AbstractAsset
$name = $this->normalizeIdentifier($name); $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 // 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. // calling this method during hydration from schema-details all the explicitly added indexes lead to duplicates.
...@@ -979,13 +980,14 @@ class Table extends AbstractAsset ...@@ -979,13 +980,14 @@ class Table extends AbstractAsset
/** /**
* @param mixed[] $columns * @param mixed[] $columns
* @param string $indexName * @param string $indexName
* @param mixed[] $options * @param mixed[] $flags
* @param array $options
* *
* @return UniqueConstraint * @return UniqueConstraint
* *
* @throws SchemaException * @throws SchemaException
*/ */
private function _createUniqueConstraint(array $columns, $indexName, array $options = []) private function _createUniqueConstraint(array $columns, $indexName, array $flags = array(), array $options = [])
{ {
if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) { if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
throw SchemaException::indexNameInvalid($indexName); throw SchemaException::indexNameInvalid($indexName);
...@@ -1003,7 +1005,7 @@ class Table extends AbstractAsset ...@@ -1003,7 +1005,7 @@ class Table extends AbstractAsset
} }
} }
return new UniqueConstraint($indexName, $columns, $options); return new UniqueConstraint($indexName, $columns, $flags, $options);
} }
/** /**
......
...@@ -22,6 +22,14 @@ class UniqueConstraint extends AbstractAsset implements Constraint ...@@ -22,6 +22,14 @@ class UniqueConstraint extends AbstractAsset implements Constraint
*/ */
protected $columns = []; protected $columns = [];
/**
* Platform specific flags
* array($flagName => true)
*
* @var array
*/
protected $flags = array();
/** /**
* Platform specific options * Platform specific options
* *
...@@ -32,9 +40,10 @@ class UniqueConstraint extends AbstractAsset implements Constraint ...@@ -32,9 +40,10 @@ class UniqueConstraint extends AbstractAsset implements Constraint
/** /**
* @param string $indexName * @param string $indexName
* @param string[] $columns * @param string[] $columns
* @param array $flags
* @param mixed[] $options * @param mixed[] $options
*/ */
public function __construct($indexName, array $columns, array $options = []) public function __construct($indexName, array $columns, array $flags = array(), array $options = [])
{ {
$this->_setName($indexName); $this->_setName($indexName);
...@@ -43,6 +52,10 @@ class UniqueConstraint extends AbstractAsset implements Constraint ...@@ -43,6 +52,10 @@ class UniqueConstraint extends AbstractAsset implements Constraint
foreach ($columns as $column) { foreach ($columns as $column) {
$this->_addColumn($column); $this->_addColumn($column);
} }
foreach ($flags as $flag) {
$this->addFlag($flag);
}
} }
/** /**
...@@ -91,6 +104,56 @@ class UniqueConstraint extends AbstractAsset implements Constraint ...@@ -91,6 +104,56 @@ class UniqueConstraint extends AbstractAsset implements Constraint
return array_map([$this, 'trimQuotes'], $this->getColumns()); return array_map([$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 * @param string $name
* *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment