Unverified Commit 18a8040a authored by Sergei Morozov's avatar Sergei Morozov Committed by GitHub

Merge pull request #3308 from bezhermoso/custom-asset-filter-as-callable

Implement {Configuration#getSchemaAssetsFilter}
parents ed25dc9c 5110a192
......@@ -4,6 +4,8 @@ namespace Doctrine\DBAL;
use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\Schema\AbstractAsset;
use function preg_match;
/**
* Configuration container for the Doctrine DBAL.
......@@ -75,6 +77,11 @@ class Configuration
public function setFilterSchemaAssetsExpression($filterExpression)
{
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
if ($filterExpression) {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression);
} else {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = null;
}
}
/**
......@@ -87,6 +94,36 @@ class Configuration
return $this->_attributes['filterSchemaAssetsExpression'] ?? null;
}
/**
* @param string $filterExpression
*/
private function buildSchemaAssetsFilterFromExpression($filterExpression) : callable
{
return static function ($assetName) use ($filterExpression) {
if ($assetName instanceof AbstractAsset) {
$assetName = $assetName->getName();
}
return preg_match($filterExpression, $assetName);
};
}
/**
* Sets the callable to use to filter schema assets.
*/
public function setSchemaAssetsFilter(?callable $callable = null) : ?callable
{
$this->_attributes['filterSchemaAssetsExpression'] = null;
return $this->_attributes['filterSchemaAssetsExpressionCallable'] = $callable;
}
/**
* Returns the callable to use to filter schema assets.
*/
public function getSchemaAssetsFilter() : ?callable
{
return $this->_attributes['filterSchemaAssetsExpressionCallable'] ?? null;
}
/**
* Sets the default auto-commit mode for connections.
*
......
......@@ -219,18 +219,12 @@ abstract class AbstractSchemaManager
*/
protected function filterAssetNames($assetNames)
{
$filterExpr = $this->getFilterSchemaAssetsExpression();
if (! $filterExpr) {
$filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter();
if (! $filter) {
return $assetNames;
}
return array_values(
array_filter($assetNames, static function ($assetName) use ($filterExpr) {
$assetName = $assetName instanceof AbstractAsset ? $assetName->getName() : $assetName;
return preg_match($filterExpr, $assetName);
})
);
return array_values(array_filter($assetNames, $filter));
}
/**
......
......@@ -10,6 +10,7 @@ use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Schema\DB2SchemaManager;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use function in_array;
/**
* @covers \Doctrine\DBAL\Schema\DB2SchemaManager
......@@ -60,4 +61,139 @@ final class DB2SchemaManagerTest extends TestCase
$this->manager->listTableNames()
);
}
/**
* @return void
*
* @group DBAL-2701
*/
public function testAssetFilteringSetsACallable()
{
$filterExpression = '/^(?!T_)/';
$this->conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
$this->conn->expects($this->once())->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
['name' => 'BAR'],
['name' => 'T_BAR'],
]));
self::assertSame(
[
'FOO',
'BAR',
],
$this->manager->listTableNames()
);
$callable = $this->conn->getConfiguration()->getSchemaAssetsFilter();
$this->assertInternalType('callable', $callable);
// BC check: Test that regexp expression is still preserved & accessible.
$this->assertEquals($filterExpression, $this->conn->getConfiguration()->getFilterSchemaAssetsExpression());
}
/**
* @return void
*/
public function testListTableNamesFiltersAssetNamesCorrectlyWithCallable()
{
$accepted = ['T_FOO', 'T_BAR'];
$this->conn->getConfiguration()->setSchemaAssetsFilter(static function ($assetName) use ($accepted) {
return in_array($assetName, $accepted);
});
$this->conn->expects($this->once())->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
['name' => 'BAR'],
['name' => 'T_BAR'],
]));
self::assertSame(
[
'T_FOO',
'T_BAR',
],
$this->manager->listTableNames()
);
$this->assertNull($this->conn->getConfiguration()->getFilterSchemaAssetsExpression());
}
/**
* @return void
*/
public function testSettingNullExpressionWillResetCallable()
{
$accepted = ['T_FOO', 'T_BAR'];
$this->conn->getConfiguration()->setSchemaAssetsFilter(static function ($assetName) use ($accepted) {
return in_array($assetName, $accepted);
});
$this->conn->expects($this->atLeastOnce())->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
['name' => 'BAR'],
['name' => 'T_BAR'],
]));
self::assertSame(
[
'T_FOO',
'T_BAR',
],
$this->manager->listTableNames()
);
$this->conn->getConfiguration()->setFilterSchemaAssetsExpression(null);
self::assertSame(
[
'FOO',
'T_FOO',
'BAR',
'T_BAR',
],
$this->manager->listTableNames()
);
$this->assertNull($this->conn->getConfiguration()->getSchemaAssetsFilter());
}
/**
* @return void
*/
public function testSettingNullAsCallableClearsExpression()
{
$filterExpression = '/^(?!T_)/';
$this->conn->getConfiguration()->setFilterSchemaAssetsExpression($filterExpression);
$this->conn->expects($this->exactly(2))->method('fetchAll')->will($this->returnValue([
['name' => 'FOO'],
['name' => 'T_FOO'],
['name' => 'BAR'],
['name' => 'T_BAR'],
]));
self::assertSame(
[
'FOO',
'BAR',
],
$this->manager->listTableNames()
);
$this->conn->getConfiguration()->setSchemaAssetsFilter(null);
self::assertSame(
[
'FOO',
'T_FOO',
'BAR',
'T_BAR',
],
$this->manager->listTableNames()
);
$this->assertNull($this->conn->getConfiguration()->getFilterSchemaAssetsExpression());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment