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; ...@@ -4,6 +4,8 @@ namespace Doctrine\DBAL;
use Doctrine\Common\Cache\Cache; use Doctrine\Common\Cache\Cache;
use Doctrine\DBAL\Logging\SQLLogger; use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\Schema\AbstractAsset;
use function preg_match;
/** /**
* Configuration container for the Doctrine DBAL. * Configuration container for the Doctrine DBAL.
...@@ -75,6 +77,11 @@ class Configuration ...@@ -75,6 +77,11 @@ class Configuration
public function setFilterSchemaAssetsExpression($filterExpression) public function setFilterSchemaAssetsExpression($filterExpression)
{ {
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression; $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
if ($filterExpression) {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression);
} else {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = null;
}
} }
/** /**
...@@ -87,6 +94,36 @@ class Configuration ...@@ -87,6 +94,36 @@ class Configuration
return $this->_attributes['filterSchemaAssetsExpression'] ?? null; 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. * Sets the default auto-commit mode for connections.
* *
......
...@@ -219,18 +219,12 @@ abstract class AbstractSchemaManager ...@@ -219,18 +219,12 @@ abstract class AbstractSchemaManager
*/ */
protected function filterAssetNames($assetNames) protected function filterAssetNames($assetNames)
{ {
$filterExpr = $this->getFilterSchemaAssetsExpression(); $filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter();
if (! $filterExpr) { if (! $filter) {
return $assetNames; return $assetNames;
} }
return array_values( return array_values(array_filter($assetNames, $filter));
array_filter($assetNames, static function ($assetName) use ($filterExpr) {
$assetName = $assetName instanceof AbstractAsset ? $assetName->getName() : $assetName;
return preg_match($filterExpr, $assetName);
})
);
} }
/** /**
......
...@@ -10,6 +10,7 @@ use Doctrine\DBAL\Platforms\DB2Platform; ...@@ -10,6 +10,7 @@ use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Schema\DB2SchemaManager; use Doctrine\DBAL\Schema\DB2SchemaManager;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject; use PHPUnit_Framework_MockObject_MockObject;
use function in_array;
/** /**
* @covers \Doctrine\DBAL\Schema\DB2SchemaManager * @covers \Doctrine\DBAL\Schema\DB2SchemaManager
...@@ -60,4 +61,139 @@ final class DB2SchemaManagerTest extends TestCase ...@@ -60,4 +61,139 @@ final class DB2SchemaManagerTest extends TestCase
$this->manager->listTableNames() $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