diff --git a/docs/configuration.rst b/docs/configuration.rst index dba0c8cc..a93c91ec 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -287,6 +287,21 @@ Idiorm can cache the queries it executes during a request. To enable query caching, set the ``caching`` option to ``true`` (it is ``false`` by default). +.. code-block:: php + + false, 'logger' => null, 'caching' => false, + 'caching_auto_clear' => false, 'return_result_sets' => false, ); @@ -1758,7 +1759,10 @@ protected function _quote_identifier_part($part) { /** * Create a cache key for the given query and parameters. */ - protected static function _create_cache_key($query, $parameters) { + protected static function _create_cache_key($query, $parameters, $table_name = null, $connection_name = self::DEFAULT_CONNECTION) { + if(isset(self::$_config[$connection_name]['create_cache_key']) and is_callable(self::$_config[$connection_name]['create_cache_key'])){ + return call_user_func_array(self::$_config[$connection_name]['create_cache_key'], array($query, $parameters, $table_name, $connection_name)); + } $parameter_string = join(',', $parameters); $key = $query . ':' . $parameter_string; return sha1($key); @@ -1768,8 +1772,10 @@ protected static function _create_cache_key($query, $parameters) { * Check the query cache for the given cache key. If a value * is cached for the key, return the value. Otherwise, return false. */ - protected static function _check_query_cache($cache_key, $connection_name = self::DEFAULT_CONNECTION) { - if (isset(self::$_query_cache[$connection_name][$cache_key])) { + protected static function _check_query_cache($cache_key, $table_name = null, $connection_name = self::DEFAULT_CONNECTION) { + if(isset(self::$_config[$connection_name]['check_query_cache']) and is_callable(self::$_config[$connection_name]['check_query_cache'])){ + return call_user_func_array(self::$_config[$connection_name]['check_query_cache'], array($cache_key, $table_name, $connection_name)); + } elseif (isset(self::$_query_cache[$connection_name][$cache_key])) { return self::$_query_cache[$connection_name][$cache_key]; } return false; @@ -1778,15 +1784,20 @@ protected static function _check_query_cache($cache_key, $connection_name = self /** * Clear the query cache */ - public static function clear_cache() { + public static function clear_cache($table_name = null, $connection_name = self::DEFAULT_CONNECTION) { self::$_query_cache = array(); + if(isset(self::$_config[$connection_name]['clear_cache']) and is_callable(self::$_config[$connection_name]['clear_cache'])){ + return call_user_func_array(self::$_config[$connection_name]['clear_cache'], array($table_name, $connection_name)); + } } /** * Add the given value to the query cache. */ - protected static function _cache_query_result($cache_key, $value, $connection_name = self::DEFAULT_CONNECTION) { - if (!isset(self::$_query_cache[$connection_name])) { + protected static function _cache_query_result($cache_key, $value, $table_name = null, $connection_name = self::DEFAULT_CONNECTION) { + if(isset(self::$_config[$connection_name]['cache_query_result']) and is_callable(self::$_config[$connection_name]['cache_query_result'])){ + return call_user_func_array(self::$_config[$connection_name]['cache_query_result'], array($cache_key, $value, $table_name, $connection_name)); + } elseif (!isset(self::$_query_cache[$connection_name])) { self::$_query_cache[$connection_name] = array(); } self::$_query_cache[$connection_name][$cache_key] = $value; @@ -1801,8 +1812,8 @@ protected function _run() { $caching_enabled = self::$_config[$this->_connection_name]['caching']; if ($caching_enabled) { - $cache_key = self::_create_cache_key($query, $this->_values); - $cached_result = self::_check_query_cache($cache_key, $this->_connection_name); + $cache_key = self::_create_cache_key($query, $this->_values, $this->_table_name, $this->_connection_name); + $cached_result = self::_check_query_cache($cache_key, $this->_table_name, $this->_connection_name); if ($cached_result !== false) { return $cached_result; @@ -1818,7 +1829,7 @@ protected function _run() { } if ($caching_enabled) { - self::_cache_query_result($cache_key, $rows, $this->_connection_name); + self::_cache_query_result($cache_key, $rows, $this->_table_name, $this->_connection_name); } // reset Idiorm after executing the query @@ -1986,7 +1997,10 @@ public function save() { } $success = self::_execute($query, $values, $this->_connection_name); - + $caching_auto_clear_enabled = self::$_config[$this->_connection_name]['caching_auto_clear']; + if($caching_auto_clear_enabled){ + self::clear_cache($this->_table_name, $this->_connection_name); + } // If we've just inserted a new record, set the ID of this object if ($this->_is_new) { $this->_is_new = false; diff --git a/test/CacheTest.php b/test/CacheTest.php index 0f7b4912..a3daa91d 100644 --- a/test/CacheTest.php +++ b/test/CacheTest.php @@ -38,4 +38,5 @@ public function testQueryGenerationOnlyOccursOnceWithMultipleConnections() { ORM::for_table('widget', self::ALTERNATE)->where('name', 'Steve')->where('age', 80)->find_one(); // this shouldn't run a query! $this->assertEquals($expected, ORM::get_last_query(self::ALTERNATE)); } + } \ No newline at end of file diff --git a/test/CacheTest53.php b/test/CacheTest53.php new file mode 100644 index 00000000..bc30b0aa --- /dev/null +++ b/test/CacheTest53.php @@ -0,0 +1,82 @@ +assertEquals(true, is_string($query)); + $phpunit->assertEquals(true, is_array($parameters)); + $phpunit->assertEquals(true, is_string($connection)); + $phpunit->assertEquals('widget', $table_name); + $parameter_string = join(',', $parameters); + $key = $query . ':' . $parameter_string; + $my_key = 'some-prefix'.crc32($key); + return $my_key; + }); + ORM::configure('cache_query_result', function ($cache_key, $value, $table_name, $connection_name) use ($phpunit, &$my_cache) { + $phpunit->assertEquals(true, is_string($cache_key)); + $phpunit->assertEquals('widget', $table_name); + $my_cache[$cache_key] = $value; + }); + ORM::configure('check_query_cache', function ($cache_key, $table_name, $connection_name) use ($phpunit, &$my_cache) { + $phpunit->assertEquals(true, is_string($cache_key)); + $phpunit->assertEquals(true, is_string($connection_name)); + $phpunit->assertEquals('widget', $table_name); + + if(isset($my_cache) and isset($my_cache[$cache_key])){ + $phpunit->assertEquals(true, is_array($my_cache[$cache_key])); + return $my_cache[$cache_key]; + } else { + return false; + } + }); + ORM::configure('clear_cache', function ($table_name, $connection_name) use ($phpunit, &$my_cache) { + $phpunit->assertEquals(true, is_string($table_name)); + $phpunit->assertEquals(true, is_string($connection_name)); + $my_cache = array(); + }); + ORM::for_table('widget')->where('name', 'Fred')->where('age', 21)->find_one(); + ORM::for_table('widget')->where('name', 'Fred')->where('age', 21)->find_one(); + ORM::for_table('widget')->where('name', 'Bob')->where('age', 42)->find_one(); + + //our custom cache should be full now + $this->assertEquals(true, !empty($my_cache)); + + //checking custom cache key + foreach($my_cache as $k=>$v){ + $this->assertEquals('some-prefix', substr($k,0,11)); + } + + $new = ORM::for_table('widget')->create(); + $new->name = "Joe"; + $new->age = 25; + $saved = $new->save(); + + //our custom cache should be empty now + $this->assertEquals(true, empty($my_cache)); + } +} \ No newline at end of file diff --git a/test/ConfigTest.php b/test/ConfigTest.php index c65c5397..c6f4631a 100644 --- a/test/ConfigTest.php +++ b/test/ConfigTest.php @@ -115,6 +115,7 @@ public function testGetConfigArray() { 'logging' => true, 'logger' => null, 'caching' => false, + 'caching_auto_clear' => false, 'return_result_sets' => false, 'limit_clause_style' => 'limit', );