Skip to content

Commit

Permalink
Refactoring the test
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed Apr 11, 2019
1 parent b4388a0 commit 1170bba
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 68 deletions.
7 changes: 2 additions & 5 deletions lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use function preg_replace;
use function sprintf;
use function str_replace;
use function stripos;
use function strlen;
use function strpos;
use function strtolower;
Expand Down Expand Up @@ -329,11 +328,9 @@ protected function _getPortableTableColumnDefinition($tableColumn)
$autoincrement = true;
}

if (preg_match("/^['(](.*)[')]::.*$/", $tableColumn['default'], $matches)) {
if (preg_match("/^['(](.*)[')]::/", $tableColumn['default'], $matches)) {
$tableColumn['default'] = $matches[1];
}

if (stripos($tableColumn['default'], 'NULL') === 0) {
} elseif (preg_match('/^NULL::/', $tableColumn['default'])) {
$tableColumn['default'] = null;
}

Expand Down
8 changes: 6 additions & 2 deletions lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected function _getPortableTableColumnDefinition($tableColumn)
'length' => $length === 0 || ! in_array($type, ['text', 'string']) ? null : $length,
'unsigned' => false,
'fixed' => (bool) $fixed,
'default' => $default !== 'NULL' ? $default : null,
'default' => $default,
'notnull' => (bool) $tableColumn['notnull'],
'scale' => $tableColumn['scale'],
'precision' => $tableColumn['precision'],
Expand All @@ -123,12 +123,16 @@ protected function _getPortableTableColumnDefinition($tableColumn)
return $column;
}

private function parseDefaultExpression(string $value) : string
private function parseDefaultExpression(string $value) : ?string
{
while (preg_match('/^\((.*)\)$/s', $value, $matches)) {
$value = $matches[1];
}

if ($value === 'NULL') {
return null;
}

if (preg_match('/^\'(.*)\'$/s', $value, $matches)) {
$value = str_replace("''", "'", $matches[1]);
}
Expand Down
143 changes: 143 additions & 0 deletions tests/Doctrine/Tests/DBAL/Functional/Schema/DefaultValueTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\DBAL\Functional\Schema;

use Doctrine\DBAL\Schema\Table;
use Doctrine\Tests\DbalFunctionalTestCase;
use function sprintf;

class DefaultValueTest extends DbalFunctionalTestCase
{
/** @var bool */
private static $initialized = false;

protected function setUp() : void
{
parent::setUp();

if (self::$initialized) {
return;
}

self::$initialized = true;

$table = new Table('default_value');
$table->addColumn('id', 'integer');

foreach (self::columnProvider() as [$name, $default]) {
$table->addColumn($name, 'string', [
'default' => $default,
'notnull' => false,
]);
}

$this->connection->getSchemaManager()
->dropAndCreateTable($table);

$this->connection->insert('default_value', ['id' => 1]);
}

/**
* @dataProvider columnProvider
*/
public function testEscapedDefaultValueCanBeIntrospected(string $name, $expectedDefault) : void
{
self::assertSame(
$expectedDefault,
$this->connection
->getSchemaManager()
->listTableDetails('default_value')
->getColumn($name)
->getDefault()
);
}

/**
* @dataProvider columnProvider
*/
public function testEscapedDefaultValueCanBeInserted(string $name, $expectedDefault) : void
{
$value = $this->connection->fetchColumn(
sprintf('SELECT %s FROM default_value', $name)
);

self::assertSame($expectedDefault, $value);
}

/**
* Returns potential escaped literals from all platforms combined.
*
* @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
* @see http://www.sqlite.org/lang_expr.html
* @see https://www.postgresql.org/docs/9.6/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
*
* @return mixed[][]
*/
public static function columnProvider() : iterable
{
return [
'Single quote' => [
'single_quote',
"foo'bar",
],
'Single quote, doubled' => [
'single_quote_doubled',
"foo''bar",
],
'Double quote' => [
'double_quote',
'foo"bar',
],
'Double quote, doubled' => [
'double_quote_doubled',
'foo""bar',
],
'Backspace' => [
'backspace',
"foo\x08bar",
],
'New line' => [
'new_line',
"foo\nbar",
],
'Carriage return' => [
'carriage_return',
"foo\rbar",
],
'Tab' => [
'tab',
"foo\tbar",
],
'Substitute' => [
'substitute',
"foo\x1abar",
],
'Backslash' => [
'backslash',
'foo\\bar',
],
'Backslash, doubled' => [
'backslash_doubled',
'foo\\\\bar',
],
'Percent' => [
'percent_sign',
'foo%bar',
],
'Underscore' => [
'underscore',
'foo_bar',
],
'NULL string' => [
'null_string',
'NULL',
],
'NULL value' => [
'null_value',
null,
],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1495,67 +1495,6 @@ public function testCreateAndListSequences() : void
self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
}

/**
* Returns potential escaped literals from all platforms combined.
*
* @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
* @see http://www.sqlite.org/lang_expr.html
* @see https://www.postgresql.org/docs/9.6/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
*
* @return mixed[][]
*/
private function getEscapedLiterals() : iterable
{
return [
['An ASCII NUL (X\'00\')', "foo\0bar"],
['Single quote, C-style', "foo'bar"],
['Single quote, doubled-style', "foo''bar"],
['Double quote, C-style', 'foo"bar'],
['Double quote, double-style', 'foo""bar'],
['Backspace', "foo\x08bar"],
['New-line', "foo\nbar"],
['Carriage return', "foo\rbar"],
['Tab', "foo\tbar"],
['ASCII 26 (Control+Z)', "foo\x1abar"],
['Backslash (\)', 'foo\\bar'],
['Double backslash', 'foo\\\\bar'],
['Percent (%)', 'foo%bar'],
['Underscore (_)', 'foo_bar'],
];
}

private function createTableForDefaultValues() : void
{
$table = new Table('string_escaped_default_value');
foreach ($this->getEscapedLiterals() as $i => $literal) {
$table->addColumn('field' . $i, 'string', ['default' => $literal[1]]);
}

$table->addColumn('def_foo', 'string');
$this->schemaManager->dropAndCreateTable($table);
}

public function testEscapedDefaultValueCanBeIntrospected() : void
{
$this->createTableForDefaultValues();

$onlineTable = $this->schemaManager->listTableDetails('string_escaped_default_value');
foreach ($this->getEscapedLiterals() as $i => $literal) {
self::assertSame($literal[1], $onlineTable->getColumn('field' . $i)->getDefault(), 'should be able introspect the value of default for: ' . $literal[0]);
}
}

public function testEscapedDefaultValueCanBeInserted() : void
{
$this->createTableForDefaultValues();

$this->connection->insert('string_escaped_default_value', ['def_foo' => 'foo']);
foreach ($this->getEscapedLiterals() as $i => $literal) {
$value = $this->connection->fetchColumn('SELECT field' . $i . ' FROM string_escaped_default_value');
self::assertSame($literal[1], $value, 'inserted default value should be the configured default value for: ' . $literal[0]);
}
}

/**
* @group #3086
*/
Expand Down

0 comments on commit 1170bba

Please sign in to comment.