aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/db/driver
diff options
context:
space:
mode:
authorTristan Darricau <tristan.darricau@sensiolabs.com>2015-10-14 16:18:46 +0200
committerTristan Darricau <tristan.darricau@sensiolabs.com>2015-10-14 16:18:46 +0200
commitcd114a68e956e448df18ffbad855a12a6f597861 (patch)
tree3118bd5045b970829b9b84eb17d94dbf672870d2 /phpBB/phpbb/db/driver
parent4682b5abdd342bd4ac7dd01afc36cf30c496ac24 (diff)
parentfe132f19e8d5c821fff936d208fbb981aa6ac92d (diff)
downloadforums-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.php137
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}
*/