Skip to content

Commit

Permalink
Added methods getIndexes hasIndex and getIndexListing into `Hyp…
Browse files Browse the repository at this point in the history
…erf\Database\Schema\Builder`. (#6883)
  • Loading branch information
zds-s authored Jun 18, 2024
1 parent 3286a38 commit 0375a4e
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Query/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ public function processColumns(array $results): array
return $columns;
}

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

/**
* Process the results of a views query.
*/
Expand Down
41 changes: 41 additions & 0 deletions src/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,47 @@ public function getColumns(): array
return $this->connection->getPostProcessor()->processColumns($results);
}

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

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

/**
* Get the names of the indexes for a given table.
*/
public function getIndexListing(string $table): array
{
return array_column($this->getIndexes($table), 'name');
}

/**
* Determine if the given table has a given index.
*/
public function hasIndex(string $table, array|string $index, ?string $type = null): bool
{
$type = is_null($type) ? $type : strtolower($type);

foreach ($this->getIndexes($table) as $value) {
$typeMatches = is_null($type)
|| ($type === 'primary' && $value['primary'])
|| ($type === 'unique' && $value['unique'])
|| $type === $value['type'];

if (($value['name'] === $index || $value['columns'] === $index) && $typeMatches) {
return true;
}
}

return false;
}

/**
* Modify a table on the schema.
*
Expand Down
15 changes: 15 additions & 0 deletions src/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,21 @@ public function compileGetAllTables()
return 'SHOW FULL TABLES WHERE table_type = \'BASE TABLE\'';
}

/**
* Compile the query to determine the indexes.
*/
public function compileIndexes(string $database, string $table): string
{
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 the SQL needed to retrieve all view names.
*
Expand Down
14 changes: 14 additions & 0 deletions src/Schema/MySqlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ public function getColumnTypeListing($table)
return $processor->processListing($results);
}

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

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

/**
* Get the tables that belong to the database.
*/
Expand Down
3 changes: 3 additions & 0 deletions src/Schema/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
* @method static array getAllTables()
* @method static array getTables()
* @method static array getAllViews()
* @method static array getIndexes(string $table)
* @method static array getIndexListing(string $table)
* @method static bool hasIndex(string $table, array|string $index, ?string $type = null)
* @method static bool hasColumn(string $table, string $column)
* @method static bool hasColumns(string $table, array $columns)
* @method static string getColumnType(string $table, string $column)
Expand Down
99 changes: 99 additions & 0 deletions tests/SchemaBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
use HyperfTest\Database\Stubs\ContainerStub;
use PHPUnit\Framework\TestCase;

use function Hyperf\Collection\collect;

/**
* @internal
* @coversNothing
Expand Down Expand Up @@ -102,4 +104,101 @@ public function testColumn(): void
$this->assertSame(['id', 'name', 'ranking'], array_column($columns, 'column_name'));
Schema::drop('column_1');
}

public function index(): void
{
Schema::create('users', function (Blueprint $table) {
$table->string('name');
$table->string('email');
});

Schema::table('users', function (Blueprint $table) {
$table->index(['name', 'email'], 'index1');
});

$indexes = Schema::getIndexListing('users');

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

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

$this->assertFalse(Schema::hasIndex('users', 'index1'));
$this->assertTrue(collect(Schema::getIndexes('users'))->contains(
fn ($index) => $index['name'] === 'index2' && $index['columns'] === ['name', 'email']
));
Schema::create('foo', function (Blueprint $table) {
$table->id();
$table->string('bar');
$table->integer('baz');

$table->unique(['baz', 'bar']);
});

$indexes = Schema::getIndexes('foo');

$this->assertCount(2, $indexes);
$this->assertTrue(collect($indexes)->contains(
fn ($index) => $index['columns'] === ['id'] && $index['primary']
));
$this->assertTrue(collect($indexes)->contains(
fn ($index) => $index['name'] === 'foo_baz_bar_unique' && $index['columns'] === ['baz', 'bar'] && $index['unique']
));
$this->assertTrue(Schema::hasIndex('foo', 'foo_baz_bar_unique'));
$this->assertTrue(Schema::hasIndex('foo', 'foo_baz_bar_unique', 'unique'));
$this->assertTrue(Schema::hasIndex('foo', ['baz', 'bar']));
$this->assertTrue(Schema::hasIndex('foo', ['baz', 'bar'], 'unique'));
$this->assertFalse(Schema::hasIndex('foo', ['baz', 'bar'], 'primary'));
Schema::drop('foo');
Schema::create('foo', function (Blueprint $table) {
$table->string('bar')->index('my_index');
});

$indexes = Schema::getIndexes('foo');

$this->assertCount(1, $indexes);
$this->assertTrue(
$indexes[0]['name'] === 'my_index'
&& $indexes[0]['columns'] === ['bar']
&& ! $indexes[0]['unique']
&& ! $indexes[0]['primary']
);
$this->assertTrue(Schema::hasIndex('foo', 'my_index'));
$this->assertTrue(Schema::hasIndex('foo', ['bar']));
$this->assertFalse(Schema::hasIndex('foo', 'my_index', 'primary'));
$this->assertFalse(Schema::hasIndex('foo', ['bar'], 'unique'));
Schema::drop('foo');
Schema::create('foo', function (Blueprint $table) {
$table->unsignedBigInteger('key');
$table->string('bar')->unique();
$table->integer('baz');

$table->primary(['baz', 'key']);
});

$indexes = Schema::getIndexes('foo');

$this->assertCount(2, $indexes);
$this->assertTrue(collect($indexes)->contains(
fn ($index) => $index['columns'] === ['baz', 'key'] && $index['primary']
));
$this->assertTrue(collect($indexes)->contains(
fn ($index) => $index['name'] === 'foo_bar_unique' && $index['columns'] === ['bar'] && $index['unique']
));
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title', 200);
$table->text('body');

$table->fulltext(['body', 'title']);
});

$indexes = Schema::getIndexes('articles');

$this->assertCount(2, $indexes);
$this->assertTrue(collect($indexes)->contains(fn ($index) => $index['columns'] === ['id'] && $index['primary']));
$this->assertTrue(collect($indexes)->contains('name', 'articles_body_title_fulltext'));
}
}

0 comments on commit 0375a4e

Please sign in to comment.