浏览代码

Deprecate orWhere().

I made time to circle back on this as I'd really like to not have this
method in the future. It is easy to replace after I thought through the
problem a bit more.
Mark Story 8 年之前
父节点
当前提交
bf25c4c25c
共有 4 个文件被更改,包括 21 次插入15 次删除
  1. 7 7
      src/Database/Dialect/TupleComparisonTranslatorTrait.php
  2. 8 0
      src/Database/Query.php
  3. 0 3
      src/Database/README.md
  4. 6 5
      src/ORM/Marshaller.php

+ 7 - 7
src/Database/Dialect/TupleComparisonTranslatorTrait.php

@@ -78,15 +78,15 @@ trait TupleComparisonTranslatorTrait
             $value = [$value];
         }
 
+        $conditions = ['OR' => []];
         foreach ($value as $tuple) {
-            $surrogate->orWhere(function ($exp) use ($fields, $tuple) {
-                foreach (array_values($tuple) as $i => $value) {
-                    $exp->add([$fields[$i] => $value]);
-                }
-
-                return $exp;
-            });
+            $item = [];
+            foreach (array_values($tuple) as $i => $value) {
+                $item[] = [$fields[$i] => $value];
+            }
+            $conditions['OR'][] = $item;
         }
+        $surrogate->where($conditions);
 
         $expression->setField($true);
         $expression->setValue($surrogate);

+ 8 - 0
src/Database/Query.php

@@ -811,6 +811,10 @@ class Query implements ExpressionInterface, IteratorAggregate
      *
      * `$query->where(['OR' => [['published' => false], ['published' => true]])`
      *
+     * Would result in:
+     *
+     * `WHERE (published = false) OR (published = true)`
+     *
      * Keep in mind that every time you call where() with the third param set to false
      * (default), it will join the passed conditions to the previous stored list using
      * the `AND` operator. Also, using the same array key twice in consecutive calls to
@@ -1008,6 +1012,10 @@ class Query implements ExpressionInterface, IteratorAggregate
      */
     public function orWhere($conditions, $types = [])
     {
+        deprecationWarning(
+            'Query::orWhere() is deprecated as it creates hard to predict SQL based on the ' .
+            'current query state. Use `Query::where()` instead.'
+        );
         $this->_conjugate('where', $conditions, 'OR', $types);
 
         return $this;

+ 0 - 3
src/Database/README.md

@@ -240,9 +240,6 @@ $query->where(['id >' => 1, 'title' => 'My title']);
 It is possible to generate `OR` conditions as well
 
 ```php
-$query->where(['id >' => 1])->orWhere(['title' => 'My Title']);
-
-// Equivalent to
 $query->where(['OR' => ['id >' => 1, 'title' => 'My title']]);
 ```
 

+ 6 - 5
src/ORM/Marshaller.php

@@ -685,19 +685,20 @@ class Marshaller
             unset($indexed[$key]);
         }
 
-        $maybeExistentQuery = (new Collection($indexed))
+        $conditions = (new Collection($indexed))
             ->map(function ($data, $key) {
                 return explode(';', $key);
             })
             ->filter(function ($keys) use ($primary) {
                 return count(array_filter($keys, 'strlen')) === count($primary);
             })
-            ->reduce(function ($query, $keys) use ($primary) {
-                /* @var \Cake\ORM\Query $query */
+            ->reduce(function ($conditions, $keys) use ($primary) {
                 $fields = array_map([$this->_table, 'aliasField'], $primary);
+                $conditions['OR'][] = array_combine($fields, $keys);
 
-                return $query->orWhere($query->newExpr()->and_(array_combine($fields, $keys)));
-            }, $this->_table->find());
+                return $conditions;
+            }, ['OR' => []]);
+        $maybeExistentQuery = $this->_table->find()->where($conditions);
 
         if (!empty($indexed) && count($maybeExistentQuery->clause('where'))) {
             foreach ($maybeExistentQuery as $entity) {