Commit 27b3c95b authored by Benjamin Eberlei's avatar Benjamin Eberlei

[DBAL-204] Add API to filter tables/sequenecs based on a regexp

parent c6c84a09
......@@ -83,4 +83,31 @@ class Configuration
{
$this->_attributes['resultCacheImpl'] = $cacheImpl;
}
}
\ No newline at end of file
/**
* Filter schema assets expression.
*
* Only include tables/sequences matching the filter expression regexp in
* schema instances generated for the active connection when calling
* {AbstractSchemaManager#createSchema()}.
*
* @param string $filterExpression
*/
public function setFilterSchemaAssetsExpression($filterExpression)
{
$this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
}
/**
* Return filter schema assets expression.
*
* @return string|null
*/
public function getFilterSchemaAssetsExpression()
{
if (isset($this->_attributes['filterSchemaAssetsExpression'])) {
return $this->_attributes['filterSchemaAssetsExpression'];
}
return null;
}
}
......@@ -2348,6 +2348,20 @@ abstract class AbstractPlatform
return false;
}
/**
* Can this platform emulate schemas?
*
* Platforms that either support or emulate schemas don't automatically
* filter a schema for the namespaced elements in {@link
* AbstractManager#createSchema}.
*
* @return bool
*/
public function canEmulateSchemas()
{
return false;
}
/**
* Some databases don't allow to create and drop databases at all or only with certain tools.
*
......
......@@ -501,4 +501,18 @@ class SqlitePlatform extends AbstractPlatform
$tableName = str_replace(".", "__", $tableName);
return $tableName;
}
/**
* Sqlite Platform emulates schema by underscoring each dot and generating tables
* into the default database.
*
* This hack is implemented to be able to use SQLite as testdriver when
* using schema supporting databases.
*
* @return bool
*/
public function canEmulateSchemas()
{
return true;
}
}
......@@ -129,7 +129,7 @@ abstract class AbstractSchemaManager
$sequences = $this->_conn->fetchAll($sql);
return $this->_getPortableSequencesList($sequences);
return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
}
/**
......@@ -188,7 +188,6 @@ abstract class AbstractSchemaManager
return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames())));
}
/**
* Return a list of all tables in the current database
*
......@@ -199,8 +198,34 @@ abstract class AbstractSchemaManager
$sql = $this->_platform->getListTablesSQL();
$tables = $this->_conn->fetchAll($sql);
$tableNames = $this->_getPortableTablesList($tables);
return $this->filterAssetNames($tableNames);
}
return $this->_getPortableTablesList($tables);
/**
* Filter asset names if they are configured to return only a subset of all
* the found elements.
*
* @param array $assetNames
* @return array
*/
protected function filterAssetNames($assetNames)
{
$filterExpr = $this->getFilterSchemaAssetsExpression();
if (!$filterExpr) {
return $assetNames;
}
return array_values (
array_filter($assetNames, function ($assetName) use ($filterExpr) {
$assetName = ($assetName instanceof AbstractAsset) ? $assetName->getName() : $assetName;
return preg_match('(' . $filterExpr . ')', $assetName);
})
);
}
protected function getFilterSchemaAssetsExpression()
{
return $this->_conn->getConfiguration()->getFilterSchemaAssetsExpression();
}
/**
......@@ -804,8 +829,7 @@ abstract class AbstractSchemaManager
}
$tables = $this->listTables();
$schema = new Schema($tables, $sequences, $this->createSchemaConfig());
return $schema;
return new Schema($tables, $sequences, $this->createSchemaConfig());
}
/**
......@@ -826,6 +850,18 @@ abstract class AbstractSchemaManager
return $schemaConfig;
}
/**
* The search path for namespaces in the currently connected database.
*
* The first entry is usually the default namespace in the Schema. All
* further namespaces contain tables/sequences which can also be addressed
* with a short, not full-qualified name.
*
* For databases that don't support subschema/namespaces this method
* returns the name of the currently connected database.
*
* @return array
*/
public function getSchemaSearchPaths()
{
return array($this->_conn->getDatabase());
......
......@@ -10,6 +10,11 @@ require_once __DIR__ . '/../../../TestInit.php';
class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
{
public function tearDown()
{
parent::tearDown();
$this->_conn->getConfiguration()->setFilterSchemaAssetsExpression(null);
}
/**
* @group DBAL-177
*/
......@@ -166,6 +171,27 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->_conn->getDatabasePlatform()->getCreateTableSQL($table)
);
}
/**
* @group DBAL-204
*/
public function testFilterSchemaExpression()
{
$testTable = new \Doctrine\DBAL\Schema\Table('dbal204_test_prefix');
$column = $testTable->addColumn('id', 'integer');
$this->_sm->createTable($testTable);
$testTable = new \Doctrine\DBAL\Schema\Table('dbal204_without_prefix');
$column = $testTable->addColumn('id', 'integer');
$this->_sm->createTable($testTable);
$this->_conn->getConfiguration()->setFilterSchemaAssetsExpression('^dbal204_');
$names = $this->_sm->listTableNames();
$this->assertEquals(2, count($names));
$this->_conn->getConfiguration()->setFilterSchemaAssetsExpression('^dbal204_test');
$names = $this->_sm->listTableNames();
$this->assertEquals(1, count($names));
}
}
class MoneyType extends Type
......@@ -181,4 +207,4 @@ class MoneyType extends Type
return 'MyMoney';
}
}
\ No newline at end of file
}
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