Skip to content

Commit

Permalink
Making composite keys tests pass in SQLServer
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Apr 12, 2014
1 parent b89392f commit 8e87317
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 53 deletions.
54 changes: 2 additions & 52 deletions src/Database/Dialect/SqliteDialectTrait.php
Expand Up @@ -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;

/**
Expand All @@ -28,6 +25,7 @@
trait SqliteDialectTrait {

use SqlDialectTrait;
use TumpleComparisonTranslatorTrait;

/**
* String used to start a database identifier quoting to make it safe
Expand Down Expand Up @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion src/Database/Dialect/SqlserverDialectTrait.php
Expand Up @@ -14,6 +14,7 @@
*/
namespace Cake\Database\Dialect;

use Cake\Database\Dialect\TupleComparisonTranslatorTrait;
use Cake\Database\Expression\FunctionExpression;
use Cake\Database\SqlDialectTrait;

Expand All @@ -24,6 +25,7 @@
trait SqlserverDialectTrait {

use SqlDialectTrait;
use TupleComparisonTranslatorTrait;

/**
* String used to start a database identifier quoting to make it safe
Expand Down Expand Up @@ -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'
];
}

Expand Down
76 changes: 76 additions & 0 deletions src/Database/Dialect/TupleComparisonTranslatorTrait.php
@@ -0,0 +1,76 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Database\Dialect;

use Cake\Database\Expression\IdentifierExpression;
use Cake\Database\Expression\QueryExpression;
use Cake\Database\Expression\TupleComparison;
use Cake\Database\Query;

/**
* Provides a translator method for tuple comparisons
*/
trait TupleComparisonTranslatorTrait {

/**
*
* 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('=');
}

}

0 comments on commit 8e87317

Please sign in to comment.