Skip to content

Commit

Permalink
Add basic table level updates.
Browse files Browse the repository at this point in the history
Add basic table level updates that can update multiple records. Don't
implement _matchRecords or other join workarounds as they often lead to
concurrency issues. We can revisit that functionality later on if
necessary.
  • Loading branch information
markstory committed Jun 20, 2013
1 parent 3184535 commit 10d97d8
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 8 deletions.
10 changes: 6 additions & 4 deletions lib/Cake/ORM/Query.php
Expand Up @@ -412,11 +412,13 @@ protected function _transformQuery() {
if (!$this->_dirty) {
return parent::_transformQuery();
}
if (empty($this->_parts['from'])) {
$this->from([$this->_table->alias() => $this->_table->table()]);
if ($this->_type === 'select') {
if (empty($this->_parts['from'])) {
$this->from([$this->_table->alias() => $this->_table->table()]);
}
$this->_addDefaultFields();
$this->_addContainments();
}
$this->_addDefaultFields();
$this->_addContainments();
return parent::_transformQuery();
}

Expand Down
28 changes: 24 additions & 4 deletions lib/Cake/ORM/Table.php
Expand Up @@ -459,7 +459,9 @@ public function belongsToMany($associated, array $options = []) {
* @return \Cake\ORM\Query
*/
public function find($type, $options = []) {
return $this->{'find' . ucfirst($type)}($this->_buildQuery(), $options);
$query = $this->_buildQuery();
$query->select();
return $this->{'find' . ucfirst($type)}($query, $options);
}

/**
Expand All @@ -481,9 +483,27 @@ public function findAll(Query $query, array $options = []) {
*/
protected function _buildQuery() {
$query = new Query($this->connection());
return $query
->repository($this)
->select();
return $query->repository($this);
}

/**
* Update one or many rows.
*
* Sets the $fields to the provided values based on $conditions.
* This method will *not* trigger beforeSave/afterSave events. If you need those
* first load a collection of records and update them.
*
* @param array $fields A hash of field => new value.
* @param array $conditions An array of conditions, similar to those used with find()
* @return boolean Success
*/
public function update($fields, $conditions) {
$query = $this->_buildQuery();
$query->update($this->table())
->set($fields)
->where($conditions);
$query->execute();
return true;
}

}
38 changes: 38 additions & 0 deletions lib/Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -374,4 +374,42 @@ public function testBelongsToMany() {
$this->assertSame('things_tags', $belongsToMany->pivot()->table());
}

/**
* Test basic multi row updates.
*
* @return void
*/
public function testUpdate() {
$table = new Table(['table' => 'users', 'connection' => $this->connection]);
$fields = ['user' => 'mark'];
$result = $table->update($fields, ['id <' => 4]);
$this->assertTrue($result);

$result = $table->find('all')->select(['user'])->toArray();
$expected = array_fill(0, 3, $fields);
$expected[] = ['user' => 'garrett'];
$this->assertEquals($expected, $result);
}

/**
* Test that exceptions from the Query bubble up.
*
* @expectedException Cake\Database\Exception
*/
public function testUpdateFailure() {
$table = $this->getMock(
'Cake\ORM\Table',
['_buildQuery'],
['table' => 'users', 'connection' => $this->connection]
);
$query = $this->getMock('Cake\ORM\Query', ['execute'], [$this->connection]);
$table->expects($this->once())
->method('_buildQuery')
->will($this->returnValue($query));
$query->expects($this->once())
->method('execute')
->will($this->throwException(new \Cake\Database\Exception('Not good')));
$table->update(['user' => 'mark'], []);
}

}

0 comments on commit 10d97d8

Please sign in to comment.