Start of caching implementation

This commit is contained in:
Timothy Warren 2016-04-05 13:19:35 -04:00
parent 972d96c0e0
commit 84e4e6ce1b
8 changed files with 277 additions and 43 deletions

View File

@ -15,6 +15,7 @@ use Zend\Diactoros\ServerRequestFactory;
use Zend\Diactoros\Response;
use Aviat\Ion\Di\Container;
use Aviat\Ion\Cache\CacheManager;
use Aviat\AnimeClient\Auth\HummingbirdAuth;
use Aviat\AnimeClient\Model;
@ -30,7 +31,6 @@ return function(array $config_array = []) {
$app_logger = new Logger('animeclient');
$app_logger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE));
$app_logger->pushHandler(new BrowserConsoleHandler(Logger::INFO));
$container->setLogger($app_logger, 'default');
// -------------------------------------------------------------------------
@ -83,6 +83,8 @@ return function(array $config_array = []) {
$container->set('anime-collection-model', new Model\AnimeCollection($container));
$container->set('auth', new HummingbirdAuth($container));
$container->set('cache', new CacheManager($container));
// -------------------------------------------------------------------------
// Dispatcher

View File

@ -14,5 +14,8 @@ show_anime_collection = true
# do you wish to show the manga collection?
show_manga_collection = false
# cache driver for api calls (SQLDriver, RedisDriver, MemcacheDriver)
cache_driver = SQLDriver
# path to public directory on the server
asset_dir = "/../../public"

View File

@ -27,8 +27,8 @@ class CacheMigration extends AbstractMigration
*/
public function change()
{
$this->table('cache', ['id' => FALSE, 'primary_key' => ['key']])
->addColumn('key', 'text')
$cacheTable = $this->table('cache', ['id' => FALSE, 'primary_key' => ['key']]);
$cacheTable->addColumn('key', 'text')
->addColumn('value', 'text')
->create();
}

View File

@ -37,6 +37,11 @@ class Anime extends BaseController {
* @var array $base_data
*/
protected $base_data;
/**
* Data cache
*/
protected $cache;
/**
* Constructor
@ -55,6 +60,8 @@ class Anime extends BaseController {
'other_type' => 'manga',
'config' => $this->config,
]);
$this->cache = $container->get('cache');
}
/**
@ -98,10 +105,14 @@ class Anime extends BaseController {
'' => 'cover',
'list' => 'list'
];
$data = ($type != 'all')
? $this->cache->get($this->model, 'get_list', ['status' => $model_map[$type]])
: $this->cache->get($this->model, 'get_all_lists', []);
/*$data = ($type != 'all')
? $this->model->get_list($model_map[$type])
: $this->model->get_all_lists();
: $this->model->get_all_lists();*/
$this->outputHTML('anime/' . $view_map[$view], [
'title' => $title,

View File

@ -1,36 +1,44 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache;
/**
* Interface for cache drivers
*/
interface CacheDriverInterface {
/**
* Retreive a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key);
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return CacheDriverInterface
*/
public function set($key, $value);
}
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache;
/**
* Interface for cache drivers
*/
interface CacheDriverInterface {
/**
* Retreive a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key);
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return CacheDriverInterface
*/
public function set($key, $value);
/**
* Invalidate a cached value
*
* @param string $key
* @return CacheDriverInterface
*/
public function invalidate($key);
}
// End of CacheDriverInterface.php

View File

@ -23,9 +23,9 @@ interface CacheInterface {
*
* @param object $object - object to retrieve fresh value from
* @param string $method - method name to call
* @param array $args - the arguments to pass to the retrieval method
* @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the cached or fresh data
*/
public function get($object, $method, array $args);
*/
public function get($object, $method, array $args=[]);
}
// End of CacheInterface.php

View File

@ -0,0 +1,100 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache;
use \Aviat\Ion\Di\ContainerInterface;
/**
* Class proxying cached and fresh values from the selected cache driver
*/
class CacheManager implements CacheInterface {
/**
* @var CacheDriverInterface
*/
protected $driver;
/**
* Retreive the appropriate driver from the container
*/
public function __construct(ContainerInterface $container)
{
$config = $container->get('config');
$driverConf = $config->get('cache_driver');
$driverClass = __NAMESPACE__ . "\\Driver\\{$driverConf}";
$driver = new $driverClass($container);
$this->driver = $driver;
}
/**
* Retreive a cached value if it exists, otherwise, get the value
* from the passed arguments
*
* @param object $object - object to retrieve fresh value from
* @param string $method - method name to call
* @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the cached or fresh data
*/
public function get($object, $method, array $args=[])
{
$hash = $this->generateHashForMethod($object, $method, $args);
$data = $this->driver->get($hash);
if (empty($data))
{
$data = call_user_func_array([$object, $method], $args);
$this->driver->set($hash, $data);
}
return $data;
}
/**
* Retreive a fresh value from the method, and update the cache
* @param object $object - object to retrieve fresh value from
* @param string $method - method name to call
* @param [array] $args - the arguments to pass to the retrieval method
* @return mixed - the fresh data
*/
public function getFresh($object, $method, array $args=[])
{
$hash = $this->generateHashForMethod($object, $method, $args);
$data = call_user_func_array([$object, $method], $args);
$this->driver->set($hash, $data);
return $data;
}
/**
* Generate a hash as a cache key from the current method call
*
* @param object $object
* @param string $method
* @param array $args
* @return string
*/
public function generateHashForMethod($object, $method, array $args)
{
$classname = get_class($object);
$keyObj = [
'class' => $classname,
'method' => $method,
'args' => $args,
];
$hash = sha1(json_encode($keyObj));
return $hash;
}
}
// End of CacheManager.php

View File

@ -0,0 +1,110 @@
<?php
/**
* Ion
*
* Building blocks for web development
*
* @package Ion
* @author Timothy J. Warren
* @copyright Copyright (c) 2015 - 2016
* @license MIT
*/
namespace Aviat\Ion\Cache\Driver;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
use Aviat\AnimeClient\Model\DB;
/**
* Driver for caching via a traditional SQL database
*/
class SQLDriver extends DB implements \Aviat\Ion\Cache\CacheDriverInterface {
/**
* The query builder object
* @var object $db
*/
protected $db;
/**
* Create the driver object
*/
public function __construct(ContainerInterface $container)
{
parent::__construct($container);
try
{
$this->db = \Query($this->db_config['collection']);
}
catch (\PDOException $e)
{
$this->valid_database = FALSE;
return FALSE;
}
}
/**
* Retreive a value from the cache backend
*
* @param string $key
* @return mixed
*/
public function get($key)
{
$query = $this->db->select('value')
->from('cache')
->where('key', $key)
->get();
$row = $query->fetch(\PDO::FETCH_ASSOC);
if ( ! empty($row))
{
return unserialize($row['value']);
}
return NULL;
}
/**
* Set a cached value
*
* @param string $key
* @param mixed $value
* @return CacheDriverInterface
*/
public function set($key, $value)
{
$this->db->set([
'key' => $key,
'value' => serialize($value),
]);
/*if ( ! empty($this->get($key)))
{
$this->db->update('cache');
}
else*/
{
$this->db->insert('cache');
}
return $this;
}
/**
* Invalidate a cached value
*
* @param string $key
* @return CacheDriverInterface
*/
public function invalidate($key)
{
$this->db->where('key', $key)
->delete('cache');
return $this;
}
}
// End of SQLDriver.php