diff --git a/src/Database/Dialect/SqliteDialectTrait.php b/src/Database/Dialect/SqliteDialectTrait.php index 596c1810375..20d560199b0 100644 --- a/src/Database/Dialect/SqliteDialectTrait.php +++ b/src/Database/Dialect/SqliteDialectTrait.php @@ -14,12 +14,9 @@ */ namespace Cake\Database\Dialect; +use Cake\Database\Dialect\TumpleComparisonTranslatorTrait; use Cake\Database\ExpressionInterface; use Cake\Database\Expression\FunctionExpression; -use Cake\Database\Expression\IdentifierExpression; -use Cake\Database\Expression\QueryExpression; -use Cake\Database\Expression\TupleComparison; -use Cake\Database\Query; use Cake\Database\SqlDialectTrait; /** @@ -28,6 +25,7 @@ trait SqliteDialectTrait { use SqlDialectTrait; + use TumpleComparisonTranslatorTrait; /** * String used to start a database identifier quoting to make it safe @@ -97,54 +95,6 @@ protected function _transformFunctionExpression(FunctionExpression $expression) } } -/** - * Receives a TupleExpression and changes it so that it conforms to this - * SQL dialect. - * - * @param \Cake\Database\Expression\TupleComparison $expression - * @param \Cake\Database\Query $query - * @return void - */ - protected function _transformTupleComparison(TupleComparison $expression, $query) { - $fields = $expression->getField(); - - if (!is_array($fields)) { - return; - } - - $value = $expression->getValue(); - $op = $expression->type(); - $true = new QueryExpression('1'); - - if ($value instanceof Query) { - $selected = array_values($value->clause('select')); - foreach ($fields as $i => $field) { - $value->andWhere([$field . " $op" => new IdentifierExpression($selected[$i])]); - } - $value->select($true, true); - $expression->field($true); - $expression->type('='); - return; - } - - $surrogate = $query->connection() - ->newQuery() - ->select($true); - - foreach ($value as $tuple) { - $surrogate->orWhere(function($exp) use ($fields, $tuple) { - foreach ($tuple as $i => $value) { - $exp->add([$fields[$i] => $value]); - } - return $exp; - }); - } - - $expression->field($true); - $expression->value($surrogate); - $expression->type('='); - } - /** * Transforms an insert query that is meant to insert multiple rows at a time, * otherwise it leaves the query untouched. diff --git a/src/Database/Dialect/SqlserverDialectTrait.php b/src/Database/Dialect/SqlserverDialectTrait.php index b14073a5f2c..f2c7691fee7 100644 --- a/src/Database/Dialect/SqlserverDialectTrait.php +++ b/src/Database/Dialect/SqlserverDialectTrait.php @@ -14,6 +14,7 @@ */ namespace Cake\Database\Dialect; +use Cake\Database\Dialect\TupleComparisonTranslatorTrait; use Cake\Database\Expression\FunctionExpression; use Cake\Database\SqlDialectTrait; @@ -24,6 +25,7 @@ trait SqlserverDialectTrait { use SqlDialectTrait; + use TupleComparisonTranslatorTrait; /** * String used to start a database identifier quoting to make it safe @@ -91,7 +93,8 @@ protected function _insertQueryTranslator($query) { protected function _expressionTranslators() { $namespace = 'Cake\Database\Expression'; return [ - $namespace . '\FunctionExpression' => '_transformFunctionExpression' + $namespace . '\FunctionExpression' => '_transformFunctionExpression', + $namespace . '\TupleComparison' => '_transformTupleComparison' ]; } diff --git a/src/Database/Dialect/TupleComparisonTranslatorTrait.php b/src/Database/Dialect/TupleComparisonTranslatorTrait.php new file mode 100644 index 00000000000..ef29d31452e --- /dev/null +++ b/src/Database/Dialect/TupleComparisonTranslatorTrait.php @@ -0,0 +1,76 @@ +getField(); + + if (!is_array($fields)) { + return; + } + + $value = $expression->getValue(); + $op = $expression->type(); + $true = new QueryExpression('1'); + + if ($value instanceof Query) { + $selected = array_values($value->clause('select')); + foreach ($fields as $i => $field) { + $value->andWhere([$field . " $op" => new IdentifierExpression($selected[$i])]); + } + $value->select($true, true); + $expression->field($true); + $expression->type('='); + return; + } + + $surrogate = $query->connection() + ->newQuery() + ->select($true); + + foreach ($value as $tuple) { + $surrogate->orWhere(function($exp) use ($fields, $tuple) { + foreach ($tuple as $i => $value) { + $exp->add([$fields[$i] => $value]); + } + return $exp; + }); + } + + $expression->field($true); + $expression->value($surrogate); + $expression->type('='); + } + +}