summaryrefslogtreecommitdiff
path: root/system/libraries/drivers/Cache
diff options
context:
space:
mode:
Diffstat (limited to 'system/libraries/drivers/Cache')
-rw-r--r--system/libraries/drivers/Cache/Apc.php64
-rw-r--r--system/libraries/drivers/Cache/Eaccelerator.php66
-rw-r--r--system/libraries/drivers/Cache/File.php268
-rw-r--r--system/libraries/drivers/Cache/Memcache.php200
-rw-r--r--system/libraries/drivers/Cache/Sqlite.php257
-rw-r--r--system/libraries/drivers/Cache/Xcache.php144
6 files changed, 293 insertions, 706 deletions
diff --git a/system/libraries/drivers/Cache/Apc.php b/system/libraries/drivers/Cache/Apc.php
deleted file mode 100644
index f7be048f..00000000
--- a/system/libraries/drivers/Cache/Apc.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php defined('SYSPATH') OR die('No direct access allowed.');
-/**
- * APC-based Cache driver.
- *
- * $Id: Apc.php 4046 2009-03-05 19:23:29Z Shadowhand $
- *
- * @package Cache
- * @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
- */
-class Cache_Apc_Driver implements Cache_Driver {
-
- public function __construct()
- {
- if ( ! extension_loaded('apc'))
- throw new Kohana_Exception('cache.extension_not_loaded', 'apc');
- }
-
- public function get($id)
- {
- return (($return = apc_fetch($id)) === FALSE) ? NULL : $return;
- }
-
- public function set($id, $data, array $tags = NULL, $lifetime)
- {
- if ( ! empty($tags))
- {
- Kohana::log('error', 'Cache: tags are unsupported by the APC driver');
- }
-
- return apc_store($id, $data, $lifetime);
- }
-
- public function find($tag)
- {
- Kohana::log('error', 'Cache: tags are unsupported by the APC driver');
-
- return array();
- }
-
- public function delete($id, $tag = FALSE)
- {
- if ($tag === TRUE)
- {
- Kohana::log('error', 'Cache: tags are unsupported by the APC driver');
- return FALSE;
- }
- elseif ($id === TRUE)
- {
- return apc_clear_cache('user');
- }
- else
- {
- return apc_delete($id);
- }
- }
-
- public function delete_expired()
- {
- return TRUE;
- }
-
-} // End Cache APC Driver \ No newline at end of file
diff --git a/system/libraries/drivers/Cache/Eaccelerator.php b/system/libraries/drivers/Cache/Eaccelerator.php
deleted file mode 100644
index a45616d5..00000000
--- a/system/libraries/drivers/Cache/Eaccelerator.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php defined('SYSPATH') OR die('No direct access allowed.');
-/**
- * Eaccelerator-based Cache driver.
- *
- * $Id: Eaccelerator.php 4046 2009-03-05 19:23:29Z Shadowhand $
- *
- * @package Cache
- * @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
- */
-class Cache_Eaccelerator_Driver implements Cache_Driver {
-
- public function __construct()
- {
- if ( ! extension_loaded('eaccelerator'))
- throw new Kohana_Exception('cache.extension_not_loaded', 'eaccelerator');
- }
-
- public function get($id)
- {
- return eaccelerator_get($id);
- }
-
- public function find($tag)
- {
- Kohana::log('error', 'tags are unsupported by the eAccelerator driver');
-
- return array();
- }
-
- public function set($id, $data, array $tags = NULL, $lifetime)
- {
- if ( ! empty($tags))
- {
- Kohana::log('error', 'tags are unsupported by the eAccelerator driver');
- }
-
- return eaccelerator_put($id, $data, $lifetime);
- }
-
- public function delete($id, $tag = FALSE)
- {
- if ($tag === TRUE)
- {
- Kohana::log('error', 'tags are unsupported by the eAccelerator driver');
- return FALSE;
- }
- elseif ($id === TRUE)
- {
- return eaccelerator_clean();
- }
- else
- {
- return eaccelerator_rm($id);
- }
- }
-
- public function delete_expired()
- {
- eaccelerator_gc();
-
- return TRUE;
- }
-
-} // End Cache eAccelerator Driver \ No newline at end of file
diff --git a/system/libraries/drivers/Cache/File.php b/system/libraries/drivers/Cache/File.php
index cc9d48d3..fc20c22d 100644
--- a/system/libraries/drivers/Cache/File.php
+++ b/system/libraries/drivers/Cache/File.php
@@ -1,55 +1,54 @@
<?php defined('SYSPATH') OR die('No direct access allowed.');
/**
- * File-based Cache driver.
+ * Memcache-based Cache driver.
*
- * $Id: File.php 4046 2009-03-05 19:23:29Z Shadowhand $
+ * $Id: File.php 4605 2009-09-14 17:22:21Z kiall $
*
* @package Cache
* @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
+ * @copyright (c) 2007-2009 Kohana Team
+ * @license http://kohanaphp.com/license
*/
-class Cache_File_Driver implements Cache_Driver {
+class Cache_File_Driver extends Cache_Driver {
+ protected $config;
+ protected $backend;
- protected $directory = '';
-
- /**
- * Tests that the storage location is a directory and is writable.
- */
- public function __construct($directory)
+ public function __construct($config)
{
- // Find the real path to the directory
- $directory = str_replace('\\', '/', realpath($directory)).'/';
+ $this->config = $config;
+ $this->config['directory'] = str_replace('\\', '/', realpath($this->config['directory'])).'/';
- // Make sure the cache directory is writable
- if ( ! is_dir($directory) OR ! is_writable($directory))
- throw new Kohana_Exception('cache.unwritable', $directory);
-
- // Directory is valid
- $this->directory = $directory;
+ if ( ! is_dir($this->config['directory']) OR ! is_writable($this->config['directory']))
+ throw new Cache_Exception('The configured cache directory, :directory:, is not writable.', array(':directory:' => $this->config['directory']));
}
/**
* Finds an array of files matching the given id or tag.
*
- * @param string cache id or tag
+ * @param string cache key or tag
* @param bool search for tags
* @return array of filenames matching the id or tag
*/
- public function exists($id, $tag = FALSE)
+ public function exists($keys, $tag = FALSE)
{
- if ($id === TRUE)
+ if ($keys === TRUE)
{
// Find all the files
- return glob($this->directory.'*~*~*');
+ return glob($this->config['directory'].'*~*~*');
}
elseif ($tag === TRUE)
{
// Find all the files that have the tag name
- $paths = glob($this->directory.'*~*'.$id.'*~*');
+ $paths = array();
+
+ foreach ( (array) $keys as $tag)
+ {
+ $paths = array_merge($paths, glob($this->config['directory'].'*~*'.$tag.'*~*'));
+ }
// Find all tags matching the given tag
$files = array();
+
foreach ($paths as $path)
{
// Split the files
@@ -60,12 +59,16 @@ class Cache_File_Driver implements Cache_Driver {
continue;
// Split the tags by plus signs, used to separate tags
- $tags = explode('+', $tags[1]);
+ $item_tags = explode('+', $tags[1]);
- if (in_array($tag, $tags))
+ // Check each supplied tag, and match aginst the tags on each item.
+ foreach ($keys as $tag)
{
- // Add the file to the array, it has the requested tag
- $files[] = $path;
+ if (in_array($tag, $item_tags))
+ {
+ // Add the file to the array, it has the requested tag
+ $files[] = $path;
+ }
}
}
@@ -73,98 +76,68 @@ class Cache_File_Driver implements Cache_Driver {
}
else
{
- // Find the file matching the given id
- return glob($this->directory.$id.'~*');
+ $paths = array();
+
+ foreach ( (array) $keys as $key)
+ {
+ // Find the file matching the given key
+ $paths = array_merge($paths, glob($this->config['directory'].str_replace(array('/', '\\', ' '), '_', $key).'~*'));
+ }
+
+ return $paths;
}
}
- /**
- * Sets a cache item to the given data, tags, and lifetime.
- *
- * @param string cache id to set
- * @param string data in the cache
- * @param array cache tags
- * @param integer lifetime
- * @return bool
- */
- public function set($id, $data, array $tags = NULL, $lifetime)
+ public function set($items, $tags = NULL, $lifetime = NULL)
{
- // Remove old cache files
- $this->delete($id);
-
- // Cache File driver expects unix timestamp
if ($lifetime !== 0)
{
+ // File driver expects unix timestamp
$lifetime += time();
}
- if ( ! empty($tags))
+
+ if ( ! is_null($tags) AND ! empty($tags))
{
// Convert the tags into a string list
- $tags = implode('+', $tags);
+ $tags = implode('+', (array) $tags);
}
- // Write out a serialized cache
- return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data));
- }
+ $success = TRUE;
- /**
- * Finds an array of ids for a given tag.
- *
- * @param string tag name
- * @return array of ids that match the tag
- */
- public function find($tag)
- {
- // An array will always be returned
- $result = array();
-
- if ($paths = $this->exists($tag, TRUE))
+ foreach ($items as $key => $value)
{
- // Length of directory name
- $offset = strlen($this->directory);
+ if (is_resource($value))
+ throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.');
- // Find all the files with the given tag
- foreach ($paths as $path)
- {
- // Get the id from the filename
- list($id, $junk) = explode('~', basename($path), 2);
+ // Remove old cache file
+ $this->delete($key);
- if (($data = $this->get($id)) !== FALSE)
- {
- // Add the result to the array
- $result[$id] = $data;
- }
+ if ( ! (bool) file_put_contents($this->config['directory'].str_replace(array('/', '\\', ' '), '_', $key).'~'.$tags.'~'.$lifetime, serialize($value)))
+ {
+ $success = FALSE;
}
}
- return $result;
+ return $success;
}
- /**
- * Fetches a cache item. This will delete the item if it is expired or if
- * the hash does not match the stored hash.
- *
- * @param string cache id
- * @return mixed|NULL
- */
- public function get($id)
+ public function get($keys, $single = FALSE)
{
- if ($file = $this->exists($id))
+ $items = array();
+
+ if ($files = $this->exists($keys))
{
- // Use the first file
- $file = current($file);
+ // Turn off errors while reading the files
+ $ER = error_reporting(0);
- // Validate that the cache has not expired
- if ($this->expired($file))
- {
- // Remove this cache, it has expired
- $this->delete($id);
- }
- else
+ foreach ($files as $file)
{
- // Turn off errors while reading the file
- $ER = error_reporting(0);
+ // Validate that the item has not expired
+ if ($this->expired($file))
+ continue;
+
+ list($key, $junk) = explode('~', basename($file), 2);
if (($data = file_get_contents($file)) !== FALSE)
{
@@ -173,80 +146,102 @@ class Cache_File_Driver implements Cache_Driver {
}
else
{
- // Delete the data
- unset($data);
+ $data = NULL;
}
- // Turn errors back on
- error_reporting($ER);
+ $items[$key] = $data;
}
+
+ // Turn errors back on
+ error_reporting($ER);
}
- // Return NULL if there is no data
- return isset($data) ? $data : NULL;
+ // Reutrn a single item if only one key was requested
+ if ($single)
+ {
+ return (count($items) > 0) ? current($items) : NULL;
+ }
+ else
+ {
+ return $items;
+ }
}
/**
- * Deletes a cache item by id or tag
- *
- * @param string cache id or tag, or TRUE for "all items"
- * @param boolean use tags
- * @return boolean
+ * Get cache items by tag
+ */
+ public function get_tag($tags)
+ {
+ // An array will always be returned
+ $result = array();
+
+ if ($paths = $this->exists($tags, TRUE))
+ {
+ // Find all the files with the given tag
+ foreach ($paths as $path)
+ {
+ // Get the id from the filename
+ list($key, $junk) = explode('~', basename($path), 2);
+
+ if (($data = $this->get($key)) !== FALSE)
+ {
+ // Add the result to the array
+ $result[$key] = $data;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Delete cache items by keys or tags
*/
- public function delete($id, $tag = FALSE)
+ public function delete($keys, $tag = FALSE)
{
- $files = $this->exists($id, $tag);
+ $success = TRUE;
- if (empty($files))
- return FALSE;
+ $paths = $this->exists($keys, $tag);
// Disable all error reporting while deleting
$ER = error_reporting(0);
- foreach ($files as $file)
+ foreach ($paths as $path)
{
// Remove the cache file
- if ( ! unlink($file))
- Kohana::log('error', 'Cache: Unable to delete cache file: '.$file);
+ if ( ! unlink($path))
+ {
+ Kohana::log('error', 'Cache: Unable to delete cache file: '.$path);
+ $success = FALSE;
+ }
}
// Turn on error reporting again
error_reporting($ER);
- return TRUE;
+ return $success;
}
/**
- * Deletes all cache files that are older than the current time.
- *
- * @return void
+ * Delete cache items by tag
*/
- public function delete_expired()
+ public function delete_tag($tags)
{
- if ($files = $this->exists(TRUE))
- {
- // Disable all error reporting while deleting
- $ER = error_reporting(0);
-
- foreach ($files as $file)
- {
- if ($this->expired($file))
- {
- // The cache file has already expired, delete it
- if ( ! unlink($file))
- Kohana::log('error', 'Cache: Unable to delete cache file: '.$file);
- }
- }
+ return $this->delete($tags, TRUE);
+ }
- // Turn on error reporting again
- error_reporting($ER);
- }
+ /**
+ * Empty the cache
+ */
+ public function delete_all()
+ {
+ return $this->delete(TRUE);
}
/**
* Check if a cache file has expired by filename.
*
- * @param string filename
+ * @param string|array array of filenames
* @return bool
*/
protected function expired($file)
@@ -257,5 +252,4 @@ class Cache_File_Driver implements Cache_Driver {
// Expirations of 0 are "never expire"
return ($expires !== 0 AND $expires <= time());
}
-
-} // End Cache File Driver \ No newline at end of file
+} // End Cache Memcache Driver
diff --git a/system/libraries/drivers/Cache/Memcache.php b/system/libraries/drivers/Cache/Memcache.php
index d801de9c..636191d4 100644
--- a/system/libraries/drivers/Cache/Memcache.php
+++ b/system/libraries/drivers/Cache/Memcache.php
@@ -2,190 +2,128 @@
/**
* Memcache-based Cache driver.
*
- * $Id: Memcache.php 4102 2009-03-19 12:55:54Z Shadowhand $
+ * $Id$
*
* @package Cache
* @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
+ * @copyright (c) 2007-2009 Kohana Team
+ * @license http://kohanaphp.com/license
*/
-class Cache_Memcache_Driver implements Cache_Driver {
-
- const TAGS_KEY = 'memcache_tags_array';
-
- // Cache backend object and flags
+class Cache_Memcache_Driver extends Cache_Driver {
+ protected $config;
protected $backend;
protected $flags;
- // Tags array
- protected static $tags;
-
- // Have the tags been changed?
- protected static $tags_changed = FALSE;
-
- public function __construct()
+ public function __construct($config)
{
if ( ! extension_loaded('memcache'))
- throw new Kohana_Exception('cache.extension_not_loaded', 'memcache');
+ throw new Kohana_Exception('The memcache PHP extension must be loaded to use this driver.');
+ ini_set('memcache.allow_failover', (isset($config['allow_failover']) AND $config['allow_failover']) ? TRUE : FALSE);
+
+ $this->config = $config;
$this->backend = new Memcache;
- $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE;
- $servers = Kohana::config('cache_memcache.servers');
+ $this->flags = (isset($config['compression']) AND $config['compression']) ? MEMCACHE_COMPRESSED : FALSE;
- foreach ($servers as $server)
+ foreach ($config['servers'] as $server)
{
// Make sure all required keys are set
- $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE);
+ $server += array('host' => '127.0.0.1',
+ 'port' => 11211,
+ 'persistent' => FALSE,
+ 'weight' => 1,
+ 'timeout' => 1,
+ 'retry_interval' => 15
+ );
// Add the server to the pool
- $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent'])
- or Kohana::log('error', 'Cache: Connection failed: '.$server['host']);
- }
-
- // Load tags
- self::$tags = $this->backend->get(self::TAGS_KEY);
-
- if ( ! is_array(self::$tags))
- {
- // Create a new tags array
- self::$tags = array();
-
- // Tags have been created
- self::$tags_changed = TRUE;
+ $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent'], (int) $server['weight'], (int) $server['timeout'], (int) $server['retry_interval'], TRUE, array($this,'_memcache_failure_callback'));
}
}
- public function __destruct()
+ public function _memcache_failure_callback($host, $port)
{
- if (self::$tags_changed === TRUE)
- {
- // Save the tags
- $this->backend->set(self::TAGS_KEY, self::$tags, $this->flags, 0);
-
- // Tags are now unchanged
- self::$tags_changed = FALSE;
- }
+ $this->backend->setServerParams($host, $port, 1, -1, FALSE);
+ Kohana_Log::add('error', __('Cache: Memcache server down: :host:::port:',array(':host:' => $host,':port:' => $port)));
}
- public function find($tag)
+ public function set($items, $tags = NULL, $lifetime = NULL)
{
- if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag]))
- {
- // Return all the found caches
- return $results;
- }
- else
+ if ($lifetime !== 0)
{
- // No matching tags
- return array();
+ // Memcache driver expects unix timestamp
+ $lifetime += time();
}
- }
- public function get($id)
- {
- return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return;
- }
+ if ($tags !== NULL)
+ throw new Cache_Exception('Memcache driver does not support tags');
- public function set($id, $data, array $tags = NULL, $lifetime)
- {
- if ( ! empty($tags))
+ foreach ($items as $key => $value)
{
- // Tags will be changed
- self::$tags_changed = TRUE;
+ if (is_resource($value))
+ throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.');
- foreach ($tags as $tag)
+ if ( ! $this->backend->set($key, $value, $this->flags, $lifetime))
{
- // Add the id to each tag
- self::$tags[$tag][$id] = $id;
+ return FALSE;
}
}
- if ($lifetime !== 0)
- {
- // Memcache driver expects unix timestamp
- $lifetime += time();
- }
-
- // Set a new value
- return $this->backend->set($id, $data, $this->flags, $lifetime);
+ return TRUE;
}
- public function delete($id, $tag = FALSE)
+ public function get($keys, $single = FALSE)
{
- // Tags will be changed
- self::$tags_changed = TRUE;
+ $items = $this->backend->get($keys);
- if ($id === TRUE)
+ if ($single)
{
- if ($status = $this->backend->flush())
- {
- // Remove all tags, all items have been deleted
- self::$tags = array();
-
- // We must sleep after flushing, or overwriting will not work!
- // @see http://php.net/manual/en/function.memcache-flush.php#81420
- sleep(1);
- }
-
- return $status;
- }
- elseif ($tag === TRUE)
- {
- if (isset(self::$tags[$id]))
- {
- foreach (self::$tags[$id] as $_id)
- {
- // Delete each id in the tag
- $this->backend->delete($_id);
- }
-
- // Delete the tag
- unset(self::$tags[$id]);
- }
-
- return TRUE;
+ return ($items === FALSE OR count($items) > 0) ? current($items) : NULL;
}
else
{
- foreach (self::$tags as $tag => $_ids)
- {
- if (isset(self::$tags[$tag][$id]))
- {
- // Remove the id from the tags
- unset(self::$tags[$tag][$id]);
- }
- }
-
- return $this->backend->delete($id);
+ return ($items === FALSE) ? array() : $items;
}
}
- public function delete_expired()
+ /**
+ * Get cache items by tag
+ */
+ public function get_tag($tags)
{
- // Tags will be changed
- self::$tags_changed = TRUE;
+ throw new Cache_Exception('Memcache driver does not support tags');
+ }
- foreach (self::$tags as $tag => $_ids)
+ /**
+ * Delete cache item by key
+ */
+ public function delete($keys)
+ {
+ foreach ($keys as $key)
{
- foreach ($_ids as $id)
+ if ( ! $this->backend->delete($key))
{
- if ( ! $this->backend->get($id))
- {
- // This id has disappeared, delete it from the tags
- unset(self::$tags[$tag][$id]);
- }
- }
-
- if (empty(self::$tags[$tag]))
- {
- // The tag no longer has any valid ids
- unset(self::$tags[$tag]);
+ return FALSE;
}
}
- // Memcache handles garbage collection internally
return TRUE;
}
+ /**
+ * Delete cache items by tag
+ */
+ public function delete_tag($tags)
+ {
+ throw new Cache_Exception('Memcache driver does not support tags');
+ }
+
+ /**
+ * Empty the cache
+ */
+ public function delete_all()
+ {
+ return $this->backend->flush();
+ }
} // End Cache Memcache Driver
diff --git a/system/libraries/drivers/Cache/Sqlite.php b/system/libraries/drivers/Cache/Sqlite.php
deleted file mode 100644
index 9458d851..00000000
--- a/system/libraries/drivers/Cache/Sqlite.php
+++ /dev/null
@@ -1,257 +0,0 @@
-<?php defined('SYSPATH') OR die('No direct access allowed.');
-/**
- * SQLite-based Cache driver.
- *
- * $Id: Sqlite.php 4046 2009-03-05 19:23:29Z Shadowhand $
- *
- * @package Cache
- * @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
- */
-class Cache_Sqlite_Driver implements Cache_Driver {
-
- // SQLite database instance
- protected $db;
-
- // Database error messages
- protected $error;
-
- /**
- * Logs an SQLite error.
- */
- protected static function log_error($code)
- {
- // Log an error
- Kohana::log('error', 'Cache: SQLite error: '.sqlite_error_string($error));
- }
-
- /**
- * Tests that the storage location is a directory and is writable.
- */
- public function __construct($filename)
- {
- // Get the directory name
- $directory = str_replace('\\', '/', realpath(pathinfo($filename, PATHINFO_DIRNAME))).'/';
-
- // Set the filename from the real directory path
- $filename = $directory.basename($filename);
-
- // Make sure the cache directory is writable
- if ( ! is_dir($directory) OR ! is_writable($directory))
- throw new Kohana_Exception('cache.unwritable', $directory);
-
- // Make sure the cache database is writable
- if (is_file($filename) AND ! is_writable($filename))
- throw new Kohana_Exception('cache.unwritable', $filename);
-
- // Open up an instance of the database
- $this->db = new SQLiteDatabase($filename, '0666', $error);
-
- // Throw an exception if there's an error
- if ( ! empty($error))
- throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error));
-
- $query = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'caches'";
- $tables = $this->db->query($query, SQLITE_BOTH, $error);
-
- // Throw an exception if there's an error
- if ( ! empty($error))
- throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error));
-
- if ($tables->numRows() == 0)
- {
- Kohana::log('error', 'Cache: Initializing new SQLite cache database');
-
- // Issue a CREATE TABLE command
- $this->db->unbufferedQuery(Kohana::config('cache_sqlite.schema'));
- }
- }
-
- /**
- * Checks if a cache id is already set.
- *
- * @param string cache id
- * @return boolean
- */
- public function exists($id)
- {
- // Find the id that matches
- $query = "SELECT id FROM caches WHERE id = '$id'";
-
- return ($this->db->query($query)->numRows() > 0);
- }
-
- /**
- * Sets a cache item to the given data, tags, and lifetime.
- *
- * @param string cache id to set
- * @param string data in the cache
- * @param array cache tags
- * @param integer lifetime
- * @return bool
- */
- public function set($id, $data, array $tags = NULL, $lifetime)
- {
- // Serialize and escape the data
- $data = sqlite_escape_string(serialize($data));
-
- if ( ! empty($tags))
- {
- // Escape the tags, adding brackets so the tag can be explicitly matched
- $tags = sqlite_escape_string('<'.implode('>,<', $tags).'>');
- }
-
- // Cache Sqlite driver expects unix timestamp
- if ($lifetime !== 0)
- {
- $lifetime += time();
- }
-
- $query = $this->exists($id)
- ? "UPDATE caches SET tags = '$tags', expiration = '$lifetime', cache = '$data' WHERE id = '$id'"
- : "INSERT INTO caches VALUES('$id', '$tags', '$lifetime', '$data')";
-
- // Run the query
- $this->db->unbufferedQuery($query, SQLITE_BOTH, $error);
-
- if ( ! empty($error))
- {
- self::log_error($error);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-
- /**
- * Finds an array of ids for a given tag.
- *
- * @param string tag name
- * @return array of ids that match the tag
- */
- public function find($tag)
- {
- $query = "SELECT id,cache FROM caches WHERE tags LIKE '%<{$tag}>%'";
- $query = $this->db->query($query, SQLITE_BOTH, $error);
-
- // An array will always be returned
- $result = array();
-
- if ( ! empty($error))
- {
- self::log_error($error);
- }
- elseif ($query->numRows() > 0)
- {
- // Disable notices for unserializing
- $ER = error_reporting(~E_NOTICE);
-
- while ($row = $query->fetchObject())
- {
- // Add each cache to the array
- $result[$row->id] = unserialize($row->cache);
- }
-
- // Turn notices back on
- error_reporting($ER);
- }
-
- return $result;
- }
-
- /**
- * Fetches a cache item. This will delete the item if it is expired or if
- * the hash does not match the stored hash.
- *
- * @param string cache id
- * @return mixed|NULL
- */
- public function get($id)
- {
- $query = "SELECT id, expiration, cache FROM caches WHERE id = '$id' LIMIT 0, 1";
- $query = $this->db->query($query, SQLITE_BOTH, $error);
-
- if ( ! empty($error))
- {
- self::log_error($error);
- }
- elseif ($cache = $query->fetchObject())
- {
- // Make sure the expiration is valid and that the hash matches
- if ($cache->expiration != 0 AND $cache->expiration <= time())
- {
- // Cache is not valid, delete it now
- $this->delete($cache->id);
- }
- else
- {
- // Disable notices for unserializing
- $ER = error_reporting(~E_NOTICE);
-
- // Return the valid cache data
- $data = $cache->cache;
-
- // Turn notices back on
- error_reporting($ER);
- }
- }
-
- // No valid cache found
- return NULL;
- }
-
- /**
- * Deletes a cache item by id or tag
- *
- * @param string cache id or tag, or TRUE for "all items"
- * @param bool delete a tag
- * @return bool
- */
- public function delete($id, $tag = FALSE)
- {
- if ($id === TRUE)
- {
- // Delete all caches
- $where = '1';
- }
- elseif ($tag === TRUE)
- {
- // Delete by tag
- $where = "tags LIKE '%<{$id}>%'";
- }
- else
- {
- // Delete by id
- $where = "id = '$id'";
- }
-
- $this->db->unbufferedQuery('DELETE FROM caches WHERE '.$where, SQLITE_BOTH, $error);
-
- if ( ! empty($error))
- {
- self::log_error($error);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-
- /**
- * Deletes all cache files that are older than the current time.
- */
- public function delete_expired()
- {
- // Delete all expired caches
- $query = 'DELETE FROM caches WHERE expiration != 0 AND expiration <= '.time();
-
- $this->db->unbufferedQuery($query);
-
- return TRUE;
- }
-
-} // End Cache SQLite Driver \ No newline at end of file
diff --git a/system/libraries/drivers/Cache/Xcache.php b/system/libraries/drivers/Cache/Xcache.php
index 6254bbb6..ad11e6d7 100644
--- a/system/libraries/drivers/Cache/Xcache.php
+++ b/system/libraries/drivers/Cache/Xcache.php
@@ -1,85 +1,128 @@
<?php defined('SYSPATH') OR die('No direct access allowed.');
/**
- * Xcache Cache driver.
- *
- * $Id: Xcache.php 4046 2009-03-05 19:23:29Z Shadowhand $
+ * XCache-based Cache driver.
+ *
+ * $Id: Memcache.php 4605 2009-09-14 17:22:21Z kiall $
*
* @package Cache
* @author Kohana Team
- * @copyright (c) 2007-2008 Kohana Team
- * @license http://kohanaphp.com/license.html
+ * @copyright (c) 2007-2009 Kohana Team
+ * @license http://kohanaphp.com/license
+ * @TODO Check if XCache cleans its own keys.
*/
-class Cache_Xcache_Driver implements Cache_Driver {
+class Cache_Xcache_Driver extends Cache_Driver {
+ protected $config;
- public function __construct()
+ public function __construct($config)
{
if ( ! extension_loaded('xcache'))
- throw new Kohana_Exception('cache.extension_not_loaded', 'xcache');
- }
-
- public function get($id)
- {
- if (xcache_isset($id))
- return xcache_get($id);
+ throw new Kohana_Exception('The xcache PHP extension must be loaded to use this driver.');
- return NULL;
+ $this->config = $config;
}
- public function set($id, $data, array $tags = NULL, $lifetime)
+ public function set($items, $tags = NULL, $lifetime = NULL)
{
- if ( ! empty($tags))
+ if ($tags !== NULL)
{
- Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver');
+ Kohana_Log::add('debug', __('Cache: XCache driver does not support tags'));
}
- return xcache_set($id, $data, $lifetime);
- }
+ foreach ($items as $key => $value)
+ {
+ if (is_resource($value))
+ throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.');
- public function find($tag)
- {
- Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver');
- return FALSE;
+ if ( ! xcache_set($key, $value, $lifetime))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
}
- public function delete($id, $tag = FALSE)
+ public function get($keys, $single = FALSE)
{
- if ($tag !== FALSE)
- {
- Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver');
- return TRUE;
- }
- elseif ($id !== TRUE)
+ $items = array();
+
+ foreach ($keys as $key)
{
if (xcache_isset($id))
- return xcache_unset($id);
+ {
+ $items[$key] = xcache_get($id);
+ }
+ else
+ {
+ $items[$key] = NULL;
+ }
+ }
- return FALSE;
+ if ($single)
+ {
+ return ($items === FALSE OR count($items) > 0) ? current($items) : NULL;
}
else
{
- // Do the login
- $this->auth();
- $result = TRUE;
- for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++)
+ return ($items === FALSE) ? array() : $items;
+ }
+ }
+
+ /**
+ * Get cache items by tag
+ */
+ public function get_tag($tags)
+ {
+ Kohana_Log::add('debug', __('Cache: XCache driver does not support tags'));
+ return NULL;
+ }
+
+ /**
+ * Delete cache item by key
+ */
+ public function delete($keys)
+ {
+ foreach ($keys as $key)
+ {
+ if ( ! xcache_unset($key))
{
- if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL)
- {
- $result = FALSE;
- break;
- }
+ return FALSE;
}
-
- // Undo the login
- $this->auth(TRUE);
- return $result;
}
return TRUE;
}
- public function delete_expired()
+ /**
+ * Delete cache items by tag
+ */
+ public function delete_tag($tags)
{
- return TRUE;
+ Kohana_Log::add('debug', __('Cache: XCache driver does not support tags'));
+ return NULL;
+ }
+
+ /**
+ * Empty the cache
+ */
+ public function delete_all()
+ {
+ $this->auth();
+ $result = TRUE;
+
+ for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++)
+ {
+ if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL)
+ {
+ $result = FALSE;
+ break;
+ }
+ }
+
+ // Undo the login
+ $this->auth(TRUE);
+
+ return $result;
}
private function auth($reverse = FALSE)
@@ -111,9 +154,8 @@ class Cache_Xcache_Driver implements Cache_Driver {
$backup[$key] = $value;
}
- $_SERVER[$key] = Kohana::config('cache_xcache.'.$key);
+ $_SERVER[$key] = $this->config->{$key};
}
}
}
-
-} // End Cache Xcache Driver
+} // End Cache XCache Driver