diff --git a/DOCS.md b/DOCS.md index ed0bae2..27d063b 100644 --- a/DOCS.md +++ b/DOCS.md @@ -82,9 +82,32 @@ $config = [ # default value: null 'prefix' => '', - # Cache Directory of the Sql Result (optional) - # default value: __DIR__ . '/cache/' - 'cachedir' => __DIR__ . '/cache/sql/' + # Cache Type: File + 'cache' => [ + 'type' => 'file', + + # Cache Directory of the Sql Result (optional) + # default value: __DIR__ . '/cache/' + 'dir' => __DIR__ . '/cache/sql/' + ], + + # Cache Type: Memcached + 'cache' => [ + 'type' => 'memcached', + + # Memcached server address + # default value: localhost + 'host' => 'localhost', + + # Memcached server address port + # default value: 11211 + 'port' => 11211, + + # The key under which to store the value. + # available characters: = 0-9 a-z A-Z _ - . + # default value: masterkey + 'masterkey' => 'database.name_key' + ], ]; $db = new \Buki\Pdox($config); @@ -549,6 +572,12 @@ $db->error(); # Usage: ...->cache($time)->... $db->table('pages')->where('slug', 'example-page')->cache(60)->get(); # cache time: 60 seconds + +# Memcached clear +print_r($db->clearCache()); + +# Cleaning using the masterkey +print_r($db->clearCache('database.name_key')); ``` ### queryCount diff --git a/src/CacheMem.php b/src/CacheMem.php new file mode 100644 index 0000000..4da2ec3 --- /dev/null +++ b/src/CacheMem.php @@ -0,0 +1,121 @@ + + * @url + * @license The MIT License (MIT) - + */ + +namespace Buki; + +use Memcached; + +class CacheMem +{ + protected $masterKey = null; + protected $cache = null; + protected $finish = null; + + protected $memcached = null; + + /** + * CacheMem constructor. + * + * @param null $config + */ + function __construct($config = []) + { + $this->masterKey = $config['masterkey']; + $this->memcached = new Memcached(); + $this->memcached->addServer($config['host'], $config['port']); + } + + /** + * @param int $time + */ + public function setCacheTime($time = 0) + { + $this->cache = $time; + $this->finish = time() + $time; + } + + /** + * @param $sql + * @param bool $array + * + * @return bool|void + */ + public function getCache($sql, $array = false) + { + + if (is_null($this->cache)) { + return false; + } + + if (($cache = $this->memcached->get($this->keyName($sql)))) { + if ($this->memcached->getResultCode() == Memcached::RES_SUCCESS) { + $cache = json_decode($cache, $array); + return ($array ? $cache['data'] : $cache->data); + } + } + + return false; + } + + /** + * @param $sql + * @param $result + * + * @return bool|void + */ + public function setCache($sql, $result) + { + if (is_null($this->cache)) { + return false; + } + $this->memcached->set($this->keyName($sql), json_encode(['data' => $result, 'finish' => $this->finish]), $this->finish); + return; + } + + /** + * @param $masterKey + * + * @return array + */ + public function clearCache($masterKey) + { + $data = null; + $keys = $this->memcached->getAllKeys(); + foreach ($keys as $item) { + if (preg_match('/' . $masterKey . '.PDOx.*/', $item)) { + $this->memcached->delete($item); + $data[] = $item; + } + } + return is_array($data) ? $data : null; + } + + /** + * @param $name + * + * @return string + */ + protected function keyName($name) + { + return $this->masterKey . '.PDOx.' . md5($this->masterKey . ':' . $name); + } + + /** + * @return void + */ + public function __destruct() + { + if (!is_null($this->memcached)) { + $this->memcached->quit(); + } + } +} diff --git a/src/Pdox.php b/src/Pdox.php index 762461c..8f79522 100644 --- a/src/Pdox.php +++ b/src/Pdox.php @@ -56,12 +56,17 @@ class Pdox implements PdoxInterface /** * @var Cache|null */ - protected $cache = null; + protected $cacheType = null; + + /** + * @var array Cache Config + */ + protected $cacheConfig = []; /** - * @var string|null Cache Directory + * @var Cache|null */ - protected $cacheDir = null; + protected $cache = null; /** * @var int Total query count @@ -91,11 +96,20 @@ public function __construct(array $config) $config['collation'] = isset($config['collation']) ? $config['collation'] : 'utf8_general_ci'; $config['port'] = isset($config['port']) ? $config['port'] - : strstr($config['host'], ':') ? explode(':', $config['host'])[1] : ''; + : (strstr($config['host'], ':') ? explode(':', $config['host'])[1] : ''); + $this->prefix = isset($config['prefix']) ? $config['prefix'] : ''; - $this->cacheDir = isset($config['cachedir']) ? $config['cachedir'] : __DIR__ . '/cache/'; $this->debug = isset($config['debug']) ? $config['debug'] : true; + if ((isset($config['cache']) && (is_array($config['cache'])))) { + $this->cacheConfig = $config['cache']; + $this->cacheType = isset($this->cacheConfig['type']) ? $this->cacheConfig['type'] : ''; + if ($this->cacheType === 'memcached') { + $this->cacheConfig['host'] = isset($this->cacheConfig['host']) ? $this->cacheConfig['host'] : 'localhost'; + $this->cacheConfig['port'] = isset($this->cacheConfig['port']) ? $this->cacheConfig['port'] : 11211; + $this->cacheConfig['masterkey'] = isset($this->cacheConfig['masterkey']) ? $this->cacheConfig['masterkey'] : 'masterkey'; + } + } $dsn = ''; if (in_array($config['driver'], ['', 'mysql', 'pgsql'])) { $dsn = $config['driver'] . ':host=' . str_replace(':' . $config['port'], '', $config['host']) . ';' @@ -1117,14 +1131,14 @@ public function query($query, $all = true, $type = null, $argument = null) if (!is_null($this->cache) && $type !== PDO::FETCH_CLASS) { $this->cache->setCache($this->query, $this->result); } - $this->cache = null; + //$this->cache = null; } else { - $this->cache = null; + //$this->cache = null; $this->error = $this->pdo->errorInfo()[2]; $this->error(); } } elseif ((!$cache && !$str) || ($cache && !$str)) { - $this->cache = null; + //$this->cache = null; $this->result = $this->pdo->exec($this->query); if ($this->result === false) { @@ -1132,7 +1146,7 @@ public function query($query, $all = true, $type = null, $argument = null) $this->error(); } } else { - $this->cache = null; + //$this->cache = null; $this->result = $cache; $this->numRows = is_array($this->result) ? count($this->result) : ($this->result === '' ? 0 : 1); } @@ -1148,9 +1162,7 @@ public function query($query, $all = true, $type = null, $argument = null) */ public function escape($data) { - return $data === null ? 'NULL' : ( - is_int($data) || is_float($data) ? $data : $this->pdo->quote($data) - ); + return $data === null ? 'NULL' : (is_int($data) || is_float($data) ? $data : $this->pdo->quote($data)); } /** @@ -1160,11 +1172,32 @@ public function escape($data) */ public function cache($time) { - $this->cache = new Cache($this->cacheDir, $time); - + if ($this->cacheType === 'file') { + $this->cache = new Cache($this->cacheConfig['dir'], $time); + } else { + if (is_null($this->cache)) { + $this->cache = new CacheMem($this->cacheConfig); + } + $this->cache->setCacheTime($time); + } return $this; } + /** + * @param $masterKey + * + * @return string + */ + public function clearCache($masterKey = null) + { + if ($this->cacheType === 'memcached') { + if (is_null($this->cache)) { + $this->cache = new CacheMem($this->cacheConfig); + } + return $this->cache->clearCache(isset($masterKey) ? $masterKey : $this->cacheConfig['masterkey']); + } + } + /** * @return int */