From 30e9369035c061fd7f1297214b6f3a9ba0228090 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Sat, 29 Dec 2012 12:15:17 +0100 Subject: [PATCH] Improving where clause support and adding tests --- .../Database/Expression/QueryExpression.php | 11 +- .../Model/Datasource/Database/QueryTest.php | 198 ++++++++++++++++++ 2 files changed, 207 insertions(+), 2 deletions(-) diff --git a/lib/Cake/Model/Datasource/Database/Expression/QueryExpression.php b/lib/Cake/Model/Datasource/Database/Expression/QueryExpression.php index 421e7a5aef2..5834777a3e7 100644 --- a/lib/Cake/Model/Datasource/Database/Expression/QueryExpression.php +++ b/lib/Cake/Model/Datasource/Database/Expression/QueryExpression.php @@ -128,8 +128,15 @@ protected function _addConditions(array $conditions, array $types) { protected function _parseCondition($field, $value, $types) { $operator = '='; - $type = isset($types[$field]) ? $types[$field] : null; - return sprintf('%s %s %s', $field, $operator, $this->bind($field, $value, $type)); + $expression = $field; + $parts = explode(' ', trim($field), 2); + + if (count($parts) > 1) { + list($expression, $operator) = $parts; + } + + $type = isset($types[$expression]) ? $types[$expression] : null; + return sprintf('%s %s %s', $expression, $operator, $this->bind($field, $value, $type)); } } diff --git a/lib/Cake/Test/TestCase/Model/Datasource/Database/QueryTest.php b/lib/Cake/Test/TestCase/Model/Datasource/Database/QueryTest.php index 86b88a214d8..3bf8f000ca8 100644 --- a/lib/Cake/Test/TestCase/Model/Datasource/Database/QueryTest.php +++ b/lib/Cake/Test/TestCase/Model/Datasource/Database/QueryTest.php @@ -166,4 +166,202 @@ public function testSelectSimpleWhere() { $this->assertCount(0, $result); } +/** + * Tests using where conditions with operators and scalar values works + * + * @return void + **/ + public function testSelectWhereOperators() { + $this->_insertTwoRecords(); + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id >' => 1]) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('title' => 'another title'), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id <' => 2]) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('title' => 'a title'), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id <' => 2]) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('title' => 'a title'), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id <=' => 2]) + ->execute(); + $this->assertCount(2, $result); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id >=' => 1]) + ->execute(); + $this->assertCount(2, $result); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id <=' => 1]) + ->execute(); + $this->assertCount(1, $result); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['id !=' => 2]) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('title' => 'a title'), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['title like' => 'a title']) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('title' => 'a title'), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['title like' => '%title%']) + ->execute(); + $this->assertCount(2, $result); + + $query = new Query($this->connection); + $result = $query + ->select(['title']) + ->from('articles') + ->where(['title not like' => '%title%']) + ->execute(); + $this->assertCount(0, $result); + } + +/** + * Auxiliary function to insert a couple rows in a newly created table containing dates + * + * @return void + **/ + protected function _insertDateRecords() { + $table = 'CREATE TEMPORARY TABLE dates(id int, name varchar(50), posted datetime)'; + $this->connection->execute($table); + $data = [ + 'id' => '1', + 'name' => 'Chuck Norris', + 'posted' => new \DateTime('2012-12-21 12:00') + ]; + $result = $this->connection->insert( + 'dates', + $data, + ['id' => 'integer', 'name' => 'string', 'posted' => 'datetime'] + ); + + $result->bindValue(1, '2', 'integer'); + $result->bindValue(2, 'Bruce Lee'); + $result->bindValue(3, new \DateTime('2012-12-22 12:00'), 'datetime'); + $result->execute(); + + $result->bindValue(1, 3, 'integer'); + $result->bindValue(2, 'Jet Li'); + $result->bindValue(3, new \DateTime('2012-12-25 12:00'), 'datetime'); + $result->execute(); + + return $result; + } + +/** + * Tests selecting with conditions and specifying types for those + * + * @return void + **/ + public function testSelectWhereTypes() { + $this->_insertDateRecords(); + + $query = new Query($this->connection); + $result = $query + ->select(['id']) + ->from('dates') + ->where(['posted' => new \DateTime('2012-12-21 12:00')], ['posted' => 'datetime']) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('id' => 1), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['id']) + ->from('dates') + ->where(['posted >' => new \DateTime('2012-12-21 12:00')], ['posted' => 'datetime']) + ->execute(); + $this->assertCount(2, $result); + $this->assertEquals(array('id' => 2), $result->fetch('assoc')); + $this->assertEquals(array('id' => 3), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['id']) + ->from('dates') + ->where( + [ + 'posted >' => new \DateTime('2012-12-21 12:00'), + 'posted <' => new \DateTime('2012-12-23 12:00') + ], + ['posted' => 'datetime'] + ) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('id' => 2), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['id']) + ->from('dates') + ->where( + [ + 'id' => '3something-crazy', + 'posted <' => new \DateTime('2013-01-01 12:00') + ], + ['posted' => 'datetime', 'id' => 'integer'] + ) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('id' => 3), $result->fetch('assoc')); + + $query = new Query($this->connection); + $result = $query + ->select(['id']) + ->from('dates') + ->where( + [ + 'id' => '3something-crazy', + 'posted <' => new \DateTime('2013-01-01 12:00') + ], + ['posted' => 'datetime', 'id' => 'boolean'] + ) + ->execute(); + $this->assertCount(1, $result); + $this->assertEquals(array('id' => 1), $result->fetch('assoc')); + } + }