Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SQLiteCache] Implemented cache based on SQLite 3 #1035

Merged
merged 3 commits into from
Feb 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions caches/SQLiteCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<?php
/**
* Cache based on SQLite 3 <https://www.sqlite.org>
*/
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);
}
}
4 changes: 1 addition & 3 deletions tests/CacheImplementationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

class CacheImplementationTest extends TestCase {
private $class;
private $obj;

/**
* @dataProvider dataCachesProvider
Expand All @@ -22,7 +21,7 @@ public function testClassName($path) {
*/
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');
}

////////////////////////////////////////////////////////////////////////////
Expand All @@ -39,6 +38,5 @@ private function setCache($path) {
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();
}
}