Skip to content

Commit

Permalink
Implementing Query::append(), which will be useful for setting extra
Browse files Browse the repository at this point in the history
options in certain queries, specifically for returning inserted values
in postgresql
  • Loading branch information
lorenzo committed Oct 21, 2013
1 parent 0ceb762 commit b67e133
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
36 changes: 31 additions & 5 deletions Cake/Database/Query.php
Expand Up @@ -72,7 +72,8 @@ class Query implements ExpressionInterface, IteratorAggregate {
'order' => null,
'limit' => null,
'offset' => null,
'union' => []
'union' => [],
'append' => null
];

/**
Expand All @@ -91,6 +92,7 @@ class Query implements ExpressionInterface, IteratorAggregate {
'order' => ' %s',
'limit' => ' LIMIT %s',
'offset' => ' OFFSET %s',
'append' => ' %s'
];

/**
Expand Down Expand Up @@ -280,7 +282,10 @@ public function traverse(callable $visitor) {
* @return void
*/
protected function _traverseSelect(callable $visitor) {
$parts = ['select', 'from', 'join', 'where', 'group', 'having', 'order', 'limit', 'offset', 'union'];
$parts = [
'select', 'from', 'join', 'where', 'group', 'having', 'order', 'limit',
'offset', 'union', 'append'
];
foreach ($parts as $name) {
$visitor($this->_parts[$name], $name);
}
Expand All @@ -293,7 +298,7 @@ protected function _traverseSelect(callable $visitor) {
* @return void
*/
protected function _traverseDelete(callable $visitor) {
$parts = ['delete', 'from', 'where'];
$parts = ['delete', 'from', 'where', 'append'];
foreach ($parts as $name) {
$visitor($this->_parts[$name], $name);
}
Expand All @@ -306,7 +311,7 @@ protected function _traverseDelete(callable $visitor) {
* @return void
*/
protected function _traverseUpdate(callable $visitor) {
$parts = ['update', 'set', 'where'];
$parts = ['update', 'set', 'where', 'append'];
foreach ($parts as $name) {
$visitor($this->_parts[$name], $name);
}
Expand All @@ -319,7 +324,7 @@ protected function _traverseUpdate(callable $visitor) {
* @return void
*/
protected function _traverseInsert(callable $visitor) {
$parts = ['insert', 'values'];
$parts = ['insert', 'values', 'append'];
foreach ($parts as $name) {
$visitor($this->_parts[$name], $name);
}
Expand Down Expand Up @@ -1319,6 +1324,27 @@ public function delete($table = null) {
return $this;
}

/**
* A string or expression that will be appended to the generated query
*
* ### Examples:
* {{{
* $query->select('id')->where(['author_id' => 1])->append('FOR UPDATE');
* $query
* ->insert('articles', ['title'])
* ->values(['author_id' => 1])
* ->append('RETURNING id');
* }}}
*
* @params string|QueryExpression the expression to be appended
* @return Query
*/
public function append($expression = null) {
$this->_dirty();
$this->_parts['append'] = $expression;
return $this;
}

/**
* Returns the type of this query (select, insert, update, delete)
*
Expand Down
19 changes: 19 additions & 0 deletions Cake/Test/TestCase/Database/QueryTest.php
Expand Up @@ -1937,6 +1937,25 @@ public function testBind() {
$this->assertEquals($expected, $results->fetchAll('assoc'));
}

/**
* Test that append() will actually append a string to a select query
*
* @return void
*/
public function testAppendSelect() {
$query = new Query($this->connection);
$sql = $query
->select(['id', 'title'])
->from('articles')
->where(['id' => 1])
->append('FOR UPDATE')
->sql();
$this->assertContains('SELECT', $sql);
$this->assertContains('FROM', $sql);
$this->assertContains('WHERE', $sql);
$this->assertEquals('FOR UPDATE', substr($sql, -10));
}

/**
* Assertion for comparing a table's contents with what is in it.
*
Expand Down

0 comments on commit b67e133

Please sign in to comment.