Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Boolean conversion #527

Closed
wants to merge 18 commits into from

6 participants

@birko

Added platform specific conversion form database Boolean type to PHP bool type

birko added some commits
@birko birko Update AbstractPlatform.php
Default Boolean conversion behaviour
4c7b2b3
@birko birko Update PostgreSqlPlatform.php
added postgresql literals to Boolean conversion
9125d0f
@birko birko Update BooleanType.php
Changed to call platform specific Boolean conversion
b45504a
@birko birko Update AbstractPostgreSqlPlatformTestCase.php
added postgresql platform conversion test
ac35c31
@doctrinebot
Collaborator

Hello,

thank you for creating this pull request. I have automatically opened an issue
on our Jira Bug Tracker for you. See the issue link:

http://www.doctrine-project.org/jira/browse/DBAL-811

We use Jira to track the state of pull requests and the versions they got
included in.

birko added some commits
@birko birko Update PostgreSqlPlatform.php
fixed bug when $item was set as bool true value
added 'off' literal
f070373
@birko birko Update AbstractPostgreSqlPlatformTestCase.php
added literals off and on to the testcase
a679776
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,21 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if(in_array((string)$item, array('false', 'f', 'n', 'no', 'off')))
@Ocramius Owner

Can you fix the CS here? We follow PSR-2 with some minor additions

@Ocramius Owner

You can avoid the call to in_array if the returned value is either null, true or false

@Ocramius Owner

Break this line

@birko
birko added a note

you mean the "if" statement?

@deeky666 Collaborator

Please don't add a newline here after the parenthesis. This is against the PSR-2 coding standard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
birko added some commits
@birko birko Update PostgreSqlPlatform.php
Changes after Ocramius comments
2371e96
@birko birko Update PostgreSqlPlatform.php
fixed parameter order in conditions
c11b1e5
@birko

@Ocramius hope I made the changes correctly in the way you wanted

lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,21 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if((null !== $item) && (false !== $item) && (true !== $item) && in_array((string)$item, array('false', 'f', 'n', 'no', 'off')))
+ {
@Ocramius Owner

The CS is still to be fixed

@birko
birko added a note

What exactly needs to be fixed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,21 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if((null !== $item) && (false !== $item) && (true !== $item) && in_array((string)$item, array('false', 'f', 'n', 'no', 'off')))
+ {
+ return false;
+ }
+ else
+ {
+ return parent::convertFromBoolean($item);
@Ocramius Owner

Do you need the parent impl?

@birko
birko added a note

Yes. I wanted to to have the default behavior as fallback option

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@birko

Ok now I don't know what more I could do for the CS.

lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,23 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if (
+ (null !== $item) &&
+ (false !== $item) &&
+ (true !== $item) &&
+ in_array((string)$item, array('false', 'f', 'n', 'no', 'off'))
+ ) {
+ return false;
+ } else {
@Ocramius Owner

You can avoid the else clause completely, since you're returning early

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,23 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if (
+ (null !== $item) &&
+ (false !== $item) &&
+ (true !== $item) &&
+ in_array((string)$item, array('false', 'f', 'n', 'no', 'off'))
@Ocramius Owner

Do the uppercase versions of these strings also act as false on pgsql? Additionally, the string cast is not needed if you pass true as the third parameter for in_array

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
birko added some commits
@birko birko Update PostgreSqlPlatform.php
updated convert function  to include uppercased values
4de9331
@birko birko Update AbstractPostgreSqlPlatformTestCase.php
Updated test for uppercased values
f5036ed
@birko

@Ocramius You were right I forgot to think about uppercased values

@Ocramius
Owner

@deeky666 think another method in the abstract platform is ok? Otherwise, looks good to me.

Could need squashing of the commits, but I can do that before someone merges

@birko

@Ocramius Sorry for too much commints. I had problems cloning the repo into my PC so most of the changes I made here via Github edit function

@Ocramius
Owner

@birko that can be dealt with, no problem

lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -2365,6 +2365,20 @@ public function convertBooleans($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
+ */
+ public function convertFromBoolean($item)
+ {
+ return (null === $item) ? null : (bool) $item;
@deeky666 Collaborator

Please use the short ternary expression: return null === $item ?: (bool) $item

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@deeky666
Collaborator

@birko Can you please give more details about the issue here? I can see that PostgreSQL allows different boolean values but I don't understand why we need to check for those when retrieving them from the database. AFAIK pdo_pgsql already converts them internally to the proper PHP boolean type. I did some quick tests about this and my assumption seems to be true. Is there another issue I am missing here?

@birko

@deeky666:
The main reason I created this pull request was when I wanted to solve this issue for my project https://github.com/l3pp4rd/DoctrineExtensions/issues/980

After a bit self brainstorming I thought it would be better if there was support for all Boolean literals (http://www.postgresql.org/docs/9.3/static/datatype-boolean.html), in case someone would like to use DBAL to parse database data that come not directly from database but in a kind of CSV export. (Like export to csv from pgadmin.)

And since in the Doctrine\DBAL\Types\BooleanType::convertToPHPValue was the $platform parameter I used it to make it more universal too.

birko added some commits
@birko birko Update PostgreSqlPlatform.php 1cb2447
@birko birko Update AbstractPlatform.php 2133f37
@birko birko Update AbstractPlatform.php
reverted @deeky666 suggestion. Since it failed on testBooleanNullConvertsToPHPValue test. 
with message Failed asserting that true is null.
Since I moved this code from BoolenType::convertToPHPValue in the first place, I presume the code there correct.
936d52d
@deeky666
Collaborator

@birko You are right. My suggestion was wrong. Sorry for that.

@stof stof commented on the diff
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,22 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if ((null !== $item) &&
+ (false !== $item) &&
+ (true !== $item) &&
@stof
stof added a note

All these cases can be removed, because they will not in be in the array

@birko
birko added a note

@stof I added this additional conditions after one of previous hints here, That I should add them there to avoid unnecessary in_array check

It avoids unnessecary in_array() checks but adds new separate checks in the if statement and makes the code more complicated which reduces readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -2365,6 +2365,20 @@ public function convertBooleans($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

Please add the null as return value also, so: @return bool|null

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lucasvanlierop lucasvanlierop commented on the diff
lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,22 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if ((null !== $item) &&
+ (false !== $item) &&
+ (true !== $item) &&
+ in_array(strtolower($item), array('false', 'f', 'n', 'no', 'off'), true)

I think '0' is missing, or does that not occur in Postgres?

Ok just noticed '0' is probably catched by the parent method doing some type juggling. Since your tests test for it.

@birko
birko added a note

yes. since it is the default common behaviuour :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lucasvanlierop lucasvanlierop commented on the diff
lib/Doctrine/DBAL/Types/BooleanType.php
@@ -49,7 +49,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
- return (null === $value) ? null : (bool) $value;
+ return $platform->convertFromBoolean($value);

+1, when the to database conversion is platform specific, the to php version should also be platform specific.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lucasvanlierop lucasvanlierop commented on the diff
...DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php
@@ -311,6 +311,36 @@ public function testConvertBooleanAsIntegers()
$this->assertEquals('1', $platform->convertBooleans(true));
$this->assertEquals('0', $platform->convertBooleans(false));
}
+
+ public function testConvertFromBoolean()
+ {
+ $platform = $this->createPlatform();
+
+ $this->assertFalse($platform->convertFromBoolean(false));

Nothing wrong with the test, but just wanted to say you could also have used data provider for this to reduce boilerplate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
birko added some commits
@birko birko updated return annotation
Updated from @return bool  -> @return bool|null since it returns null too
51842a3
@birko birko just styling fix
sorry
fb9c961
@Ocramius
Owner

Merged in #625

@Ocramius Ocramius closed this
@Ocramius Ocramius self-assigned this
@Ocramius Ocramius referenced this pull request in zendframework/zf2
Open

PDO, PostgreSQL and bool #7284

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 12, 2014
  1. @birko

    Update AbstractPlatform.php

    birko authored
    Default Boolean conversion behaviour
  2. @birko

    Update PostgreSqlPlatform.php

    birko authored
    added postgresql literals to Boolean conversion
  3. @birko

    Update BooleanType.php

    birko authored
    Changed to call platform specific Boolean conversion
  4. @birko

    Update AbstractPostgreSqlPlatformTestCase.php

    birko authored
    added postgresql platform conversion test
  5. @birko

    Update PostgreSqlPlatform.php

    birko authored
    fixed bug when $item was set as bool true value
    added 'off' literal
  6. @birko

    Update AbstractPostgreSqlPlatformTestCase.php

    birko authored
    added literals off and on to the testcase
Commits on Feb 14, 2014
  1. @birko

    Update PostgreSqlPlatform.php

    birko authored
    Changes after Ocramius comments
  2. @birko

    Update PostgreSqlPlatform.php

    birko authored
    fixed parameter order in conditions
  3. @birko

    Update AbstractPlatform.php

    birko authored
    Description fix
  4. @birko

    Update PostgreSqlPlatform.php

    birko authored
  5. @birko

    Update PostgreSqlPlatform.php

    birko authored
Commits on Feb 15, 2014
  1. @birko

    Update PostgreSqlPlatform.php

    birko authored
    updated convert function  to include uppercased values
  2. @birko

    Update AbstractPostgreSqlPlatformTestCase.php

    birko authored
    Updated test for uppercased values
Commits on Feb 21, 2014
  1. @birko

    Update PostgreSqlPlatform.php

    birko authored
  2. @birko

    Update AbstractPlatform.php

    birko authored
Commits on Feb 24, 2014
  1. @birko

    Update AbstractPlatform.php

    birko authored
    reverted @deeky666 suggestion. Since it failed on testBooleanNullConvertsToPHPValue test. 
    with message Failed asserting that true is null.
    Since I moved this code from BoolenType::convertToPHPValue in the first place, I presume the code there correct.
Commits on Jun 30, 2014
  1. @birko

    updated return annotation

    birko authored
    Updated from @return bool  -> @return bool|null since it returns null too
  2. @birko

    just styling fix

    birko authored
    sorry
This page is out of date. Refresh to see the latest.
View
14 lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -2365,6 +2365,20 @@ public function convertBooleans($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 ;
+ }
/**
* Returns the SQL specific for the platform to get the current date.
View
16 lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -728,6 +728,22 @@ public function convertBooleans($item)
return $item;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public function convertFromBoolean($item)
+ {
+ if ((null !== $item) &&
+ (false !== $item) &&
+ (true !== $item) &&
@stof
stof added a note

All these cases can be removed, because they will not in be in the array

@birko
birko added a note

@stof I added this additional conditions after one of previous hints here, That I should add them there to avoid unnecessary in_array check

It avoids unnessecary in_array() checks but adds new separate checks in the if statement and makes the code more complicated which reduces readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ in_array(strtolower($item), array('false', 'f', 'n', 'no', 'off'), true)

I think '0' is missing, or does that not occur in Postgres?

Ok just noticed '0' is probably catched by the parent method doing some type juggling. Since your tests test for it.

@birko
birko added a note

yes. since it is the default common behaviuour :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ ) {
+ return false;
+ }
+
+ return parent::convertFromBoolean($item);
+ }
/**
* {@inheritDoc}
View
2  lib/Doctrine/DBAL/Types/BooleanType.php
@@ -49,7 +49,7 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform)
*/
public function convertToPHPValue($value, AbstractPlatform $platform)
{
- return (null === $value) ? null : (bool) $value;
+ return $platform->convertFromBoolean($value);

+1, when the to database conversion is platform specific, the to php version should also be platform specific.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
/**
View
30 tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php
@@ -311,6 +311,36 @@ public function testConvertBooleanAsIntegers()
$this->assertEquals('1', $platform->convertBooleans(true));
$this->assertEquals('0', $platform->convertBooleans(false));
}
+
+ public function testConvertFromBoolean()
+ {
+ $platform = $this->createPlatform();
+
+ $this->assertFalse($platform->convertFromBoolean(false));

Nothing wrong with the test, but just wanted to say you could also have used data provider for this to reduce boilerplate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ $this->assertFalse($platform->convertFromBoolean('false'));
+ $this->assertFalse($platform->convertFromBoolean('FALSE'));
+ $this->assertFalse($platform->convertFromBoolean('f'));
+ $this->assertFalse($platform->convertFromBoolean('F'));
+ $this->assertFalse($platform->convertFromBoolean('no'));
+ $this->assertFalse($platform->convertFromBoolean('NO'));
+ $this->assertFalse($platform->convertFromBoolean('n'));
+ $this->assertFalse($platform->convertFromBoolean('N'));
+ $this->assertFalse($platform->convertFromBoolean('off'));
+ $this->assertFalse($platform->convertFromBoolean('OFF'));
+ $this->assertFalse($platform->convertFromBoolean('0'));
+ $this->assertTrue($platform->convertFromBoolean(true));
+ $this->assertTrue($platform->convertFromBoolean('true'));
+ $this->assertTrue($platform->convertFromBoolean('TRUE'));
+ $this->assertTrue($platform->convertFromBoolean('t'));
+ $this->assertTrue($platform->convertFromBoolean('T'));
+ $this->assertTrue($platform->convertFromBoolean('yes'));
+ $this->assertTrue($platform->convertFromBoolean('YES'));
+ $this->assertTrue($platform->convertFromBoolean('y'));
+ $this->assertTrue($platform->convertFromBoolean('Y'));
+ $this->assertTrue($platform->convertFromBoolean('on'));
+ $this->assertTrue($platform->convertFromBoolean('ON'));
+ $this->assertTrue($platform->convertFromBoolean('1'));
+ }
public function testGetCreateSchemaSQL()
{
Something went wrong with that request. Please try again.