Skip to content

Commit

Permalink
Start implementing delete.
Browse files Browse the repository at this point in the history
Basic simple deletes are working now.
  • Loading branch information
markstory committed Nov 2, 2013
1 parent 669848d commit 4449dfa
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 1 deletion.
80 changes: 80 additions & 0 deletions Cake/ORM/Table.php
Expand Up @@ -899,6 +899,86 @@ protected function _update($entity, $data) {
return $success;
}

/**
* Delete a single entity.
*
* Deletes an entity and possibly related associations from the database.
* Any associations marked as dependent will be removed. Any
* rows in a BelongsToMany join table will be removed as well.
*
* ## Options
*
* - `cascade` Defaults to true. Set to false to disable cascaded deletes.
* Use this when you don't want to cascade or when your foreign keys
* will handle the cascading delete for you.
* - `atomic` Defaults to true. When true the deletion happens within a transaction.
*
* ## Events
*
* - `beforeDelete` Fired before the delete occurs. If stopped the delete
* will be aborted. Receives the event, entity, and options.
* - `afterDelete` Fired after the delete has been successful. Receives
* the event, entity, and options.
*
* @param Entity $entity The entity to remove.
* @param array $options The options fo the delete.
* @return boolean success
*/
public function delete(Entity $entity, array $options = []) {
$options = new \ArrayObject($options + ['atomic' => true, 'cascade' => true]);
$event = new Event('Model.beforeDelete', $this, [
'entity' => $entity,
'options' => $options
]);
$this->getEventManager()->dispatch($event);
if ($event->isStopped()) {
return $event->result;
}

$process = function () use ($entity, $options) {
return $this->_processDelete($entity, $options);
};
if ($options['atomic']) {
$success = $this->connection()->transactional($process);
} else {
$success = $process();
}
if (!$success) {
return $success;
}
// TODO add deletion of BelongsToMany and dependents.

$event = new Event('Model.afterDelete', $this, [
'entity' => $entity,
'options' => $options
]);
$this->getEventManager()->dispatch($event);
return $success;
}

/**
* Perform the delete operation.
*
* @param Entity $entity The entity to delete.
* @param array $options The options for the delete.
* @return boolean success
*/
protected function _processDelete($entity, $options) {
if ($entity->isNew()) {
return false;
}
$primaryKey = (array)$this->primaryKey();
$values = (array)$entity->extract($primaryKey);
$conditions = array_combine($primaryKey, $values);

$query = $this->_buildQuery();
$statement = $query->delete($this->table())
->where($conditions)
->executeStatement();

return $statement->rowCount() > 0;
}

/**
* Calls a finder method directly and applies it to the passed query,
* if no query is passed a new one will be created and returned
Expand Down
16 changes: 15 additions & 1 deletion Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -1560,7 +1560,21 @@ public function testUpdateNoPrimaryButOtherKeys() {
* @return void
*/
public function testDelete() {
$this->markTestIncomplete('not done');
$table = TableRegistry::get('user');
$conditions = [
'limit' => 1,
'conditions' => [
'username' => 'nate'
]
];
$query = $table->find('all', $conditions);
$entity = $query->first();
$result = $table->delete($entity);
$this->assertTrue($result);

$query = $table->find('all', $conditions);
$results = $query->execute();
$this->assertCount(0, $results, 'Find should fail.');
}

/**
Expand Down

0 comments on commit 4449dfa

Please sign in to comment.