Skip to content

Commit

Permalink
Apply the connection filter to indexes
Browse files Browse the repository at this point in the history
When there are indexes that are not supported by doctrine present in
a database, they will consistently create "DROP" migrations.  By
applying the schema filter to the indexes one will be able to exclude
these indexes from future migrations preventing the manual work of
removing the DROP statement each time a migration is created.

Fixes: #5420
  • Loading branch information
Allen Lai committed Jul 18, 2023
1 parent 1c462ee commit d3b365f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 8 deletions.
39 changes: 31 additions & 8 deletions src/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public function listTableIndexes($table)

$tableIndexes = $this->_conn->fetchAllAssociative($sql);

return $this->_getPortableTableIndexesList($tableIndexes, $table);
return $this->filterIndexAssets($this->_getPortableTableIndexesList($tableIndexes, $table));

Check warning on line 277 in src/Schema/AbstractSchemaManager.php

View check run for this annotation

Codecov / codecov/patch

src/Schema/AbstractSchemaManager.php#L277

Added line #L277 was not covered by tests
}

/**
Expand All @@ -289,12 +289,14 @@ protected function doListTableIndexes($table): array
$database = $this->getDatabase(__METHOD__);
$table = $this->normalizeName($table);

return $this->_getPortableTableIndexesList(
$this->selectIndexColumns(
$database,
return $this->filterIndexAssets(
$this->_getPortableTableIndexesList(
$this->selectIndexColumns(
$database,
$table,
)->fetchAllAssociative(),
$table,
)->fetchAllAssociative(),
$table,
),
);
}

Expand Down Expand Up @@ -377,6 +379,26 @@ protected function filterAssetNames($assetNames)
return array_values(array_filter($assetNames, $filter));
}

/**
* @param array<int|string, Index> $indexes
*
* @return array<int|string, Index>
*/
protected function filterIndexAssets(array $indexes): array
{
$filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter();
if ($filter === null) {
return $indexes;

Check warning on line 391 in src/Schema/AbstractSchemaManager.php

View check run for this annotation

Codecov / codecov/patch

src/Schema/AbstractSchemaManager.php#L391

Added line #L391 was not covered by tests
}

return array_filter(
$indexes,
static function (Index $i) use ($filter): bool {
return $filter($i->getName());
},
);
}

/**
* Lists the tables for this connection.
*
Expand Down Expand Up @@ -418,10 +440,11 @@ protected function doListTables(): array
continue;
}

$tables[] = new Table(
$tableIndexes = $this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName);
$tables[] = new Table(
$tableName,
$this->_getPortableTableColumnList($tableName, $database, $tableColumns),
$this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName),
$this->filterIndexAssets($tableIndexes),
[],
$this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []),
$tableOptionsByTable[$tableName] ?? [],
Expand Down
42 changes: 42 additions & 0 deletions tests/Functional/Schema/SchemaManagerFunctionalTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,48 @@ public static function tableFilterProvider(): iterable
yield 'Two tables' => ['filter_test_', 2];
}

/** @dataProvider indexFilterProvider */
public function testListTableIndexesWithFilter(string $prefix, int $expectedCount): void
{
$tableName = 'list_table_indexes_test';
$table = $this->getTestTable($tableName);
$table->addUniqueIndex(['test'], 'test_index_name');
$table->addIndex(['id', 'test'], 'test_composite_idx');

$this->dropAndCreateTable($table);

$this->markConnectionNotReusable();

$this->connection->getConfiguration()->setSchemaAssetsFilter(
static function (string $name) use ($prefix): bool {
return substr(strtolower($name), 0, strlen($prefix)) !== $prefix;
},
);

$table = null;
foreach ($this->schemaManager->listTables() as $t) {
if ($tableName !== strtolower($t->getName())) {
continue;
}

$table = $t;
}

self::assertNotNull($table);
self::assertCount($expectedCount, $this->schemaManager->listTableIndexes($tableName));
self::assertCount($expectedCount, $table->getIndexes());
}

/** @return iterable<string, array{string, int}> */
public static function indexFilterProvider(): iterable
{
// index count includes the primary key on the table
yield 'Filter index' => ['test_index_', 2];
yield 'Filter unique index' => ['test_composite', 2];
yield 'No indexes returned' => ['test_', 1];
yield 'Both indexes returned' => ['includes_all', 3];
}

public function testRenameTable(): void
{
$this->createTestTable('old_name');
Expand Down

0 comments on commit d3b365f

Please sign in to comment.