Permalink
Browse files

Fixing issues in DboSource::defaultConditions() and DboSource::condit…

…ions() where doubly deleting a record from the beforeDelete and delete() could create incorrect conditions that would delete all records in a table. Fixes #250
  • Loading branch information...
1 parent 3174630 commit 5d35fd8d38b0b3a89b1f72d9e069b82e11e0acb4 @markstory markstory committed Jan 22, 2010
View
27 cake/libs/model/datasources/dbo_source.php
@@ -1378,6 +1378,7 @@ function update(&$model, $fields = array(), $values = null, $conditions = null)
} else {
$combined = array_combine($fields, $values);
}
+
$fields = implode(', ', $this->_prepareUpdateFields($model, $combined, empty($conditions)));
$alias = $joins = null;
@@ -1605,18 +1606,27 @@ function rollback(&$model) {
}
/**
* Creates a default set of conditions from the model if $conditions is null/empty.
+ * If conditions are supplied then they will be returned. If a model doesn't exist and no conditions
+ * were provided either null or false will be returned based on what was input.
*
* @param object $model
- * @param mixed $conditions
+ * @param mixed $conditions Array of conditions, conditions string, null or false. If an array of conditions,
+ * or string conditions those conditions will be returned. With other values the model's existance will be checked.
+ * If the model doesn't exist a null or false will be returned depending on the input value.
* @param boolean $useAlias Use model aliases rather than table names when generating conditions
- * @return mixed
+ * @return mixed Either null, false, $conditions or an array of default conditions to use.
+ * @see DboSource::update()
+ * @see DboSource::conditions()
*/
function defaultConditions(&$model, $conditions, $useAlias = true) {
if (!empty($conditions)) {
return $conditions;
}
- if (!$model->exists()) {
+ $exists = $model->exists();
+ if (!$exists && $conditions !== null) {
return false;
+ } elseif (!$exists) {
+ return null;
}
$alias = $model->alias;
@@ -1741,9 +1751,11 @@ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
return array_unique($fields);
}
/**
- * Creates a WHERE clause by parsing given conditions data.
+ * Creates a WHERE clause by parsing given conditions data. If an array or string
+ * conditions are provided those conditions will be parsed and quoted. If a boolean
+ * is given it will be integer cast as condition. Null will return 1 = 1.
*
- * @param mixed $conditions Array or string of conditions
+ * @param mixed $conditions Array or string of conditions, or any value.
* @param boolean $quoteValues If true, values should be quoted
* @param boolean $where If true, "WHERE " will be prepended to the return value
* @param Model $model A reference to the Model instance making the query
@@ -1764,8 +1776,11 @@ function conditions($conditions, $quoteValues = true, $where = true, $model = nu
}
return $clause . implode(' AND ', $out);
}
+ if ($conditions === false || $conditions === true) {
+ return $clause . (int)$conditions . ' = 1';
+ }
- if (empty($conditions) || trim($conditions) == '' || $conditions === true) {
+ if (empty($conditions) || trim($conditions) == '') {
return $clause . '1 = 1';
}
$clauses = '/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i';
View
25 cake/tests/cases/libs/model/datasources/dbo_source.test.php
@@ -2097,6 +2097,30 @@ function testSelectDistict() {
$this->assertEqual($result, $expected);
}
/**
+ * test that booleans and null make logical condition strings.
+ *
+ * @return void
+ */
+ function testBooleanNullConditionsParsing() {
+ $result = $this->testDb->conditions(true);
+ $this->assertEqual($result, ' WHERE 1 = 1', 'true conditions failed %s');
+
+ $result = $this->testDb->conditions(false);
+ $this->assertEqual($result, ' WHERE 0 = 1', 'false conditions failed %s');
+
+ $result = $this->testDb->conditions(null);
+ $this->assertEqual($result, ' WHERE 1 = 1', 'null conditions failed %s');
+
+ $result = $this->testDb->conditions(array());
+ $this->assertEqual($result, ' WHERE 1 = 1', 'array() conditions failed %s');
+
+ $result = $this->testDb->conditions('');
+ $this->assertEqual($result, ' WHERE 1 = 1', '"" conditions failed %s');
+
+ $result = $this->testDb->conditions(' ', '" " conditions failed %s');
+ $this->assertEqual($result, ' WHERE 1 = 1');
+ }
+/**
* testStringConditionsParsing method
*
* @access public
@@ -3093,6 +3117,7 @@ function testRenderStatement() {
$result = $this->testDb->renderStatement('delete', array('fields' => 'value=2', 'table' => 'table', 'conditions' => 'WHERE 1=1', 'alias' => 'alias', 'joins' => ''));
$this->assertPattern('/^\s*DELETE\s+alias\s+FROM\s+table\s+AS\s+alias\s+WHERE\s+1=1\s*$/', $result);
}
+
/**
* testStatements method
*

0 comments on commit 5d35fd8

Please sign in to comment.