Skip to content

Commit

Permalink
Create IndexType and IndexMethod classes (#339)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov authored Feb 10, 2025
1 parent 72f7814 commit ff63069
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Enh #335: Remove `ColumnInterface` (@Tigrov)
- Enh #337: Rename `ColumnSchemaInterface` to `ColumnInterface` (@Tigrov)
- Enh #338: Replace `DbArrayHelper::getColumn()` with `array_column()` (@Tigrov)
- New #339: Add `IndexType` and `IndexMethod` classes (@Tigrov)

## 1.2.0 March 21, 2024

Expand Down
14 changes: 14 additions & 0 deletions src/DDLQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,20 @@ public function checkIntegrity(string $schema = '', string $table = '', bool $ch
return $command;
}

public function createIndex(
string $table,
string $name,
array|string $columns,
string|null $indexType = null,
string|null $indexMethod = null
): string {
return 'CREATE ' . (!empty($indexType) ? $indexType . ' ' : '') . 'INDEX '
. $this->quoter->quoteTableName($name) . ' ON '
. $this->quoter->quoteTableName($table)
. (!empty($columns) ? ' (' . $this->queryBuilder->buildColumns($columns) . ')' : '')
. (!empty($indexMethod) ? " USING $indexMethod" : '');
}

/**
* @throws InvalidArgumentException
*/
Expand Down
28 changes: 28 additions & 0 deletions src/IndexMethod.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Mssql;

/**
* Defines the available index methods for {@see DDLQueryBuilder::createIndex()} method.
*/
final class IndexMethod
{
/**
* Define the method of the index as `GEOMETRY_GRID`.
*/
public const GEOMETRY_GRID = 'GEOMETRY_GRID';
/**
* Define the method of the index as `GEOMETRY_AUTO_GRID`.
*/
public const GEOMETRY_AUTO_GRID = 'GEOMETRY_AUTO_GRID';
/**
* Define the method of the index as `GEOGRAPHY_GRID`.
*/
public const GEOGRAPHY_GRID = 'GEOGRAPHY_GRID';
/**
* Define the method of the index as `GEOGRAPHY_AUTO_GRID`.
*/
public const GEOGRAPHY_AUTO_GRID = 'GEOGRAPHY_AUTO_GRID';
}
48 changes: 48 additions & 0 deletions src/IndexType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Db\Mssql;

/**
* Defines the available index types for {@see DDLQueryBuilder::createIndex()} method.
*/
final class IndexType
{
/**
* Define the type of the index as `CLUSTERED`.
*/
public const CLUSTERED = 'CLUSTERED';
/**
* Define the type of the index as `CLUSTERED COLUMNSTORE`.
*/
public const CLUSTERED_COLUMNSTORE = 'CLUSTERED COLUMNSTORE';
/**
* Define the type of the index as `COLUMNSTORE`.
*/
public const COLUMNSTORE = 'COLUMNSTORE';
/**
* Define the type of the index as `NONCLUSTERED`.
*/
public const NONCLUSTERED = 'NONCLUSTERED';
/**
* Define the type of the index as `PRIMARY XML`.
*/
public const PRIMARY_XML = 'PRIMARY XML';
/**
* Define the type of the index as `SPATIAL`.
*/
public const SPATIAL = 'SPATIAL';
/**
* Define the type of the index as `UNIQUE`.
*/
public const UNIQUE = 'UNIQUE';
/**
* Define the type of the index as `UNIQUE CLUSTERED`.
*/
public const UNIQUE_CLUSTERED = 'UNIQUE CLUSTERED';
/**
* Define the type of the index as `XML`.
*/
public const XML = 'XML';
}
67 changes: 67 additions & 0 deletions tests/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Yiisoft\Db\Mssql\Tests;

use PHPUnit\Framework\Attributes\DataProviderExternal;
use Throwable;
use Yiisoft\Db\Exception\Exception;
use Yiisoft\Db\Exception\IntegrityException;
Expand All @@ -16,11 +17,14 @@
use Yiisoft\Db\Mssql\Connection;
use Yiisoft\Db\Mssql\Dsn;
use Yiisoft\Db\Mssql\Driver;
use Yiisoft\Db\Mssql\IndexType;
use Yiisoft\Db\Mssql\Tests\Provider\CommandProvider;
use Yiisoft\Db\Mssql\Tests\Support\TestTrait;
use Yiisoft\Db\Query\Query;
use Yiisoft\Db\Tests\Common\CommonCommandTest;
use Yiisoft\Db\Tests\Support\DbHelper;

use function array_filter;
use function trim;

/**
Expand Down Expand Up @@ -348,4 +352,67 @@ public function testAlterColumnWithDefaultNull()

$command->dropTable('column_with_constraint');
}

#[DataProviderExternal(CommandProvider::class, 'createIndex')]
public function testCreateIndex(array $columns, array $indexColumns, string|null $indexType, string|null $indexMethod): void
{
parent::testCreateIndex($columns, $indexColumns, $indexType, $indexMethod);
}

public function createCreateClusteredColumnstoreIndex()
{
$db = $this->getConnection();

$command = $db->createCommand();
$schema = $db->getSchema();

$tableName = 'test_create_index';
$indexName = 'test_index_name';

if ($schema->getTableSchema($tableName) !== null) {
$command->dropTable($tableName)->execute();
}

$command->createTable($tableName, ['col1' => ColumnBuilder::integer()])->execute();
$command->createIndex($tableName, $indexName, '', IndexType::CLUSTERED_COLUMNSTORE)->execute();

$this->assertCount(1, $schema->getTableIndexes($tableName));

$index = $schema->getTableIndexes($tableName)[0];

$this->assertSame(['col1'], $index->getColumnNames());
$this->assertFalse($index->isUnique());
$this->assertFalse($index->isPrimary());

$db->close();
}

public function testCreateXmlIndex(): void
{
$db = $this->getConnection();
$command = $db->createCommand();
$schema = $db->getSchema();

$tableName = 'test_create_index';
$primaryXmlIndexName = 'test_index_name';
$xmlIndexName = 'test_index_name_xml';
$indexColumns = ['col1'];

if ($schema->getTableSchema($tableName) !== null) {
$command->dropTable($tableName)->execute();
}

$command->createTable($tableName, ['id' => ColumnBuilder::primaryKey(), 'col1' => 'xml'])->execute();
$command->createIndex($tableName, $primaryXmlIndexName, $indexColumns, IndexType::PRIMARY_XML)->execute();
$command->createIndex($tableName, $xmlIndexName, $indexColumns, IndexType::XML, "XML INDEX $primaryXmlIndexName FOR PATH")->execute();

$this->assertCount(3, $schema->getTableIndexes($tableName));

$index = array_filter($schema->getTableIndexes($tableName), static fn ($index) => !$index->isPrimary())[1];

$this->assertSame($indexColumns, $index->getColumnNames());
$this->assertFalse($index->isUnique());

$db->close();
}
}
21 changes: 21 additions & 0 deletions tests/Provider/CommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use JsonException;
use PDO;
use Yiisoft\Db\Command\Param;
use Yiisoft\Db\Mssql\Column\ColumnBuilder;
use Yiisoft\Db\Mssql\IndexMethod;
use Yiisoft\Db\Mssql\IndexType;
use Yiisoft\Db\Mssql\Tests\Support\TestTrait;

use function json_encode;
Expand Down Expand Up @@ -70,4 +73,22 @@ public static function rawSql(): array

return $rawSql;
}

public static function createIndex(): array
{
return [
...parent::createIndex(),
[['col1' => ColumnBuilder::integer()], ['col1'], IndexType::CLUSTERED, null],
[['col1' => ColumnBuilder::integer()], ['col1'], IndexType::NONCLUSTERED, null],
[['col1' => ColumnBuilder::integer()], ['col1'], IndexType::UNIQUE, null],
[['col1' => ColumnBuilder::integer()], ['col1'], IndexType::UNIQUE_CLUSTERED, null],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'geometry'], ['col1'], IndexType::SPATIAL, IndexMethod::GEOMETRY_GRID . ' WITH(BOUNDING_BOX = (0, 0, 100, 100))'],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'geometry'], ['col1'], IndexType::SPATIAL, IndexMethod::GEOMETRY_AUTO_GRID . ' WITH(BOUNDING_BOX = (0, 0, 100, 100))'],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'geography'], ['col1'], IndexType::SPATIAL, null],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'geography'], ['col1'], IndexType::SPATIAL, IndexMethod::GEOGRAPHY_GRID],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'geography'], ['col1'], IndexType::SPATIAL, IndexMethod::GEOGRAPHY_AUTO_GRID],
[['col1' => ColumnBuilder::integer()], ['col1'], IndexType::COLUMNSTORE, null],
[['id' => ColumnBuilder::primaryKey(), 'col1' => 'xml'], ['col1'], IndexType::PRIMARY_XML, null],
];
}
}

0 comments on commit ff63069

Please sign in to comment.