Skip to content
Permalink
Browse files

Optimizations for DbouSource.

Now the result for some methods is stored in a memory cache inside the poperty $methodCache
  • Loading branch information...
lorenzo committed Jan 29, 2010
1 parent 3836592 commit 1dd0a6470cb51d1462be8c7a2f0088188264e276
Showing with 65 additions and 30 deletions.
  1. +65 −30 cake/libs/model/datasources/dbo_source.php
@@ -53,12 +53,12 @@ class DboSource extends DataSource {
var $alias = 'AS ';
/**
* Caches fields quoted in DboSource::name()
* Caches result from query parsing operations
*
* @var array
* @access public
*/
var $fieldCache = array();
var $methodCache = array();
/**
* Bypass automatic adding of joined fields/associations.
@@ -481,6 +481,10 @@ function name($data) {
}
return $data;
}
$cacheKey = crc32($data);
if (isset($this->methodCache[__FUNCTION__][$cacheKey])) {
return $this->methodCache[__FUNCTION__][$cacheKey];
}
$data = trim($data);
if (preg_match('/^\w+(\.\w+)*$/', $data)) { // string, string.string
if (strpos($data, '.') === false) { // string
@@ -499,7 +503,7 @@ function name($data) {
if (preg_match('/^(\w+(\.\w+|\(.*\))*)\s+' . preg_quote($this->alias) . '\s*(\w+)$/', $data, $matches)) {
return preg_replace('/\s{2,}/', ' ', $this->name($matches[1]) . ' ' . $this->alias . ' ' . $this->name($matches[3]));
}
return $data;
return $this->methodCache[__FUNCTION__][$cacheKey] = $data;
}
/**
@@ -1848,6 +1852,20 @@ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
if (empty($alias)) {
$alias = $model->alias;
}
$cacheKey = array(
$model->useDbConfig,
$model->table,
array_keys($model->schema()),
$model->name,
$model->getVirtualField(),
$alias,
$fields,
$quote
);
$cacheKey = crc32(serialize($cacheKey));
if (isset($this->methodCache[__FUNCTION__][$cacheKey])) {
return $this->methodCache[__FUNCTION__][$cacheKey];
}
$allFields = empty($fields);
if ($allFields) {
$fields = array_keys($model->schema());
@@ -1930,7 +1948,7 @@ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
} else {
$field[0] = explode('.', $field[1]);
if (!Set::numeric($field[0])) {
$field[0] = implode('.', array_map(array($this, 'name'), $field[0]));
$field[0] = implode('.', array_map(array(&$this, 'name'), $field[0]));
$fields[$i] = preg_replace('/\(' . $field[1] . '\)/', '(' . $field[0] . ')', $fields[$i], 1);
}
}
@@ -1941,7 +1959,7 @@ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
if (!empty($virtual)) {
$fields = array_merge($fields, $this->_constructVirtualFields($model, $alias, $virtual));
}
return array_unique($fields);
return $this->methodCache[__FUNCTION__][$cacheKey] = array_unique($fields);
}
/**
@@ -1957,6 +1975,25 @@ function fields(&$model, $alias = null, $fields = array(), $quote = true) {
* @access public
*/
function conditions($conditions, $quoteValues = true, $where = true, $model = null) {
if (is_object($model)) {
$cacheKey = array(
$model->useDbConfig,
$model->table,
$model->schema(),
$model->name,
$model->getVirtualField(),
$conditions,
$quoteValues,
$where
);
} else {
$cacheKey = array($conditions, $quoteValues, $where);
}
$cacheKey = crc32(serialize($cacheKey));
if (isset($this->methodCache[__FUNCTION__][$cacheKey])) {
return $this->methodCache[__FUNCTION__][$cacheKey];
}
$clause = $out = '';
if ($where) {
@@ -1967,16 +2004,16 @@ function conditions($conditions, $quoteValues = true, $where = true, $model = nu
$out = $this->conditionKeysToString($conditions, $quoteValues, $model);
if (empty($out)) {
return $clause . ' 1 = 1';
return $this->methodCache[__FUNCTION__][$cacheKey] = $clause . ' 1 = 1';
}
return $clause . implode(' AND ', $out);
return $this->methodCache[__FUNCTION__][$cacheKey] = $clause . implode(' AND ', $out);
}
if ($conditions === false || $conditions === true) {
return $clause . (int)$conditions . ' = 1';
return $this->methodCache[__FUNCTION__][$cacheKey] = $clause . (int)$conditions . ' = 1';
}
if (empty($conditions) || trim($conditions) == '') {
return $clause . '1 = 1';
return $this->methodCache[__FUNCTION__][$cacheKey] = $clause . '1 = 1';
}
$clauses = '/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i';
@@ -1988,7 +2025,7 @@ function conditions($conditions, $quoteValues = true, $where = true, $model = nu
} else {
$conditions = $this->__quoteFields($conditions);
}
return $clause . $conditions;
return $this->methodCache[__FUNCTION__][$cacheKey] = $clause . $conditions;
}
/**
@@ -2088,9 +2125,6 @@ function conditionKeysToString($conditions, $quoteValues = true, $model = null)
}
if ($data != null) {
if (preg_match('/^\(\(\((.+)\)\)\)$/', $data)) {
$data = substr($data, 1, strlen($data) - 2);
}
$out[] = $data;
$data = null;
}
@@ -2153,7 +2187,7 @@ function __parseKey(&$model, $key, $value) {
}
if ($bound) {
return String::insert($key . ' ' . trim($operator), $value);
return String::insert($key . ' ' . trim($operator), $value);
}
if (!preg_match($operatorMatch, trim($operator))) {
@@ -2209,21 +2243,28 @@ function __quoteFields($conditions) {
$end = preg_quote($this->endQuote);
}
$conditions = str_replace(array($start, $end), '', $conditions);
preg_match_all('/(?:[\'\"][^\'\"\\\]*(?:\\\.[^\'\"\\\]*)*[\'\"])|([a-z0-9_' . $start . $end . ']*\\.[a-z0-9_' . $start . $end . ']*)/i', $conditions, $replace, PREG_PATTERN_ORDER);
if (isset($replace['1']['0'])) {
$pregCount = count($replace['1']);
$conditions = preg_replace_callback('/(?:[\'\"][^\'\"\\\]*(?:\\\.[^\'\"\\\]*)*[\'\"])|([a-z0-9_' . $start . $end . ']*\\.[a-z0-9_' . $start . $end . ']*)/i', array(&$this, '__quoteMatchedField'), $conditions);
for ($i = 0; $i < $pregCount; $i++) {
if (!empty($replace['1'][$i]) && !is_numeric($replace['1'][$i])) {
$conditions = preg_replace('/\b' . preg_quote($replace['1'][$i]) . '\b/', $this->name($replace['1'][$i]), $conditions);
}
}
if ($conditions !== null) {
return $conditions;
}
return $original;
}
/**
* Auxiliary function to qoute matches `Model.fields` from a preg_replace_callback call
*
* @param string matched string
* @return string quoted strig
* @access private
*/
function __quoteMatchedField($match) {
if (is_numeric($match[0])) {
return $match[0];
}
return $this->name($match[0]);
}
/**
* Returns a limit statement in the correct format for the particular database.
*
@@ -2295,13 +2336,7 @@ function order($keys, $direction = 'ASC', $model = null) {
}
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 = preg_replace_callback('/([a-zA-Z0-9_]{1,})\\.([a-zA-Z0-9_]{1,})/', array(&$this, '__quoteMatchedField'), $key);
}
$key = trim($key);

0 comments on commit 1dd0a64

Please sign in to comment.
You can’t perform that action at this time.