diff options
author | Tristan Darricau <tristan.darricau@sensiolabs.com> | 2015-10-14 16:18:46 +0200 |
---|---|---|
committer | Tristan Darricau <tristan.darricau@sensiolabs.com> | 2015-10-14 16:18:46 +0200 |
commit | cd114a68e956e448df18ffbad855a12a6f597861 (patch) | |
tree | 3118bd5045b970829b9b84eb17d94dbf672870d2 /phpBB/phpbb/db/driver | |
parent | 4682b5abdd342bd4ac7dd01afc36cf30c496ac24 (diff) | |
parent | fe132f19e8d5c821fff936d208fbb981aa6ac92d (diff) | |
download | forums-cd114a68e956e448df18ffbad855a12a6f597861.tar forums-cd114a68e956e448df18ffbad855a12a6f597861.tar.gz forums-cd114a68e956e448df18ffbad855a12a6f597861.tar.bz2 forums-cd114a68e956e448df18ffbad855a12a6f597861.tar.xz forums-cd114a68e956e448df18ffbad855a12a6f597861.zip |
Merge pull request #3441 from brunoais/feature/sql-bool-builder
[feature/sql-bool-builder] Extending DBAL query builder for boolean generation
* brunoais/feature/sql-bool-builder:
[feature/sql-bool-builder] Improved tests output to show the SQL error.
[feature/sql-bool-builder] Adding the IS operator to predicted operators
[feature/sql-bool-builder] test_single_not_like
[feature/sql-bool-builder] test_single_like
[feature/sql-bool-builder] test_single_not_in
[feature/sql-bool-builder] test_single_in
[feature/sql-bool-builder] test_and_of_or_of_and
[feature/sql-bool-builder] test_triple_and_with_in
[feature/sql-bool-builder] test_double_and_with_not_of_and
[feature/sql-bool-builder] test_triple_and_with_is_null
[feature/sql-bool-builder] Prepare testing class
[feature/sql-bool-builder] Added LIKE and NOT_LIKE to the comparations
[feature/sql-bool-builder] Explain better the code in the first
[feature/sql-bool-builder] Also use parenthesis for the NOT operator
[feature/sql-bool-builder] AS keyword must be lowercase;
[feature/sql-bool-builder] Added code to use this feature for the WHERE clause
[feature/sql-bool-builder] Removed non-necessary spaces
[feature/sql-bool-builder] First working version
Diffstat (limited to 'phpBB/phpbb/db/driver')
-rw-r--r-- | phpBB/phpbb/db/driver/driver.php | 137 |
1 files changed, 136 insertions, 1 deletions
diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 2925765e94..e497e6dda1 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -774,7 +774,18 @@ abstract class driver implements driver_interface if (!empty($array['WHERE'])) { - $sql .= ' WHERE ' . $this->_sql_custom_build('WHERE', $array['WHERE']); + $sql .= ' WHERE '; + + if (is_array($array['WHERE'])) + { + $sql_where = $this->_process_boolean_tree_first($array['WHERE']); + } + else + { + $sql_where = $array['WHERE']; + } + + $sql .= $this->_sql_custom_build('WHERE', $sql_where); } if (!empty($array['GROUP_BY'])) @@ -793,6 +804,130 @@ abstract class driver implements driver_interface return $sql; } + + protected function _process_boolean_tree_first($operations_ary) + { + // In cases where an array exists but there is no head condition, + // it should be because there's only 1 WHERE clause. This seems the best way to deal with it. + if ($operations_ary[0] !== 'AND' && + $operations_ary[0] !== 'OR') + { + $operations_ary = array('AND', $operations_ary); + } + return $this->_process_boolean_tree($operations_ary) . "\n"; + } + + protected function _process_boolean_tree($operations_ary) + { + $operation = array_shift($operations_ary); + + foreach ($operations_ary as &$condition) + { + switch ($condition[0]) + { + case 'AND': + case 'OR': + + $condition = ' ( ' . $this->_process_boolean_tree($condition) . ') '; + + break; + case 'NOT': + + $condition = ' NOT (' . $this->_process_boolean_tree($condition) . ') '; + + break; + + default: + + switch (sizeof($condition)) + { + case 3: + + // Typical 3 element clause with {left hand} {operator} {right hand} + switch ($condition[1]) + { + case 'IN': + case 'NOT_IN': + + // As this is used with an IN, assume it is a set of elements for sql_in_set() + $condition = $this->sql_in_set($condition[0], $condition[2], $condition[1] === 'NOT_IN', true); + + break; + + case 'LIKE': + + $condition = $condition[0] . ' ' . $this->sql_like_expression($condition[2]) . ' '; + + break; + + case 'NOT_LIKE': + + $condition = $condition[0] . ' ' . $this->sql_not_like_expression($condition[2]) . ' '; + + break; + + case 'IS_NOT': + + $condition[1] = 'IS NOT'; + + // no break + case 'IS': + + // If the value is NULL, the string of it is the empty string ('') which is not the intended result. + // this should solve that + if ($condition[2] === null) + { + $condition[2] = 'NULL'; + } + + $condition = implode(' ', $condition); + + break; + + default: + + $condition = implode(' ', $condition); + + break; + } + + break; + + case 5: + + // Subquery with {left hand} {operator} {compare kind} {SELECT Kind } {Sub Query} + + $condition = $condition[0] . ' ' . $condition[1] . ' ' . $condition[2] . ' ( '; + $condition .= $this->sql_build_query($condition[3], $condition[4]); + $condition .= ' )'; + + break; + + default: + // This is an unpredicted clause setup. Just join all elements. + $condition = implode(' ', $condition); + + break; + } + + break; + } + + } + + if($operation === 'NOT') + { + $operations_ary = implode("", $operations_ary); + } + else + { + $operations_ary = implode(" \n $operation ", $operations_ary); + } + + return $operations_ary; + } + + /** * {@inheritDoc} */ |