Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
e3ab1276
Unverified
Commit
e3ab1276
authored
Jan 02, 2018
by
Marco Pivetta
Committed by
GitHub
Jan 02, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2850 from PowerKiKi/default-values-with-backslashes
Support for backslashes in default values
parents
f988b0a6
2971f862
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
119 additions
and
40 deletions
+119
-40
UPGRADE.md
UPGRADE.md
+14
-0
AbstractPlatform.php
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
+13
-1
PostgreSqlPlatform.php
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
+8
-0
PostgreSqlSchemaManager.php
lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
+21
-2
SqliteSchemaManager.php
lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php
+3
-2
MySqlSchemaManagerTest.php
...e/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php
+0
-35
SchemaManagerFunctionalTestCase.php
...BAL/Functional/Schema/SchemaManagerFunctionalTestCase.php
+60
-0
No files found.
UPGRADE.md
View file @
e3ab1276
# Upgrade to UNRELEASED
## MINOR BC BREAK: escaped default values
Default values will be automatically escaped. So default values must now be specified non-escaped.
Before:
$column->setDefault('Foo\\\\Bar\\\\Baz');
After:
$column->setDefault('Foo\\Bar\\Baz');
# Upgrade to 2.6
## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement`
...
...
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
View file @
e3ab1276
...
...
@@ -2306,7 +2306,7 @@ abstract class AbstractPlatform
return
" DEFAULT '"
.
$this
->
convertBooleans
(
$default
)
.
"'"
;
}
return
" DEFAULT
'"
.
$default
.
"'"
;
return
" DEFAULT
"
.
$this
->
quoteDefaultStringLiteral
(
$default
)
;
}
/**
...
...
@@ -3570,4 +3570,16 @@ abstract class AbstractPlatform
{
return
"'"
;
}
/**
* Quote a literal string for usage as DEFAULT value.
*
* @param string $str
*
* @return string
*/
protected
function
quoteDefaultStringLiteral
(
string
$str
)
:
string
{
return
$this
->
quoteStringLiteral
(
$str
);
}
}
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
View file @
e3ab1276
...
...
@@ -1236,4 +1236,12 @@ class PostgreSqlPlatform extends AbstractPlatform
{
return
$type
instanceof
IntegerType
||
$type
instanceof
BigIntType
;
}
/**
* {@inheritDoc}
*/
protected
function
quoteDefaultStringLiteral
(
string
$str
)
:
string
{
return
parent
::
quoteStringLiteral
(
$str
);
}
}
lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
View file @
e3ab1276
...
...
@@ -384,11 +384,12 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$length
=
null
;
break
;
case
'text'
:
case
'_varchar'
:
case
'varchar'
:
$tableColumn
[
'default'
]
=
$this
->
unescapeDefaultValue
(
$tableColumn
[
'default'
]);
$fixed
=
false
;
break
;
case
'varchar'
:
case
'interval'
:
case
'_varchar'
:
$fixed
=
false
;
break
;
case
'char'
:
...
...
@@ -468,4 +469,22 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
return
$defaultValue
;
}
/**
* Un-escape a default value as given by PostgreSQL
*
* @param null|string $default
*
* @return null|string
*/
private
function
unescapeDefaultValue
(
?
string
$default
)
:
?
string
{
if
(
$default
===
null
)
{
return
$default
;
}
$default
=
str_replace
(
"''"
,
"'"
,
$default
);
return
$default
;
}
}
lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php
View file @
e3ab1276
...
...
@@ -308,8 +308,9 @@ class SqliteSchemaManager extends AbstractSchemaManager
$default
=
null
;
}
if
(
$default
!==
null
)
{
// SQLite returns strings wrapped in single quotes, so we need to strip them
$default
=
preg_replace
(
"/^'(.*)'$/"
,
'\1'
,
$default
);
// SQLite returns strings wrapped in single quotes and escaped, so we need to strip them
$default
=
preg_replace
(
"/^'(.*)'$/s"
,
'\1'
,
$default
);
$default
=
str_replace
(
"''"
,
"'"
,
$default
);
}
$notnull
=
(
bool
)
$tableColumn
[
'notnull'
];
...
...
tests/Doctrine/Tests/DBAL/Functional/Schema/MySqlSchemaManagerTest.php
View file @
e3ab1276
...
...
@@ -442,39 +442,4 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$diff
=
$comparator
->
diffTable
(
$table
,
$onlineTable
);
self
::
assertFalse
(
$diff
,
"Tables should be identical with column defauts time and date."
);
}
/**
* Ensure default values (un-)escaping is properly done by mysql platforms.
* The test is voluntarily relying on schema introspection due to current
* doctrine limitations. Once #2850 is landed, this test can be removed.
* @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
*/
public
function
testEnsureDefaultsAreUnescapedFromSchemaIntrospection
()
:
void
{
$platform
=
$this
->
_sm
->
getDatabasePlatform
();
$this
->
_conn
->
query
(
'DROP TABLE IF EXISTS test_column_defaults_with_create'
);
$escapeSequences
=
[
"
\\
0"
,
// An ASCII NUL (X'00') character
"
\\
'"
,
"''"
,
// Single quote
'\\"'
,
'""'
,
// Double quote
'\\b'
,
// A backspace character
'\\n'
,
// A new-line character
'\\r'
,
// A carriage return character
'\\t'
,
// A tab character
'\\Z'
,
// ASCII 26 (Control+Z)
'\\\\'
,
// A backslash (\) character
'\\%'
,
// A percent (%) character
'\\_'
,
// An underscore (_) character
];
$default
=
implode
(
'+'
,
$escapeSequences
);
$sql
=
"CREATE TABLE test_column_defaults_with_create(
col1 VARCHAR(255) NULL DEFAULT
{
$platform
->
quoteStringLiteral
(
$default
)
}
)"
;
$this
->
_conn
->
query
(
$sql
);
$onlineTable
=
$this
->
_sm
->
listTableDetails
(
"test_column_defaults_with_create"
);
self
::
assertSame
(
$default
,
$onlineTable
->
getColumn
(
'col1'
)
->
getDefault
());
}
}
tests/Doctrine/Tests/DBAL/Functional/Schema/SchemaManagerFunctionalTestCase.php
View file @
e3ab1276
...
...
@@ -1397,4 +1397,64 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
self
::
assertEquals
(
$sequence2AllocationSize
,
$actualSequence2
->
getAllocationSize
());
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 array
*/
private
function
getEscapedLiterals
()
:
array
{
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\\bbar'
],
[
'New-line'
,
'foo\\nbar'
],
[
'Carriage return'
,
'foo\\rbar'
],
[
'Tab'
,
'foo\\tbar'
],
[
'ASCII 26 (Control+Z)'
,
'foo\\Zbar'
],
[
'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
->
_sm
->
dropAndCreateTable
(
$table
);
}
public
function
testEscapedDefaultValueCanBeIntrospected
()
:
void
{
$this
->
createTableForDefaultValues
();
$onlineTable
=
$this
->
_sm
->
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
->
_conn
->
insert
(
'string_escaped_default_value'
,
[
'def_foo'
=>
'foo'
]);
$row
=
$this
->
_conn
->
fetchAssoc
(
'SELECT * FROM string_escaped_default_value'
);
foreach
(
$this
->
getEscapedLiterals
()
as
$i
=>
$literal
)
{
self
::
assertSame
(
$literal
[
1
],
$row
[
'field'
.
$i
],
'inserted default value should be the configured default value for: '
.
$literal
[
0
]);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment