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

Decouple unique index from unique constraint

parent 9dbec4b5
......@@ -23,6 +23,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Schema\UniqueConstraint;
use Doctrine\DBAL\TransactionIsolationLevel;
use Doctrine\DBAL\Types;
use Doctrine\DBAL\Types\Type;
......@@ -1534,15 +1535,30 @@ abstract class AbstractPlatform
$options['indexes'] = [];
$options['primary'] = [];
if (($createFlags&self::CREATE_INDEXES) > 0) {
if (($createFlags & self::CREATE_INDEXES) > 0) {
foreach ($table->getIndexes() as $index) {
/** @var $index Index */
if ($index->isPrimary()) {
if (! $index->isPrimary()) {
$options['indexes'][$index->getQuotedName($this)] = $index;
continue;
}
$options['primary'] = $index->getQuotedColumns($this);
$options['primary_index'] = $index;
} else {
$options['indexes'][$index->getQuotedName($this)] = $index;
}
foreach ($table->getUniqueConstraints() as $uniqueConstraint) {
/** @var UniqueConstraint $uniqueConstraint */
$options['uniqueConstraints'][$uniqueConstraint->getQuotedName($this)] = $uniqueConstraint;
}
}
if (($createFlags & self::CREATE_FOREIGNKEYS) > 0) {
$options['foreignKeys'] = [];
foreach ($table->getForeignKeys() as $fkConstraint) {
$options['foreignKeys'][] = $fkConstraint;
}
}
......@@ -1551,7 +1567,6 @@ abstract class AbstractPlatform
foreach ($table->getColumns() as $column) {
/** @var Column $column */
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) {
$eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs);
......@@ -1579,13 +1594,6 @@ abstract class AbstractPlatform
$columns[$columnData['name']] = $columnData;
}
if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) {
$options['foreignKeys'] = [];
foreach ($table->getForeignKeys() as $fkConstraint) {
$options['foreignKeys'][] = $fkConstraint;
}
}
if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) {
$eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this);
$this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs);
......
......@@ -893,10 +893,11 @@ class SqlitePlatform extends AbstractPlatform
$sql = [];
$tableSql = [];
if (! $this->onSchemaAlterTable($diff, $tableSql)) {
$dataTable = new Table('__temp__' . $table->getName());
$newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
$newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), [], $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
$newTable->addOption('alter', true);
$sql = $this->getPreAlterTableIndexForeignKeySQL($diff);
......
......@@ -263,12 +263,14 @@ abstract class AbstractSchemaManager
{
$columns = $this->listTableColumns($tableName);
$foreignKeys = [];
if ($this->_platform->supportsForeignKeyConstraints()) {
$foreignKeys = $this->listTableForeignKeys($tableName);
}
$indexes = $this->listTableIndexes($tableName);
return new Table($tableName, $columns, $indexes, $foreignKeys, false, []);
return new Table($tableName, $columns, $indexes, [], $foreignKeys, false, []);
}
/**
......@@ -587,6 +589,7 @@ abstract class AbstractSchemaManager
public function alterTable(TableDiff $tableDiff)
{
$queries = $this->_platform->getAlterTableSQL($tableDiff);
if (! is_array($queries) || ! count($queries)) {
return;
}
......
......@@ -57,6 +57,7 @@ class Index extends AbstractAsset implements Constraint
$isUnique = $isUnique || $isPrimary;
$this->_setName($indexName);
$this->_isUnique = $isUnique;
$this->_isPrimary = $isPrimary;
$this->options = $options;
......@@ -64,6 +65,7 @@ class Index extends AbstractAsset implements Constraint
foreach ($columns as $column) {
$this->_addColumn($column);
}
foreach ($flags as $flag) {
$this->addFlag($flag);
}
......
......@@ -18,7 +18,8 @@ class SchemaException extends DBALException
public const SEQUENCE_ALREADY_EXISTS = 80;
public const INDEX_INVALID_NAME = 90;
public const FOREIGNKEY_DOESNT_EXIST = 100;
public const NAMESPACE_ALREADY_EXISTS = 110;
public const CONSTRAINT_DOESNT_EXIST = 110;
public const NAMESPACE_ALREADY_EXISTS = 120;
/**
* @param string $tableName
......@@ -142,6 +143,21 @@ class SchemaException extends DBALException
return new self("There exists no sequence with the name '" . $sequenceName . "'.", self::SEQUENCE_DOENST_EXIST);
}
/**
* @param string $constraintName
* @param string $table
*
* @return self
*/
public static function uniqueConstraintDoesNotExist($constraintName, $table)
{
return new self(sprintf(
'There exists no unique constraint with the name "%s" on table "%s".',
$constraintName,
$table
), self::CONSTRAINT_DOESNT_EXIST);
}
/**
* @param string $fkName
* @param string $table
......
This diff is collapsed.
<?php
namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use InvalidArgumentException;
use function array_keys;
use function array_map;
use function is_string;
use function strtolower;
/**
* Class for a unique constraint.
*/
class UniqueConstraint extends AbstractAsset implements Constraint
{
/**
* Asset identifier instances of the column names the unique constraint is associated with.
* array($columnName => Identifier)
*
* @var Identifier[]
*/
protected $columns = [];
/**
* Platform specific options
*
* @var mixed[]
*/
private $options = [];
/**
* @param string $indexName
* @param string[] $columns
* @param mixed[] $options
*/
public function __construct($indexName, array $columns, array $options = [])
{
$this->_setName($indexName);
$this->options = $options;
foreach ($columns as $column) {
$this->_addColumn($column);
}
}
/**
* @param string $column
*
* @return void
*
* @throws InvalidArgumentException
*/
protected function _addColumn($column)
{
if (! is_string($column)) {
throw new InvalidArgumentException('Expecting a string as Index Column');
}
$this->_columns[$column] = new Identifier($column);
}
/**
* {@inheritdoc}
*/
public function getColumns()
{
return array_keys($this->_columns);
}
/**
* {@inheritdoc}
*/
public function getQuotedColumns(AbstractPlatform $platform)
{
$columns = [];
foreach ($this->_columns as $column) {
$columns[] = $column->getQuotedName($platform);
}
return $columns;
}
/**
* @return string[]
*/
public function getUnquotedColumns()
{
return array_map([$this, 'trimQuotes'], $this->getColumns());
}
/**
* @param string $name
*
* @return bool
*/
public function hasOption($name)
{
return isset($this->options[strtolower($name)]);
}
/**
* @param string $name
*
* @return mixed
*/
public function getOption($name)
{
return $this->options[strtolower($name)];
}
/**
* @return mixed[]
*/
public function getOptions()
{
return $this->options;
}
}
......@@ -314,6 +314,7 @@ class ExceptionTest extends DbalFunctionalTestCase
$table->addColumn('id', 'integer');
$this->expectException($exceptionClass);
foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) {
$conn->exec($sql);
}
......
......@@ -976,7 +976,7 @@ class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
protected function getTestTable($name, $options = [])
{
$table = new Table($name, [], [], [], false, $options);
$table = new Table($name, [], [], [], [], false, $options);
$table->setSchemaConfig($this->schemaManager->createSchemaConfig());
$table->addColumn('id', 'integer', ['notnull' => true]);
$table->setPrimaryKey(['id']);
......@@ -987,7 +987,7 @@ class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
protected function getTestCompositeTable($name)
{
$table = new Table($name, [], [], [], false, []);
$table = new Table($name, [], [], [], [], false, []);
$table->setSchemaConfig($this->schemaManager->createSchemaConfig());
$table->addColumn('id', 'integer', ['notnull' => true]);
$table->addColumn('other_id', 'integer', ['notnull' => true]);
......@@ -999,14 +999,17 @@ class SchemaManagerFunctionalTestCase extends DbalFunctionalTestCase
protected function assertHasTable($tables, $tableName)
{
$foundTable = false;
foreach ($tables as $table) {
self::assertInstanceOf(Table::class, $table, 'No Table instance was found in tables array.');
if (strtolower($table->getName()) !== 'list_tables_test_new_name') {
continue;
}
$foundTable = true;
}
self::assertTrue($foundTable, 'Could not find new table');
}
......
......@@ -1272,6 +1272,7 @@ class ComparatorTest extends TestCase
'id_table1' => new Column('id_table1', Type::getType('integer')),
],
[],
[],
[
new ForeignKeyConstraint(['id_table1'], 'table1', ['id'], 'fk_table2_table1'),
]
......@@ -1285,6 +1286,7 @@ class ComparatorTest extends TestCase
'id_table3' => new Column('id_table3', Type::getType('integer')),
],
[],
[],
[
new ForeignKeyConstraint(['id_table3'], 'table3', ['id'], 'fk_table2_table3'),
]
......
......@@ -200,7 +200,7 @@ class TableTest extends DbalTestCase
{
$constraint = new ForeignKeyConstraint([], 'foo', []);
$tableA = new Table('foo', [], [], [$constraint]);
$tableA = new Table('foo', [], [], [], [$constraint]);
$constraints = $tableA->getForeignKeys();
self::assertCount(1, $constraints);
......@@ -209,7 +209,7 @@ class TableTest extends DbalTestCase
public function testOptions()
{
$table = new Table('foo', [], [], [], false, ['foo' => 'bar']);
$table = new Table('foo', [], [], [], [], false, ['foo' => 'bar']);
self::assertTrue($table->hasOption('foo'));
self::assertEquals('bar', $table->getOption('foo'));
......
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