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 ...@@ -83,4 +83,31 @@ class Configuration
{ {
$this->_attributes['resultCacheImpl'] = $cacheImpl; $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 ...@@ -2348,6 +2348,20 @@ abstract class AbstractPlatform
return false; 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. * 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 ...@@ -501,4 +501,18 @@ class SqlitePlatform extends AbstractPlatform
$tableName = str_replace(".", "__", $tableName); $tableName = str_replace(".", "__", $tableName);
return $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 ...@@ -129,7 +129,7 @@ abstract class AbstractSchemaManager
$sequences = $this->_conn->fetchAll($sql); $sequences = $this->_conn->fetchAll($sql);
return $this->_getPortableSequencesList($sequences); return $this->filterAssetNames($this->_getPortableSequencesList($sequences));
} }
/** /**
...@@ -188,7 +188,6 @@ abstract class AbstractSchemaManager ...@@ -188,7 +188,6 @@ abstract class AbstractSchemaManager
return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames()))); return count($tableNames) == count(\array_intersect($tableNames, array_map('strtolower', $this->listTableNames())));
} }
/** /**
* Return a list of all tables in the current database * Return a list of all tables in the current database
* *
...@@ -199,8 +198,34 @@ abstract class AbstractSchemaManager ...@@ -199,8 +198,34 @@ abstract class AbstractSchemaManager
$sql = $this->_platform->getListTablesSQL(); $sql = $this->_platform->getListTablesSQL();
$tables = $this->_conn->fetchAll($sql); $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 ...@@ -804,8 +829,7 @@ abstract class AbstractSchemaManager
} }
$tables = $this->listTables(); $tables = $this->listTables();
$schema = new Schema($tables, $sequences, $this->createSchemaConfig()); return new Schema($tables, $sequences, $this->createSchemaConfig());
return $schema;
} }
/** /**
...@@ -826,6 +850,18 @@ abstract class AbstractSchemaManager ...@@ -826,6 +850,18 @@ abstract class AbstractSchemaManager
return $schemaConfig; 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() public function getSchemaSearchPaths()
{ {
return array($this->_conn->getDatabase()); return array($this->_conn->getDatabase());
......
...@@ -10,6 +10,11 @@ require_once __DIR__ . '/../../../TestInit.php'; ...@@ -10,6 +10,11 @@ require_once __DIR__ . '/../../../TestInit.php';
class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
{ {
public function tearDown()
{
parent::tearDown();
$this->_conn->getConfiguration()->setFilterSchemaAssetsExpression(null);
}
/** /**
* @group DBAL-177 * @group DBAL-177
*/ */
...@@ -166,6 +171,27 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -166,6 +171,27 @@ class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->_conn->getDatabasePlatform()->getCreateTableSQL($table) $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 class MoneyType extends Type
...@@ -181,4 +207,4 @@ class MoneyType extends Type ...@@ -181,4 +207,4 @@ class MoneyType extends Type
return 'MyMoney'; 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