Skip to content

Commit

Permalink
FIxing query caching to take in account bound parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Oct 17, 2010
1 parent 0971912 commit 7e2fe43
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 25 deletions.
19 changes: 12 additions & 7 deletions cake/libs/model/datasources/dbo_source.php
Expand Up @@ -427,7 +427,7 @@ public function fetchAll($sql, $params = array(), $options = array()) {
$defaults = array('cache' => true);
$options = $options + $defaults;
$cache = $options['cache'];
if ($cache && ($cached = $this->getQueryCache($sql)) !== false) {
if ($cache && ($cached = $this->getQueryCache($sql, $params)) !== false) {
return $cached;
}
if ($this->execute($sql, array(), $params)) {
Expand All @@ -443,7 +443,7 @@ public function fetchAll($sql, $params = array(), $options = array()) {
}

if ($cache) {
$this->_writeQueryCache($sql, $out);
$this->_writeQueryCache($sql, $out, $params);
}
if (empty($out) && is_bool($this->_result)) {
return $this->_result;
Expand Down Expand Up @@ -2902,23 +2902,28 @@ public function introspectType($value) {
*
* @param string $sql SQL query
* @param mixed $data result of $sql query
* @param array $params query params bound as values
* @return void
*/
protected function _writeQueryCache($sql, $data) {
if (strpos(trim(strtolower($sql)), 'select') !== false) {
$this->_queryCache[$sql] = $data;
protected function _writeQueryCache($sql, $data, $params = array()) {
if (preg_match('/^\s*select/i', $sql)) {
$this->_queryCache[$sql][serialize($params)] = $data;
}
}

/**
* Returns the result for a sql query if it is already cached
*
* @param string $sql SQL query
* @param array $params query params bound as values
* @return mixed results for query if it is cached, false otherwise
*/
public function getQueryCache($sql = null) {
public function getQueryCache($sql, $params = array()) {
if (isset($this->_queryCache[$sql]) && preg_match('/^\s*select/i', $sql)) {
return $this->_queryCache[$sql];
$serialized = serialize($params);
if (isset($this->_queryCache[$sql][$serialized])) {
return $this->_queryCache[$sql][$serialized];
}
}
return false;
}
Expand Down
21 changes: 3 additions & 18 deletions cake/tests/cases/libs/model/model_read.test.php
Expand Up @@ -279,13 +279,6 @@ function testPreparedQuery() {
$this->loadFixtures('Article', 'User', 'Tag', 'ArticlesTag');
$Article = new Article();

$finalQuery = 'SELECT title, published FROM ';
$finalQuery .= $this->db->fullTableName('articles');
$finalQuery .= ' WHERE ' . $this->db->fullTableName('articles');
$finalQuery .= '.id = ' . $this->db->value(1);
$finalQuery .= ' AND ' . $this->db->fullTableName('articles');
$finalQuery .= '.published = ' . $this->db->value('Y');

$query = 'SELECT title, published FROM ';
$query .= $this->db->fullTableName('articles');
$query .= ' WHERE ' . $this->db->fullTableName('articles');
Expand All @@ -305,14 +298,9 @@ function testPreparedQuery() {
}

$this->assertEqual($result, $expected);
$result = $this->db->getQueryCache($finalQuery);
$result = $this->db->getQueryCache($query, $params);
$this->assertFalse(empty($result));

$finalQuery = 'SELECT id, created FROM ';
$finalQuery .= $this->db->fullTableName('articles');
$finalQuery .= ' WHERE ' . $this->db->fullTableName('articles');
$finalQuery .= '.title = ' . $this->db->value('First Article');

$query = 'SELECT id, created FROM ';
$query .= $this->db->fullTableName('articles');
$query .= ' WHERE ' . $this->db->fullTableName('articles') . '.title = ?';
Expand All @@ -324,7 +312,7 @@ function testPreparedQuery() {
isset($result[0][$this->db->fullTableName('articles', false)])
|| isset($result[0][0])
);
$result = $this->db->getQueryCache($finalQuery);
$result = $this->db->getQueryCache($query, $params);
$this->assertTrue(empty($result));

$query = 'SELECT title FROM ';
Expand All @@ -345,10 +333,7 @@ function testPreparedQuery() {
$params = array('First? Article', 'Y');
$Article->query($query, $params);

$expected = 'SELECT title FROM ';
$expected .= $this->db->fullTableName('articles');
$expected .= " WHERE title = 'First? Article' AND published = 'Y'";
$result = $this->db->getQueryCache($expected);
$result = $this->db->getQueryCache($query, $params);
$this->assertFalse($result === false);

}
Expand Down

0 comments on commit 7e2fe43

Please sign in to comment.