From 675581823288b094043f6c4f7d60f79573d361b2 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 7 Nov 2014 12:14:46 -0500 Subject: [PATCH] Fix some issues with multiple array items in where statements --- .gitignore | 4 +- Query/Abstract_Query_Builder.php | 10 +- Query/Query_Builder.php | 4 +- common.php | 53 +++++++++++ phpci.yml | 2 - tests/core/db_qb_test.php | 158 ++++++++++++++++++------------- 6 files changed, 154 insertions(+), 77 deletions(-) diff --git a/.gitignore b/.gitignore index 17d72c0..b26bc4d 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ tests/settings.json coverage/* vendor/* composer.lock -docs/phpdoc* \ No newline at end of file +docs/phpdoc* +.project +all_tests \ No newline at end of file diff --git a/Query/Abstract_Query_Builder.php b/Query/Abstract_Query_Builder.php index e17ca6e..8c0eeda 100644 --- a/Query/Abstract_Query_Builder.php +++ b/Query/Abstract_Query_Builder.php @@ -361,7 +361,7 @@ abstract class Abstract_Query_Builder { * @param string $conj * @return Query_Builder */ - protected function _where_string($key, $val=array(), $conj='AND') + protected function _where_string($key, $val=array(), $defaultConj='AND') { // Create key/value placeholders foreach($this->_where($key, $val) as $f => $val) @@ -374,13 +374,11 @@ abstract class Abstract_Query_Builder { // Simple key value, or an operator $item .= (count($f_array) === 1) ? '=?' : " {$f_array[1]} ?"; - - // Get the type of the first item in the query map - $first_item = current($this->query_map); $last_item = end($this->query_map); // Determine the correct conjunction - if (empty($this->query_map) || stripos($first_item['conjunction'], 'JOIN') !== FALSE) + $conjunctionList = array_pluck($this->query_map, 'conjunction'); + if (empty($this->query_map) || ( ! regex_in_array($conjunctionList, "/^ ?\n?WHERE/i"))) { $conj = "\nWHERE "; } @@ -390,7 +388,7 @@ abstract class Abstract_Query_Builder { } else { - $conj = " {$conj} "; + $conj = " {$defaultConj} "; } $this->_append_map($conj, $item, 'where'); diff --git a/Query/Query_Builder.php b/Query/Query_Builder.php index da45ba1..b5b4ecc 100644 --- a/Query/Query_Builder.php +++ b/Query/Query_Builder.php @@ -164,13 +164,13 @@ class Query_Builder extends Abstract_Query_Builder implements Query_Builder_Inte /** * Alias to driver util class - * @var \Query\Driver\Abstract_Util + * @var \Query\Driver\Util\Abstract_Util */ public $util; /** * Alias to driver sql class - * @var \Query\Driver\SQL_Interface + * @var \Query\Driver\SQL\SQL_Interface */ public $sql; diff --git a/common.php b/common.php index 8afacc9..4d6416c 100644 --- a/common.php +++ b/common.php @@ -123,6 +123,59 @@ function array_zipper(Array $zipper_input) // -------------------------------------------------------------------------- +/** + * Get an array out of an multi-dimensional array based on a common + * key + * + * @param array $array + * @param string $key + * @return array + */ +function array_pluck(Array $array, $key) +{ + $output = array(); + + // No point iterating over an empty array + if (empty($array)) return $array; + + foreach($array as $inner_array) + { + if (array_key_exists($key, $inner_array)) + { + $output[] = $inner_array[$key]; + } + } + + return $output; +} + +// -------------------------------------------------------------------------- + +/** + * Determine whether a value in the passed array matches the pattern + * passed + * + * @param array $array + * @param string $pattern + * @return bool + */ +function regex_in_array(Array $array, $pattern) +{ + if (empty($array)) return FALSE; + + foreach($array as $item) + { + if (is_scalar($item)) + { + if (preg_match($pattern, $item)) return TRUE; + } + } + + return FALSE; +} + +// -------------------------------------------------------------------------- + /** * Connection function * diff --git a/phpci.yml b/phpci.yml index f0fb4a3..0917cbb 100644 --- a/phpci.yml +++ b/phpci.yml @@ -11,8 +11,6 @@ test: php_unit: config: 'tests/phpunit.xml' run_from: 'tests' - #args: ' --debug ' - coverage: '../coverage/' php_docblock_checker: allowed_warnings: 0 skip_classes: true diff --git a/tests/core/db_qb_test.php b/tests/core/db_qb_test.php index e2b8942..048b9a8 100644 --- a/tests/core/db_qb_test.php +++ b/tests/core/db_qb_test.php @@ -167,6 +167,71 @@ abstract class QBTest extends Query_TestCase { $this->assertIsA($query, 'PDOStatement'); } + // -------------------------------------------------------------------------- + + public function testSelectAvg() + { + $query = $this->db->select_avg('id', 'di') + ->get('test'); + + $this->assertIsA($query, 'PDOStatement'); + } + + // -------------------------------------------------------------------------- + + public function testSelectSum() + { + $query = $this->db->select_sum('id', 'di') + ->get('test'); + + $this->assertIsA($query, 'PDOStatement'); + } + + // -------------------------------------------------------------------------- + + public function testSelectDistinct() + { + $query = $this->db->select_sum('id', 'di') + ->distinct() + ->get('test'); + + $this->assertIsA($query, 'PDOStatement'); + } + + // -------------------------------------------------------------------------- + + public function testSelectGet() + { + $query = $this->db->select('id, key as k, val') + ->get('test', 2, 1); + + $this->assertIsA($query, 'PDOStatement'); + } + + // -------------------------------------------------------------------------- + + public function testSelectFromGet() + { + $query = $this->db->select('id, key as k, val') + ->from('test ct') + ->where('id >', 1) + ->get(); + + $this->assertIsA($query, 'PDOStatement'); + } + + // -------------------------------------------------------------------------- + + public function testSelectFromLimitGet() + { + $query = $this->db->select('id, key as k, val') + ->from('test ct') + ->where('id >', 1) + ->limit(3) + ->get(); + + $this->assertIsA($query, 'PDOStatement'); + } // -------------------------------------------------------------------------- @@ -335,72 +400,6 @@ abstract class QBTest extends Query_TestCase { $this->assertIsA($query, 'PDOStatement'); } - // -------------------------------------------------------------------------- - - public function testSelectAvg() - { - $query = $this->db->select_avg('id', 'di') - ->get('test'); - - $this->assertIsA($query, 'PDOStatement'); - } - - // -------------------------------------------------------------------------- - - public function testSelectSum() - { - $query = $this->db->select_sum('id', 'di') - ->get('test'); - - $this->assertIsA($query, 'PDOStatement'); - } - - // -------------------------------------------------------------------------- - - public function testSelectDistinct() - { - $query = $this->db->select_sum('id', 'di') - ->distinct() - ->get('test'); - - $this->assertIsA($query, 'PDOStatement'); - } - - // -------------------------------------------------------------------------- - - public function testSelectGet() - { - $query = $this->db->select('id, key as k, val') - ->get('test', 2, 1); - - $this->assertIsA($query, 'PDOStatement'); - } - - // -------------------------------------------------------------------------- - - public function testSelectFromGet() - { - $query = $this->db->select('id, key as k, val') - ->from('test ct') - ->where('id >', 1) - ->get(); - - $this->assertIsA($query, 'PDOStatement'); - } - - // -------------------------------------------------------------------------- - - public function testSelectFromLimitGet() - { - $query = $this->db->select('id, key as k, val') - ->from('test ct') - ->where('id >', 1) - ->limit(3) - ->get(); - - $this->assertIsA($query, 'PDOStatement'); - } - // -------------------------------------------------------------------------- // ! Query modifier tests // -------------------------------------------------------------------------- @@ -572,6 +571,21 @@ abstract class QBTest extends Query_TestCase { $this->assertIsA($query, 'PDOStatement'); } + // -------------------------------------------------------------------------- + + public function testJoinWithMultipleWhereValues() + { + $query = $this->db->from('test ct') + ->join('join cj', 'cj.id=ct.id', 'inner') + ->where(array( + 'ct.id < ' => 3, + 'ct.key' => 'foo' + )) + ->get(); + + $this->assertIsA($query, 'PDOStatement'); + } + // -------------------------------------------------------------------------- // ! DB update tests // -------------------------------------------------------------------------- @@ -680,6 +694,18 @@ abstract class QBTest extends Query_TestCase { $this->assertIsA($query, 'PDOStatement'); } + // -------------------------------------------------------------------------- + + public function testDeleteWithMultipleWhereValues() + { + $query = $this->db->delete('test', array( + 'id' => 5, + 'key' => 'gogle' + )); + + $this->assertIsA($query, 'PDOStatement'); + } + // -------------------------------------------------------------------------- // ! Non-data read queries // --------------------------------------------------------------------------