Skip to content
Permalink
Browse files

Added modifiers support for UPDATE statements

  • Loading branch information...
lorenzo committed Feb 22, 2016
1 parent 4123ba1 commit 747eb2dcc7e2d45c1703a226fba8ec21285eb7de
Showing with 80 additions and 6 deletions.
  1. +33 −5 src/Database/QueryCompiler.php
  2. +4 −1 src/Database/SqlserverCompiler.php
  3. +43 −0 tests/TestCase/Database/QueryTest.php
@@ -31,7 +31,6 @@ class QueryCompiler
*/
protected $_templates = [
'delete' => 'DELETE',
'update' => 'UPDATE %s',
'where' => ' WHERE %s',
'group' => ' GROUP BY %s ',
'having' => ' HAVING %s ',
@@ -56,7 +55,7 @@ class QueryCompiler
*
* @var array
*/
protected $_updateParts = ['update', 'modifier', 'set', 'where', 'epilog'];
protected $_updateParts = ['update', 'set', 'where', 'epilog'];
/**
* The list of query clauses to traverse for generating a DELETE statement
@@ -309,12 +308,40 @@ protected function _buildValuesPart($parts, $query, $generator)
return implode('', $this->_stringifyExpressions($parts, $generator));
}
/**
* Builds the SQL fragment for UPDATE.
*
* @param array $parts The update parts.
* @param \Cake\Database\Query $query The query that is being compiled
* @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions
* @return string SQL fragment.
*/
protected function _buildUpdatePart($parts, $query, $generator)
{
$table = $this->_stringifyExpressions($parts, $generator);
$modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator);
if ($modifiers !== null) {
$modifiers .= ' ';
}
return sprintf('UPDATE %s%s', $modifiers, implode(',', $table));
}
/**
* Builds the SQL modifier fragment
*
* @param array $parts The query modifier parts
* @param \Cake\Database\Query $query The query that is being compiled
* @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions
* @return string SQL fragment.
*/
protected function _buildModifierPart($parts, $query, $generator)
{
if ($parts === []) {
return null;
}
return implode(' ', $this->_stringifyExpressions($parts, $generator));
return implode(' ', $this->_stringifyExpressions($parts, $generator, false));
}
/**
@@ -323,15 +350,16 @@ protected function _buildModifierPart($parts, $query, $generator)
*
* @param array $expressions list of strings and ExpressionInterface objects
* @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions
* @param bool $wrap Whether to wrap each expression object with parenthesis
* @return array
*/
protected function _stringifyExpressions($expressions, $generator)
protected function _stringifyExpressions($expressions, $generator, $wrap = true)
{
$result = [];
foreach ($expressions as $k => $expression) {
if ($expression instanceof ExpressionInterface) {
$value = $expression->sql($generator);
$expression = '(' . $value . ')';
$expression = $wrap ? '(' . $value . ')' : $value;
}
$result[$k] = $expression;
}
@@ -35,7 +35,6 @@ class SqlserverCompiler extends QueryCompiler
*/
protected $_templates = [
'delete' => 'DELETE',
'update' => 'UPDATE %s',
'where' => ' WHERE %s',
'group' => ' GROUP BY %s ',
'having' => ' HAVING %s ',
@@ -70,6 +69,10 @@ protected function _buildInsertPart($parts, $query, $generator)
$columns = $this->_stringifyExpressions($parts[1], $generator);
$modifiers = $this->_buildModifierPart($query->clause('modifier'), $query, $generator);
if ($modifiers !== null) {
$modifiers .= ' ';
}
return sprintf('INSERT %sINTO %s (%s) OUTPUT INSERTED.*',
$modifiers,
$table,
@@ -3669,6 +3669,49 @@ public function testInsertModifiers()
);
}
/**
* Test use of modifiers in a UPDATE query
*
* Testing the generated SQL since the modifiers are usually different per driver
*
* @return void
*/
public function testUpdateModifiers()
{
$query = new Query($this->connection);
$result = $query
->update('authors')
->set('name', 'mark')
->modifier('TOP 10 PERCENT');
$this->assertQuotedQuery(
'UPDATE TOP 10 PERCENT <authors> SET <name> = :c0',
$result->sql(),
!$this->autoQuote
);
$query = new Query($this->connection);
$result = $query
->update('authors')
->set('name', 'mark')
->modifier(['TOP 10 PERCENT', 'FOO']);
$this->assertQuotedQuery(
'UPDATE TOP 10 PERCENT FOO <authors> SET <name> = :c0',
$result->sql(),
!$this->autoQuote
);
$query = new Query($this->connection);
$result = $query
->update('authors')
->set('name', 'mark')
->modifier([$query->newExpr('TOP 10 PERCENT')]);
$this->assertQuotedQuery(
'UPDATE TOP 10 PERCENT <authors> SET <name> = :c0',
$result->sql(),
!$this->autoQuote
);
}
/**
* Assertion for comparing a table's contents with what is in it.
*

0 comments on commit 747eb2d

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