Skip to content
Permalink
Browse files

Add basic table level updates.

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 18, 2013
1 parent 3184535 commit 10d97d8e51971322d59b590229b5f107b0b0b4d9
Showing with 68 additions and 8 deletions.
  1. +6 −4 lib/Cake/ORM/Query.php
  2. +24 −4 lib/Cake/ORM/Table.php
  3. +38 −0 lib/Cake/Test/TestCase/ORM/TableTest.php
@@ -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();
}
@@ -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);
}
/**
@@ -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;
}
}
@@ -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.
You can’t perform that action at this time.