Skip to content

Commit

Permalink
Implement {Configuration#getFilterSchemaAssetsCallable}
Browse files Browse the repository at this point in the history
  • Loading branch information
bezhermoso committed Oct 6, 2018
1 parent ed25dc9 commit 348e600
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 9 deletions.
37 changes: 37 additions & 0 deletions lib/Doctrine/DBAL/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

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.
Expand Down Expand Up @@ -75,6 +77,11 @@ public function setResultCacheImpl(Cache $cacheImpl)
public function setFilterSchemaAssetsExpression($filterExpression)
{
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
if ($filterExpression) {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression);
} else {
$this->_attributes['filterSchemaAssetsExpressionCallable'] = null;
}
}

/**
Expand All @@ -87,6 +94,36 @@ public function getFilterSchemaAssetsExpression()
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.
*
Expand Down
12 changes: 3 additions & 9 deletions lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,18 +219,12 @@ public function listTableNames()
*/
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));
}

/**
Expand Down
136 changes: 136 additions & 0 deletions tests/Doctrine/Tests/DBAL/Schema/DB2SchemaManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Doctrine\DBAL\Schema\DB2SchemaManager;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use function in_array;

/**
* @covers \Doctrine\DBAL\Schema\DB2SchemaManager
Expand Down Expand Up @@ -60,4 +61,139 @@ public function testListTableNamesFiltersAssetNamesCorrectly()
$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());
}
}

0 comments on commit 348e600

Please sign in to comment.