Browse Source

Using the typeMap in the specific comparison functions

Jose Lorenzo Rodriguez 10 years ago
parent
commit
63e9f0324b

+ 48 - 0
src/Database/Expression/QueryExpression.php

@@ -150,6 +150,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function eq($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '='));
     }
 
@@ -165,6 +168,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function notEq($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '!='));
     }
 
@@ -178,6 +184,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function gt($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '>'));
     }
 
@@ -191,6 +200,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function lt($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '<'));
     }
 
@@ -204,6 +216,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function gte($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '>='));
     }
 
@@ -217,6 +232,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function lte($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, '<='));
     }
 
@@ -260,6 +278,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function like($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, 'LIKE'));
     }
 
@@ -273,6 +294,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function notLike($field, $value, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new Comparison($field, $value, $type, 'NOT LIKE'));
     }
 
@@ -287,6 +311,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function in($field, $values, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         $type = $type ?: 'string';
         $type .= '[]';
         $values = $values instanceof ExpressionInterface ? $values : (array)$values;
@@ -320,6 +347,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function notIn($field, $values, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         $type = $type ?: 'string';
         $type .= '[]';
         $values = $values instanceof ExpressionInterface ? $values : (array)$values;
@@ -338,6 +368,9 @@ class QueryExpression implements ExpressionInterface, Countable
      */
     public function between($field, $from, $to, $type = null)
     {
+        if ($type === null) {
+            $type = $this->_calculateType($field);
+        }
         return $this->add(new BetweenExpression($field, $from, $to, $type));
     }
 
@@ -664,6 +697,21 @@ class QueryExpression implements ExpressionInterface, Countable
     }
 
     /**
+     * Returns the type name for the passed field if it was stored in the typeMap
+     *
+     * @param mixed $field
+     * @return string|null
+     */
+    protected function _calculateType($field)
+    {
+        $field = $field instanceof IdentifierExpression ? $field->getIdentifier() : $field;
+        if (is_string($field)) {
+            return $this->typeMap()->type($field);
+        }
+        return null;
+    }
+
+    /**
      * Clone this object and its subtree of expressions.
      *
      * @return void

+ 33 - 0
tests/TestCase/Database/Expression/QueryExpressionTest.php

@@ -133,4 +133,37 @@ class QueryExpressionTest extends TestCase
         $expr->add(new QueryExpression('1 = 1'));
         $this->assertTrue($expr->hasNestedExpression());
     }
+
+    /**
+     * Returns the list of specific comparison methods
+     *
+     * @return void
+     */
+    public function methodsProvider()
+    {
+        return [
+            ['eq'], ['notEq'], ['gt'], ['lt'], ['gte'], ['lte'], ['like'],
+            ['notLike'], ['in'], ['notIn']
+        ];
+    }
+
+    /**
+     * Tests that the query expression uses the type map when the
+     * specific comparison functions are used.
+     *
+     * @dataProvider methodsProvider
+     * @return void
+     */
+    public function testTypeMapUsage($method)
+    {
+        $expr = new QueryExpression([], ['created' => 'date']);
+        $expr->{$method}('created', 'foo');
+
+        $binder = new ValueBinder();
+        $expr->sql($binder);
+        $bindings = $binder->bindings();
+        $type = current($bindings)['type'];
+
+        $this->assertEquals('date', $type);
+    }
 }

+ 20 - 0
tests/TestCase/Database/QueryTest.php

@@ -3550,6 +3550,26 @@ class QueryTest extends TestCase
     }
 
     /**
+     * Tests that types in the type map are used in the
+     * specific comparison functions when using a callable
+     *
+     * @return void
+     */
+    public function testBetweenExpressionAndTypeMap()
+    {
+        $query = new Query($this->connection);
+        $query->select('id')
+            ->from('comments')
+            ->defaultTypes(['created' => 'datetime'])
+            ->where(function ($expr) {
+                $from = new \DateTime('2007-03-18 10:45:00');
+                $to = new \DateTime('2007-03-18 10:48:00');
+                return $expr->between('created', $from, $to);
+            });
+        $this->assertCount(2, $query->execute()->fetchAll());
+    }
+
+    /**
      * Assertion for comparing a table's contents with what is in it.
      *
      * @param string $table