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
/* @var $index Index */
if ($index->isPrimary()) {
$options['primary'] = $index->getColumns();
$options['primary_index'] = $index;
} else {
$options['indexes'][$index->getName()] = $index;
}
......@@ -1250,18 +1251,29 @@ abstract class AbstractPlatform
if ($index->isPrimary()) {
return $this->getCreatePrimaryKeySQL($index, $table);
} 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) . ')';
}
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.
*
......
......@@ -519,6 +519,22 @@ class MySqlPlatform extends AbstractPlatform
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
* field to be used in statements like CREATE TABLE.
......
......@@ -195,7 +195,11 @@ class SQLServerPlatform extends AbstractPlatform
}
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;
......@@ -223,6 +227,22 @@ class SQLServerPlatform extends AbstractPlatform
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
*/
......@@ -249,6 +269,25 @@ class SQLServerPlatform extends AbstractPlatform
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
*
......
......@@ -711,6 +711,7 @@ abstract class AbstractSchemaManager
'columns' => array($tableIndex['column_name']),
'unique' => $tableIndex['non_unique'] ? false : true,
'primary' => $tableIndex['primary'],
'flags' => isset($tableIndex['flags']) ? $tableIndex['flags'] : array(),
);
} else {
$result[$keyName]['columns'][] = $tableIndex['column_name'];
......@@ -733,7 +734,7 @@ abstract class AbstractSchemaManager
}
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) {
......
......@@ -38,13 +38,20 @@ class Index extends AbstractAsset implements Constraint
*/
protected $_isPrimary = false;
/**
* Platform specific flags for indexes.
*
* @var array
*/
protected $_flags = array();
/**
* @param string $indexName
* @param array $column
* @param bool $isUnique
* @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;
......@@ -52,9 +59,12 @@ class Index extends AbstractAsset implements Constraint
$this->_isUnique = $isUnique;
$this->_isPrimary = $isPrimary;
foreach($columns AS $column) {
foreach ($columns AS $column) {
$this->_addColumn($column);
}
foreach ($flags as $flag) {
$this->addFlag($flag);
}
}
/**
......@@ -185,4 +195,40 @@ class Index extends AbstractAsset implements Constraint
}
return false;
}
/**
* 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
} else {
$v['primary'] = false;
}
if (strpos($v['index_type'], 'FULLTEXT') !== false) {
$v['flags'] = array('FULLTEXT');
}
$tableIndexes[$k] = $v;
}
......
......@@ -104,6 +104,7 @@ class SQLServerSchemaManager extends AbstractSchemaManager
*/
protected function _getPortableTableIndexesList($tableIndexRows, $tableName=null)
{
// TODO: Remove code duplication with AbstractSchemaManager;
$result = array();
foreach ($tableIndexRows AS $tableIndex) {
$indexName = $keyName = $tableIndex['index_name'];
......@@ -112,11 +113,19 @@ class SQLServerSchemaManager extends AbstractSchemaManager
}
$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(
'name' => $indexName,
'columns' => explode(', ', $tableIndex['index_keys']),
'unique' => strpos($tableIndex['index_description'], 'unique') !== false,
'primary' => strpos($tableIndex['index_description'], 'primary key') !== false,
'flags' => $flags,
);
}
......
......@@ -14,7 +14,7 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
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()
......@@ -188,4 +188,37 @@ class SQLServerPlatformTest extends AbstractPlatformTestCase
$this->assertEquals('[test]', $this->_platform->quoteSingleIdentifier('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
$this->assertTrue($idx1->isFullfilledBy($pri));
$this->assertTrue($idx1->isFullfilledBy($uniq));
}
/**
* @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