diff --git a/src/ClickHouseSchemaManager.php b/src/ClickHouseSchemaManager.php index 69cc2b4..b7e68d1 100644 --- a/src/ClickHouseSchemaManager.php +++ b/src/ClickHouseSchemaManager.php @@ -16,12 +16,22 @@ use Doctrine\DBAL\Schema\AbstractSchemaManager; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\View; use Doctrine\DBAL\Types\Type; use const CASE_LOWER; use function array_change_key_case; +use function array_filter; +use function array_key_exists; +use function array_map; +use function array_reverse; +use function current; +use function explode; +use function is_array; +use function preg_match; use function preg_replace; use function stripos; +use function strpos; use function strtolower; use function trim; @@ -53,6 +63,32 @@ protected function _getPortableViewDefinition($view) */ public function listTableIndexes($table) : array { + $tableView = $this->_getPortableViewDefinition(['name' => $table]); + + preg_match( + '/MergeTree\(([\w+, \(\)]+)(?= \(((?:[^()]|\((?2)\))+)\),)/mi', + $tableView->getSql(), + $matches + ); + + if (is_array($matches) && array_key_exists(2, $matches)) { + $indexColumns = array_filter( + array_map('trim', explode(',', $matches[2])), + function (string $column) { + return strpos($column, '(') === false; + } + ); + + return [ + new Index( + current(array_reverse(explode('.', $table))) . '__pk', + $indexColumns, + false, + true + ), + ]; + } + return []; } diff --git a/src/ClickHouseStatement.php b/src/ClickHouseStatement.php index d9532be..9587257 100644 --- a/src/ClickHouseStatement.php +++ b/src/ClickHouseStatement.php @@ -185,7 +185,7 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n if ($this->assumeFetchMode($fetchMode) === FetchMode::NUMERIC) { return array_map( 'array_values', - (array) $this->rows + $this->rows ); } @@ -194,7 +194,7 @@ public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = n function ($row) { return array_values($row) + $row; }, - (array) $this->rows + $this->rows ); } @@ -203,7 +203,7 @@ function ($row) { function ($row) { return (object) $row; }, - (array) $this->rows + $this->rows ); } @@ -218,7 +218,7 @@ function ($row) { return [array_shift($row) => array_shift($row)]; }, - (array) $this->rows + $this->rows ); } diff --git a/tests/CreateSchemaTest.php b/tests/CreateSchemaTest.php index 3b3ad5e..7866a3d 100644 --- a/tests/CreateSchemaTest.php +++ b/tests/CreateSchemaTest.php @@ -12,6 +12,7 @@ namespace FOD\DBALClickHouse\Tests; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Types\Type; use FOD\DBALClickHouse\ClickHouseSchemaManager; use FOD\DBALClickHouse\Connection; @@ -240,6 +241,37 @@ public function testEventDateProviderColumnBadOption() $this->connection->exec('DROP TABLE test_table'); } + public function testListTableIndexes() + { + $fromSchema = $this->connection->getSchemaManager()->createSchema(); + $toSchema = clone $fromSchema; + + $newTable = $toSchema->createTable('test_indexes_table'); + + $newTable->addColumn('id', 'integer', ['unsigned' => true]); + $newTable->addColumn('payload', 'string'); + $newTable->addColumn('event_date', Type::DATE); + $newTable->addOption('eventDateColumn', 'event_date'); + $newTable->setPrimaryKey(['id', 'event_date']); + $migrationSQLs = $fromSchema->getMigrateToSql($toSchema, $this->connection->getDatabasePlatform()); + foreach ($migrationSQLs as $sql) { + $this->connection->exec($sql); + } + + $indexes = $this->connection->getSchemaManager()->listTableIndexes('test_indexes_table'); + + $this->assertEquals(1, \count($indexes)); + + if($index = current($indexes)) { + $this->assertInstanceOf(Index::class, $index); + + $this->assertEquals(['id', 'event_date'], $index->getColumns()); + $this->assertTrue($index->isPrimary()); + } + + $this->connection->exec('DROP TABLE test_indexes_table'); + } + public function testNullableColumns() { $fromSchema = $this->connection->getSchemaManager()->createSchema();