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
11fd2c9a
Commit
11fd2c9a
authored
Jul 29, 2014
by
Marco Pivetta
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'hotfix/#636-backport-#625-pgsql-boolean-conversion' into 2.4
parents
38db41d8
339aa795
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
352 additions
and
28 deletions
+352
-28
.travis.yml
.travis.yml
+1
-2
AbstractPlatform.php
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
+35
-6
PostgreSqlPlatform.php
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
+119
-10
SqliteSchemaManager.php
lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php
+1
-1
BooleanType.php
lib/Doctrine/DBAL/Types/BooleanType.php
+2
-2
DBAL630Test.php
tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php
+94
-0
PostgreSqlPlatformTest.php
.../Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php
+100
-7
No files found.
.travis.yml
View file @
11fd2c9a
...
...
@@ -20,5 +20,4 @@ before_script:
-
sh -c "if [ '$DB' = 'mysqli' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
-
composer --prefer-source --dev install
script
:
phpunit --configuration tests/travis/$DB.travis.xml
script
:
./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
View file @
11fd2c9a
...
...
@@ -2214,13 +2214,13 @@ abstract class AbstractPlatform
}
/**
*
Some platforms need the boolean values to be convert
ed.
*
Note: if the input is not a boolean the original input might be return
ed.
*
* The default conversion in this implementation converts to integers (false => 0, true => 1).
* There are two contexts when converting booleans: Literals and Prepared Statements.
* This method should handle the literal case
*
* @param mixed $item
*
* @return mixed
* @param mixed $item A boolean or an array of them.
* @return mixed A boolean database value or an array of them.
*/
public
function
convertBooleans
(
$item
)
{
...
...
@@ -2230,13 +2230,42 @@ abstract class AbstractPlatform
$item
[
$k
]
=
(
int
)
$value
;
}
}
}
else
if
(
is_bool
(
$item
))
{
}
elseif
(
is_bool
(
$item
))
{
$item
=
(
int
)
$item
;
}
return
$item
;
}
/**
* Some platforms have boolean literals that needs to be correctly converted
*
* The default conversion tries to convert value into bool "(bool)$item"
*
* @param mixed $item
*
* @return bool|null
*/
public
function
convertFromBoolean
(
$item
)
{
return
null
===
$item
?
null
:
(
bool
)
$item
;
}
/**
* This method should handle the prepared statements case. When there is no
* distinction, it's OK to use the same method.
*
* Note: if the input is not a boolean the original input might be returned.
*
* @param mixed $item A boolean or an array of them.
* @return mixed A boolean database value or an array of them.
*/
public
function
convertBooleansToDatabaseValue
(
$item
)
{
return
$this
->
convertBooleans
(
$item
);
}
/**
* Returns the SQL specific for the platform to get the current date.
*
...
...
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
View file @
11fd2c9a
...
...
@@ -50,6 +50,28 @@ class PostgreSqlPlatform extends AbstractPlatform
$this
->
useBooleanTrueFalseStrings
=
(
bool
)
$flag
;
}
/**
* @var array PostgreSQL booleans literals
*/
private
$booleanLiterals
=
array
(
'true'
=>
array
(
't'
,
'true'
,
'y'
,
'yes'
,
'on'
,
'1'
),
'false'
=>
array
(
'f'
,
'false'
,
'n'
,
'no'
,
'off'
,
'0'
)
);
/**
* {@inheritDoc}
*/
...
...
@@ -573,6 +595,71 @@ class PostgreSqlPlatform extends AbstractPlatform
return
$sql
;
}
/**
* Converts a single boolean value.
*
* First converts the value to its native PHP boolean type
* and passes it to the given callback function to be reconverted
* into any custom representation.
*
* @param mixed $value The value to convert.
* @param callable $callback The callback function to use for converting the real boolean value.
*
* @return mixed
*/
private
function
convertSingleBooleanValue
(
$value
,
$callback
)
{
if
(
null
===
$value
)
{
return
$callback
(
false
);
}
if
(
is_bool
(
$value
)
||
is_numeric
(
$value
))
{
return
$callback
(
$value
?
true
:
false
);
}
if
(
!
is_string
(
$value
))
{
return
$callback
(
true
);
}
/**
* Better safe than sorry: http://php.net/in_array#106319
*/
if
(
in_array
(
trim
(
strtolower
(
$value
)),
$this
->
booleanLiterals
[
'false'
],
true
))
{
return
$callback
(
false
);
}
if
(
in_array
(
trim
(
strtolower
(
$value
)),
$this
->
booleanLiterals
[
'true'
],
true
))
{
return
$callback
(
true
);
}
throw
new
\UnexpectedValueException
(
"Unrecognized boolean literal '${value}'"
);
}
/**
* Converts one or multiple boolean values.
*
* First converts the value(s) to their native PHP boolean type
* and passes them to the given callback function to be reconverted
* into any custom representation.
*
* @param mixed $item The value(s) to convert.
* @param callable $callback The callback function to use for converting the real boolean value(s).
*
* @return mixed
*/
private
function
doConvertBooleans
(
$item
,
$callback
)
{
if
(
is_array
(
$item
))
{
foreach
(
$item
as
$key
=>
$value
)
{
$item
[
$key
]
=
$this
->
convertSingleBooleanValue
(
$value
,
$callback
);
}
return
$item
;
}
return
$this
->
convertSingleBooleanValue
(
$item
,
$callback
);
}
/**
* {@inheritDoc}
*
...
...
@@ -584,19 +671,41 @@ class PostgreSqlPlatform extends AbstractPlatform
return
parent
::
convertBooleans
(
$item
);
}
if
(
is_array
(
$item
))
{
foreach
(
$item
as
$key
=>
$value
)
{
if
(
is_bool
(
$value
)
||
is_numeric
(
$item
))
{
$item
[
$key
]
=
(
$value
)
?
'true'
:
'false'
;
}
return
$this
->
doConvertBooleans
(
$item
,
function
(
$boolean
)
{
return
true
===
$boolean
?
'true'
:
'false'
;
}
}
else
{
if
(
is_bool
(
$item
)
||
is_numeric
(
$item
))
{
$item
=
(
$item
)
?
'true'
:
'false'
;
}
);
}
/**
* {@inheritDoc}
*/
public
function
convertBooleansToDatabaseValue
(
$item
)
{
if
(
!
$this
->
useBooleanTrueFalseStrings
)
{
return
parent
::
convertBooleansToDatabaseValue
(
$item
);
}
return
$this
->
doConvertBooleans
(
$item
,
function
(
$boolean
)
{
return
(
int
)
$boolean
;
}
);
}
/**
* {@inheritDoc}
*/
public
function
convertFromBoolean
(
$item
)
{
if
(
in_array
(
strtolower
(
$item
),
$this
->
booleanLiterals
[
'false'
],
true
))
{
return
false
;
}
return
$item
;
return
parent
::
convertFromBoolean
(
$item
)
;
}
/**
...
...
lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php
View file @
11fd2c9a
...
...
@@ -167,7 +167,7 @@ class SqliteSchemaManager extends AbstractSchemaManager
$stmt
=
$this
->
_conn
->
executeQuery
(
"PRAGMA TABLE_INFO ('
$tableName
')"
);
$indexArray
=
$stmt
->
fetchAll
(
\PDO
::
FETCH_ASSOC
);
foreach
(
$indexArray
as
$indexColumnRow
)
{
if
(
$indexColumnRow
[
'pk'
]
==
"1
"
)
{
if
(
$indexColumnRow
[
'pk'
]
!==
"0
"
)
{
$indexBuffer
[]
=
array
(
'key_name'
=>
'primary'
,
'primary'
=>
true
,
...
...
lib/Doctrine/DBAL/Types/BooleanType.php
View file @
11fd2c9a
...
...
@@ -41,7 +41,7 @@ class BooleanType extends Type
*/
public
function
convertToDatabaseValue
(
$value
,
AbstractPlatform
$platform
)
{
return
$platform
->
convertBooleans
(
$value
);
return
$platform
->
convertBooleans
ToDatabaseValue
(
$value
);
}
/**
...
...
@@ -49,7 +49,7 @@ class BooleanType extends Type
*/
public
function
convertToPHPValue
(
$value
,
AbstractPlatform
$platform
)
{
return
(
null
===
$value
)
?
null
:
(
bool
)
$value
;
return
$platform
->
convertFromBoolean
(
$value
)
;
}
/**
...
...
tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php
0 → 100644
View file @
11fd2c9a
<?php
namespace
Doctrine\Tests\DBAL\Functional\Ticket
;
use
Doctrine\DBAL\DBALException
;
use
PDO
;
/**
* @group DBAL-630
*/
class
DBAL630Test
extends
\Doctrine\Tests\DbalFunctionalTestCase
{
private
$running
=
false
;
protected
function
setUp
()
{
parent
::
setUp
();
$platform
=
$this
->
_conn
->
getDatabasePlatform
()
->
getName
();
if
(
!
in_array
(
$platform
,
array
(
'postgresql'
)))
{
$this
->
markTestSkipped
(
'Currently restricted to PostgreSQL'
);
}
try
{
$this
->
_conn
->
exec
(
'CREATE TABLE dbal630 (id SERIAL, bool_col BOOLEAN NOT NULL);'
);
}
catch
(
DBALException
$e
)
{
}
$this
->
running
=
true
;
}
protected
function
tearDown
()
{
if
(
$this
->
running
)
{
$this
->
_conn
->
getWrappedConnection
()
->
setAttribute
(
PDO
::
ATTR_EMULATE_PREPARES
,
false
);
// PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated in php 5.6. PDO::ATTR_EMULATE_PREPARES should
// be used instead. so should only it be set when it is supported.
if
(
PHP_VERSION_ID
<
50600
)
{
$this
->
_conn
->
getWrappedConnection
()
->
setAttribute
(
PDO
::
PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT
,
false
);
}
}
}
public
function
testBooleanConversionSqlLiteral
()
{
$this
->
_conn
->
executeUpdate
(
'INSERT INTO dbal630 (bool_col) VALUES(false)'
);
$id
=
$this
->
_conn
->
lastInsertId
(
'dbal630_id_seq'
);
$this
->
assertNotEmpty
(
$id
);
$row
=
$this
->
_conn
->
fetchAssoc
(
'SELECT bool_col FROM dbal630 WHERE id = ?'
,
array
(
$id
));
$this
->
assertFalse
(
$row
[
'bool_col'
]);
}
public
function
testBooleanConversionBoolParamRealPrepares
()
{
$this
->
_conn
->
executeUpdate
(
'INSERT INTO dbal630 (bool_col) VALUES(?)'
,
array
(
'false'
),
array
(
PDO
::
PARAM_BOOL
));
$id
=
$this
->
_conn
->
lastInsertId
(
'dbal630_id_seq'
);
$this
->
assertNotEmpty
(
$id
);
$row
=
$this
->
_conn
->
fetchAssoc
(
'SELECT bool_col FROM dbal630 WHERE id = ?'
,
array
(
$id
));
$this
->
assertFalse
(
$row
[
'bool_col'
]);
}
public
function
testBooleanConversionBoolParamEmulatedPrepares
()
{
$this
->
_conn
->
getWrappedConnection
()
->
setAttribute
(
PDO
::
ATTR_EMULATE_PREPARES
,
true
);
// PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated in php 5.6. PDO::ATTR_EMULATE_PREPARES should
// be used instead. so should only it be set when it is supported.
if
(
PHP_VERSION_ID
<
50600
)
{
$this
->
_conn
->
getWrappedConnection
()
->
setAttribute
(
PDO
::
PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT
,
true
);
}
$platform
=
$this
->
_conn
->
getDatabasePlatform
();
$stmt
=
$this
->
_conn
->
prepare
(
'INSERT INTO dbal630 (bool_col) VALUES(?)'
);
$stmt
->
bindValue
(
1
,
$platform
->
convertBooleansToDatabaseValue
(
'false'
),
PDO
::
PARAM_BOOL
);
$stmt
->
execute
();
$id
=
$this
->
_conn
->
lastInsertId
(
'dbal630_id_seq'
);
$this
->
assertNotEmpty
(
$id
);
$row
=
$this
->
_conn
->
fetchAssoc
(
'SELECT bool_col FROM dbal630 WHERE id = ?'
,
array
(
$id
));
$this
->
assertFalse
(
$row
[
'bool_col'
]);
}
}
tests/Doctrine/Tests/DBAL/Platforms/PostgreSqlPlatformTest.php
View file @
11fd2c9a
...
...
@@ -294,27 +294,120 @@ class PostgreSqlPlatformTest extends AbstractPlatformTestCase
);
}
/**
* @group DBAL-457
* @dataProvider pgBooleanProvider
*
* @param string $databaseValue
* @param string $preparedStatementValue
* @param integer $integerValue
* @param boolean $booleanValue
*/
public
function
testConvertBooleanAsLiteralStrings
(
$databaseValue
,
$preparedStatementValue
,
$integerValue
,
$booleanValue
)
{
$platform
=
$this
->
createPlatform
();
$this
->
assertEquals
(
$preparedStatementValue
,
$platform
->
convertBooleans
(
$databaseValue
));
}
/**
* @group DBAL-457
*/
public
function
testConvertBooleanAs
String
s
()
public
function
testConvertBooleanAs
LiteralInteger
s
()
{
$platform
=
$this
->
createPlatform
();
$platform
->
setUseBooleanTrueFalseStrings
(
false
);
$this
->
assertEquals
(
'true'
,
$platform
->
convertBooleans
(
true
));
$this
->
assertEquals
(
'false'
,
$platform
->
convertBooleans
(
false
));
$this
->
assertEquals
(
1
,
$platform
->
convertBooleans
(
true
));
$this
->
assertEquals
(
1
,
$platform
->
convertBooleans
(
'1'
));
$this
->
assertEquals
(
0
,
$platform
->
convertBooleans
(
false
));
$this
->
assertEquals
(
0
,
$platform
->
convertBooleans
(
'0'
));
}
/**
* @group DBAL-457
* @group DBAL-630
* @dataProvider pgBooleanProvider
*
* @param string $databaseValue
* @param string $preparedStatementValue
* @param integer $integerValue
* @param boolean $booleanValue
*/
public
function
testConvertBooleanAsIntegers
()
public
function
testConvertBooleanAsDatabaseValueStrings
(
$databaseValue
,
$preparedStatementValue
,
$integerValue
,
$booleanValue
)
{
$platform
=
$this
->
createPlatform
();
$this
->
assertSame
(
$integerValue
,
$platform
->
convertBooleansToDatabaseValue
(
$booleanValue
));
}
/**
* @group DBAL-630
*/
public
function
testConvertBooleanAsDatabaseValueIntegers
()
{
$platform
=
$this
->
createPlatform
();
$platform
->
setUseBooleanTrueFalseStrings
(
false
);
$this
->
assertEquals
(
'1'
,
$platform
->
convertBooleans
(
true
));
$this
->
assertEquals
(
'0'
,
$platform
->
convertBooleans
(
false
));
$this
->
assertSame
(
1
,
$platform
->
convertBooleansToDatabaseValue
(
true
));
$this
->
assertSame
(
0
,
$platform
->
convertBooleansToDatabaseValue
(
false
));
}
/**
* @dataProvider pgBooleanProvider
*
* @param string $databaseValue
* @param string $prepareStatementValue
* @param integer $integerValue
* @param boolean $booleanValue
*/
public
function
testConvertFromBoolean
(
$databaseValue
,
$prepareStatementValue
,
$integerValue
,
$booleanValue
)
{
$platform
=
$this
->
createPlatform
();
$this
->
assertSame
(
$booleanValue
,
$platform
->
convertFromBoolean
(
$databaseValue
));
}
/**
* @expectedException UnexpectedValueException
* @expectedExceptionMessage Unrecognized boolean literal 'my-bool'
*/
public
function
testThrowsExceptionWithInvalidBooleanLiteral
()
{
$platform
=
$this
->
createPlatform
()
->
convertBooleansToDatabaseValue
(
"my-bool"
);
}
/**
* PostgreSQL boolean strings provider
* @return array
*/
public
function
pgBooleanProvider
()
{
return
array
(
// Database value, prepared statement value, boolean integer value, boolean value.
array
(
true
,
'true'
,
1
,
true
),
array
(
't'
,
'true'
,
1
,
true
),
array
(
'true'
,
'true'
,
1
,
true
),
array
(
'y'
,
'true'
,
1
,
true
),
array
(
'yes'
,
'true'
,
1
,
true
),
array
(
'on'
,
'true'
,
1
,
true
),
array
(
'1'
,
'true'
,
1
,
true
),
array
(
false
,
'false'
,
0
,
false
),
array
(
'f'
,
'false'
,
0
,
false
),
array
(
'false'
,
'false'
,
0
,
false
),
array
(
'n'
,
'false'
,
0
,
false
),
array
(
'no'
,
'false'
,
0
,
false
),
array
(
'off'
,
'false'
,
0
,
false
),
array
(
'0'
,
'false'
,
0
,
false
),
);
}
public
function
testAlterDecimalPrecisionScale
()
...
...
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