Skip to content
Permalink
Browse files

Adding support for eager laoding and composite keys in Sqlite

While it has several deficiencies if one wants to use TupleComparison in
a more general sense, this covers an 80% of the cases
  • Loading branch information...
lorenzo committed Jan 14, 2014
1 parent 277422c commit befb1e3296c2de97dfd2c89e2a5ec249fc66a9da
@@ -18,6 +18,9 @@
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;
@@ -55,7 +58,8 @@ trait SqliteDialectTrait {
protected function _expressionTranslators() {
$namespace = 'Cake\Database\Expression';
return [
$namespace . '\FunctionExpression' => '_transformFunctionExpression'
$namespace . '\FunctionExpression' => '_transformFunctionExpression',
$namespace . '\TupleComparison' => '_transformTupleComparison'
];
}
@@ -92,6 +96,52 @@ protected function _transformFunctionExpression(FunctionExpression $expression)
}
}
/**
* Receives a TupleExpression and changes it so that it conforms to this
* SQL dialect.
*
* @param Cake\Database\Expression\TupleComparison
* @return void
*/
protected function _transformTupleComparison(TupleComparison $expression, $query) {
$fields = $expression->getField();
if (!is_array($fields)) {
return;
}
$value = $expression->getValue();
$op = $expression->type();
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(new IdentifierExpression(1), true);
$expression->field(new IdentifierExpression('1'));
$expression->type('=');
return;
}
$surrogate = $query->connection()
->newQuery()
->select(new IdentifierExpression('1'));
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(new IdentifierExpression('1'));
$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.
@@ -82,7 +82,7 @@ protected function _stringifyValues($generator) {
$type = $this->_type;
$multiType = is_array($type);
$isMulti = $this->_isMulti($i, $type);
$isMulti = $this->isMulti($i, $type);
$type = $isMulti ? str_replace('[]', '', $type) : $type;
if ($isMulti) {
@@ -116,9 +116,17 @@ public function traverse(callable $callable) {
foreach ($this->getField() as $field) {
$this->_traverseValue($field, $callable);
}
foreach ($this->getValue() as $i => $value) {
$value = $this->getValue();
if ($value instanceof ExpressionInterface) {
$callable($value);
$value->traverse($callable);
return;
}
foreach ($value as $i => $value) {
$type = isset($this->_type[$i]) ? $this->_type[$i] : null;
if ($this->_isMulti($type)) {
if ($this->isMulti()) {
foreach ($value as $v) {
$this->_traverseValue($v, $callable);
}
@@ -147,12 +155,10 @@ protected function _traverseValue($value, $callable) {
* Determines if each of the values in this expressions is a tuple in
* itself
*
* @param string $type the type to bind for values
* @return boolean
*/
protected function _isMulti($type) {
$multi = in_array(strtolower($this->_conjunction), ['in', 'not in']);
return $multi || strpos($type, '[]') !== false;
protected function isMulti() {
return in_array(strtolower($this->_conjunction), ['in', 'not in']);;
}
}
@@ -82,10 +82,10 @@ public function queryTranslator($type) {
return $query;
}
$query->traverseExpressions(function($expression) use ($translators) {
$query->traverseExpressions(function($expression) use ($translators, $query) {
foreach ($translators as $class => $method) {
if ($expression instanceof $class) {
$this->{$method}($expression);
$this->{$method}($expression, $query);
}
}
});

0 comments on commit befb1e3

Please sign in to comment.
You can’t perform that action at this time.