123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- <?php
- /**
- * Kohana Cache Sqlite Driver
- *
- * Requires SQLite3 and PDO
- *
- * @package Kohana/Cache
- * @category Base
- * @author Kohana Team
- * @copyright (c) Kohana Team
- * @license https://koseven.ga/LICENSE.md
- */
- class Kohana_Cache_Sqlite extends Cache implements Cache_Tagging, Cache_GarbageCollect {
- /**
- * Database resource
- *
- * @var PDO
- */
- protected $_db;
- /**
- * Sets up the PDO SQLite table and
- * initialises the PDO connection
- *
- * @param array $config configuration
- * @throws Cache_Exception
- */
- protected function __construct(array $config)
- {
- parent::__construct($config);
- $database = Arr::get($this->_config, 'database', NULL);
- if ($database === NULL)
- {
- throw new Cache_Exception('Database path not available in Kohana Cache configuration');
- }
- // Load new Sqlite DB
- $this->_db = new PDO('sqlite:'.$database);
- // Test for existing DB
- $result = $this->_db->query("SELECT * FROM sqlite_master WHERE name = 'caches' AND type = 'table'")->fetchAll();
- // If there is no table, create a new one
- if (0 == count($result))
- {
- $database_schema = Arr::get($this->_config, 'schema', NULL);
- if ($database_schema === NULL)
- {
- throw new Cache_Exception('Database schema not found in Kohana Cache configuration');
- }
- try
- {
- // Create the caches table
- $this->_db->query(Arr::get($this->_config, 'schema', NULL));
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('Failed to create new SQLite caches table with the following error : :error', [':error' => $e->getMessage()]);
- }
- }
- }
- /**
- * Retrieve a value based on an id
- *
- * @param string $id id
- * @param string $default default [Optional] Default value to return if id not found
- * @return mixed
- * @throws Cache_Exception
- */
- public function get($id, $default = NULL)
- {
- // Prepare statement
- $statement = $this->_db->prepare('SELECT id, expiration, cache FROM caches WHERE id = :id LIMIT 0, 1');
- // Try and load the cache based on id
- try
- {
- $statement->execute([':id' => $this->_sanitize_id($id)]);
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- if ( ! $result = $statement->fetch(PDO::FETCH_OBJ))
- {
- return $default;
- }
- // If the cache has expired
- if ($result->expiration != 0 and $result->expiration <= time())
- {
- // Delete it and return default value
- $this->delete($id);
- return $default;
- }
- // Otherwise return cached object
- else
- {
- // Return the valid cache data
- $data = @unserialize($result->cache);
- // Return the resulting data
- return $data;
- }
- }
- /**
- * Set a value based on an id. Optionally add tags.
- *
- * @param string $id id
- * @param mixed $data data
- * @param integer $lifetime lifetime [Optional]
- * @return boolean
- */
- public function set($id, $data, $lifetime = NULL)
- {
- return (bool) $this->set_with_tags($id, $data, $lifetime);
- }
- /**
- * Delete a cache entry based on id
- *
- * @param string $id id
- * @return boolean
- * @throws Cache_Exception
- */
- public function delete($id)
- {
- // Prepare statement
- $statement = $this->_db->prepare('DELETE FROM caches WHERE id = :id');
- // Remove the entry
- try
- {
- $statement->execute([':id' => $this->_sanitize_id($id)]);
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- return (bool) $statement->rowCount();
- }
- /**
- * Delete all cache entries
- *
- * @return boolean
- */
- public function delete_all()
- {
- // Prepare statement
- $statement = $this->_db->prepare('DELETE FROM caches');
- // Remove the entry
- try
- {
- $statement->execute();
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- return (bool) $statement->rowCount();
- }
- /**
- * Set a value based on an id. Optionally add tags.
- *
- * @param string $id id
- * @param mixed $data data
- * @param integer $lifetime lifetime [Optional]
- * @param array $tags tags [Optional]
- * @return boolean
- * @throws Cache_Exception
- */
- public function set_with_tags($id, $data, $lifetime = NULL, array $tags = NULL)
- {
- // Serialize the data
- $data = serialize($data);
- // Normalise tags
- $tags = (NULL === $tags) ? NULL : ('<'.implode('>,<', $tags).'>');
- // Setup lifetime
- if ($lifetime === NULL)
- {
- $lifetime = (0 === Arr::get($this->_config, 'default_expire', NULL)) ? 0 : (Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE) + time());
- }
- else
- {
- $lifetime = (0 === $lifetime) ? 0 : ($lifetime + time());
- }
- // Prepare statement
- // $this->exists() may throw Cache_Exception, no need to catch/rethrow
- $statement = $this->exists($id) ? $this->_db->prepare('UPDATE caches SET expiration = :expiration, cache = :cache, tags = :tags WHERE id = :id') : $this->_db->prepare('INSERT INTO caches (id, cache, expiration, tags) VALUES (:id, :cache, :expiration, :tags)');
- // Try to insert
- try
- {
- $statement->execute([':id' => $this->_sanitize_id($id), ':cache' => $data, ':expiration' => $lifetime, ':tags' => $tags]);
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- return (bool) $statement->rowCount();
- }
- /**
- * Delete cache entries based on a tag
- *
- * @param string $tag tag
- * @return boolean
- * @throws Cache_Exception
- */
- public function delete_tag($tag)
- {
- // Prepare the statement
- $statement = $this->_db->prepare('DELETE FROM caches WHERE tags LIKE :tag');
- // Try to delete
- try
- {
- $statement->execute([':tag' => "%<{$tag}>%"]);
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- return (bool) $statement->rowCount();
- }
- /**
- * Find cache entries based on a tag
- *
- * @param string $tag tag
- * @return array
- * @throws Cache_Exception
- */
- public function find($tag)
- {
- // Prepare the statement
- $statement = $this->_db->prepare('SELECT id, cache FROM caches WHERE tags LIKE :tag');
- // Try to find
- try
- {
- if ( ! $statement->execute([':tag' => "%<{$tag}>%"]))
- {
- return [];
- }
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- $result = [];
- while ($row = $statement->fetchObject())
- {
- $result[$row->id] = @unserialize($row->cache);
- }
- return $result;
- }
- /**
- * Garbage collection method that cleans any expired
- * cache entries from the cache.
- *
- * @return void
- */
- public function garbage_collect()
- {
- // Create the sequel statement
- $statement = $this->_db->prepare('DELETE FROM caches WHERE expiration < :expiration');
- try
- {
- $statement->execute([':expiration' => time()]);
- }
- catch (PDOException $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- }
- /**
- * Tests whether an id exists or not
- *
- * @param string $id id
- * @return boolean
- * @throws Cache_Exception
- */
- protected function exists($id)
- {
- $statement = $this->_db->prepare('SELECT id FROM caches WHERE id = :id');
- try
- {
- $statement->execute([':id' => $this->_sanitize_id($id)]);
- }
- catch (PDOExeption $e)
- {
- throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', [':error' => $e->getMessage()]);
- }
- return (bool) $statement->fetchAll();
- }
- }
|