Commit 793d249e authored by Benjamin Eberlei's avatar Benjamin Eberlei

Merge pull request #98 from doctrine/DBAL-204

[DBAL-204] Full Schema Namespacing Support
parents 087b6937 27b3c95b
......@@ -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;
}
}
......@@ -2239,7 +2239,7 @@ abstract class AbstractPlatform
return Connection::TRANSACTION_READ_COMMITTED;
}
/* supports*() metods */
/* supports*() methods */
/**
* Whether the platform supports sequences.
......@@ -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;
}
}
......@@ -39,6 +39,16 @@ abstract class AbstractAsset
*/
protected $_name;
/**
* Namespace of the asset. If none isset the default namespace is assumed.
*
* @var string
*/
protected $_namespace;
/**
* @var bool
*/
protected $_quoted = false;
/**
......@@ -52,9 +62,73 @@ abstract class AbstractAsset
$this->_quoted = true;
$name = $this->trimQuotes($name);
}
if (strpos($name, ".") !== false) {
$parts = explode(".", $name);
$this->_namespace = $parts[0];
$name = $parts[1];
}
$this->_name = $name;
}
/**
* Is this asset in the default namespace?
*
* @param string $defaultNamespaceName
* @return bool
*/
public function isInDefaultNamespace($defaultNamespaceName)
{
return $this->_namespace == $defaultNamespaceName || $this->_namespace === null;
}
/**
* Get namespace name of this asset.
*
* If NULL is returned this means the default namespace is used.
*
* @return string
*/
public function getNamespaceName()
{
return $this->_namespace;
}
/**
* The shortest name is stripped of the default namespace. All other
* namespaced elements are returned as full-qualified names.
*
* @param string
* @return string
*/
public function getShortestName($defaultNamespaceName)
{
$shortestName = $this->getName();
if ($this->_namespace == $defaultNamespaceName) {
$shortestName = $this->_name;
}
return strtolower($shortestName);
}
/**
* The normalized name is full-qualified and lowerspaced. Lowerspacing is
* actually wrong, but we have to do it to keep our sanity. If you are
* using database objects that only differentiate in the casing (FOO vs
* Foo) then you will NOT be able to use Doctrine Schema abstraction.
*
* Every non-namespaced element is prefixed with the default namespace
* name which is passed as argument to this method.
*
* @return string
*/
public function getFullQualifiedName($defaultNamespaceName)
{
$name = $this->getName();
if (!$this->_namespace) {
$name = $defaultNamespaceName . "." . $name;
}
return strtolower($name);
}
/**
* Check if this identifier is quoted.
*
......@@ -84,6 +158,9 @@ abstract class AbstractAsset
*/
public function getName()
{
if ($this->_namespace) {
return $this->_namespace . "." . $this->_name;
}
return $this->_name;
}
......@@ -97,7 +174,7 @@ abstract class AbstractAsset
public function getQuotedName(AbstractPlatform $platform)
{
$keywords = $platform->getReservedKeywordsList();
$parts = explode(".", $this->_name);
$parts = explode(".", $this->getName());
foreach ($parts AS $k => $v) {
$parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
}
......@@ -124,4 +201,4 @@ abstract class AbstractAsset
}, $columnNames));
return substr(strtoupper($prefix . "_" . $hash), 0, $maxSize);
}
}
\ No newline at end of file
}
......@@ -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();
}
/**
......@@ -817,9 +842,31 @@ abstract class AbstractSchemaManager
$schemaConfig = new SchemaConfig();
$schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength());
$searchPaths = $this->getSchemaSearchPaths();
if (isset($searchPaths[0])) {
$schemaConfig->setName($searchPaths[0]);
}
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());
}
/**
* Given a table comment this method tries to extract a typehint for Doctrine Type, or returns
* the type given as default.
......
......@@ -61,20 +61,24 @@ class Comparator
$foreignKeysToTable = array();
foreach ( $toSchema->getTables() AS $tableName => $table ) {
if ( !$fromSchema->hasTable($tableName) ) {
$diff->newTables[$tableName] = $table;
foreach ( $toSchema->getTables() AS $table ) {
$tableName = $table->getShortestName($toSchema->getName());
if ( ! $fromSchema->hasTable($tableName)) {
$diff->newTables[$tableName] = $toSchema->getTable($tableName);
} else {
$tableDifferences = $this->diffTable( $fromSchema->getTable($tableName), $table );
if ( $tableDifferences !== false ) {
$tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName));
if ($tableDifferences !== false) {
$diff->changedTables[$tableName] = $tableDifferences;
}
}
}
/* Check if there are tables removed */
foreach ( $fromSchema->getTables() AS $tableName => $table ) {
if ( !$toSchema->hasTable($tableName) ) {
foreach ($fromSchema->getTables() AS $table) {
$tableName = $table->getShortestName($fromSchema->getName());
$table = $fromSchema->getTable($tableName);
if ( ! $toSchema->hasTable($tableName) ) {
$diff->removedTables[$tableName] = $table;
}
......@@ -94,7 +98,8 @@ class Comparator
}
}
foreach ( $toSchema->getSequences() AS $sequenceName => $sequence) {
foreach ($toSchema->getSequences() AS $sequence) {
$sequenceName = $sequence->getShortestName($toSchema->getName());
if (!$fromSchema->hasSequence($sequenceName)) {
$diff->newSequences[] = $sequence;
} else {
......@@ -104,7 +109,8 @@ class Comparator
}
}
foreach ($fromSchema->getSequences() AS $sequenceName => $sequence) {
foreach ($fromSchema->getSequences() AS $sequence) {
$sequenceName = $sequence->getShortestName($fromSchema->getName());
if (!$toSchema->hasSequence($sequenceName)) {
$diff->removedSequences[] = $sequence;
}
......
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -28,10 +26,30 @@ use Doctrine\DBAL\Schema\Visitor\Visitor;
/**
* Object representation of a database schema
*
* Different vendors have very inconsistent naming with regard to the concept
* of a "schema". Doctrine understands a schema as the entity that conceptually
* wraps a set of database objects such as tables, sequences, indexes and
* foreign keys that belong to each other into a namespace. A Doctrine Schema
* has nothing to do with the "SCHEMA" defined as in PostgreSQL, it is more
* related to the concept of "DATABASE" that exists in MySQL and PostgreSQL.
*
* Every asset in the doctrine schema has a name. A name consists of either a
* namespace.local name pair or just a local unqualified name.
*
* The abstraction layer that covers a PostgreSQL schema is the namespace of an
* database object (asset). A schema can have a name, which will be used as
* default namespace for the unqualified database objects that are created in
* the schema.
*
* In the case of MySQL where cross-database queries are allowed this leads to
* databases being "misinterpreted" as namespaces. This is intentional, however
* the CREATE/DROP SQL visitors will just filter this queries and do not
* execute them. Only the queries for the currently connected database are
* executed.
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class Schema extends AbstractAsset
......@@ -64,6 +82,7 @@ class Schema extends AbstractAsset
$schemaConfig = new SchemaConfig();
}
$this->_schemaConfig = $schemaConfig;
$this->_setName($schemaConfig->getName() ?: 'public');
foreach ($tables AS $table) {
$this->_addTable($table);
......@@ -86,7 +105,7 @@ class Schema extends AbstractAsset
*/
protected function _addTable(Table $table)
{
$tableName = strtolower($table->getName());
$tableName = $table->getFullQualifiedName($this->getName());
if(isset($this->_tables[$tableName])) {
throw SchemaException::tableAlreadyExists($tableName);
}
......@@ -100,7 +119,7 @@ class Schema extends AbstractAsset
*/
protected function _addSequence(Sequence $sequence)
{
$seqName = strtolower($sequence->getName());
$seqName = $sequence->getFullQualifiedName($this->getName());
if (isset($this->_sequences[$seqName])) {
throw SchemaException::sequenceAlreadyExists($seqName);
}
......@@ -123,7 +142,7 @@ class Schema extends AbstractAsset
*/
public function getTable($tableName)
{
$tableName = strtolower($tableName);
$tableName = $this->getFullQualifiedAssetName($tableName);
if (!isset($this->_tables[$tableName])) {
throw SchemaException::tableDoesNotExist($tableName);
}
......@@ -131,6 +150,17 @@ class Schema extends AbstractAsset
return $this->_tables[$tableName];
}
/**
* @return string
*/
private function getFullQualifiedAssetName($name)
{
if (strpos($name, ".") === false) {
$name = $this->getName() . "." . $name;
}
return strtolower($name);
}
/**
* Does this schema have a table with the given name?
*
......@@ -139,17 +169,24 @@ class Schema extends AbstractAsset
*/
public function hasTable($tableName)
{
$tableName = strtolower($tableName);
$tableName = $this->getFullQualifiedAssetName($tableName);
return isset($this->_tables[$tableName]);
}
/**
* @param string $sequenceName
* @return bool
* Get all table names, prefixed with a schema name, even the default one
* if present.
*
* @return array
*/
public function getTableNames()
{
return array_keys($this->_tables);
}
public function hasSequence($sequenceName)
{
$sequenceName = strtolower($sequenceName);
$sequenceName = $this->getFullQualifiedAssetName($sequenceName);
return isset($this->_sequences[$sequenceName]);
}
......@@ -160,7 +197,7 @@ class Schema extends AbstractAsset
*/
public function getSequence($sequenceName)
{
$sequenceName = strtolower($sequenceName);
$sequenceName = $this->getFullQualifiedAssetName($sequenceName);
if(!$this->hasSequence($sequenceName)) {
throw SchemaException::sequenceDoesNotExist($sequenceName);
}
......@@ -213,7 +250,7 @@ class Schema extends AbstractAsset
*/
public function dropTable($tableName)
{
$tableName = strtolower($tableName);
$tableName = $this->getFullQualifiedAssetName($tableName);
$table = $this->getTable($tableName);
unset($this->_tables[$tableName]);
return $this;
......@@ -240,7 +277,7 @@ class Schema extends AbstractAsset
*/
public function dropSequence($sequenceName)
{
$sequenceName = strtolower($sequenceName);
$sequenceName = $this->getFullQualifiedAssetName($sequenceName);
unset($this->_sequences[$sequenceName]);
return $this;
}
......
<?php
/*
* $Id: Schema.php 6876 2009-12-06 23:11:35Z beberlei $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
......@@ -27,7 +25,6 @@ namespace Doctrine\DBAL\Schema;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org
* @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class SchemaConfig
......@@ -42,6 +39,11 @@ class SchemaConfig
*/
protected $_maxIdentifierLength = 63;
/**
* @var string
*/
protected $_name;
/**
* @return bool
*/
......@@ -73,4 +75,24 @@ class SchemaConfig
{
return $this->_maxIdentifierLength;
}
}
\ No newline at end of file
/**
* Get default namespace of schema objects.
*
* @return string
*/
public function getName()
{
return $this->_name;
}
/**
* set default namespace name of schema objects.
*
* @param _name the value to set.
*/
public function setName($name)
{
$this->_name = $name;
}
}
......@@ -632,4 +632,4 @@ class Table extends AbstractAsset
$this->_fkConstraints[$k]->setLocalTable($this);
}
}
}
\ No newline at end of file
}
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\DBAL\Schema\Visitor;
use Doctrine\DBAL\Platforms\AbstractPlatform,
Doctrine\DBAL\Schema\Table,
Doctrine\DBAL\Schema\Schema,
Doctrine\DBAL\Schema\Column,
Doctrine\DBAL\Schema\ForeignKeyConstraint,
Doctrine\DBAL\Schema\Constraint,
Doctrine\DBAL\Schema\Sequence,
Doctrine\DBAL\Schema\Index;
/**
* Remove assets from a schema that are not in the default namespace.
*
* Some databases such as MySQL support cross databases joins, but don't
* allow to call DDLs to a database from another connected database.
* Before a schema is serialized into SQL this visitor can cleanup schemas with
* non default namespaces.
*
* This visitor filters all these non-default namespaced tables and sequences
* and removes them from the SChema instance.
*
* @author Benjamin Eberlei <kontakt@beberlei.de>
* @since 2.2
*/
class RemoveNamespacedAssets implements Visitor
{
/**
* @var Schema
*/
private $schema;
/**
* @param Schema $schema
*/
public function acceptSchema(Schema $schema)
{
$this->schema = $schema;
}
/**
* @param Table $table
*/
public function acceptTable(Table $table)
{
if ( ! $table->isInDefaultNamespace($this->schema->getName()) ) {
$this->schema->dropTable($table->getName());
}
}
/**
* @param Sequence $sequence
*/
public function acceptSequence(Sequence $sequence)
{
if ( ! $sequence->isInDefaultNamespace($this->schema->getName()) ) {
$this->schema->dropSequence($sequence->getName());
}
}
/**
* @param Column $column
*/
public function acceptColumn(Table $table, Column $column)
{
}
/**
* @param Table $localTable
* @param ForeignKeyConstraint $fkConstraint
*/
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
{
}
/**
* @param Table $table
* @param Index $index
*/
public function acceptIndex(Table $table, Index $index)
{
}
}
......@@ -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
}
......@@ -366,7 +366,6 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$this->createTestTable('test_table');
$schema = $this->_sm->createSchema();
$this->assertTrue($schema->hasTable('test_table'));
}
......
......@@ -22,6 +22,7 @@ namespace Doctrine\Tests\DBAL\Schema;
require_once __DIR__ . '/../../TestInit.php';
use Doctrine\DBAL\Schema\Schema,
Doctrine\DBAL\Schema\SchemaConfig,
Doctrine\DBAL\Schema\Table,
Doctrine\DBAL\Schema\Column,
Doctrine\DBAL\Schema\Index,
......@@ -702,6 +703,62 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array(), $c->diffColumn($column, $column2));
}
/**
* @group DBAL-204
*/
public function testFqnSchemaComparision()
{
$config = new SchemaConfig();
$config->setName("foo");
$oldSchema = new Schema(array(), array(), $config);
$oldSchema->createTable('bar');
$newSchema= new Schema(array(), array(), $config);
$newSchema->createTable('foo.bar');
$c = new Comparator();
$this->assertEquals(new SchemaDiff(), $c->compare($oldSchema, $newSchema));
}
/**
* @group DBAL-204
*/
public function testFqnSchemaComparisionDifferentSchemaNameButSameTableNoDiff()
{
$config = new SchemaConfig();
$config->setName("foo");
$oldSchema = new Schema(array(), array(), $config);
$oldSchema->createTable('foo.bar');
$newSchema = new Schema();
$newSchema->createTable('bar');
$c = new Comparator();
$diff = $c->compare($oldSchema, $newSchema);
$this->assertEquals(new SchemaDiff(), $c->compare($oldSchema, $newSchema));
}
/**
* @group DBAL-204
*/
public function testFqnSchemaComparisionNoSchemaSame()
{
$config = new SchemaConfig();
$config->setName("foo");
$oldSchema = new Schema(array(), array(), $config);
$oldSchema->createTable('bar');
$newSchema = new Schema();
$newSchema->createTable('bar');
$c = new Comparator();
$diff = $c->compare($oldSchema, $newSchema);
$this->assertEquals(new SchemaDiff(), $c->compare($oldSchema, $newSchema));
}
/**
* @param SchemaDiff $diff
* @param int $newTableCount
......@@ -727,4 +784,4 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($changeSequenceCount, count($diff->changedSequences), "Expected number of changed sequences is wrong.");
$this->assertEquals($removeSequenceCount, count($diff->removedSequences), "Expected number of removed sequences is wrong.");
}
}
\ No newline at end of file
}
......@@ -12,7 +12,7 @@ class SchemaTest extends \PHPUnit_Framework_TestCase
{
public function testAddTable()
{
$tableName = "foo";
$tableName = "public.foo";
$table = new Table($tableName);
$schema = new Schema(array($table));
......@@ -107,7 +107,7 @@ class SchemaTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Doctrine\DBAL\Schema\Sequence', $schema->getSequence("a_seq"));
$sequences = $schema->getSequences();
$this->assertArrayHasKey('a_seq', $sequences);
$this->assertArrayHasKey('public.a_seq', $sequences);
}
public function testSequenceAccessCaseInsensitive()
......@@ -145,7 +145,7 @@ class SchemaTest extends \PHPUnit_Framework_TestCase
$this->assertInstanceOf('Doctrine\DBAL\Schema\Sequence', $schema->getSequence("a_seq"));
$sequences = $schema->getSequences();
$this->assertArrayHasKey('a_seq', $sequences);
$this->assertArrayHasKey('public.a_seq', $sequences);
}
public function testDropSequence()
......@@ -208,4 +208,4 @@ class SchemaTest extends \PHPUnit_Framework_TestCase
$fk = current($fk);
$this->assertSame($schemaNew->getTable('bar'), $this->readAttribute($fk, '_localTable'));
}
}
\ No newline at end of file
}
......@@ -483,4 +483,18 @@ class TableTest extends \Doctrine\Tests\DbalTestCase
$this->assertEquals("test.test", $table->getName());
$this->assertEquals("`test`.`test`", $table->getQuotedName(new \Doctrine\DBAL\Platforms\MySqlPlatform));
}
}
\ No newline at end of file
/**
* @group DBAL-204
*/
public function testFullQualifiedTableName()
{
$table = new Table("`test`.`test`");
$this->assertEquals('test.test', $table->getFullQualifiedName("test"));
$this->assertEquals('test.test', $table->getFullQualifiedName("other"));
$table = new Table("test");
$this->assertEquals('test.test', $table->getFullQualifiedName("test"));
$this->assertEquals('other.test', $table->getFullQualifiedName("other"));
}
}
<?php
namespace Doctrine\Tests\DBAL\Schema\Visitor;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\SchemaConfig;
use Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets;
class RemoveNamespacedAssetsTest extends \PHPUnit_Framework_TestCase
{
/**
* @group DBAL-204
*/
public function testRemoveNamespacedAssets()
{
$config = new SchemaConfig;
$config->setName("test");
$schema = new Schema(array(), array(), $config);
$schema->createTable("test.test");
$schema->createTable("foo.bar");
$schema->createTable("baz");
$schema->visit(new RemoveNamespacedAssets());
$tables = $schema->getTables();
$this->assertEquals(array("test.test", "test.baz"), array_keys($tables), "Only 2 tables should be present, both in 'test' namespace.");
}
}
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