Skip to content

Commit

Permalink
Add SchemaDialect::describeIndexes
Browse files Browse the repository at this point in the history
Add more of the api from #18123. This formalizes an array API for index
reflection. Because `TableSchema` is being used to shim dialects
together, we need to reflect the columns in order to build index data.
  • Loading branch information
markstory committed Jan 18, 2025
1 parent b1423ec commit 4948151
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/Database/Schema/SchemaDialect.php
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,16 @@ public function describe(string $name): TableSchemaInterface
* Get a list of column metadata as a array
*
* Each item in the array will contain the following:
*
* - name : the name of the column.
* - type : the abstract type of the column.
* - length : the length of the column.
* - default : the default value of the column or null.
* - null : boolean indicating whether the column can be null.
* - comment : the column comment or null.
*
* @param string $tableName The name of the table to describe columns on.
* @return array
*/
public function describeColumns(string $tableName): array
{
Expand All @@ -447,6 +457,7 @@ public function describeColumns(string $tableName): array
}
/** @var \Cake\Database\Schema\TableSchema $table */
$table = $this->_driver->newTableSchema($tableName);

[$sql, $params] = $this->describeColumnSql($tableName, $config);
$statement = $this->_driver->execute($sql, $params);
foreach ($statement->fetchAll('assoc') as $row) {
Expand All @@ -461,4 +472,45 @@ public function describeColumns(string $tableName): array

return $columns;
}

/**
* Get a list of index metadata as a array
*
* Each item in the array will contain the following:
*
* - name : the name of the index.
* - type : the type of the index. One of `unique`, `index`
* - columns : the columns in the index.
* - length : the length of the index if applicable.
*
* @param string $tableName The name of the table to describe indexes on.
* @return array
*/
public function describeIndexes(string $tableName): array
{
$config = $this->_driver->config();
if (str_contains($tableName, '.')) {
[$config['schema'], $tableName] = explode('.', $tableName);

Check warning on line 493 in src/Database/Schema/SchemaDialect.php

View check run for this annotation

Codecov / codecov/patch

src/Database/Schema/SchemaDialect.php#L493

Added line #L493 was not covered by tests
}
/** @var \Cake\Database\Schema\TableSchema $table */
$table = $this->_driver->newTableSchema($tableName);
// Add the columns because TableSchema needs them.
foreach ($this->describeColumns($tableName) as $column) {
$table->addColumn($column['name'], $column);
}

[$sql, $params] = $this->describeIndexSql($tableName, $config);
$statement = $this->_driver->execute($sql, $params);
foreach ($statement->fetchAll('assoc') as $row) {
$this->convertIndexDescription($table, $row);
}
$indexes = [];
foreach ($table->indexes() as $name) {
$index = $table->getIndex($name);
$index['name'] = $name;
$indexes[] = $index;
}

return $indexes;
}
}
21 changes: 21 additions & 0 deletions tests/TestCase/Database/Schema/SchemaDialectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ class SchemaDialectTest extends TestCase
* @var array<string>
*/
protected array $fixtures = [
'core.Products',
'core.Users',
'core.Orders',
];

/**
Expand Down Expand Up @@ -105,4 +107,23 @@ public function testDescribeColumns(): void
$this->assertTrue(is_string($column['comment']) || $column['comment'] === null);
}
}

public function testDescribeIndexes(): void
{
$result = $this->dialect->describeIndexes('orders');
$this->assertCount(1, $result);
foreach ($result as $index) {
// Validate the interface for column array shape
$this->assertArrayHasKey('name', $index);
$this->assertTrue(is_string($index['name']));

$this->assertArrayHasKey('type', $index);
$this->assertTrue(is_string($index['type']));

$this->assertArrayHasKey('length', $index);

$this->assertArrayHasKey('columns', $index);
$this->assertTrue(is_array($index['columns']));
}
}
}

0 comments on commit 4948151

Please sign in to comment.