Skip to content

Commit

Permalink
Merge pull request #326 from krichprollsch/fix-reverse-mssql-quote
Browse files Browse the repository at this point in the history
fix #320 reverse engineering : select tablename can returns quoted name ...
  • Loading branch information
willdurand committed Mar 29, 2012
2 parents 89d686e + 22fec05 commit ac4eb50
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
29 changes: 21 additions & 8 deletions generator/lib/reverse/mssql/MssqlSchemaParser.php
Expand Up @@ -82,7 +82,7 @@ public function parse(Database $database, Task $task = null)
// First load the tables (important that this happen before filling out details of tables)
$tables = array();
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$name = $row[0];
$name = $this->cleanDelimitedIdentifiers($row[0]);
if ($name == $this->getMigrationTable()) {
continue;
}
Expand Down Expand Up @@ -118,7 +118,7 @@ protected function addColumns(Table $table)

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

$name = $row['COLUMN_NAME'];
$name = $this->cleanDelimitedIdentifiers($row['COLUMN_NAME']);
$type = $row['TYPE_NAME'];
$size = $row['LENGTH'];
$is_nullable = $row['NULLABLE'];
Expand Down Expand Up @@ -171,9 +171,9 @@ protected function addForeignKeys(Table $table)
$foreignKeys = array(); // local store to avoid duplicates
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

$lcol = $row['COLUMN_NAME'];
$ftbl = $row['FK_TABLE_NAME'];
$fcol = $row['FK_COLUMN_NAME'];
$lcol = $this->cleanDelimitedIdentifiers($row['COLUMN_NAME']);
$ftbl = $this->cleanDelimitedIdentifiers($row['FK_TABLE_NAME']);
$fcol = $this->cleanDelimitedIdentifiers($row['FK_COLUMN_NAME']);

$foreignTable = $database->getTable($ftbl);
$foreignColumn = $foreignTable->getColumn($fcol);
Expand Down Expand Up @@ -202,8 +202,8 @@ protected function addIndexes(Table $table)

$indexes = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$colName = $row["COLUMN_NAME"];
$name = $row['INDEX_NAME'];
$colName = $this->cleanDelimitedIdentifiers($row["COLUMN_NAME"]);
$name = $this->cleanDelimitedIdentifiers($row['INDEX_NAME']);

// FIXME -- Add UNIQUE support
if (!isset($indexes[$name])) {
Expand All @@ -230,9 +230,22 @@ protected function addPrimaryKey(Table $table)
// Loop through the returned results, grouping the same key_name together
// adding each column for that key.
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$name = $row[0];
$name = $this->cleanDelimitedIdentifiers($row[0]);
$table->getColumn($name)->setPrimaryKey(true);
}
}

/**
* according to the identifier definition, we have to clean simple quote (') around the identifier name
* returns by mssql
* @see http://msdn.microsoft.com/library/ms175874.aspx
*
* @param string $identifier
* @return string
*/
protected function cleanDelimitedIdentifiers($identifier)
{
return preg_replace('/^\'(.*)\'$/U', '$1', $identifier);
}

}
69 changes: 69 additions & 0 deletions test/testsuite/generator/reverse/mssql/MssqlSchemaParserTest.php
@@ -0,0 +1,69 @@
<?php

/**
* This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/

require_once dirname(__FILE__) . '/../../../../../generator/lib/reverse/mssql/MssqlSchemaParser.php';
require_once dirname(__FILE__) . '/../../../../../generator/lib/model/PropelTypes.php';

/**
* Tests for Mssql database schema parser.
*
* @author Pierre Tachoire
* @version $Revision$
* @package propel.generator.reverse.mssql
*/
class MssqlSchemaParserTest extends PHPUnit_Framework_TestCase
{
public function testCleanDelimitedIdentifiers()
{
$parser = new TestableMssqlSchemaParser(null);

$expected = 'this is a tablename';

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected.'\'');
$this->assertEquals($expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected);
$this->assertEquals('\''.$expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers($expected.'\'');
$this->assertEquals($expected.'\'', $tested);

$expected = 'this is a tabl\'ename';

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected.'\'');
$this->assertEquals($expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected);
$this->assertEquals('\''.$expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers($expected.'\'');
$this->assertEquals($expected.'\'', $tested);

$expected = 'this is a\'tabl\'ename';

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected.'\'');
$this->assertEquals($expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers('\''.$expected);
$this->assertEquals('\''.$expected, $tested);

$tested = $parser->cleanDelimitedIdentifiers($expected.'\'');
$this->assertEquals($expected.'\'', $tested);

}
}

class TestableMssqlSchemaParser extends MssqlSchemaParser
{
public function cleanDelimitedIdentifiers($identifier)
{
return parent::cleanDelimitedIdentifiers($identifier);
}
}

0 comments on commit ac4eb50

Please sign in to comment.