Commit 1ae87bf3 authored by Benjamin Eberlei's avatar Benjamin Eberlei

DBAL-177 - Make sure schema.table syntax is supported in Assets for quoted assets

parent bb844961
<?php <?php
/* /*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
...@@ -32,7 +30,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; ...@@ -32,7 +30,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.org * @link www.doctrine-project.org
* @since 2.0 * @since 2.0
* @version $Revision$
* @author Benjamin Eberlei <kontakt@beberlei.de> * @author Benjamin Eberlei <kontakt@beberlei.de>
*/ */
abstract class AbstractAsset abstract class AbstractAsset
...@@ -77,7 +74,7 @@ abstract class AbstractAsset ...@@ -77,7 +74,7 @@ abstract class AbstractAsset
*/ */
protected function trimQuotes($identifier) protected function trimQuotes($identifier)
{ {
return trim($identifier, '`"'); return str_replace(array('`', '"'), '', $identifier);
} }
/** /**
...@@ -100,7 +97,12 @@ abstract class AbstractAsset ...@@ -100,7 +97,12 @@ abstract class AbstractAsset
public function getQuotedName(AbstractPlatform $platform) public function getQuotedName(AbstractPlatform $platform)
{ {
$keywords = $platform->getReservedKeywordsList(); $keywords = $platform->getReservedKeywordsList();
return ($this->_quoted || $keywords->isKeyword($this->_name)) ? $platform->quoteIdentifier($this->_name) : $this->_name; $parts = explode(".", $this->_name);
foreach ($parts AS $k => $v) {
$parts[$k] = ($this->_quoted || $keywords->isKeyword($v)) ? $platform->quoteIdentifier($v) : $v;
}
return implode(".", $parts);
} }
/** /**
...@@ -117,25 +119,6 @@ abstract class AbstractAsset ...@@ -117,25 +119,6 @@ abstract class AbstractAsset
*/ */
protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30) protected function _generateIdentifierName($columnNames, $prefix='', $maxSize=30)
{ {
/*$columnCount = count($columnNames);
$postfixLen = strlen($postfix);
$parts = array_map(function($columnName) use($columnCount, $postfixLen, $maxSize) {
return substr($columnName, -floor(($maxSize-$postfixLen)/$columnCount - 1));
}, $columnNames);
$parts[] = $postfix;
$identifier = trim(implode("_", $parts), '_');
// using implicit schema support of DB2 and Postgres there might be dots in the auto-generated
// identifier names which can easily be replaced by underscores.
$identifier = str_replace(".", "_", $identifier);
if (is_numeric(substr($identifier, 0, 1))) {
$identifier = "i" . substr($identifier, 0, strlen($identifier)-1);
}
return $identifier;*/
$hash = implode("", array_map(function($column) { $hash = implode("", array_map(function($column) {
return dechex(crc32($column)); return dechex(crc32($column));
}, $columnNames)); }, $columnNames));
......
...@@ -32,6 +32,70 @@ namespace Doctrine\DBAL\Schema; ...@@ -32,6 +32,70 @@ namespace Doctrine\DBAL\Schema;
*/ */
class PostgreSqlSchemaManager extends AbstractSchemaManager class PostgreSqlSchemaManager extends AbstractSchemaManager
{ {
/**
* @var array
*/
private $existingSchemaPaths;
/**
* Get all the existing schema names.
*
* @return array
*/
public function getSchemaNames()
{
$rows = $this->_conn->fetchAll('SELECT schema_name FROM information_schema.schemata');
return array_map(function($v) { return $v['schema_name']; }, $rows);
}
/**
* Return an array of schema search paths
*
* This is a PostgreSQL only function.
*
* @return array
*/
public function getSchemaSearchPaths()
{
$params = $this->_conn->getParams();
$schema = explode(",", $this->_conn->fetchColumn('SHOW search_path'));
if (isset($params['user'])) {
$schema = str_replace('"$user"', $params['user'], $schema);
}
return $schema;
}
/**
* Get names of all existing schemas in the current users search path.
*
* This is a PostgreSQL only function.
*
* @return array
*/
public function getExistingSchemaSearchPaths()
{
if ($this->existingSchemaPaths === null) {
$this->determineExistingSchemaSearchPaths();
}
return $this->existingSchemaPaths;
}
/**
* Use this to set or reset the order of the existing schemas in the current search path of the user
*
* This is a PostgreSQL only function.
*
* @return type
*/
public function determineExistingSchemaSearchPaths()
{
$names = $this->getSchemaNames();
$paths = $this->getSchemaSearchPaths();
$this->existingSchemaPaths = array_filter($paths, function ($v) use ($names) {
return in_array($v, $names);
});
}
protected function _getPortableTableForeignKeyDefinition($tableForeignKey) protected function _getPortableTableForeignKeyDefinition($tableForeignKey)
{ {
...@@ -111,7 +175,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -111,7 +175,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
protected function _getPortableTableDefinition($table) protected function _getPortableTableDefinition($table)
{ {
if ($table['schema_name'] == 'public') { $schemas = $this->getExistingSchemaSearchPaths();
$firstSchema = array_shift($schemas);
var_dump($firstSchema);
if ($table['schema_name'] == $firstSchema) {
return $table['table_name']; return $table['table_name'];
} else { } else {
return $table['schema_name'] . "." . $table['table_name']; return $table['schema_name'] . "." . $table['table_name'];
......
...@@ -10,6 +10,17 @@ require_once __DIR__ . '/../../../TestInit.php'; ...@@ -10,6 +10,17 @@ require_once __DIR__ . '/../../../TestInit.php';
class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase class PostgreSqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
{ {
/**
* @group DBAL-177
*/
public function testGetSearchPath()
{
$params = $this->_conn->getParams();
$paths = $this->_sm->getSchemaSearchPaths();
$this->assertEquals(array($params['user'], 'public'), $paths);
}
/** /**
* @group DBAL-21 * @group DBAL-21
*/ */
......
...@@ -12,7 +12,7 @@ use Doctrine\DBAL\Schema\Index; ...@@ -12,7 +12,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
class TableTest extends \PHPUnit_Framework_TestCase class TableTest extends \Doctrine\Tests\DbalTestCase
{ {
public function testCreateWithInvalidTableName() public function testCreateWithInvalidTableName()
{ {
...@@ -111,7 +111,7 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -111,7 +111,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
$type = \Doctrine\DBAL\Types\Type::getType('integer'); $type = \Doctrine\DBAL\Types\Type::getType('integer');
$columns = array(new Column("foo", $type), new Column("bar", $type), new Column("baz", $type)); $columns = array(new Column("foo", $type), new Column("bar", $type), new Column("baz", $type));
$table = new Table("foo", $columns); $table = new Table("foo", $columns);
$table->addIndex(array("foo", "bar"), "foo_foo_bar_idx"); $table->addIndex(array("foo", "bar"), "foo_foo_bar_idx");
$table->addUniqueIndex(array("bar", "baz"), "foo_bar_baz_uniq"); $table->addUniqueIndex(array("bar", "baz"), "foo_bar_baz_uniq");
...@@ -312,7 +312,7 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -312,7 +312,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
$constraints = $table->getForeignKeys(); $constraints = $table->getForeignKeys();
$this->assertEquals(1, count($constraints)); $this->assertEquals(1, count($constraints));
$constraint = current($constraints); $constraint = current($constraints);
$this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $constraint); $this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $constraint);
$this->assertTrue($constraint->hasOption("foo")); $this->assertTrue($constraint->hasOption("foo"));
...@@ -339,7 +339,7 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -339,7 +339,7 @@ class TableTest extends \PHPUnit_Framework_TestCase
$this->assertFalse($column->getNotnull()); $this->assertFalse($column->getNotnull());
$table->setPrimaryKey(array('id')); $table->setPrimaryKey(array('id'));
$this->assertTrue($column->getNotnull()); $this->assertTrue($column->getNotnull());
} }
...@@ -406,18 +406,18 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -406,18 +406,18 @@ class TableTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(1, count($table->getIndexes())); $this->assertEquals(1, count($table->getIndexes()));
$this->assertFalse($table->hasIndex($index->getName())); $this->assertFalse($table->hasIndex($index->getName()));
} }
public function testPrimaryKeyOverrulesUniqueIndex() public function testPrimaryKeyOverrulesUniqueIndex()
{ {
$table = new Table("bar"); $table = new Table("bar");
$table->addColumn('baz', 'integer', array()); $table->addColumn('baz', 'integer', array());
$table->addUniqueIndex(array('baz')); $table->addUniqueIndex(array('baz'));
$table->setPrimaryKey(array('baz')); $table->setPrimaryKey(array('baz'));
$indexes = $table->getIndexes(); $indexes = $table->getIndexes();
$this->assertEquals(1, count($indexes), "Table should only contain the primary key table index, not the unique one anymore, because it was overruled."); $this->assertEquals(1, count($indexes), "Table should only contain the primary key table index, not the unique one anymore, because it was overruled.");
$index = current($indexes); $index = current($indexes);
$this->assertTrue($index->isPrimary()); $this->assertTrue($index->isPrimary());
} }
...@@ -473,4 +473,14 @@ class TableTest extends \PHPUnit_Framework_TestCase ...@@ -473,4 +473,14 @@ class TableTest extends \PHPUnit_Framework_TestCase
$table->addColumn('bar', 'integer'); $table->addColumn('bar', 'integer');
$table->addForeignKeyConstraint('"boing"', array('"foo"', '"bar"'), array("id")); $table->addForeignKeyConstraint('"boing"', array('"foo"', '"bar"'), array("id"));
} }
/**
* @group DBAL-177
*/
public function testQuoteSchemaPrefixed()
{
$table = new Table("`test`.`test`");
$this->assertEquals("test.test", $table->getName());
$this->assertEquals("`test`.`test`", $table->getQuotedName(new \Doctrine\DBAL\Platforms\MySqlPlatform));
}
} }
\ 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