Unverified Commit cfd9c0ac authored by Luís Cobucci's avatar Luís Cobucci

Merge branch 'fix/sqlite-schema-regex' into 2.6

Backporting: https://github.com/doctrine/dbal/pull/2865
parents 8302030c a3b5386c
...@@ -264,7 +264,7 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -264,7 +264,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$comment = $this->parseColumnCommentFromSQL($columnName, $createSql); $comment = $this->parseColumnCommentFromSQL($columnName, $createSql);
if (false !== $comment) { if ($comment !== null) {
$type = $this->extractDoctrineTypeFromComment($comment, null); $type = $this->extractDoctrineTypeFromComment($comment, null);
if (null !== $type) { if (null !== $type) {
...@@ -435,43 +435,29 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -435,43 +435,29 @@ class SqliteSchemaManager extends AbstractSchemaManager
return $tableDiff; return $tableDiff;
} }
/** private function parseColumnCollationFromSQL(string $column, string $sql) : ?string
* @param string $column
* @param string $sql
*
* @return string|false
*/
private function parseColumnCollationFromSQL($column, $sql)
{ {
if (preg_match( $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' . preg_quote($this->_platform->quoteSingleIdentifier($column))
'{(?:'.preg_quote($column).'|'.preg_quote($this->_platform->quoteSingleIdentifier($column)).') . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}isx';
[^,(]+(?:\([^()]+\)[^,]*)?
(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)* if (preg_match($pattern, $sql, $match) !== 1) {
COLLATE\s+["\']?([^\s,"\')]+)}isx', $sql, $match)) { return null;
return $match[1];
} }
return false; return $match[1];
} }
/** private function parseColumnCommentFromSQL(string $column, string $sql) : ?string
* @param string $column
* @param string $sql
*
* @return string|false
*/
private function parseColumnCommentFromSQL($column, $sql)
{ {
if (preg_match( $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column)
'{[\s(,](?:'.preg_quote($this->_platform->quoteSingleIdentifier($column)).'|'.preg_quote($column).') . '\W)(?:\(.*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}ix';
(?:\(.*?\)|[^,(])*?,?((?:\s*--[^\n]*\n?)+)
}isx', $sql, $match
)) {
$comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n"));
return '' === $comment ? false : $comment; if (preg_match($pattern, $sql, $match) !== 1) {
return null;
} }
return false; $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n"));
return '' === $comment ? null : $comment;
} }
} }
...@@ -2,45 +2,101 @@ ...@@ -2,45 +2,101 @@
namespace Doctrine\Tests\DBAL\Schema; namespace Doctrine\Tests\DBAL\Schema;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\SqlitePlatform; use Doctrine\DBAL\Platforms\SqlitePlatform;
use Doctrine\DBAL\Schema\SqliteSchemaManager; use Doctrine\DBAL\Schema\SqliteSchemaManager;
class SqliteSchemaManagerTest extends \PHPUnit_Framework_TestCase class SqliteSchemaManagerTest extends \PHPUnit_Framework_TestCase
{ {
/** /**
* @dataProvider getDataColumnCollation * @dataProvider getDataColumnCollation
*
* @group 2865
*/ */
public function testParseColumnCollation($collation, $column, $sql) public function testParseColumnCollation(?string $collation, string $column, string $sql) : void
{ {
$conn = $this->getMockBuilder('Doctrine\DBAL\Connection')->disableOriginalConstructor()->getMock(); $conn = $this->createMock(Connection::class);
$conn->expects($this->any())->method('getDatabasePlatform')->will($this->returnValue(new SqlitePlatform())); $conn->method('getDatabasePlatform')->willReturn(new SqlitePlatform());
$manager = new SqliteSchemaManager($conn); $manager = new SqliteSchemaManager($conn);
$ref = new \ReflectionMethod($manager, 'parseColumnCollationFromSQL'); $ref = new \ReflectionMethod($manager, 'parseColumnCollationFromSQL');
$ref->setAccessible(true); $ref->setAccessible(true);
$this->assertEquals($collation, $ref->invoke($manager, $column, $sql)); self::assertSame($collation, $ref->invoke($manager, $column, $sql));
} }
public function getDataColumnCollation() public function getDataColumnCollation()
{ {
return array( return [
array( ['RTRIM', 'a', 'CREATE TABLE "a" ("a" text DEFAULT "aa" COLLATE "RTRIM" NOT NULL)'],
'RTRIM', 'a', 'CREATE TABLE "a" ("a" text DEFAULT "aa" COLLATE "RTRIM" NOT NULL)' ['utf-8', 'a', 'CREATE TABLE "a" ("b" text UNIQUE NOT NULL COLLATE NOCASE, "a" text DEFAULT "aa" COLLATE "utf-8" NOT NULL)'],
), ['NOCASE', 'a', 'CREATE TABLE "a" ("a" text DEFAULT (lower(ltrim(" a") || rtrim("a "))) CHECK ("a") NOT NULL COLLATE NOCASE UNIQUE, "b" text COLLATE RTRIM)'],
array( [null, 'a', 'CREATE TABLE "a" ("a" text CHECK ("a") NOT NULL, "b" text COLLATE RTRIM)'],
'utf-8', 'a', 'CREATE TABLE "a" ("b" text UNIQUE NOT NULL COLLATE NOCASE, "a" text DEFAULT "aa" COLLATE "utf-8" NOT NULL)' ['RTRIM', 'a"b', 'CREATE TABLE "a" ("a""b" text COLLATE RTRIM)'],
), ['BINARY', 'b', 'CREATE TABLE "a" (bb TEXT COLLATE RTRIM, b VARCHAR(42) NOT NULL COLLATE BINARY)'],
array( ['BINARY', 'b', 'CREATE TABLE "a" (bbb TEXT COLLATE NOCASE, bb TEXT COLLATE RTRIM, b VARCHAR(42) NOT NULL COLLATE BINARY)'],
'NOCASE', 'a', 'CREATE TABLE "a" ("a" text DEFAULT (lower(ltrim(" a") || rtrim("a "))) CHECK ("a") NOT NULL COLLATE NOCASE UNIQUE, "b" text COLLATE RTRIM)' ['BINARY', 'b', 'CREATE TABLE "a" (b VARCHAR(42) NOT NULL COLLATE BINARY, bb TEXT COLLATE RTRIM)'],
), ];
array( }
false, 'a', 'CREATE TABLE "a" ("a" text CHECK ("a") NOT NULL, "b" text COLLATE RTRIM)'
), /**
array( * @dataProvider getDataColumnComment
'RTRIM', 'a"b', 'CREATE TABLE "a" ("a""b" text COLLATE RTRIM)' *
), * @group 2865
); */
public function testParseColumnCommentFromSQL(?string $comment, string $column, string $sql) : void
{
$conn = $this->createMock(Connection::class);
$conn->method('getDatabasePlatform')->willReturn(new SqlitePlatform());
$manager = new SqliteSchemaManager($conn);
$ref = new \ReflectionMethod($manager, 'parseColumnCommentFromSQL');
$ref->setAccessible(true);
self::assertSame($comment, $ref->invoke($manager, $column, $sql));
}
public function getDataColumnComment()
{
return [
'Single column with no comment' => [
null, 'a', 'CREATE TABLE "a" ("a" TEXT DEFAULT "a" COLLATE RTRIM)',
],
'Single column with type comment' => [
'(DC2Type:x)', 'a', 'CREATE TABLE "a" ("a" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
)',
],
'Multiple similar columns with type comment 1' => [
null, 'b', 'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "b" TEXT DEFAULT "a" COLLATE RTRIM, "bb" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
)',
],
'Multiple similar columns with type comment 2' => [
'(DC2Type:x)', 'b', 'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "bb" TEXT DEFAULT "a" COLLATE RTRIM, "b" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
)',
],
'Multiple similar columns on different lines, with type comment 1' => [
null, 'bb', 'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "b" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
, "bb" TEXT DEFAULT "a" COLLATE RTRIM',
],
'Multiple similar columns on different lines, with type comment 2' => [
'(DC2Type:x)', 'bb', 'CREATE TABLE "a" (a TEXT COLLATE RTRIM, "bb" CLOB DEFAULT NULL COLLATE BINARY --(DC2Type:x)
, "b" TEXT DEFAULT "a" COLLATE RTRIM',
],
'Column with numeric but no comment 1' => [
null, 'a', 'CREATE TABLE "a" ("a" NUMERIC(10, 0) NOT NULL, "b" CLOB NOT NULL --(DC2Type:array)
, "c" CHAR(36) NOT NULL --(DC2Type:guid)
)',
],
'Column with numeric but no comment 2' => [
null, 'a', 'CREATE TABLE "b" ("a" NUMERIC(10, 0) NOT NULL, "b" CLOB NOT NULL --(DC2Type:array)
, "c" CHAR(36) NOT NULL --(DC2Type:guid)
)',
],
'Column with numeric but no comment 3' => [
'(DC2Type:guid)', 'c', 'CREATE TABLE "b" ("a" NUMERIC(10, 0) NOT NULL, "b" CLOB NOT NULL --(DC2Type:array)
, "c" CHAR(36) NOT NULL --(DC2Type:guid)
)',
],
];
} }
} }
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