Skip to content

Commit

Permalink
Remove support for update with joins.
Browse files Browse the repository at this point in the history
This feature is inconsistently implemented or not implemented across all
drivers. What is implemented consistently across all drivers is the
ability to do update/delete with subquery conditions. This will be the
recommended/documented way to preform multi table update/delete
operations.
  • Loading branch information
markstory committed Jun 26, 2013
1 parent b9dc86c commit 690f890
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 88 deletions.
34 changes: 0 additions & 34 deletions lib/Cake/Database/Dialect/PostgresDialectTrait.php
Expand Up @@ -80,40 +80,6 @@ protected function _selectQueryTranslator($query) {
return $query;
}

/**
* Returns an update query that has been transformed for Postgres.
*
* Postgres requires joins to be defined in the FROM list instead of
* as standard joins. This translator will erase joins and replace them with
* an expression object in the FROM clause.
*
* @param Cake\Database\Query $query
* @return Cake\Database\Query
*/
protected function _updateQueryTranslator($query) {
$joins = $query->clause('join');
if (empty($joins)) {
return $query;
}
$first = array_shift($joins);
$sql = sprintf('%s %s', $first['table'], $first['alias']);
if (isset($first['conditions']) && count($first['conditions'])) {
$query->where($first['conditions']);
}
foreach ($joins as $i => $join) {
$sql .= sprintf(' %s JOIN %s %s', $join['type'], $join['table'], $join['alias']);
if (isset($join['conditions']) && count($join['conditions'])) {
$sql .= sprintf(' ON %s', $join['conditions']);
} else {
$sql .= ' ON 1 = 1';
}
}
$expr = $query->newExpr()->add($sql);
$query->join([], [], true);
$query->from([$expr]);
return $query;
}

/**
* Returns a function that will be used as a callback for a results decorator.
* this function is responsible for deleting the artificial column in results
Expand Down
2 changes: 1 addition & 1 deletion lib/Cake/Database/Query.php
Expand Up @@ -289,7 +289,7 @@ protected function _traverseDelete(callable $visitor) {
* @return void
*/
protected function _traverseUpdate(callable $visitor) {
$parts = ['update', 'join', 'set', 'from', 'where'];
$parts = ['update', 'set', 'where'];
foreach ($parts as $name) {
call_user_func($visitor, $this->_parts[$name], $name);
}
Expand Down
24 changes: 0 additions & 24 deletions lib/Cake/Test/TestCase/Database/Driver/PostgresTest.php
Expand Up @@ -136,28 +136,4 @@ public function testConnectionConfigCustom() {
$driver->connect();
}

public function testUpdateWithJoin() {
$driver = $this->getMock('Cake\Database\driver\Postgres', ['_connect', 'connection']);
$connection = new Connection(Configure::read('Datasource.test'));
$connection->driver($driver);

$query = new Query($connection);

$query->update('articles')
->set('title', 'New title')
->join([
'table' => 'authors',
'alias' => 'a',
'conditions' => 'author_id = a.id'
])
->join('comments')
->where(['articles.id' => 1]);
$result = $query->sql(true);

$this->assertContains('UPDATE articles SET title = :', $result);
$this->assertContains('FROM authors a INNER JOIN comments ON 1 = 1', $result);
$this->assertContains('WHERE (articles.id = :', $result);
$this->assertContains('AND author_id = a.id)', $result);
}

}
29 changes: 0 additions & 29 deletions lib/Cake/Test/TestCase/Database/QueryTest.php
Expand Up @@ -1635,35 +1635,6 @@ public function testUpdateWithExpression() {
$this->assertCount(1, $result);
}

/**
* Test updates with joins.
*
* @return void
*/
public function testUpdateWithJoins() {
$config = Configure::read('Datasource.test');
$this->skipIf(strpos($config['datasource'], 'Sqlite') !== false, 'Sqlite update with join does not work.');

$query = new Query($this->connection);

$query->update('articles')
->set('title', 'New title')
->join([
'table' => 'authors',
'alias' => 'a',
'conditions' => 'author_id = a.id'
])
->where(['articles.id' => 1]);
$result = $query->sql(false);

$this->assertContains('UPDATE articles INNER JOIN authors a ON author_id = a.id', $result);
$this->assertContains('SET title = :', $result);
$this->assertContains('WHERE articles.id = :', $result);

$result = $query->execute();
$this->assertCount(1, $result);
}

/**
* You cannot call values() before insert() it causes all sorts of pain.
*
Expand Down

0 comments on commit 690f890

Please sign in to comment.