Fixing code formatting to wrap at 100 characters, adding fix for ticket #5596, counterCache now decrements properly when foreign key value changes.

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@7927 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
nate 2008-12-17 04:13:45 +00:00
parent ea414c8574
commit 8eade1adb3
9 changed files with 483 additions and 92 deletions

View file

@ -249,8 +249,14 @@ class Configure extends Object {
* Usage * Usage
* Configure::write('One.key1', 'value of the Configure::One[key1]'); * Configure::write('One.key1', 'value of the Configure::One[key1]');
* Configure::write(array('One.key1' => 'value of the Configure::One[key1]')); * Configure::write(array('One.key1' => 'value of the Configure::One[key1]'));
* Configure::write('One', array('key1'=>'value of the Configure::One[key1]', 'key2'=>'value of the Configure::One[key2]'); * Configure::write('One', array(
* Configure::write(array('One.key1' => 'value of the Configure::One[key1]', 'One.key2' => 'value of the Configure::One[key2]')); * 'key1' => 'value of the Configure::One[key1]',
* 'key2' => 'value of the Configure::One[key2]'
* );
* Configure::write(array(
* 'One.key1' => 'value of the Configure::One[key1]',
* 'One.key2' => 'value of the Configure::One[key2]'
* ));
* *
* @link http://book.cakephp.org/view/412/write * @link http://book.cakephp.org/view/412/write
* @param array $config Name of var to write * @param array $config Name of var to write
@ -379,7 +385,8 @@ class Configure extends Object {
* Usage Configure::load('configure_file'); * Usage Configure::load('configure_file');
* *
* @link http://book.cakephp.org/view/415/load * @link http://book.cakephp.org/view/415/load
* @param string $fileName name of file to load, extension must be .php and only the name should be used, not the extenstion * @param string $fileName name of file to load, extension must be .php and only the name
* should be used, not the extenstion
* @return mixed false if file not found, void if load successful * @return mixed false if file not found, void if load successful
* @access public * @access public
*/ */
@ -407,7 +414,8 @@ class Configure extends Object {
} }
if (!isset($config)) { if (!isset($config)) {
trigger_error(sprintf(__("Configure::load() - no variable \$config found in %s.php", true), $fileName), E_USER_WARNING); $error = __("Configure::load() - no variable \$config found in %s.php", true);
trigger_error(sprintf($error, $fileName), E_USER_WARNING);
return false; return false;
} }
return Configure::write($config); return Configure::write($config);
@ -433,7 +441,9 @@ class Configure extends Object {
/** /**
* Used to write a config file to disk. * Used to write a config file to disk.
* *
* Configure::store('Model', 'class.paths', array('Users' => array('path' => 'users', 'plugin' => true))); * Configure::store('Model', 'class.paths', array('Users' => array(
* 'path' => 'users', 'plugin' => true
* )));
* *
* @param string $type Type of config file to write, ex: Models, Controllers, Helpers, Components * @param string $type Type of config file to write, ex: Models, Controllers, Helpers, Components
* @param string $name file name. * @param string $name file name.
@ -470,7 +480,8 @@ class Configure extends Object {
* Returns a key/value list of all paths where core libs are found. * Returns a key/value list of all paths where core libs are found.
* Passing $type only returns the values for a given value of $key. * Passing $type only returns the values for a given value of $key.
* *
* @param string $type valid values are: 'model', 'behavior', 'controller', 'component', 'view', 'helper', 'libs', and 'cake' * @param string $type valid values are: 'model', 'behavior', 'controller', 'component',
* 'view', 'helper', 'datasource', 'libs', and 'cake'
* @return array numeric keyed array of core lib paths * @return array numeric keyed array of core lib paths
* @access public * @access public
*/ */
@ -589,7 +600,8 @@ class Configure extends Object {
'plugin' => array(APP . 'plugins' . DS), 'plugin' => array(APP . 'plugins' . DS),
'vendor' => array(APP . 'vendors' . DS, VENDORS), 'vendor' => array(APP . 'vendors' . DS, VENDORS),
'locale' => array(APP . 'locale' . DS), 'locale' => array(APP . 'locale' . DS),
'shell' => array() 'shell' => array(),
'datasource' => array(MODELS . 'datasources')
); );
foreach ($basePaths as $type => $default) { foreach ($basePaths as $type => $default) {
@ -609,7 +621,9 @@ class Configure extends Object {
$_this->{$pathsVar} = $default; $_this->{$pathsVar} = $default;
if (isset($paths[$pathsVar]) && !empty($paths[$pathsVar])) { if (isset($paths[$pathsVar]) && !empty($paths[$pathsVar])) {
$path = array_flip(array_flip((array_merge($_this->{$pathsVar}, (array)$paths[$pathsVar], $merge)))); $path = array_flip(array_flip((array_merge(
$_this->{$pathsVar}, (array)$paths[$pathsVar], $merge
))));
$_this->{$pathsVar} = array_values($path); $_this->{$pathsVar} = array_values($path);
} else { } else {
$path = array_flip(array_flip((array_merge($_this->{$pathsVar}, $merge)))); $path = array_flip(array_flip((array_merge($_this->{$pathsVar}, $merge))));
@ -676,7 +690,10 @@ class Configure extends Object {
} }
Cache::config('default'); Cache::config('default');
} }
Configure::buildPaths(compact('modelPaths', 'viewPaths', 'controllerPaths', 'helperPaths', 'componentPaths', 'behaviorPaths', 'pluginPaths', 'vendorPaths', 'localePaths', 'shellPaths')); Configure::buildPaths(compact(
'modelPaths', 'viewPaths', 'controllerPaths', 'helperPaths', 'componentPaths',
'behaviorPaths', 'pluginPaths', 'vendorPaths', 'localePaths', 'shellPaths'
));
} }
} }
/** /**
@ -745,13 +762,17 @@ class App extends Object {
* Finds classes based on $name or specific file(s) to search. * Finds classes based on $name or specific file(s) to search.
* *
* @link http://book.cakephp.org/view/529/Using-App-import * @link http://book.cakephp.org/view/529/Using-App-import
* @param mixed $type The type of Class if passed as a string, or all params can be passed as an single array to $type, * @param mixed $type The type of Class if passed as a string, or all params can be passed as
* an single array to $type,
* @param string $name Name of the Class or a unique name for the file * @param string $name Name of the Class or a unique name for the file
* @param mixed $parent boolean true if Class Parent should be searched, accepts key => value array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext'); * @param mixed $parent boolean true if Class Parent should be searched, accepts key => value
* $ext allows setting the extension of the file name based on Inflector::underscore($name) . ".$ext"; * array('parent' => $parent ,'file' => $file, 'search' => $search, 'ext' => '$ext');
* $ext allows setting the extension of the file name
* based on Inflector::underscore($name) . ".$ext";
* @param array $search paths to search for files, array('path 1', 'path 2', 'path 3'); * @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
* @param string $file full name of the file to search for including extension * @param string $file full name of the file to search for including extension
* @param boolean $return, return the loaded file, the file must have a return statement in it to work: return $variable; * @param boolean $return, return the loaded file, the file must have a return
* statement in it to work: return $variable;
* @return boolean true if Class is already in memory or if file is found and loaded, false if not * @return boolean true if Class is already in memory or if file is found and loaded, false if not
* @access public * @access public
*/ */

View file

@ -174,7 +174,8 @@ class ConnectionManager extends Object {
} elseif (fileExistsInPath(LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php')) { } elseif (fileExistsInPath(LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php')) {
require (LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php'); require (LIBS . 'model' . DS . 'datasources' . DS . $conn['filename'] . '.php');
} else { } else {
trigger_error(sprintf(__('Unable to load DataSource file %s.php', true), $conn['filename']), E_USER_ERROR); $error = __('Unable to load DataSource file %s.php', true);
trigger_error(sprintf($error, $conn['filename']), E_USER_ERROR);
return null; return null;
} }
} }

View file

@ -1141,8 +1141,9 @@ class Model extends Overloadable {
foreach ($dateFields as $updateCol) { foreach ($dateFields as $updateCol) {
if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) { if ($this->hasField($updateCol) && !in_array($updateCol, $fields)) {
$colType = array_merge(array('formatter' => 'date'), $db->columns[$this->getColumnType($updateCol)]); $default = array('formatter' => 'date');
if (!array_key_exists('formatter', $colType) || !array_key_exists('format', $colType)) { $colType = array_merge($default, $db->columns[$this->getColumnType($updateCol)]);
if (!array_key_exists('format', $colType)) {
$time = strtotime('now'); $time = strtotime('now');
} else { } else {
$time = $colType['formatter']($colType['format']); $time = $colType['formatter']($colType['format']);
@ -1155,7 +1156,10 @@ class Model extends Overloadable {
} }
if ($options['callbacks'] === true || $options['callbacks'] === 'before') { if ($options['callbacks'] === true || $options['callbacks'] === 'before') {
if (!$this->Behaviors->trigger($this, 'beforeSave', array($options), array('break' => true, 'breakOn' => false)) || !$this->beforeSave($options)) { $result = $this->Behaviors->trigger($this, 'beforeSave', array($options), array(
'break' => true, 'breakOn' => false
));
if (!$result || !$this->beforeSave($options)) {
$this->whitelist = $_whitelist; $this->whitelist = $_whitelist;
return false; return false;
} }
@ -1197,15 +1201,18 @@ class Model extends Overloadable {
$created = false; $created = false;
if ($count > 0) { if ($count > 0) {
$cache = $this->_prepareUpdateFields(array_combine($fields, $values));
if (!empty($this->id)) { if (!empty($this->id)) {
if (!$db->update($this, $fields, $values)) { $success = (bool)$db->update($this, $fields, $values);
$success = false;
}
} else { } else {
foreach ($this->_schema as $field => $properties) { foreach ($this->_schema as $field => $properties) {
if ($this->primaryKey === $field) { if ($this->primaryKey === $field) {
$isUUID = ($this->_schema[$field]['type'] === 'string' && $this->_schema[$field]['length'] === 36) $fInfo = $this->_schema[$field];
|| ($this->_schema[$field]['type'] === 'binary' && $this->_schema[$field]['length'] === 16); $isUUID = (
($fInfo['type'] === 'string' && $fInfo['length'] === 36) ||
($fInfo['type'] === 'binary' && $fInfo['length'] === 16)
);
if (empty($this->data[$this->alias][$this->primaryKey]) && $isUUID) { if (empty($this->data[$this->alias][$this->primaryKey]) && $isUUID) {
list($fields[], $values[]) = array($this->primaryKey, String::uuid()); list($fields[], $values[]) = array($this->primaryKey, String::uuid());
} }
@ -1219,10 +1226,10 @@ class Model extends Overloadable {
$created = true; $created = true;
} }
} }
}
if (!empty($this->belongsTo)) { if ($success && !empty($this->belongsTo)) {
$this->updateCounterCache(array(), $created); $this->updateCounterCache($cache, $created);
}
} }
if (!empty($joined) && $success === true) { if (!empty($joined) && $success === true) {
@ -1334,32 +1341,80 @@ class Model extends Overloadable {
* @access public * @access public
*/ */
function updateCounterCache($keys = array(), $created = false) { function updateCounterCache($keys = array(), $created = false) {
if (empty($keys)) { $keys = empty($keys) ? $this->data[$this->alias] : $keys;
$keys = $this->data[$this->alias]; $keys['old'] = isset($keys['old']) ? $keys['old'] : array();
}
foreach ($this->belongsTo as $parent => $assoc) { foreach ($this->belongsTo as $parent => $assoc) {
$foreignKey = $assoc['foreignKey'];
$fkQuoted = $this->escapeField($assoc['foreignKey']);
if (!empty($assoc['counterCache'])) { if (!empty($assoc['counterCache'])) {
if ($assoc['counterCache'] === true) { if ($assoc['counterCache'] === true) {
$assoc['counterCache'] = Inflector::underscore($this->alias) . '_count'; $assoc['counterCache'] = Inflector::underscore($this->alias) . '_count';
} }
if (!isset($keys[$assoc['foreignKey']]) || empty($keys[$assoc['foreignKey']])) { if (!$this->{$parent}->hasField($assoc['counterCache'])) {
$keys[$assoc['foreignKey']] = $this->field($assoc['foreignKey']); continue;
} }
if ($this->{$parent}->hasField($assoc['counterCache'])) {
$conditions = array($this->escapeField($assoc['foreignKey']) => $keys[$assoc['foreignKey']]); if (!array_key_exists($foreignKey, $keys)) {
$recursive = -1; $keys[$foreignKey] = $this->field($foreignKey);
if (isset($assoc['counterScope'])) { }
$conditions = array_merge($conditions, (array)$assoc['counterScope']); $recursive = (isset($assoc['counterScope']) ? 1 : -1);
$recursive = 1; $conditions = ($recursive == 1) ? (array)$assoc['counterScope'] : array();
if (isset($keys['old'][$foreignKey])) {
if ($keys['old'][$foreignKey] == $keys[$foreignKey]) {
continue;
} }
$conditions[$fkQuoted] = $keys['old'][$foreignKey];
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll( $this->{$parent}->updateAll(
array($assoc['counterCache'] => intval($this->find('count', compact('conditions', 'recursive')))), array($assoc['counterCache'] => $count),
array($this->{$parent}->escapeField() => $keys[$assoc['foreignKey']]) array($this->{$parent}->escapeField() => $keys['old'][$foreignKey])
); );
} }
$conditions[$fkQuoted] = $keys[$foreignKey];
if ($recursive == 1) {
$conditions = array_merge($conditions, (array)$assoc['counterScope']);
}
$count = intval($this->find('count', compact('conditions', 'recursive')));
$this->{$parent}->updateAll(
array($assoc['counterCache'] => $count),
array($this->{$parent}->escapeField() => $keys[$foreignKey])
);
} }
} }
} }
/**
* Helper method for Model::updateCounterCache(). Checks the fields to be updated for
*
* @param array $data The fields of the record that will be updated
* @return array Returns updated foreign key values, along with an 'old' key containing the old
* values, or empty if no foreign keys are updated.
* @access protected
*/
function _prepareUpdateFields($data) {
$foreignKeys = array();
foreach ($this->belongsTo as $assoc => $info) {
if ($info['counterCache']) {
$foreignKeys[$assoc] = $info['foreignKey'];
}
}
$included = array_intersect($foreignKeys, array_keys($data));
if (empty($included) || empty($this->id)) {
return array();
}
$old = $this->find('first', array(
'conditions' => array('id' => $this->id),
'fields' => array_values($included),
'recursive' => -1
));
return array_merge($data, array('old' => $old[$this->alias]));
}
/** /**
* Saves multiple individual records for a single model; Also works with a single record, as well as * Saves multiple individual records for a single model; Also works with a single record, as well as
* all its associated records. * all its associated records.
@ -2419,6 +2474,7 @@ class Model extends Overloadable {
* *
* @return string The name of the display field for this Model (i.e. 'name', 'title'). * @return string The name of the display field for this Model (i.e. 'name', 'title').
* @access public * @access public
* @deprecated
*/ */
function getDisplayField() { function getDisplayField() {
return $this->displayField; return $this->displayField;

View file

@ -406,7 +406,7 @@ class Set extends Object {
if (count($context['trace']) == 1) { if (count($context['trace']) == 1) {
$context['trace'][] = $context['key']; $context['trace'][] = $context['key'];
} }
$parent = join('/', $context['trace']).'/.'; $parent = join('/', $context['trace']) . '/.';
$context['item'] = Set::extract($parent, $data); $context['item'] = Set::extract($parent, $data);
$context['key'] = array_pop($context['trace']); $context['key'] = array_pop($context['trace']);
if (isset($context['trace'][1]) && $context['trace'][1] > 0) { if (isset($context['trace'][1]) && $context['trace'][1] > 0) {
@ -455,7 +455,7 @@ class Set extends Object {
$filtered = array(); $filtered = array();
$length = count($matches); $length = count($matches);
foreach ($matches as $i => $match) { foreach ($matches as $i => $match) {
if (Set::matches(array($condition), $match['item'], $i+1, $length)) { if (Set::matches(array($condition), $match['item'], $i + 1, $length)) {
$filtered[] = $match; $filtered[] = $match;
} }
} }

View file

@ -65,7 +65,8 @@ class ModelTest extends CakeTestCase {
'core.dependency', 'core.story', 'core.stories_tag', 'core.cd', 'core.book', 'core.basket', 'core.dependency', 'core.story', 'core.stories_tag', 'core.cd', 'core.book', 'core.basket',
'core.overall_favorite', 'core.account', 'core.content', 'core.content_account', 'core.overall_favorite', 'core.account', 'core.content', 'core.content_account',
'core.film_file', 'core.test_plugin_article', 'core.test_plugin_comment', 'core.uuiditem', 'core.film_file', 'core.test_plugin_article', 'core.test_plugin_comment', 'core.uuiditem',
'core.uuidportfolio', 'core.uuiditems_uuidportfolio', 'core.uuiditems_uuidportfolio_numericid' 'core.counter_cache_user', 'core.counter_cache_post', 'core.uuidportfolio',
'core.uuiditems_uuidportfolio', 'core.uuiditems_uuidportfolio_numericid'
); );
/** /**
* start method * start method
@ -190,7 +191,8 @@ class ModelTest extends CakeTestCase {
$this->assertTrue(isset($TestModel->Behaviors->Tree)); $this->assertTrue(isset($TestModel->Behaviors->Tree));
$TestModel =& ClassRegistry::init('MergeVarPluginComment'); $TestModel =& ClassRegistry::init('MergeVarPluginComment');
$this->assertEqual($TestModel->actsAs, array('Containable', 'Containable' => array('some_settings'))); $expected = array('Containable', 'Containable' => array('some_settings'));
$this->assertEqual($TestModel->actsAs, $expected);
$this->assertTrue(isset($TestModel->Behaviors->Containable)); $this->assertTrue(isset($TestModel->Behaviors->Containable));
} }
/** /**
@ -1073,13 +1075,15 @@ class ModelTest extends CakeTestCase {
$TestModel->id = 7; $TestModel->id = 7;
$result = $TestModel->read(); $result = $TestModel->read();
$expected = array( $expected = array(
'CategoryThread' => array('id' => 7, 'parent_id' => 6, 'name' => 'Category 2.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'), 'CategoryThread' => array('id' => 7, 'parent_id' => 6, 'name' => 'Category 2.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
'ParentCategory' => array('id' => 6, 'parent_id' => 5, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 6, 'parent_id' => 5, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 5, 'parent_id' => 4, 'name' => 'Category 1.1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 5, 'parent_id' => 4, 'name' => 'Category 1.1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 4, 'parent_id' => 3, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 4, 'parent_id' => 3, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 3, 'parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 3, 'parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 2, 'parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 2, 'parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 1, 'parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'))))))); 'ParentCategory' => array('id' => 1, 'parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31')))))
)
);
$this->db->fullDebug = $fullDebug; $this->db->fullDebug = $fullDebug;
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
@ -1099,13 +1103,15 @@ class ModelTest extends CakeTestCase {
$result = $TestModel->find(array('CategoryThread.id' => 7)); $result = $TestModel->find(array('CategoryThread.id' => 7));
$expected = array( $expected = array(
'CategoryThread' => array('id' => 7, 'parent_id' => 6, 'name' => 'Category 2.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'), 'CategoryThread' => array('id' => 7, 'parent_id' => 6, 'name' => 'Category 2.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'),
'ParentCategory' => array('id' => 6, 'parent_id' => 5, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 6, 'parent_id' => 5, 'name' => 'Category 2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 5, 'parent_id' => 4, 'name' => 'Category 1.1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 5, 'parent_id' => 4, 'name' => 'Category 1.1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 4, 'parent_id' => 3, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 4, 'parent_id' => 3, 'name' => 'Category 1.1.2', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 3, 'parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 3, 'parent_id' => 2, 'name' => 'Category 1.1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 2, 'parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31', 'ParentCategory' => array('id' => 2, 'parent_id' => 1, 'name' => 'Category 1.1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31',
'ParentCategory' => array('id' => 1, 'parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31'))))))); 'ParentCategory' => array('id' => 1, 'parent_id' => 0, 'name' => 'Category 1', 'created' => '2007-03-18 15:30:23', 'updated' => '2007-03-18 15:32:31')))))
)
);
$this->db->fullDebug = $fullDebug; $this->db->fullDebug = $fullDebug;
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
@ -3681,7 +3687,70 @@ class ModelTest extends CakeTestCase {
$this->assertIdentical($result['Syfile']['item_count'], '2'); $this->assertIdentical($result['Syfile']['item_count'], '2');
$result = $TestModel->findById(2); $result = $TestModel->findById(2);
$this->assertIdentical($result['Syfile']['item_count'], null); $this->assertIdentical($result['Syfile']['item_count'], '0');
}
/**
* Tests that counter caches are updated when records are added
*
* @access public
* @return void
*/
function testCounterCacheIncrease() {
$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
$User = new CounterCacheUser();
$Post = new CounterCachePost();
$data = array('Post' => array('title' => 'New Post', 'user_id' => 66));
$Post->save($data);
$user = $User->find('first', array(
'conditions' => array('id' => 66),'recursive' => -1
));
$result = $user[$User->alias]['post_count'];
$expected = 3;
$this->assertEqual($result, $expected);
}
/**
* Tests that counter caches are updated when records are deleted
*
* @access public
* @return void
*/
function testCounterCacheDecrease() {
$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
$User = new CounterCacheUser();
$Post = new CounterCachePost();
$Post->del(2);
$user = $User->find('first', array(
'conditions' => array('id' => 66),'recursive' => -1
));
$result = $user[$User->alias]['post_count'];
$expected = 1;
$this->assertEqual($result, $expected);
}
/**
* Tests that counter caches are updated when foreign keys of counted records change
*
* @access public
* @return void
*/
function testCounterCacheUpdated() {
$this->loadFixtures('CounterCacheUser', 'CounterCachePost');
$User = new CounterCacheUser();
$Post = new CounterCachePost();
$data = $Post->find('first', array(
'conditions' => array('id' => 1),'recursive' => -1
));
$data[$Post->alias]['user_id'] = 301;
$Post->save($data);
$users = $User->find('all',array('order' => 'User.id'));
$this->assertEqual($users[0]['User']['post_count'], 1);
$this->assertEqual($users[1]['User']['post_count'], 2);
} }
/** /**
* test Counter Cache With Self Joining table * test Counter Cache With Self Joining table

View file

@ -2840,6 +2840,29 @@ class TranslatedArticle extends CakeTestModel {
var $belongsTo = array('User'); var $belongsTo = array('User');
} }
class CounterCacheUser extends CakeTestModel {
var $name = 'CounterCacheUser';
var $alias = 'User';
var $fixture = 'counter_cache_user';
var $hasMany = array('Post' => array(
'className' => 'CounterCachePost',
'foreignKey' => 'user_id'
));
}
class CounterCachePost extends CakeTestModel {
var $name = 'CounterCachePost';
var $alias = 'Post';
var $fixture = 'counter_cache_user';
var $belongsTo = array('User' => array(
'className' => 'CounterCacheUser',
'foreignKey' => 'user_id',
'counterCache' => true
));
}
class ArticleB extends CakeTestModel { class ArticleB extends CakeTestModel {
var $name = 'ArticleB'; var $name = 'ArticleB';
var $useTable = 'articles'; var $useTable = 'articles';
@ -2848,8 +2871,9 @@ class ArticleB extends CakeTestModel {
'className' => 'TagB', 'className' => 'TagB',
'joinTable' => 'articles_tags', 'joinTable' => 'articles_tags',
'foreignKey' => 'article_id', 'foreignKey' => 'article_id',
'associationForeignKey' => 'tag_id') 'associationForeignKey' => 'tag_id'
); )
);
} }
class TagB extends CakeTestModel { class TagB extends CakeTestModel {
@ -2860,7 +2884,9 @@ class TagB extends CakeTestModel {
'className' => 'ArticleB', 'className' => 'ArticleB',
'joinTable' => 'articles_tags', 'joinTable' => 'articles_tags',
'foreignKey' => 'tag_id', 'foreignKey' => 'tag_id',
'associationForeignKey' => 'article_id') 'associationForeignKey' => 'article_id'
); )
);
} }
?> ?>

View file

@ -395,28 +395,13 @@ class SetTest extends CakeTestCase {
); );
$b = array('Deep' => $a[0]['Deep']); $b = array('Deep' => $a[0]['Deep']);
$c = array( $c = array(
array( array('a' => array('I' => array('a' => 1))),
'a' => array(
'I' => array(
'a' => 1
)
)
),
array( array(
'a' => array( 'a' => array(
2 2
) )
), ),
array( array('a' => array('II' => array('a' => 3, 'III' => array('a' => array('foo' => 4))))),
'a' => array(
'II' => array(
'a' => 3,
'III' => array(
'a' => array('foo' => 4)
)
)
)
),
); );
$nonSequential = array( $nonSequential = array(
@ -447,9 +432,25 @@ class SetTest extends CakeTestCase {
$this->assertEqual(Set::extract('/User/id', $a), $expected); $this->assertEqual(Set::extract('/User/id', $a), $expected);
$this->assertEqual(Set::extract('/User/id', $nonSequential), $expected); $this->assertEqual(Set::extract('/User/id', $nonSequential), $expected);
$this->assertEqual(Set::extract('/User/id', $nonZero), $expected, 'Failed non zero array key extract'); $result = Set::extract('/User/id', $nonZero);
$this->assertEqual($result, $expected, 'Failed non zero array key extract');
Configure::write('foo', null);
// $expected = array(
// array('id' => 1), array('id' => 2), array('id' => 3), array('id' => 4), array('id' => 5)
// );
$expected = array(1, 2, 3, 4, 5);
$this->assertEqual(Set::extract('/User/id', $a), $expected);
$this->assertEqual(Set::extract('/User/id', $nonSequential), $expected);
$result = Set::extract('/User/id', $nonZero);
$this->assertEqual($result, $expected, 'Failed non zero array key extract');
$expected = array(
array('id' => 1), array('id' => 2), array('id' => 3), array('id' => 4), array('id' => 5)
);
$expected = array(array('id' => 1), array('id' => 2), array('id' => 3), array('id' => 4), array('id' => 5));
$r = Set::extract('/User/id', $a, array('flatten' => false)); $r = Set::extract('/User/id', $a, array('flatten' => false));
$this->assertEqual($r, $expected); $this->assertEqual($r, $expected);
@ -701,6 +702,103 @@ class SetTest extends CakeTestCase {
$this->assertEqual($r[1]['Comment']['User']['name'], 'dan'); $this->assertEqual($r[1]['Comment']['User']['name'], 'dan');
$this->assertEqual(count($r), 2); $this->assertEqual(count($r), 2);
$r = Set::extract('/Comment/User[name=/bob|tod/]/..', $habtm);
$this->assertEqual($r[0]['Comment']['User']['name'], 'bob');
$this->assertEqual($r[1]['Comment']['User']['name'], 'tod');
$this->assertEqual(count($r), 2);
$tree = array(
array(
'Category' => array('name' => 'Category 1'),
'children' => array(array('Category' => array('name' => 'Category 1.1')))
),
array(
'Category' => array('name' => 'Category 2'),
'children' => array(
array('Category' => array('name' => 'Category 2.1')),
array('Category' => array('name' => 'Category 2.2'))
)
),
array(
'Category' => array('name' => 'Category 3'),
'children' => array(array('Category' => array('name' => 'Category 3.1')))
)
);
$expected = array(array('Category' => $tree[1]['Category']));
$r = Set::extract('/Category[name=Category 2]', $tree);
$this->assertEqual($r, $expected);
$expected = array(
array('Category' => $tree[1]['Category'], 'children' => $tree[1]['children'])
);
$r = Set::extract('/Category[name=Category 2]/..', $tree);
$this->assertEqual($r, $expected);
$expected = array(
array('children' => $tree[1]['children'][0]),
array('children' => $tree[1]['children'][1])
);
$r = Set::extract('/Category[name=Category 2]/../children', $tree);
$this->assertEqual($r, $expected);
$habtm = array(
array(
'Post' => array(
'id' => 1,
'title' => 'great post',
),
'Comment' => array(
array(
'id' => 1,
'text' => 'foo',
'User' => array(
'id' => 1,
'name' => 'bob'
),
),
array(
'id' => 2,
'text' => 'bar',
'User' => array(
'id' => 2,
'name' => 'tod'
),
),
),
),
array(
'Post' => array(
'id' => 2,
'title' => 'fun post',
),
'Comment' => array(
array(
'id' => 3,
'text' => '123',
'User' => array(
'id' => 3,
'name' => 'dan'
),
),
array(
'id' => 4,
'text' => '987',
'User' => array(
'id' => 4,
'name' => 'jim'
),
),
),
),
);
$r = Set::extract('/Comment/User[name=/bob|dan/]/..', $habtm);
$this->assertEqual($r[0]['Comment']['User']['name'], 'bob');
$this->assertEqual($r[1]['Comment']['User']['name'], 'dan');
$this->assertEqual(count($r), 2);
$r = Set::extract('/Comment/User[name=/bob|tod/]/..', $habtm); $r = Set::extract('/Comment/User[name=/bob|tod/]/..', $habtm);
$this->assertEqual($r[0]['Comment']['User']['name'], 'bob'); $this->assertEqual($r[0]['Comment']['User']['name'], 'bob');
// Currently failing, needs fix // Currently failing, needs fix
@ -773,7 +871,8 @@ class SetTest extends CakeTestCase {
$a = array( $a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1')), array('Article' => array('id' => 1, 'title' => 'Article 1')),
array('Article' => array('id' => 2, 'title' => 'Article 2')), array('Article' => array('id' => 2, 'title' => 'Article 2')),
array('Article' => array('id' => 3, 'title' => 'Article 3'))); array('Article' => array('id' => 3, 'title' => 'Article 3'))
);
$this->assertTrue(Set::matches(array('id=2'), $a[1]['Article'])); $this->assertTrue(Set::matches(array('id=2'), $a[1]['Article']));
$this->assertFalse(Set::matches(array('id>2'), $a[1]['Article'])); $this->assertFalse(Set::matches(array('id>2'), $a[1]['Article']));
@ -805,7 +904,8 @@ class SetTest extends CakeTestCase {
$a = array( $a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1')), array('Article' => array('id' => 1, 'title' => 'Article 1')),
array('Article' => array('id' => 2, 'title' => 'Article 2')), array('Article' => array('id' => 2, 'title' => 'Article 2')),
array('Article' => array('id' => 3, 'title' => 'Article 3'))); array('Article' => array('id' => 3, 'title' => 'Article 3'))
);
$result = Set::extract($a, '{n}.Article.id'); $result = Set::extract($a, '{n}.Article.id');
$expected = array( 1, 2, 3 ); $expected = array( 1, 2, 3 );
@ -824,12 +924,19 @@ class SetTest extends CakeTestCase {
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$a = array( $a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1', array(
'User' => array('id' => 1, 'username' => 'mariano.iglesias'))), 'Article' => array('id' => 1, 'title' => 'Article 1',
array('Article' => array('id' => 2, 'title' => 'Article 2', 'User' => array('id' => 1, 'username' => 'mariano.iglesias'))
'User' => array('id' => 1, 'username' => 'mariano.iglesias'))), ),
array('Article' => array('id' => 3, 'title' => 'Article 3', array(
'User' => array('id' => 2, 'username' => 'phpnut')))); 'Article' => array('id' => 2, 'title' => 'Article 2',
'User' => array('id' => 1, 'username' => 'mariano.iglesias'))
),
array(
'Article' => array('id' => 3, 'title' => 'Article 3',
'User' => array('id' => 2, 'username' => 'phpnut'))
)
);
$result = Set::extract($a, '{n}.Article.User.username'); $result = Set::extract($a, '{n}.Article.User.username');
$expected = array( 'mariano.iglesias', 'mariano.iglesias', 'phpnut' ); $expected = array( 'mariano.iglesias', 'mariano.iglesias', 'phpnut' );
@ -852,7 +959,11 @@ class SetTest extends CakeTestCase {
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$result = Set::extract($a, '{n}.Article.Comment.{n}.title'); $result = Set::extract($a, '{n}.Article.Comment.{n}.title');
$expected = array (array('Comment 10', 'Comment 11', 'Comment 12'), array('Comment 13', 'Comment 14'), null); $expected = array(
array('Comment 10', 'Comment 11', 'Comment 12'),
array('Comment 13', 'Comment 14'),
null
);
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$a = array(array('1day' => '20 sales'), array('1day' => '2 sales')); $a = array(array('1day' => '20 sales'), array('1day' => '2 sales'));
@ -885,7 +996,12 @@ class SetTest extends CakeTestCase {
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$result = Set::extract($a,'{\w+}.{\w+}.name'); $result = Set::extract($a,'{\w+}.{\w+}.name');
$expected = array(array('pages' => 'page'), array('fruites' => 'fruit'), 'test' => array('jippi'), 'dot.test' => array('jippi')); $expected = array(
array('pages' => 'page'),
array('fruites' => 'fruit'),
'test' => array('jippi'),
'dot.test' => array('jippi')
);
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$result = Set::extract($a,'{\d+}.{\w+}.name'); $result = Set::extract($a,'{\d+}.{\w+}.name');
@ -905,7 +1021,10 @@ class SetTest extends CakeTestCase {
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$result = Set::extract($a,'{[a-z]}'); $result = Set::extract($a,'{[a-z]}');
$expected = array('test' => array(array('name' => 'jippi')), 'dot.test' => array(array('name' => 'jippi'))); $expected = array(
'test' => array(array('name' => 'jippi')),
'dot.test' => array(array('name' => 'jippi'))
);
$this->assertIdentical($result, $expected); $this->assertIdentical($result, $expected);
$result = Set::extract($a, '{dot\.test}.{n}'); $result = Set::extract($a, '{dot\.test}.{n}');

View file

@ -0,0 +1,50 @@
<?php
/* SVN FILE: $Id: counter_cache_fixture.php 7848 2008-11-08 02:58:37Z nate $ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake.tests
* @subpackage cake.tests.fixtures
* @since CakePHP(tm) v 1.2.0.4667
* @version $Revision: 7848 $
* @modifiedby $LastChangedBy: renan.saddam $
* @lastmodified $Date: 2008-11-07 21:58:37 -0500 (Fri, 07 Nov 2008) $
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
/**
* Short description for class.
*
* @package cake.tests
* @subpackage cake.tests.fixtures
*/
class CounterCachePostFixture extends CakeTestFixture {
var $name = 'CounterCachePost';
var $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'user_id' => array('type' => 'integer', 'null' => true),
);
var $records = array(
array('id' => 1, 'title' => 'Rock and Roll', 'user_id' => 66),
array('id' => 2, 'title' => 'Music', 'user_id' => 66),
array('id' => 3, 'title' => 'Food', 'user_id' => 301),
);
}
?>

View file

@ -0,0 +1,49 @@
<?php
/* SVN FILE: $Id: counter_cache_user_fixture.php 7848 2008-11-08 02:58:37Z nate $ */
/**
* Short description for file.
*
* Long description for file
*
* PHP versions 4 and 5
*
* CakePHP(tm) Tests <https://trac.cakephp.org/wiki/Developement/TestSuite>
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
*
* Licensed under The Open Group Test Suite License
* Redistributions of files must retain the above copyright notice.
*
* @filesource
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
* @link https://trac.cakephp.org/wiki/Developement/TestSuite CakePHP(tm) Tests
* @package cake.tests
* @subpackage cake.tests.fixtures
* @since CakePHP(tm) v 1.2.0.4667
* @version $Revision: 7848 $
* @modifiedby $LastChangedBy: renan.saddam $
* @lastmodified $Date: 2008-11-07 21:58:37 -0500 (Fri, 07 Nov 2008) $
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
/**
* Short description for class.
*
* @package cake.tests
* @subpackage cake.tests.fixtures
*/
class CounterCacheUserFixture extends CakeTestFixture {
var $name = 'CounterCacheUser';
var $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'name' => array('type' => 'string', 'length' => 255, 'null' => false),
'post_count' => array('type' => 'integer', 'null' => true)
);
var $records = array(
array('id' => 66, 'name' => 'Alexander','post_count' => 2),
array('id' => 301, 'name' => 'Steven','post_count' => 1),
);
}
?>