Merge branch 'virtual-fields' into 1.3-misc

Conflicts:
	cake/tests/cases/libs/controller/controller.test.php
This commit is contained in:
Mark Story 2009-12-19 19:40:12 -05:00
commit 4ac0a55aff
6 changed files with 436 additions and 72 deletions
cake
libs
controller
model
tests/cases/libs

View file

@ -1102,9 +1102,11 @@ class Controller extends Object {
$value = $options['order'][$key]; $value = $options['order'][$key];
unset($options['order'][$key]); unset($options['order'][$key]);
if (isset($object->{$alias}) && $object->{$alias}->hasField($field)) { if ($object->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value; $options['order'][$alias . '.' . $field] = $value;
} elseif ($object->hasField($field)) { } elseif ($object->hasField($field, true)) {
$options['order'][$field] = $value;
} elseif (isset($object->{$alias}) && $object->{$alias}->hasField($field)) {
$options['order'][$alias . '.' . $field] = $value; $options['order'][$alias . '.' . $field] = $value;
} }
} }

View file

@ -363,6 +363,9 @@ class DboSource extends DataSource {
if ($this->hasResult()) { if ($this->hasResult()) {
$this->resultSet($this->_result); $this->resultSet($this->_result);
$resultRow = $this->fetchResult(); $resultRow = $this->fetchResult();
if (!empty($resultRow)) {
$this->fetchVirtualField($resultRow);
}
return $resultRow; return $resultRow;
} else { } else {
return null; return null;
@ -393,6 +396,7 @@ class DboSource extends DataSource {
$out[] = $first; $out[] = $first;
} }
while ($this->hasResult() && $item = $this->fetchResult()) { while ($this->hasResult() && $item = $this->fetchResult()) {
$this->fetchVirtualField($item);
$out[] = $item; $out[] = $item;
} }
@ -410,6 +414,35 @@ class DboSource extends DataSource {
} }
} }
/**
* Modifies $result array to place virtual fields in model entry where they belongs to
*
* @param array $resut REference to the fetched row
* @return void
*/
function fetchVirtualField(&$result) {
if (isset($result[0]) && is_array($result[0])) {
foreach ($result[0] as $field => $value) {
if (strpos($field, '__') === false) {
continue;
}
list($alias, $virtual) = explode('__', $field);
if (!ClassRegistry::isKeySet($alias)) {
return;
}
$model = ClassRegistry::getObject($alias);
if ($model->isVirtualField($virtual)) {
$result[$alias][$virtual] = $value;
unset($result[0][$field]);
}
}
if (empty($result[0])) {
unset($result[0]);
}
}
}
/** /**
* Returns a single field of the first of query results for a given SQL query, or false if empty. * Returns a single field of the first of query results for a given SQL query, or false if empty.
* *
@ -420,7 +453,6 @@ class DboSource extends DataSource {
*/ */
function field($name, $sql) { function field($name, $sql) {
$data = $this->fetchRow($sql); $data = $this->fetchRow($sql);
if (!isset($data[$name]) || empty($data[$name])) { if (!isset($data[$name]) || empty($data[$name])) {
return false; return false;
} else { } else {
@ -1363,7 +1395,7 @@ class DboSource extends DataSource {
* @access public * @access public
* @see DboSource::renderStatement() * @see DboSource::renderStatement()
*/ */
function buildStatement($query, $model) { function buildStatement($query, &$model) {
$query = array_merge(array('offset' => null, 'joins' => array()), $query); $query = array_merge(array('offset' => null, 'joins' => array()), $query);
if (!empty($query['joins'])) { if (!empty($query['joins'])) {
$count = count($query['joins']); $count = count($query['joins']);
@ -1378,7 +1410,7 @@ class DboSource extends DataSource {
'fields' => implode(', ', $query['fields']), 'fields' => implode(', ', $query['fields']),
'table' => $query['table'], 'table' => $query['table'],
'alias' => $this->alias . $this->name($query['alias']), 'alias' => $this->alias . $this->name($query['alias']),
'order' => $this->order($query['order']), 'order' => $this->order($query['order'], 'ASC', $model),
'limit' => $this->limit($query['limit'], $query['offset']), 'limit' => $this->limit($query['limit'], $query['offset']),
'joins' => implode(' ', $query['joins']), 'joins' => implode(' ', $query['joins']),
'group' => $this->group($query['group']) 'group' => $this->group($query['group'])
@ -1657,13 +1689,23 @@ class DboSource extends DataSource {
if (!isset($params[1])) { if (!isset($params[1])) {
$params[1] = 'count'; $params[1] = 'count';
} }
return 'COUNT(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]); if (is_object($model) && $model->isVirtualField($params[0])){
$arg = $this->__quoteFields($model->getVirtualField($params[0]));
} else {
$arg = $this->name($params[0]);
}
return 'COUNT(' . $arg . ') AS ' . $this->name($params[1]);
case 'max': case 'max':
case 'min': case 'min':
if (!isset($params[1])) { if (!isset($params[1])) {
$params[1] = $params[0]; $params[1] = $params[0];
} }
return strtoupper($func) . '(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]); if (is_object($model) && $model->isVirtualField($params[0])) {
$arg = $this->__quoteFields($model->getVirtualField($params[0]));
} else {
$arg = $this->name($params[0]);
}
return strtoupper($func) . '(' . $arg . ') AS ' . $this->name($params[1]);
break; break;
} }
} }
@ -1790,6 +1832,24 @@ class DboSource extends DataSource {
return $data; return $data;
} }
/**
* Converts model virtual fields into sql expressions to be fetched later
*
* @param Model $model
* @param string $alias Alias tablename
* @param mixed $fields virtual fields to be used on query
* @return array
*/
function _constructVirtualFields(&$model,$alias,$fields) {
$virtual = array();
foreach ($fields as $field) {
$virtualField = $this->name("{$alias}__{$field}");
$expression = $this->__quoteFields($model->getVirtualField($field));
$virtual[] = '(' .$expression . ") {$this->alias} {$virtualField}";
}
return $virtual;
}
/** /**
* Generates the fields list of an SQL query. * Generates the fields list of an SQL query.
* *
@ -1804,7 +1864,8 @@ class DboSource extends DataSource {
if (empty($alias)) { if (empty($alias)) {
$alias = $model->alias; $alias = $model->alias;
} }
if (empty($fields)) { $allFields = empty($fields);
if ($allFields) {
$fields = array_keys($model->schema()); $fields = array_keys($model->schema());
} elseif (!is_array($fields)) { } elseif (!is_array($fields)) {
$fields = String::tokenize($fields); $fields = String::tokenize($fields);
@ -1814,10 +1875,19 @@ class DboSource extends DataSource {
if (!$quote) { if (!$quote) {
return $fields; return $fields;
} }
$virtual = array();
if ($model->getVirtualField()) {
$keys = array_keys($model->getVirtualField());
$virtual = ($allFields) ? $keys : array_intersect($keys, $fields);
}
$count = count($fields); $count = count($fields);
if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) { if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
for ($i = 0; $i < $count; $i++) { for ($i = 0; $i < $count; $i++) {
if (in_array($fields[$i], $virtual)) {
unset($fields[$i]);
continue;
}
if (preg_match('/^\(.*\)\s' . $this->alias . '.*/i', $fields[$i])){ if (preg_match('/^\(.*\)\s' . $this->alias . '.*/i', $fields[$i])){
continue; continue;
} elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) { } elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
@ -1871,6 +1941,9 @@ class DboSource extends DataSource {
} }
} }
} }
if (!empty($virtual)) {
$fields = array_merge($fields,$this->_constructVirtualFields($model, $alias, $virtual));
}
return array_unique($fields); return array_unique($fields);
} }
@ -2053,6 +2126,11 @@ class DboSource extends DataSource {
} }
} }
$virtual = false;
if (is_object($model) && $model->isVirtualField($key)) {
$key = $this->__quoteFields($model->getVirtualField($key));
$virtual = true;
}
$type = (is_object($model) ? $model->getColumnType($key) : null); $type = (is_object($model) ? $model->getColumnType($key) : null);
@ -2067,7 +2145,7 @@ class DboSource extends DataSource {
$value = $this->value($value, $type); $value = $this->value($value, $type);
if ($key !== '?') { if (!$virtual && $key !== '?') {
$isKey = (strpos($key, '(') !== false || strpos($key, ')') !== false); $isKey = (strpos($key, '(') !== false || strpos($key, ')') !== false);
$key = $isKey ? $this->__quoteFields($key) : $this->name($key); $key = $isKey ? $this->__quoteFields($key) : $this->name($key);
} }
@ -2105,7 +2183,9 @@ class DboSource extends DataSource {
break; break;
} }
} }
if ($virtual) {
return "({$key}) {$operator} {$value}";
}
return "{$key} {$operator} {$value}"; return "{$key} {$operator} {$value}";
} }
@ -2172,69 +2252,71 @@ class DboSource extends DataSource {
* *
* @param string $key Field reference, as a key (i.e. Post.title) * @param string $key Field reference, as a key (i.e. Post.title)
* @param string $direction Direction (ASC or DESC) * @param string $direction Direction (ASC or DESC)
* @param object $model model reference (used to look for virtual field)
* @return string ORDER BY clause * @return string ORDER BY clause
* @access public * @access public
*/ */
function order($keys, $direction = 'ASC') { function order($keys, $direction = 'ASC', &$model = null) {
if (is_string($keys) && strpos($keys, ',') && !preg_match('/\(.+\,.+\)/', $keys)) { if (!is_array($keys)) {
$keys = array_map('trim', explode(',', $keys)); $keys = array($keys);
} }
if (is_array($keys)) {
$keys = array_filter($keys); $keys = array_filter($keys);
} $result = array();
while (!empty($keys)) {
list($key, $dir) = each($keys);
array_shift($keys);
if (empty($keys) || (is_array($keys) && isset($keys[0]) && empty($keys[0]))) {
return '';
}
if (is_array($keys)) {
$keys = (Set::countDim($keys) > 1) ? array_map(array(&$this, 'order'), $keys) : $keys;
foreach ($keys as $key => $value) {
if (is_numeric($key)) { if (is_numeric($key)) {
$key = $value = ltrim(str_replace('ORDER BY ', '', $this->order($value))); $key = $dir;
$value = (!preg_match('/\\x20ASC|\\x20DESC/i', $key) ? ' ' . $direction : ''); $dir = $direction;
} else {
$value = ' ' . $value;
} }
if (!preg_match('/^.+\\(.*\\)/', $key) && !strpos($key, ',')) { if (is_string($key) && strpos($key, ',') && !preg_match('/\(.+\,.+\)/', $key)) {
if (preg_match('/\\x20ASC|\\x20DESC/i', $key, $dir)) { $key = array_map('trim', explode(',', $key));
$dir = $dir[0];
$key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
} else {
$dir = '';
} }
if (is_array($key)) {
//Flatten the array
$key = array_reverse($key, true);
foreach ($key as $k => $v) {
if (is_numeric($k)) {
array_unshift($keys, $v);
} else {
$keys = array($k => $v) + $keys;
}
}
continue;
}
if (preg_match('/\\x20ASC|\\x20DESC/i', $key, $_dir)) {
$dir = $_dir[0];
$key = preg_replace('/\\x20ASC|\\x20DESC/i', '', $key);
}
if (strpos($key, '.')) {
preg_match_all('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', $key, $matches, PREG_PATTERN_ORDER);
$pregCount = count($matches[0]);
for ($i = 0; $i < $pregCount; $i++) {
if (!is_numeric($matches[0][$i])) {
$key = preg_replace('/' . $matches[0][$i] . '/', $this->name($matches[0][$i]), $key);
}
}
}
$key = trim($key); $key = trim($key);
if (!preg_match('/\s/', $key)) { if (!preg_match('/\s/', $key) && !strpos($key,'.')) {
if (is_object($model) && $model->isVirtualField($key)) {
$key = '('.$this->__quoteFields($model->getVirtualField($key)).')';
} else {
$key = $this->name($key); $key = $this->name($key);
} }
}
$key .= ' ' . trim($dir); $key .= ' ' . trim($dir);
$result[] = $key;
} }
$order[] = $this->order($key . $value); if (!empty($result)) {
return ' ORDER BY ' . implode(', ', $result);
} }
return ' ORDER BY ' . trim(str_replace('ORDER BY', '', implode(',', $order))); return '';
}
$keys = preg_replace('/ORDER\\x20BY/i', '', $keys);
if (strpos($keys, '.')) {
preg_match_all('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', $keys, $result, PREG_PATTERN_ORDER);
$pregCount = count($result[0]);
for ($i = 0; $i < $pregCount; $i++) {
if (!is_numeric($result[0][$i])) {
$keys = preg_replace('/' . $result[0][$i] . '/', $this->name($result[0][$i]), $keys);
}
}
$result = ' ORDER BY ' . $keys;
return $result . (!preg_match('/\\x20ASC|\\x20DESC/i', $keys) ? ' ' . $direction : '');
} elseif (preg_match('/(\\x20ASC|\\x20DESC)/i', $keys, $match)) {
$direction = $match[1];
return ' ORDER BY ' . preg_replace('/' . $match[1] . '/', '', $keys) . $direction;
}
return ' ORDER BY ' . $keys . ' ' . $direction;
} }
/** /**

View file

@ -1009,21 +1009,28 @@ class Model extends Overloadable {
* Returns true if the supplied field exists in the model's database table. * Returns true if the supplied field exists in the model's database table.
* *
* @param mixed $name Name of field to look for, or an array of names * @param mixed $name Name of field to look for, or an array of names
* @param boolean $checkVirtual checks if the field is declared as virtual
* @return mixed If $name is a string, returns a boolean indicating whether the field exists. * @return mixed If $name is a string, returns a boolean indicating whether the field exists.
* If $name is an array of field names, returns the first field that exists, * If $name is an array of field names, returns the first field that exists,
* or false if none exist. * or false if none exist.
* @access public * @access public
*/ */
function hasField($name) { function hasField($name, $checkVirtual = false) {
if (is_array($name)) { if (is_array($name)) {
foreach ($name as $n) { foreach ($name as $n) {
if ($this->hasField($n)) { if ($this->hasField($n, $checkVirtual)) {
return $n; return $n;
} }
} }
return false; return false;
} }
if ($checkVirtual && !empty($this->virtualFields)) {
if ($this->isVirtualField($name)) {
return true;
}
}
if (empty($this->_schema)) { if (empty($this->_schema)) {
$this->schema(); $this->schema();
} }
@ -1034,6 +1041,36 @@ class Model extends Overloadable {
return false; return false;
} }
/**
* Returns true if the supplied field is a model Virtual Field
*
* @param mixed $name Name of field to look for
* @return boolean indicating whether the field exists as a model virtual field.
* @access public
*/
function isVirtualField($field) {
return !empty($this->virtualFields) && is_string($field) && array_key_exists($field, $this->virtualFields);
}
/**
* Returns the expression for a model virtual field
*
* @param mixed $name Name of field to look for
* @return mixed If $field is string expression bound to virtual field $field
* If $field is null, returns an array of all model virtual fields
* or false if none $field exist.
* @access public
*/
function getVirtualField($field = null) {
if ($field == null) {
return empty($this->virtualFields) ? false : $this->virtualFields;
}
if ($this->isVirtualField($field)) {
return $this->virtualFields[$field];
}
return false;
}
/** /**
* Initializes the model for writing a new record, loading the default values * Initializes the model for writing a new record, loading the default values
* for those fields that are not defined in $data, and clearing previous validation errors. * for those fields that are not defined in $data, and clearing previous validation errors.
@ -1121,7 +1158,8 @@ class Model extends Overloadable {
} else { } else {
$recursive = $this->recursive; $recursive = $this->recursive;
} }
if ($data = $this->find($conditions, $name, $order, $recursive)) { $fields = $name;
if ($data = $this->find('first', compact('conditions', 'fields', 'order', 'recursive'))) {
if (strpos($name, '.') === false) { if (strpos($name, '.') === false) {
if (isset($data[$this->alias][$name])) { if (isset($data[$this->alias][$name])) {
return $data[$this->alias][$name]; return $data[$this->alias][$name];
@ -1132,9 +1170,8 @@ class Model extends Overloadable {
return $data[$name[0]][$name[1]]; return $data[$name[0]][$name[1]];
} }
} }
if (!empty($data[0])) { if (isset($data[0]) && count($data[0]) > 0) {
$name = key($data[0]); return array_shift($data[0]);
return $data[0][$name];
} }
} else { } else {
return false; return false;

View file

@ -1281,5 +1281,26 @@ class ControllerTest extends CakeTestCase {
$expected = array(404 => 'Sorry Bro'); $expected = array(404 => 'Sorry Bro');
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
function testPaginateOrderVirtualField() {
$Controller =& new Controller();
$Controller->uses = array('ControllerPost', 'ControllerComment');
$Controller->params['url'] = array();
$Controller->constructClasses();
$Controller->ControllerPost->virtualFields = array(
'offset_test' => 'ControllerPost.id + 1'
);
$Controller->paginate = array(
'fields' => array('id', 'title', 'offset_test'),
'order' => array('offset_test' => 'DESC')
);
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(4, 3, 2));
$Controller->passedArgs = array('sort' => 'offset_test', 'direction' => 'asc');
$result = $Controller->paginate('ControllerPost');
$this->assertEqual(Set::extract($result, '{n}.ControllerPost.offset_test'), array(2, 3, 4));
}
} }
?> ?>

View file

@ -4081,5 +4081,147 @@ class DboSourceTest extends CakeTestCase {
$this->assertNoPattern('/Num:/s', $contents); $this->assertNoPattern('/Num:/s', $contents);
$this->assertNoPattern('/Took:/s', $contents); $this->assertNoPattern('/Took:/s', $contents);
} }
/**
* test fields generating usable virtual fields to use in query
*
* @return void
*/
function testVirtualFields() {
$this->loadFixtures('Article');
$Article =& ClassRegistry::init('Article');
$Article->virtualFields = array(
'this_moment' => 'NOW()',
'two' => '1 + 1',
'comment_count' => 'SELECT COUNT(*) FROM ' . $this->db->fullTableName('comments') .
' WHERE Article.id = ' . $this->db->fullTableName('comments') . '.article_id'
);
$result = $this->db->fields($Article);
$expected = array(
'`Article`.`id`',
'`Article`.`user_id`',
'`Article`.`title`',
'`Article`.`body`',
'`Article`.`published`',
'`Article`.`created`',
'`Article`.`updated`',
'(NOW()) AS `Article__this_moment`',
'(1 + 1) AS `Article__two`',
'(SELECT COUNT(*) FROM comments WHERE `Article`.`id` = `comments`.`article_id`) AS `Article__comment_count`'
);
$this->assertEqual($expected,$result);
$result = $this->db->fields($Article, null, array('this_moment','title'));
$expected = array(
'`Article`.`title`',
'(NOW()) AS `Article__this_moment`',
);
$this->assertEqual($expected,$result);
}
/**
* test conditions to generate query conditions for virtual fields
*
* @return void
*/
function testVirtualFieldsInConditions() {
$this->loadFixtures('Article');
$Article =& ClassRegistry::init('Article');
$Article->virtualFields = array(
'this_moment' => 'NOW()',
'two' => '1 + 1',
'comment_count' => 'SELECT COUNT(*) FROM ' . $this->db->fullTableName('comments') .
' WHERE Article.id = ' . $this->db->fullTableName('comments') . '.article_id'
);
$conditions = array('two' => 2);
$result = $this->db->conditions($conditions,true,false,$Article);
$expected = '(1 + 1) = 2';
$this->assertEqual($expected, $result);
$conditions = array('this_moment BETWEEN ? AND ?' => array(1,2));
$expected = 'NOW() BETWEEN 1 AND 2';
$result = $this->db->conditions($conditions, true, false, $Article);
$this->assertEqual($expected, $result);
$conditions = array('comment_count >' => 5);
$expected = '(SELECT COUNT(*) FROM comments WHERE `Article`.`id` = `comments`.`article_id`) > 5';
$result = $this->db->conditions($conditions, true, false, $Article);
$this->assertEqual($expected, $result);
$conditions = array('NOT' => array('two' => 2));
$result = $this->db->conditions($conditions, true, false, $Article);
$expected = 'NOT ((1 + 1) = 2)';
$this->assertEqual($expected, $result);
}
/**
* test order to generate query order clause for virtual fields
*
* @return void
*/
function testVirtualFieldsInOrder() {
$this->loadFixtures('Article');
$Article =& ClassRegistry::init('Article');
$Article->virtualFields = array(
'this_moment' => 'NOW()',
'two' => '1 + 1',
);
$order = array('two', 'this_moment');
$result = $this->db->order($order, 'ASC', $Article);
$expected = ' ORDER BY (1 + 1) ASC, (NOW()) ASC';
$this->assertEqual($expected, $result);
}
/**
* test calculate to generate claculate statements on virtual fields
*
* @return void
*/
function testVirtualFieldsInCalculate() {
$this->loadFixtures('Article');
$Article =& ClassRegistry::init('Article');
$Article->virtualFields = array(
'this_moment' => 'NOW()',
'two' => '1 + 1',
'comment_count' => 'SELECT COUNT(*) FROM ' . $this->db->fullTableName('comments') .
' WHERE Article.id = ' . $this->db->fullTableName('comments'). '.article_id'
);
$result = $this->db->calculate($Article, 'count', array('this_moment'));
$expected = 'COUNT(NOW()) AS `count`';
$this->assertEqual($expected, $result);
$result = $this->db->calculate($Article, 'max', array('comment_count'));
$expected = 'MAX(SELECT COUNT(*) FROM comments WHERE `Article`.`id` = `comments`.`article_id`) AS `comment_count`';
$this->assertEqual($expected, $result);
}
/**
* test a full example of using virtual fields
*
* @return void
*/
function testVirtualFieldsFetch() {
$this->loadFixtures('Article', 'Comment');
$Article =& ClassRegistry::init('Article');
$Article->virtualFields = array(
'comment_count' => 'SELECT COUNT(*) FROM ' . $this->db->fullTableName('comments') .
' WHERE Article.id = ' . $this->db->fullTableName('comments') . '.article_id'
);
$conditions = array('comment_count >' => 2);
$query = 'SELECT ' . join(',',$this->db->fields($Article, null, array('id', 'comment_count'))) .
' FROM ' . $this->db->fullTableName($Article) . ' Article ' . $this->db->conditions($conditions, true, true, $Article);
$result = $this->db->fetchAll($query);
$expected = array(array(
'Article' => array('id' => 1, 'comment_count' => 4)
));
$this->assertEqual($expected, $result);
}
} }
?> ?>

View file

@ -7161,5 +7161,85 @@ class ModelReadTest extends BaseModelTest {
$comments = $Comment->find('first'); $comments = $Comment->find('first');
$this->assertEqual($comments['Comment']['querytype'], 'first'); $this->assertEqual($comments['Comment']['querytype'], 'first');
} }
/**
* testVirtualFields()
*
* Test correct fetching of virtual fields
* currently is not possible to do Relation.virtualField
*
* @access public
* @return void
*/
function testVirtualFields() {
$this->loadFixtures('Post','Author');
$Post = ClassRegistry::init('Post');
$Post->virtualFields = array('two' => "1 + 1");
$result = $Post->find('first');
$this->assertEqual($result['Post']['two'], 2);
$Post->Author->virtualFields = array('false' => '1 = 2');
$result = $Post->find('first');
$this->assertEqual($result['Post']['two'], 2);
$this->assertEqual($result['Author']['false'],false);
$result = $Post->find('first',array('fields' => array('author_id')));
$this->assertFalse(isset($result['Post']['two']));
$this->assertFalse(isset($result['Author']['false']));
$result = $Post->find('first',array('fields' => array('author_id', 'two')));
$this->assertEqual($result['Post']['two'], 2);
$this->assertFalse(isset($result['Author']['false']));
$result = $Post->find('first',array('fields' => array('two')));
$this->assertEqual($result['Post']['two'], 2);
$Post->id = 1;
$result = $Post->field('two');
$this->assertEqual($result, 2);
$result = $Post->find('first',array(
'conditions' => array('two' => 2),
'limit' => 1
));
$this->assertEqual($result['Post']['two'], 2);
$result = $Post->find('first',array(
'conditions' => array('two <' => 3),
'limit' => 1
));
$this->assertEqual($result['Post']['two'], 2);
$result = $Post->find('first',array(
'conditions' => array('NOT' => array('two >' => 3)),
'limit' => 1
));
$this->assertEqual($result['Post']['two'], 2);
$dbo =& $Post->getDataSource();
$Post->virtualFields = array('other_field' => 'Post.id + 1');
$result = $Post->find('first',array(
'conditions' => array('other_field' => 3),
'limit' => 1
));
$this->assertEqual($result['Post']['id'], 2);
$Post->virtualFields = array('other_field' => 'Post.id + 1');
$result = $Post->find('all',array(
'fields' => array($dbo->calculate($Post, 'max',array('other_field')))
));
$this->assertEqual($result[0][0]['other_field'], 4);
ClassRegistry::flush();
$Writing = ClassRegistry::init(array('class' => 'Post', 'alias' => 'Writing'), 'Model');
$Writing->virtualFields = array('two' => "1 + 1");
$result = $Writing->find('first');
$this->assertEqual($result['Writing']['two'], 2);
$Post->create();
$Post->virtualFields = array('other_field' => 'COUNT(Post.id) + 1');
$result = $Post->field('other_field');
$this->assertEqual($result, 4);
}
} }
?> ?>