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
/*
* $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
......@@ -32,7 +30,6 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
* @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>
*/
abstract class AbstractAsset
......@@ -77,7 +74,7 @@ abstract class AbstractAsset
*/
protected function trimQuotes($identifier)
{
return trim($identifier, '`"');
return str_replace(array('`', '"'), '', $identifier);
}
/**
......@@ -100,7 +97,12 @@ abstract class AbstractAsset
public function getQuotedName(AbstractPlatform $platform)
{
$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
*/
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) {
return dechex(crc32($column));
}, $columnNames));
......
......@@ -32,6 +32,70 @@ namespace Doctrine\DBAL\Schema;
*/
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)
{
......@@ -111,7 +175,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
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'];
} else {
return $table['schema_name'] . "." . $table['table_name'];
......
......@@ -10,6 +10,17 @@ require_once __DIR__ . '/../../../TestInit.php';
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
*/
......
......@@ -12,7 +12,7 @@ use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Types\Type;
class TableTest extends \PHPUnit_Framework_TestCase
class TableTest extends \Doctrine\Tests\DbalTestCase
{
public function testCreateWithInvalidTableName()
{
......@@ -473,4 +473,14 @@ class TableTest extends \PHPUnit_Framework_TestCase
$table->addColumn('bar', 'integer');
$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