From 7e2fe43ee3fd4e4772e93f7df266ac69240d71d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Lorenzo=20Rodr=C3=ADguez?= Date: Sun, 17 Oct 2010 10:51:54 -0430 Subject: [PATCH] FIxing query caching to take in account bound parameters --- cake/libs/model/datasources/dbo_source.php | 19 ++++++++++------- .../cases/libs/model/model_read.test.php | 21 +++---------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/cake/libs/model/datasources/dbo_source.php b/cake/libs/model/datasources/dbo_source.php index 9f26b378cd4..de060fb4485 100755 --- a/cake/libs/model/datasources/dbo_source.php +++ b/cake/libs/model/datasources/dbo_source.php @@ -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)) { @@ -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; @@ -2902,11 +2902,12 @@ 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; } } @@ -2914,11 +2915,15 @@ protected function _writeQueryCache($sql, $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; } diff --git a/cake/tests/cases/libs/model/model_read.test.php b/cake/tests/cases/libs/model/model_read.test.php index 1eb3b13f6e0..68dc9ce3130 100755 --- a/cake/tests/cases/libs/model/model_read.test.php +++ b/cake/tests/cases/libs/model/model_read.test.php @@ -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'); @@ -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 = ?'; @@ -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 '; @@ -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); }