-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DBAL-2644] Fix fetchAll(PDO::FETCH_COLUMN) on DB2 with Portability wrapper #2647
Conversation
d4d404f
to
9b923bd
Compare
@@ -175,8 +175,20 @@ public function fetchAll($fetchMode = null, $columnIndex = 0) | |||
return $rows; | |||
} | |||
|
|||
foreach ($rows as $num => $row) { | |||
$rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); | |||
if ($fetchMode === PDO::FETCH_COLUMN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@morozov can you isolate the contents of the if
and else
statements into private methods? Early return preferred
if ($fetchMode === PDO::FETCH_COLUMN) { | ||
if ($iterateRow) { | ||
foreach ($rows as $num => $value) { | ||
if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first bitwise expression does not need re-computing within the loop, and should be moved to a variable
foreach ($rows as $num => $value) { | ||
if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') { | ||
$rows[$num] = null; | ||
} elseif (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first bitwise expression does not need re-computing within the loop, and should be moved to a variable
6246cfc
to
6ed6465
Compare
foreach ($rows as $num => $row) { | ||
$rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); | ||
if ($fetchMode === PDO::FETCH_COLUMN) { | ||
$rows = $this->fixColumn($rows, $emptyToNull, $rTrim); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return early please
$rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); | ||
if ($fetchMode === PDO::FETCH_COLUMN) { | ||
$rows = $this->fixColumn($rows, $emptyToNull, $rTrim); | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for else
*/ | ||
private function fixColumn(array $values, $emptyToNull, $rTrim) | ||
{ | ||
if (!$emptyToNull && !$rTrim) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it simpler to loop twice, and call two separate methods that do one the emptyToNull
fixing, and the other the rTrim
fixing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ideally (if performance allows), we could have just 2-3 lower level functions which convert keys and values, and combine them together in reusable combinations based on fetch*(PDO::FETCH_*)
. But let's try your suggestion first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another idea that comes to mind is to normalize the rows at the beginning if PDO::FETCH_COLUMN
is given and denormalize again at the end? Like expand the rows to a multi-dimensional array at the beginning and flatten again after portability adjustments? Not sure if that might be a better solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd look hacky but definitely save some lines of code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The most important thing is it saves a lot of complexity and function calls which only serve for 1 use-case. But as I said, not sure about that, it is just an idea that came to my mind.
539788d
to
caaedea
Compare
caaedea
to
66f3119
Compare
@Ocramius are you okay with the current approach? Off-topic: I tried putting together an alternative implementation which uses a functional approach to converting data and avoids code duplication, but… for some reason, there's even more code there than in the original one 😕 |
@morozov I'm fine with it, and merging :-) |
@@ -71,11 +71,11 @@ public function connect() | |||
} elseif ($this->getDatabasePlatform()->getName() === "sqlite") { | |||
$params['portability'] = $params['portability'] & self::PORTABILITY_SQLITE; | |||
} elseif ($this->getDatabasePlatform()->getName() === "drizzle") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for the next person that has to maintain this: we're sorry about this massive chain of doom and elseif
:-(
Backported to |
Fixes #2644: