Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10.x] Get indexes of a table #49204

Merged
merged 5 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/Illuminate/Database/Query/Processors/MySqlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,25 @@ public function processColumns($results)
];
}, $results);
}

/**
* Process the results of an indexes query.
*
* @param array $results
* @return array
*/
public function processIndexes($results)
{
return array_map(function ($result) {
$result = (object) $result;

return [
'name' => $name = strtolower($result->name),
'columns' => explode(',', $result->columns),
'type' => strtolower($result->type),
'unique' => (bool) $result->unique,
'primary' => $name === 'primary',
];
}, $results);
}
}
21 changes: 21 additions & 0 deletions src/Illuminate/Database/Query/Processors/PostgresProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,25 @@ public function processColumns($results)
];
}, $results);
}

/**
* Process the results of an indexes query.
*
* @param array $results
* @return array
*/
public function processIndexes($results)
{
return array_map(function ($result) {
$result = (object) $result;

return [
'name' => strtolower($result->name),
'columns' => explode(',', $result->columns),
'type' => strtolower($result->type),
'unique' => (bool) $result->unique,
'primary' => (bool) $result->primary,
];
}, $results);
}
}
11 changes: 11 additions & 0 deletions src/Illuminate/Database/Query/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ public function processColumns($results)
return $results;
}

/**
* Process the results of an indexes query.
*
* @param array $results
* @return array
*/
public function processIndexes($results)
{
return $results;
}

/**
* Process the results of a column listing query.
*
Expand Down
33 changes: 33 additions & 0 deletions src/Illuminate/Database/Query/Processors/SQLiteProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,37 @@ public function processColumns($results)
];
}, $results);
}

/**
* Process the results of an indexes query.
*
* @param array $results
* @return array
*/
public function processIndexes($results)
{
$primaryCount = 0;

$indexes = array_map(function ($result) use (&$primaryCount) {
$result = (object) $result;

if ($isPrimary = (bool) $result->primary) {
$primaryCount += 1;
}

return [
'name' => strtolower($result->name),
'columns' => explode(',', $result->columns),
'type' => null,
'unique' => (bool) $result->unique,
'primary' => $isPrimary,
];
}, $results);

if ($primaryCount > 1) {
$indexes = array_filter($indexes, fn ($index) => $index['name'] !== 'primary');
}

return $indexes;
}
}
21 changes: 21 additions & 0 deletions src/Illuminate/Database/Query/Processors/SqlServerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,25 @@ public function processColumns($results)
];
}, $results);
}

/**
* Process the results of an indexes query.
*
* @param array $results
* @return array
*/
public function processIndexes($results)
{
return array_map(function ($result) {
$result = (object) $result;

return [
'name' => strtolower($result->name),
'columns' => explode(',', $result->columns),
'type' => strtolower($result->type),
'unique' => (bool) $result->unique,
'primary' => (bool) $result->primary,
];
}, $results);
}
}
15 changes: 15 additions & 0 deletions src/Illuminate/Database/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,21 @@ public function getColumns($table)
);
}

/**
* Get the indexes for a given table.
*
* @param string $table
* @return array
*/
public function getIndexes($table)
{
$table = $this->connection->getTablePrefix().$table;

return $this->connection->getPostProcessor()->processIndexes(
$this->connection->selectFromWriteConnection($this->grammar->compileIndexes($table))
);
}

/**
* Modify a table on the schema.
*
Expand Down
19 changes: 19 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ public function compileColumns($database, $table)
);
}

/**
* Compile the query to determine the indexes.
*
* @param string $database
* @param string $table
* @return string
*/
public function compileIndexes($database, $table)
{
return sprintf(
'select index_name as `name`, group_concat(column_name order by seq_in_index) as `columns`, '
.'index_type as `type`, not non_unique as `unique` '
.'from information_schema.statistics where table_schema = %s and table_name = %s '
.'group by index_name, index_type, non_unique',
$this->quoteString($database),
$this->quoteString($table)
);
}

/**
* Compile a create table command.
*
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,32 @@ public function compileColumns($database, $schema, $table)
);
}

/**
* Compile the query to determine the indexes.
*
* @param string $schema
* @param string $table
* @return string
*/
public function compileIndexes($schema, $table)
{
return sprintf(
"select ic.relname as name, string_agg(a.attname, ',' order by indseq.ord) as columns, "
.'am.amname as "type", i.indisunique as "unique", i.indisprimary as "primary" '
.'from pg_index i '
.'join pg_class tc on tc.oid = i.indrelid '
.'join pg_namespace tn on tn.oid = tc.relnamespace '
.'join pg_class ic on ic.oid = i.indexrelid '
.'join pg_am am on am.oid = ic.relam '
.'join lateral unnest(i.indkey) with ordinality as indseq(num, ord) on true '
.'left join pg_attribute a on a.attrelid = i.indrelid and a.attnum = indseq.num '
.'where tc.relname = %s and tn.nspname = %s '
.'group by ic.relname, am.amname, i.indisunique, i.indisprimary',
$this->quoteString($table),
$this->quoteString($schema)
);
}

/**
* Compile a create table command.
*
Expand Down
19 changes: 19 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,25 @@ public function compileColumns($table)
);
}

/**
* Compile the query to determine the indexes.
*
* @param string $table
* @return string
*/
public function compileIndexes($table)
{
return sprintf(
'select "primary" as name, group_concat(col) as columns, 1 as "unique", 1 as "primary" '
.'from (select name as col from pragma_table_info(%s) where pk > 0 order by pk, cid) group by name '
.'union select name, group_concat(col) as columns, "unique", origin = "pk" as "primary" '
.'from (select il.*, ii.name as col from pragma_index_list(%s) il, pragma_index_info(il.name) ii order by il.seq, ii.seqno) '
.'group by name, "unique", "primary"',
$table = $this->wrap(str_replace('.', '__', $table)),
$table
);
}

/**
* Compile a create table command.
*
Expand Down
22 changes: 22 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,28 @@ public function compileColumns($table)
);
}

/**
* Compile the query to determine the indexes.
*
* @param string $table
* @return string
*/
public function compileIndexes($table)
{
return sprintf(
"select idx.name as name, string_agg(col.name, ',') within group (order by idxcol.key_ordinal) as columns, "
.'idx.type_desc as [type], idx.is_unique as [unique], idx.is_primary_key as [primary] '
.'from sys.indexes as idx '
.'join sys.tables as tbl on idx.object_id = tbl.object_id '
.'join sys.schemas as scm on tbl.schema_id = scm.schema_id '
.'join sys.index_columns as idxcol on idx.object_id = idxcol.object_id and idx.index_id = idxcol.index_id '
.'join sys.columns as col on idxcol.object_id = col.object_id and idxcol.column_id = col.column_id '
.'where tbl.name = %s and scm.name = SCHEMA_NAME() '
.'group by idx.name, idx.type_desc, idx.is_unique, idx.is_primary_key',
$this->quoteString($table),
);
}

/**
* Compile a create table command.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Illuminate/Database/Schema/MySqlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,23 @@ public function getColumns($table)
return $this->connection->getPostProcessor()->processColumns($results);
}

/**
* Get the indexes for a given table.
*
* @param string $table
* @return array
*/
public function getIndexes($table)
{
$table = $this->connection->getTablePrefix().$table;

return $this->connection->getPostProcessor()->processIndexes(
$this->connection->selectFromWriteConnection(
$this->grammar->compileIndexes($this->connection->getDatabaseName(), $table)
)
);
}

/**
* Drop all tables from the database.
*
Expand Down
17 changes: 17 additions & 0 deletions src/Illuminate/Database/Schema/PostgresBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,23 @@ public function getColumns($table)
return $this->connection->getPostProcessor()->processColumns($results);
}

/**
* Get the indexes for a given table.
*
* @param string $table
* @return array
*/
public function getIndexes($table)
{
[, $schema, $table] = $this->parseSchemaAndTable($table);

$table = $this->connection->getTablePrefix().$table;

return $this->connection->getPostProcessor()->processIndexes(
$this->connection->selectFromWriteConnection($this->grammar->compileIndexes($schema, $table))
);
}

/**
* Get the schemas for the connection.
*
Expand Down
1 change: 1 addition & 0 deletions src/Illuminate/Support/Facades/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* @method static string getColumnType(string $table, string $column, bool $fullDefinition = false)
* @method static array getColumnListing(string $table)
* @method static array getColumns(string $table)
* @method static array getIndexes(string $table)
* @method static void table(string $table, \Closure $callback)
* @method static void create(string $table, \Closure $callback)
* @method static void drop(string $table)
Expand Down
17 changes: 9 additions & 8 deletions tests/Database/DatabaseSQLiteSchemaGrammarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,21 @@ public function testRenameIndex()
$table->index(['name', 'email'], 'index1');
});

$manager = $db->getConnection()->getDoctrineSchemaManager();
$details = $manager->listTableDetails('prefix_users');
$this->assertTrue($details->hasIndex('index1'));
$this->assertFalse($details->hasIndex('index2'));
$indexes = array_column($schema->getIndexes('users'), 'name');

$this->assertContains('index1', $indexes);
$this->assertNotContains('index2', $indexes);

$schema->table('users', function (Blueprint $table) {
$table->renameIndex('index1', 'index2');
});

$details = $manager->listTableDetails('prefix_users');
$this->assertFalse($details->hasIndex('index1'));
$this->assertTrue($details->hasIndex('index2'));
$indexes = $schema->getIndexes('users');

$this->assertEquals(['name', 'email'], $details->getIndex('index2')->getUnquotedColumns());
$this->assertNotContains('index1', array_column($indexes, 'name'));
$this->assertTrue(collect($indexes)->contains(
fn ($index) => $index['name'] === 'index2' && $index['columns'] === ['name', 'email']
));
}

public function testAddingPrimaryKey()
Expand Down
10 changes: 8 additions & 2 deletions tests/Database/DatabaseSchemaBuilderIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ public function testHasColumnAndIndexWithPrefixIndexDisabled()
$table->string('name')->index();
});

$this->assertArrayHasKey('table1_name_index', $this->db->connection()->getDoctrineSchemaManager()->listTableIndexes('example_table1'));
$this->assertContains(
'table1_name_index',
array_column($this->db->connection()->getSchemaBuilder()->getIndexes('table1'), 'name')
);
}

public function testHasColumnAndIndexWithPrefixIndexEnabled()
Expand All @@ -104,7 +107,10 @@ public function testHasColumnAndIndexWithPrefixIndexEnabled()
$table->string('name')->index();
});

$this->assertArrayHasKey('example_table1_name_index', $this->db->connection()->getDoctrineSchemaManager()->listTableIndexes('example_table1'));
$this->assertContains(
'example_table1_name_index',
array_column($this->db->connection()->getSchemaBuilder()->getIndexes('table1'), 'name')
);
}

public function testDropColumnWithTablePrefix()
Expand Down
Loading