Commit a56e01cf authored by Benjamin Eberlei's avatar Benjamin Eberlei

[DBAL-220] Add support for Index flags and implement support for SQL Server...

[DBAL-220] Add support for Index flags and implement support for SQL Server CLUSTERED/NONCLUSTERED and MySQL FULLTEXT.
parent 7a956794
...@@ -1028,6 +1028,7 @@ abstract class AbstractPlatform ...@@ -1028,6 +1028,7 @@ abstract class AbstractPlatform
/* @var $index Index */ /* @var $index Index */
if ($index->isPrimary()) { if ($index->isPrimary()) {
$options['primary'] = $index->getColumns(); $options['primary'] = $index->getColumns();
$options['primary_index'] = $index;
} else { } else {
$options['indexes'][$index->getName()] = $index; $options['indexes'][$index->getName()] = $index;
} }
...@@ -1250,18 +1251,29 @@ abstract class AbstractPlatform ...@@ -1250,18 +1251,29 @@ abstract class AbstractPlatform
if ($index->isPrimary()) { if ($index->isPrimary()) {
return $this->getCreatePrimaryKeySQL($index, $table); return $this->getCreatePrimaryKeySQL($index, $table);
} else { } else {
$type = '';
if ($index->isUnique()) {
$type = 'UNIQUE ';
}
$query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table; $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table;
$query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')'; $query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')';
} }
return $query; return $query;
} }
/**
* Adds additional flags for index generation
*
* @param Index $index
* @return string
*/
protected function getCreateIndexSQLFlags(Index $index)
{
$type = '';
if ($index->isUnique()) {
$type = 'UNIQUE ';
}
return $type;
}
/** /**
* Get SQL to create an unnamed primary key constraint. * Get SQL to create an unnamed primary key constraint.
* *
......
...@@ -519,6 +519,22 @@ class MySqlPlatform extends AbstractPlatform ...@@ -519,6 +519,22 @@ class MySqlPlatform extends AbstractPlatform
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
} }
/**
* @override
*/
protected function getCreateIndexSQLFlags(Index $index)
{
$type = '';
if ($index->isUnique()) {
$type .= 'UNIQUE ';
} else if ($index->hasFlag('fulltext')) {
$type .= 'FULLTEXT ';
}
return $type;
}
/** /**
* Obtain DBMS specific SQL code portion needed to declare an integer type * Obtain DBMS specific SQL code portion needed to declare an integer type
* field to be used in statements like CREATE TABLE. * field to be used in statements like CREATE TABLE.
......
...@@ -195,7 +195,11 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -195,7 +195,11 @@ class SQLServerPlatform extends AbstractPlatform
} }
if (isset($options['primary']) && !empty($options['primary'])) { if (isset($options['primary']) && !empty($options['primary'])) {
$columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; $flags = '';
if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) {
$flags = ' NONCLUSTERED';
}
$columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')';
} }
$query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql;
...@@ -223,6 +227,22 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -223,6 +227,22 @@ class SQLServerPlatform extends AbstractPlatform
return $sql; return $sql;
} }
/**
* Get SQL to create an unnamed primary key constraint.
*
* @param Index $index
* @param string|Table $table
* @return string
*/
public function getCreatePrimaryKeySQL(Index $index, $table)
{
$flags = '';
if ($index->hasFlag('nonclustered')) {
$flags = ' NONCLUSTERED';
}
return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($index->getColumns()) . ')';
}
/** /**
* @override * @override
*/ */
...@@ -249,6 +269,25 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -249,6 +269,25 @@ class SQLServerPlatform extends AbstractPlatform
return $constraint; return $constraint;
} }
/**
* @override
*/
protected function getCreateIndexSQLFlags(Index $index)
{
$type = '';
if ($index->isUnique()) {
$type .= 'UNIQUE ';
}
if ($index->hasFlag('clustered')) {
$type .= 'CLUSTERED ';
} else if ($index->hasFlag('nonclustered')) {
$type .= 'NONCLUSTERED ';
}
return $type;
}
/** /**
* Extend unique key constraint with required filters * Extend unique key constraint with required filters
* *
......
...@@ -711,6 +711,7 @@ abstract class AbstractSchemaManager ...@@ -711,6 +711,7 @@ abstract class AbstractSchemaManager
'columns' => array($tableIndex['column_name']), 'columns' => array($tableIndex['column_name']),
'unique' => $tableIndex['non_unique'] ? false : true, 'unique' => $tableIndex['non_unique'] ? false : true,
'primary' => $tableIndex['primary'], 'primary' => $tableIndex['primary'],
'flags' => isset($tableIndex['flags']) ? $tableIndex['flags'] : array(),
); );
} else { } else {
$result[$keyName]['columns'][] = $tableIndex['column_name']; $result[$keyName]['columns'][] = $tableIndex['column_name'];
...@@ -733,7 +734,7 @@ abstract class AbstractSchemaManager ...@@ -733,7 +734,7 @@ abstract class AbstractSchemaManager
} }
if (!$defaultPrevented) { if (!$defaultPrevented) {
$index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary']); $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary'], $data['flags']);
} }
if ($index) { if ($index) {
......
...@@ -38,13 +38,20 @@ class Index extends AbstractAsset implements Constraint ...@@ -38,13 +38,20 @@ class Index extends AbstractAsset implements Constraint
*/ */
protected $_isPrimary = false; protected $_isPrimary = false;
/**
* Platform specific flags for indexes.
*
* @var array
*/
protected $_flags = array();
/** /**
* @param string $indexName * @param string $indexName
* @param array $column * @param array $column
* @param bool $isUnique * @param bool $isUnique
* @param bool $isPrimary * @param bool $isPrimary
*/ */
public function __construct($indexName, array $columns, $isUnique=false, $isPrimary=false) public function __construct($indexName, array $columns, $isUnique = false, $isPrimary = false, array $flags = array())
{ {
$isUnique = ($isPrimary)?true:$isUnique; $isUnique = ($isPrimary)?true:$isUnique;
...@@ -52,9 +59,12 @@ class Index extends AbstractAsset implements Constraint ...@@ -52,9 +59,12 @@ class Index extends AbstractAsset implements Constraint
$this->_isUnique = $isUnique; $this->_isUnique = $isUnique;
$this->_isPrimary = $isPrimary; $this->_isPrimary = $isPrimary;
foreach($columns AS $column) { foreach ($columns AS $column) {
$this->_addColumn($column); $this->_addColumn($column);
} }
foreach ($flags as $flag) {
$this->addFlag($flag);
}
} }
/** /**
...@@ -185,4 +195,40 @@ class Index extends AbstractAsset implements Constraint ...@@ -185,4 +195,40 @@ class Index extends AbstractAsset implements Constraint
} }
return false; return false;
} }
}
\ No newline at end of file /**
* Add Flag for an index that translates to platform specific handling.
*
* @example $index->addFlag('CLUSTERED')
* @param string $flag
* @return Index
*/
public function addFlag($flag)
{
$this->flags[strtolower($flag)] = true;
return $this;
}
/**
* Does this index have a specific flag?
*
* @param string $flag
* @return bool
*/
public function hasFlag($flag)
{
return isset($this->flags[strtolower($flag)]);
}
/**
* Remove a flag
*
* @param string $flag
* @return void
*/
public function removeFlag($flag)
{
unset($this->flags[strtolower($flag)]);
}
}
...@@ -59,6 +59,9 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -59,6 +59,9 @@ class MySqlSchemaManager extends AbstractSchemaManager
} else { } else {
$v['primary'] = false; $v['primary'] = false;
} }
if (strpos($v['index_type'], 'FULLTEXT') !== false) {
$v['flags'] = array('FULLTEXT');
}
$tableIndexes[$k] = $v; $tableIndexes[$k] = $v;
} }
......
...@@ -104,6 +104,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -104,6 +104,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
*/ */
protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null) protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
{ {
// TODO: Remove code duplication with AbstractSchemaManager;
$result = array(); $result = array();
foreach ($tableIndexRows AS $tableIndex) { foreach ($tableIndexRows AS $tableIndex) {
$indexName = $keyName = $tableIndex['index_name']; $indexName = $keyName = $tableIndex['index_name'];
...@@ -112,11 +113,19 @@ class SQLServerSchemaManager extends AbstractSchemaManager ...@@ -112,11 +113,19 @@ class SQLServerSchemaManager extends AbstractSchemaManager
} }
$keyName = strtolower($keyName); $keyName = strtolower($keyName);
$flags = array();
if (strpos($tableIndex['index_description'], 'clustered') !== false) {
$flags[] = 'clustered';
} else if (strpos($tableIndex['index_description'], 'nonclustered') !== false) {
$flags[] = 'nonclustered';
}
$result[$keyName] = array( $result[$keyName] = array(
'name' => $indexName, 'name' => $indexName,
'columns' => explode(', ', $tableIndex['index_keys']), 'columns' => explode(', ', $tableIndex['index_keys']),
'unique' => strpos($tableIndex['index_description'], 'unique') !== false, 'unique' => strpos($tableIndex['index_description'], 'unique') !== false,
'primary' => strpos($tableIndex['index_description'], 'primary key') !== false, 'primary' => strpos($tableIndex['index_description'], 'primary key') !== false,
'flags' => $flags,
); );
} }
......
...@@ -14,7 +14,7 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase ...@@ -14,7 +14,7 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
public function getGenerateTableSql() public function getGenerateTableSql()
{ {
return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test NVARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'; return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test NVARCHAR(255) DEFAULT NULL, PRIMARY KEY (id))';
} }
public function getGenerateTableWithMultiColumnUniqueIndexSql() public function getGenerateTableWithMultiColumnUniqueIndexSql()
...@@ -188,4 +188,37 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase ...@@ -188,4 +188,37 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
$this->assertEquals('[test]', $this->_platform->quoteSingleIdentifier('test')); $this->assertEquals('[test]', $this->_platform->quoteSingleIdentifier('test'));
$this->assertEquals('[test.test]', $this->_platform->quoteSingleIdentifier('test.test')); $this->assertEquals('[test.test]', $this->_platform->quoteSingleIdentifier('test.test'));
} }
/**
* @group DBAL-220
*/
public function testCreateClusteredIndex()
{
$idx = new \Doctrine\DBAL\Schema\Index('idx', array('id'));
$idx->addFlag('clustered');
$this->assertEquals('CREATE CLUSTERED INDEX idx ON tbl (id)', $this->_platform->getCreateIndexSQL($idx, 'tbl'));
}
/**
* @group DBAL-220
*/
public function testCreateNonClusteredPrimaryKeyInTable()
{
$table = new \Doctrine\DBAL\Schema\Table("tbl");
$table->addColumn("id", "integer");
$table->setPrimaryKey(Array("id"));
$table->getIndex('primary')->addFlag('nonclustered');
$this->assertEquals(array('CREATE TABLE tbl (id INT NOT NULL, PRIMARY KEY NONCLUSTERED (id))'), $this->_platform->getCreateTableSQL($table));
}
/**
* @group DBAL-220
*/
public function testCreateNonClusteredPrimaryKey()
{
$idx = new \Doctrine\DBAL\Schema\Index('idx', array('id'), false, true);
$idx->addFlag('nonclustered');
$this->assertEquals('ALTER TABLE tbl ADD PRIMARY KEY NONCLUSTERED (id)', $this->_platform->getCreatePrimaryKeySQL($idx, 'tbl'));
}
} }
...@@ -81,4 +81,20 @@ class IndexTest extends \PHPUnit_Framework_TestCase ...@@ -81,4 +81,20 @@ class IndexTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($idx1->isFullfilledBy($pri)); $this->assertTrue($idx1->isFullfilledBy($pri));
$this->assertTrue($idx1->isFullfilledBy($uniq)); $this->assertTrue($idx1->isFullfilledBy($uniq));
} }
}
\ No newline at end of file /**
* @group DBAL-220
*/
public function testFlags()
{
$idx1 = $this->createIndex();
$this->assertFalse($idx1->hasFlag('clustered'));
$idx1->addFlag('clustered');
$this->assertTrue($idx1->hasFlag('clustered'));
$this->assertTrue($idx1->hasFlag('CLUSTERED'));
$idx1->removeFlag('clustered');
$this->assertFalse($idx1->hasFlag('clustered'));
}
}
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