Browse Source

Harmonize default value type across db classes to null.
Currently a mix of `null` and 'string' was used.

Improve code readability of Comparison and TupleComparison classes.
Required methods are now overridden in TupleComparison instead of trying
to make Comparison's code deal with types array too.

ADmad 6 years ago
parent
commit
c3b73ef3ff

+ 13 - 14
src/Database/Expression/Comparison.php

@@ -41,7 +41,7 @@ class Comparison implements ExpressionInterface, FieldInterface
     /**
      * The type to be used for casting the value to a database representation
      *
-     * @var string
+     * @var string|null
      */
     protected $_type;
 
@@ -50,7 +50,7 @@ class Comparison implements ExpressionInterface, FieldInterface
      *
      * @var string
      */
-    protected $_operator;
+    protected $_operator = '=';
 
     /**
      * Whether or not the value in this expression is a traversable
@@ -75,7 +75,7 @@ class Comparison implements ExpressionInterface, FieldInterface
      * @param string|array|null $type the type name used to cast the value
      * @param string $operator the operator used for comparing field and value
      */
-    public function __construct($field, $value, $type, string $operator)
+    public function __construct($field, $value, $type = null, string $operator = '=')
     {
         if (is_string($type)) {
             $this->_type = $type;
@@ -94,13 +94,9 @@ class Comparison implements ExpressionInterface, FieldInterface
      */
     public function setValue($value): void
     {
-        $hasType = isset($this->_type) && is_string($this->_type);
-        $isMultiple = $hasType && strpos($this->_type, '[]') !== false;
-
-        if ($hasType) {
-            $value = $this->_castToExpression($value, $this->_type);
-        }
+        $value = $this->_castToExpression($value, $this->_type);
 
+        $isMultiple = $this->_type && strpos($this->_type, '[]') !== false;
         if ($isMultiple) {
             [$value, $this->_valueExpressions] = $this->_collectExpressions($value);
         }
@@ -221,7 +217,10 @@ class Comparison implements ExpressionInterface, FieldInterface
 
         if ($this->_isMultiple) {
             $template .= '%s (%s)';
-            $type = str_replace('[]', '', $this->_type);
+            $type = $this->_type;
+            if ($type !== null) {
+                $type = str_replace('[]', '', $type);
+            }
             $value = $this->_flattenValue($this->_value, $generator, $type);
 
             // To avoid SQL errors when comparing a field to a list of empty values,
@@ -246,10 +245,10 @@ class Comparison implements ExpressionInterface, FieldInterface
      *
      * @param mixed $value The value to bind
      * @param \Cake\Database\ValueBinder $generator The value binder to use
-     * @param string $type The type of $value
+     * @param string|null $type The type of $value
      * @return string generated placeholder
      */
-    protected function _bindValue($value, ValueBinder $generator, $type): string
+    protected function _bindValue($value, ValueBinder $generator, ?string $type = null): string
     {
         $placeholder = $generator->placeholder('c');
         $generator->bind($placeholder, $value, $type);
@@ -263,10 +262,10 @@ class Comparison implements ExpressionInterface, FieldInterface
      *
      * @param iterable $value the value to flatten
      * @param \Cake\Database\ValueBinder $generator The value binder to use
-     * @param string $type the type to cast values to
+     * @param string|null $type the type to cast values to
      * @return string
      */
-    protected function _flattenValue(iterable $value, ValueBinder $generator, string $type = 'string'): string
+    protected function _flattenValue(iterable $value, ValueBinder $generator, ?string $type = null): string
     {
         $parts = [];
         if (is_array($value)) {

+ 20 - 15
src/Database/Expression/TupleComparison.php

@@ -50,6 +50,17 @@ class TupleComparison extends Comparison
     }
 
     /**
+     * Sets the value
+     *
+     * @param mixed $value The value to compare
+     * @return void
+     */
+    public function setValue($value): void
+    {
+        $this->_value = $value;
+    }
+
+    /**
      * Convert the expression into a SQL fragment.
      *
      * @param \Cake\Database\ValueBinder $generator Placeholder generator object
@@ -99,16 +110,16 @@ class TupleComparison extends Comparison
             }
 
             $type = $this->_type;
-            $multiType = is_array($type);
-            $isMulti = $this->isMulti();
-            $type = $multiType ? $type : str_replace('[]', '', $type);
-            $type = $type ?: null;
+            $isMultiOperation = $this->isMulti();
+            if (empty($type)) {
+                $type = null;
+            }
 
-            if ($isMulti) {
+            if ($isMultiOperation) {
                 $bound = [];
                 foreach ($value as $k => $val) {
                     /** @psalm-suppress PossiblyNullArrayAccess */
-                    $valType = $multiType ? $type[$k] : $type;
+                    $valType = $type ? $type[$k] : $type;
                     $bound[] = $this->_bindValue($val, $generator, $valType);
                 }
 
@@ -116,7 +127,7 @@ class TupleComparison extends Comparison
                 continue;
             }
 
-            $valType = $multiType && isset($type[$i]) ? $type[$i] : $type;
+            $valType = $type && isset($type[$i]) ? $type[$i] : $type;
             $values[] = $this->_bindValue($value, $generator, $valType);
         }
 
@@ -124,15 +135,9 @@ class TupleComparison extends Comparison
     }
 
     /**
-     * Registers a value in the placeholder generator and returns the generated
-     * placeholder
-     *
-     * @param mixed $value The value to bind
-     * @param \Cake\Database\ValueBinder $generator The value binder
-     * @param string $type The type to use
-     * @return string generated placeholder
+     * @inheritDoc
      */
-    protected function _bindValue($value, ValueBinder $generator, $type): string
+    protected function _bindValue($value, ValueBinder $generator, ?string $type = null): string
     {
         $placeholder = $generator->placeholder('tuple');
         $generator->bind($placeholder, $value, $type);

+ 2 - 2
src/Database/Query.php

@@ -1924,11 +1924,11 @@ class Query implements ExpressionInterface, IteratorAggregate
      * @param string|int $param placeholder to be replaced with quoted version
      *   of $value
      * @param mixed $value The value to be bound
-     * @param string|int $type the mapped type name, used for casting when sending
+     * @param string|int|null $type the mapped type name, used for casting when sending
      *   to database
      * @return $this
      */
-    public function bind($param, $value, $type = 'string')
+    public function bind($param, $value, $type = null)
     {
         $this->getValueBinder()->bind($param, $value, $type);
 

+ 3 - 3
src/Database/Type/ExpressionTypeCasterTrait.php

@@ -31,12 +31,12 @@ trait ExpressionTypeCasterTrait
      * returns the value unmodified.
      *
      * @param mixed $value The value to converto to ExpressionInterface
-     * @param string $type The type name
+     * @param string|null $type The type name
      * @return mixed
      */
-    protected function _castToExpression($value, $type)
+    protected function _castToExpression($value, ?string $type = null)
     {
-        if (empty($type)) {
+        if ($type === null) {
             return $value;
         }
 

+ 4 - 4
src/Database/ValueBinder.php

@@ -45,11 +45,11 @@ class ValueBinder
      * @param string|int $param placeholder to be replaced with quoted version
      * of $value
      * @param mixed $value The value to be bound
-     * @param string|int $type the mapped type name, used for casting when sending
+     * @param string|int|null $type the mapped type name, used for casting when sending
      * to database
      * @return void
      */
-    public function bind($param, $value, $type = 'string'): void
+    public function bind($param, $value, $type = null): void
     {
         $this->_bindings[$param] = compact('value', 'type') + [
             'placeholder' => is_int($param) ? $param : substr($param, 1),
@@ -80,10 +80,10 @@ class ValueBinder
      * and binds them with the specified type.
      *
      * @param iterable $values The list of values to be bound
-     * @param string $type The type with which all values will be bound
+     * @param string|int|null $type The type with which all values will be bound
      * @return array with the placeholders to insert in the query
      */
-    public function generateManyNamed(iterable $values, string $type = 'string'): array
+    public function generateManyNamed(iterable $values, $type = null): array
     {
         $placeholders = [];
         foreach ($values as $k => $value) {

+ 2 - 2
tests/TestCase/Database/ValueBinderTest.php

@@ -39,7 +39,7 @@ class ValueBinderTest extends TestCase
         $expected = [
             ':c0' => [
                 'value' => 'value0',
-                'type' => 'string',
+                'type' => null,
                 'placeholder' => 'c0',
             ],
             ':c1' => [
@@ -49,7 +49,7 @@ class ValueBinderTest extends TestCase
             ],
             ':c2' => [
                 'value' => 'value2',
-                'type' => 'string',
+                'type' => null,
                 'placeholder' => 'c2',
             ],
         ];