diff --git a/caches/SQLiteCache.php b/caches/SQLiteCache.php new file mode 100644 index 00000000..b3caac34 --- /dev/null +++ b/caches/SQLiteCache.php @@ -0,0 +1,96 @@ + + */ +class SQLiteCache implements CacheInterface { + protected $path; + protected $param; + + private $db = null; + + public function __construct() { + $file = PATH_CACHE . 'cache.sqlite'; + + if (!is_file($file)) { + $this->db = new SQLite3($file); + $this->db->enableExceptions(true); + $this->db->exec("CREATE TABLE storage ('key' BLOB PRIMARY KEY, 'value' BLOB, 'updated' INTEGER)"); + } else { + $this->db = new SQLite3($file); + $this->db->enableExceptions(true); + } + $this->db->busyTimeout(5000); + } + + public function loadData(){ + $Qselect = $this->db->prepare('SELECT value FROM storage WHERE key = :key'); + $Qselect->bindValue(':key', $this->getCacheKey()); + $result = $Qselect->execute(); + if ($result instanceof SQLite3Result) { + $data = $result->fetchArray(SQLITE3_ASSOC); + if (isset($data['value'])) { + return unserialize($data['value']); + } + } + + return null; + } + + public function saveData($datas){ + $Qupdate = $this->db->prepare('INSERT OR REPLACE INTO storage (key, value, updated) VALUES (:key, :value, :updated)'); + $Qupdate->bindValue(':key', $this->getCacheKey()); + $Qupdate->bindValue(':value', serialize($datas)); + $Qupdate->bindValue(':updated', time()); + $Qupdate->execute(); + + return $this; + } + + public function getTime(){ + $Qselect = $this->db->prepare('SELECT updated FROM storage WHERE key = :key'); + $Qselect->bindValue(':key', $this->getCacheKey()); + $result = $Qselect->execute(); + if ($result instanceof SQLite3Result) { + $data = $result->fetchArray(SQLITE3_ASSOC); + if (isset($data['updated'])) { + return $data['updated']; + } + } + + return false; + } + + public function purgeCache($duration){ + $Qdelete = $this->db->prepare('DELETE FROM storage WHERE updated < :expired'); + $Qdelete->bindValue(':expired', time() - $duration); + $Qdelete->execute(); + } + + /** + * Set cache path + * @return self + */ + public function setPath($path){ + $this->path = $path; + return $this; + } + + /** + * Set HTTP GET parameters + * @return self + */ + public function setParameters(array $param){ + $this->param = array_map('strtolower', $param); + return $this; + } + + //////////////////////////////////////////////////////////////////////////// + + protected function getCacheKey(){ + if(is_null($this->param)) { + throw new \Exception('Call "setParameters" first!'); + } + + return hash('sha1', $this->path . http_build_query($this->param), true); + } +} diff --git a/tests/CacheImplementationTest.php b/tests/CacheImplementationTest.php index 7eb1af51..25189134 100644 --- a/tests/CacheImplementationTest.php +++ b/tests/CacheImplementationTest.php @@ -5,7 +5,6 @@ use PHPUnit\Framework\TestCase; class CacheImplementationTest extends TestCase { private $class; - private $obj; /** * @dataProvider dataCachesProvider @@ -22,7 +21,7 @@ class CacheImplementationTest extends TestCase { */ public function testClassType($path) { $this->setCache($path); - $this->assertInstanceOf(CacheInterface::class, $this->obj); + $this->assertTrue(is_subclass_of($this->class, CacheInterface::class), 'class must be subclass of CacheInterface'); } //////////////////////////////////////////////////////////////////////////// @@ -39,6 +38,5 @@ class CacheImplementationTest extends TestCase { require_once $path; $this->class = basename($path, '.php'); $this->assertTrue(class_exists($this->class), 'class ' . $this->class . ' doesn\'t exist'); - $this->obj = new $this->class(); } }