Fix restructured datastorage

This commit is contained in:
Dennis Eichhorn 2018-03-01 20:31:02 +01:00
parent b810e72588
commit 24252655eb
25 changed files with 221 additions and 122 deletions

View File

@ -15,6 +15,8 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Cache;
use phpOMS\DataStorage\DataStoragePoolInterface;
use phpOMS\DataStorage\DataStorageConnectionInterface;
use phpOMS\DataStorage\Cache\Connection\ConnectionFactory;
/**
* Cache class.
@ -32,7 +34,7 @@ class CachePool implements DataStoragePoolInterface
/**
* MemCache instance.
*
* @var \phpOMS\DataStorage\Cache\CacheInterface[]
* @var DataStorageConnectionInterface[]
* @since 1.0.0
*/
private $pool = null;
@ -49,14 +51,14 @@ class CachePool implements DataStoragePoolInterface
/**
* Add database.
*
* @param mixed $key Database key
* @param CacheInterface $cache Cache
* @param mixed $key Database key
* @param DataStorageConnectionInterface $cache Cache
*
* @return bool
*
* @since 1.0.0
*/
public function add(string $key, CacheInterface $cache) : bool
public function add(string $key, DataStorageConnectionInterface $cache) : bool
{
if (isset($this->pool[$key])) {
return false;
@ -125,7 +127,7 @@ class CachePool implements DataStoragePoolInterface
return false;
}
$this->pool[$key] = CacheFactory::create($config);
$this->pool[$key] = ConnectionFactory::create($config);
return true;
}

View File

@ -28,7 +28,8 @@ use phpOMS\Stdlib\Base\Enum;
*/
abstract class CacheStatus extends Enum
{
/* public */ const ACTIVE = 0;
/* public */ const INACTIVE = 1;
/* public */ const ERROR = 2;
/* public */ const ACTIVE = 0;
/* public */ const INACTIVE = 1;
/* public */ const ERROR = 2;
/* public */ const UNDEFINED = 3;
}

View File

@ -29,7 +29,8 @@ use phpOMS\Stdlib\Base\Enum;
abstract class CacheType extends Enum
{
/* public */ const FILE = 'file';
/* public */ const MEMCACHED = 'sqlite';
/* public */ const MEMCACHED = 'mem';
/* public */ const REDIS = 'redis';
/* public */ const WINCACHE = 'win';
/* public */ const UNDEFINED = 'na';
}

View File

@ -35,4 +35,5 @@ abstract class CacheValueType extends Enum
/* public */ const _FLOAT = 4; /* Data is float */
/* public */ const _BOOL = 5; /* Data is bool */
/* public */ const _JSONSERIALIZABLE = 6;
/* public */ const _NULL = 7;
}

View File

@ -35,7 +35,7 @@ abstract class ConnectionAbstract implements ConnectionInterface
*
* This can be used externally to define queries and execute them.
*
* @var ConnectionInterface
* @var mixed
* @since 1.0.0
*/
private $con = null;
@ -64,7 +64,7 @@ abstract class ConnectionAbstract implements ConnectionInterface
* @var string
* @since 1.0.0
*/
protected $type = 'undefined';
protected $type = CacheStatus::UNDEFINED;
/**
* Database status.

View File

@ -14,7 +14,7 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\CacheStatus;
use phpOMS\DataStorage\Cache\CacheType;
/**
* Cache connection factory.
@ -24,7 +24,7 @@ use phpOMS\DataStorage\Cache\CacheStatus;
* @link http://website.orange-management.de
* @since 1.0.0
*/
class CacheFactory
class ConnectionFactory
{
/**
@ -44,22 +44,22 @@ class CacheFactory
*
* @param string[] $cacheData the basic cache information for establishing a connection
*
* @return CacheInterface
* @return ConnectionInterface
*
* @throws \InvalidArgumentException Throws this exception if the cache is not supported.
*
* @since 1.0.0
*/
public static function create(array $cacheData) : CacheInterface
public static function create(array $cacheData) : ConnectionInterface
{
switch ($cacheData['type']) {
case CacheStatus::FILE:
case CacheType::FILE:
return new FileCache($cacheData['path']);
case CacheStatus::REDIS:
case CacheType::REDIS:
return new RedisCache($cacheData);
case CacheStatus::MEMCACHED:
case CacheType::MEMCACHED:
return new MemcachedCache($cacheData);
case CacheStatus::WINCACHE:
case CacheType::WINCACHE:
return new WinCache($cacheData);
default:
throw new \InvalidArgumentException('Cache "' . $cacheData['type'] . '" is not supported.');

View File

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Cache\Connection;
use phpOMS\DataStorage\DataStorageConnectionInterface;
use phpOMS\Stdlib\Base\Exception\InvalidEnumValue;
/**
@ -97,19 +98,6 @@ interface ConnectionInterface extends DataStorageConnectionInterface
*/
public function flushAll() : bool;
/**
* Set cache status
*
* @param int $status Cache status
*
* @return void
*
* @throws InvalidEnumValue
*
* @since 1.0.0
*/
public function setStatus(int $status); /* : void */
/**
* Updating existing value/key.
*

View File

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\CacheStatus;
use phpOMS\Stdlib\Base\Exception\InvalidEnumValue;
use phpOMS\System\File\Local\Directory;
use phpOMS\System\File\Local\File;
@ -47,14 +48,6 @@ class FileCache extends ConnectionAbstract
*/
/* private */ const SANITIZE = '~';
/**
* Cache path.
*
* @var string
* @since 1.0.0
*/
private $cachePath = __DIR__ . '/../../../Cache';
/**
* Only cache if data is larger than threshold (0-100).
*
@ -63,14 +56,6 @@ class FileCache extends ConnectionAbstract
*/
private $threshold = 50;
/**
* Cache status.
*
* @var int
* @since 1.0.0
*/
private $status = CacheStatus::ACTIVE;
/**
* Constructor
*
@ -80,11 +65,20 @@ class FileCache extends ConnectionAbstract
*/
public function __construct(string $path)
{
if (!Directory::exists(File::parent($path))) {
if (!Directory::exists($path)) {
Directory::create($path, 0664, true);
}
$this->cachePath = realpath($path);
$this->status = CacheStatus::ACTIVE;
$this->con = realpath($path);
}
/**
* {@inheritdoc}
*/
public function connect(array $dbdata) /* : void */
{
$this->status = CacheStatus::ACTIVE;
}
/**
@ -96,23 +90,11 @@ class FileCache extends ConnectionAbstract
return false;
}
array_map('unlink', glob($this->cachePath . '/*'));
array_map('unlink', glob($this->con . '/*'));
return true;
}
/**
* {@inheritdoc}
*/
public function setStatus(int $status) /* : void */
{
if (!CacheStatus::isValidValue($status)) {
throw new InvalidEnumValue($status);
}
$this->status = $status;
}
/**
* {@inheritdoc}
*/
@ -120,9 +102,9 @@ class FileCache extends ConnectionAbstract
{
$stats = [];
$stats['status'] = $this->status;
$stats['count'] = Directory::count($this->cachePath);
$stats['size'] = Directory::size($this->cachePath);
$stats['changed'] = Directory::changed($this->cachePath);
$stats['count'] = Directory::count($this->con);
$stats['size'] = Directory::size($this->con);
$stats['changed'] = Directory::changed($this->con);
return $stats;
}
@ -147,7 +129,7 @@ class FileCache extends ConnectionAbstract
// todo: allow $key to contain / as char and create subdirectory if necessary. This is important for cleaner caching.
$path = File::sanitize($key, self::SANITIZE);
File::put($this->cachePath . '/' . trim($path, '/') . '.cache', $this->build($value, $expire));
File::put($this->con . '/' . trim($path, '/') . '.cache', $this->build($value, $expire));
}
/**
@ -200,19 +182,21 @@ class FileCache extends ConnectionAbstract
private function dataType($value) : int
{
if (is_int($value)) {
return CacheType::_INT;
return CacheValueType::_INT;
} elseif (is_float($value)) {
return CacheType::_FLOAT;
return CacheValueType::_FLOAT;
} elseif (is_string($value)) {
return CacheType::_STRING;
return CacheValueType::_STRING;
} elseif (is_bool($value)) {
return CacheType::_BOOL;
return CacheValueType::_BOOL;
} elseif (is_array($value)) {
return CacheType::_ARRAY;
return CacheValueType::_ARRAY;
} elseif ($value === null) {
return CacheValueType::_NULL;
} elseif ($value instanceof \Serializable) {
return CacheType::_SERIALIZABLE;
return CacheValueType::_SERIALIZABLE;
} elseif ($value instanceof \JsonSerializable) {
return CacheType::_JSONSERIALIZABLE;
return CacheValueType::_JSONSERIALIZABLE;
}
throw new \InvalidArgumentException('Invalid value');
@ -232,14 +216,16 @@ class FileCache extends ConnectionAbstract
*/
private function stringify($value, int $type) : string
{
if ($type === CacheType::_INT || $type === CacheType::_FLOAT || $type === CacheType::_STRING || $type === CacheType::_BOOL) {
if ($type === CacheValueType::_INT || $type === CacheValueType::_FLOAT || $type === CacheValueType::_STRING || $type === CacheValueType::_BOOL) {
return (string) $value;
} elseif ($type === CacheType::_ARRAY) {
} elseif ($type === CacheValueType::_ARRAY) {
return json_encode($value);
} elseif ($type === CacheType::_SERIALIZABLE) {
} elseif ($type === CacheValueType::_SERIALIZABLE) {
return get_class($value) . self::DELIM . $value->serialize();
} elseif ($type === CacheType::_JSONSERIALIZABLE) {
} elseif ($type === CacheValueType::_JSONSERIALIZABLE) {
return get_class($value) . self::DELIM . $value->jsonSerialize();
} elseif ($type === CacheValueType::_NULL) {
return '';
}
throw new InvalidEnumValue($type);
@ -316,23 +302,26 @@ class FileCache extends ConnectionAbstract
$value = null;
switch ($type) {
case CacheType::_INT:
case CacheValueType::_INT:
$value = (int) substr($raw, $expireEnd + 1);
break;
case CacheType::_FLOAT:
case CacheValueType::_FLOAT:
$value = (float) substr($raw, $expireEnd + 1);
break;
case CacheType::_BOOL:
case CacheValueType::_BOOL:
$value = (bool) substr($raw, $expireEnd + 1);
break;
case CacheType::_STRING:
case CacheValueType::_STRING:
$value = substr($raw, $expireEnd + 1);
break;
case CacheType::_ARRAY:
case CacheValueType::_ARRAY:
$value = json_decode(substr($raw, $expireEnd + 1));
break;
case CacheType::_SERIALIZABLE:
case CacheType::_JSONSERIALIZABLE:
case CacheValueType::_NULL:
$value = null;
break;
case CacheValueType::_SERIALIZABLE:
case CacheValueType::_JSONSERIALIZABLE:
$namespaceStart = strpos($raw, self::DELIM, $expireEnd);
$namespaceEnd = strpos($raw, self::DELIM, $namespaceStart + 1);
$namespace = substr($raw, $namespaceStart, $namespaceEnd);
@ -388,7 +377,7 @@ class FileCache extends ConnectionAbstract
return false;
}
$dir = new Directory($this->cachePath);
$dir = new Directory($this->con);
$now = time();
foreach ($dir as $file) {
@ -437,6 +426,6 @@ class FileCache extends ConnectionAbstract
private function getPath($key) : string
{
$path = File::sanitize($key, self::SANITIZE);
return $this->cachePath . '/' . trim($path, '/') . '.cache';
return $this->con . '/' . trim($path, '/') . '.cache';
}
}

View File

@ -25,6 +25,13 @@ namespace phpOMS\DataStorage\Cache\Connection;
class NullCache extends ConnectionAbstract
{
/**
* {@inheritdoc}
*/
public function connect(array $data) /* : void */
{
}
/**
* {@inheritdoc}
*/

View File

@ -34,7 +34,7 @@ interface DataStorageConnectionInterface
*
* @return void
*
* @todo make private
* @todo make private, reason was that not everyone wants to connect during initialization?!
*
* @since 1.0.0
*/

View File

@ -30,14 +30,14 @@ interface DataStoragePoolInterface
/**
* Add connection.
*
* @param mixed $key Connection key
* @param ConnectionInterface $db Connection
* @param mixed $key Connection key
* @param DataStorageConnectionInterface $db Connection
*
* @return bool
*
* @since 1.0.0
*/
public function add(string $key, ConnectionInterface $db);
public function add(string $key, DataStorageConnectionInterface $db) : bool;
/**
* Get connection.
@ -64,12 +64,12 @@ interface DataStoragePoolInterface
/**
* Create connection.
*
* @param mixed $key Connection key
* @param array $config Connection config data
* @param string $key Connection key
* @param array $config Connection config data
*
* @return bool
*
* @since 1.0.0
*/
public function create($key, array $config) : bool;
public function create(string $key, array $config) : bool;
}

View File

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace phpOMS\DataStorage\Database\Connection;
use phpOMS\DataStorage\DataStorageConnectionInterface;
use phpOMS\DataStorage\Database\Query\Grammar\Grammar;
use phpOMS\DataStorage\Database\Schema\Grammar\Grammar as SchemaGrammar;

View File

@ -48,7 +48,7 @@ class MysqlConnection extends ConnectionAbstract
$this->type = DatabaseType::MYSQL;
$this->grammar = new MysqlGrammar();
$this->schemaGrammar = new MysqlSchemaGrammar();
$this->connect($dbdata);
$this->connect($dbdata); // todo: remove since this is a side effect that doesn't belong to constructor
}
/**

View File

@ -18,6 +18,7 @@ use phpOMS\DataStorage\DataStoragePoolInterface;
use phpOMS\DataStorage\DataStorageConnectionInterface;
use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
use phpOMS\DataStorage\Database\Connection\ConnectionFactory;
use phpOMS\DataStorage\Database\Connection\ConnectionInterface;
/**
* Database pool handler.
@ -50,14 +51,14 @@ class DatabasePool implements DataStoragePoolInterface
/**
* Add database.
*
* @param mixed $key Database key
* @param ConnectionInterface $db Database
* @param mixed $key Database key
* @param DataStorageConnectionInterface $db Database
*
* @return bool
*
* @since 1.0.0
*/
public function add(string $key, ConnectionInterface $db) : bool
public function add(string $key, DataStorageConnectionInterface $db) : bool
{
if (isset($this->pool[$key])) {
return false;
@ -113,14 +114,14 @@ class DatabasePool implements DataStoragePoolInterface
/**
* Create database.
*
* @param mixed $key Database key
* @param array $config Database config data
* @param string $key Database key
* @param array $config Database config data
*
* @return bool
*
* @since 1.0.0
*/
public function create($key, array $config) : bool
public function create(string $key, array $config) : bool
{
if (isset($this->pool[$key])) {
return false;

View File

@ -14,7 +14,7 @@
namespace phpOMS\tests\DataStorage\Cache;
use phpOMS\DataStorage\Cache\CachePool;
use phpOMS\DataStorage\Cache\FileCache;
use phpOMS\DataStorage\Cache\Connection\FileCache;
class CachePoolTest extends \PHPUnit\Framework\TestCase
{
@ -32,12 +32,12 @@ class CachePoolTest extends \PHPUnit\Framework\TestCase
self::assertTrue($pool->add('test', new FileCache(__DIR__)));
self::assertFalse($pool->add('test', new FileCache(__DIR__)));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\CacheInterface', $pool->get('test'));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\Connection\ConnectionInterface', $pool->get('test'));
self::assertTrue($pool->create('abc', ['type' => 'file', 'path' => __DIR__]));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\CacheInterface', $pool->get('abc'));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\Connection\ConnectionInterface', $pool->get('abc'));
self::assertTrue($pool->remove('abc'));
self::assertEquals(null, $pool->get('abc'));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\CacheInterface', $pool->get('test'));
self::assertInstanceOf('\phpOMS\DataStorage\Cache\Connection\ConnectionInterface', $pool->get('test'));
self::assertFalse($pool->remove('abc'));
}
}

View File

@ -19,9 +19,10 @@ class CacheStatusTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(3, count(CacheStatus::getConstants()));
self::assertEquals(4, count(CacheStatus::getConstants()));
self::assertEquals(0, CacheStatus::ACTIVE);
self::assertEquals(1, CacheStatus::INACTIVE);
self::assertEquals(2, CacheStatus::ERROR);
self::assertEquals(3, CacheStatus::UNDEFINED);
}
}

View File

@ -19,13 +19,11 @@ class CacheTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(7, count(CacheType::getConstants()));
self::assertEquals(0, CacheType::_INT);
self::assertEquals(1, CacheType::_STRING);
self::assertEquals(2, CacheType::_ARRAY);
self::assertEquals(3, CacheType::_SERIALIZABLE);
self::assertEquals(4, CacheType::_FLOAT);
self::assertEquals(5, CacheType::_BOOL);
self::assertEquals(6, CacheType::_JSONSERIALIZABLE);
self::assertEquals(5, count(CacheType::getConstants()));
self::assertEquals('file', CacheType::FILE);
self::assertEquals('mem', CacheType::MEMCACHED);
self::assertEquals('redis', CacheType::REDIS);
self::assertEquals('win', CacheType::WINCACHE);
self::assertEquals('na', CacheType::UNDEFINED);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\Connection\CacheValueType;
class CacheValueTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums()
{
self::assertEquals(8, count(CacheValueType::getConstants()));
self::assertEquals(0, CacheValueType::_INT);
self::assertEquals(1, CacheValueType::_STRING);
self::assertEquals(2, CacheValueType::_ARRAY);
self::assertEquals(3, CacheValueType::_SERIALIZABLE);
self::assertEquals(4, CacheValueType::_FLOAT);
self::assertEquals(5, CacheValueType::_BOOL);
self::assertEquals(6, CacheValueType::_JSONSERIALIZABLE);
self::assertEquals(7, CacheValueType::_NULL);
}
}

View File

@ -11,17 +11,17 @@
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\DataStorage\Cache;
namespace phpOMS\tests\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\CacheFactory;
use phpOMS\DataStorage\Cache\Connection\ConnectionFactory;
class CacheFactoryTest extends \PHPUnit\Framework\TestCase
class ConnectionFactoryTest extends \PHPUnit\Framework\TestCase
{
public function testCreate()
{
self::assertInstanceOf(
\phpOMS\DataStorage\Cache\FileCache::class,
CacheFactory::create(['type' => 'file', 'path' => 'Cache'])
\phpOMS\DataStorage\Cache\Connection\FileCache::class,
ConnectionFactory::create(['type' => 'file', 'path' => 'Cache'])
);
}
@ -30,6 +30,6 @@ class CacheFactoryTest extends \PHPUnit\Framework\TestCase
*/
public function testInvalidCacheType()
{
CacheFactory::create(['type' => 'invalid', 'path' => 'Cache']);
ConnectionFactory::create(['type' => 'invalid', 'path' => 'Cache']);
}
}

View File

@ -0,0 +1,77 @@
<?php
/**
* Orange Management
*
* PHP Version 7.1
*
* @package TBD
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\Connection\FileCache;
class FileCacheTest extends \PHPUnit\Framework\TestCase
{
public function testDefault()
{
if (file_exists(__DIR__ . '/Cache')) {
rmdir(__DIR__ . '/Cache');
}
$cache = new FileCache(__DIR__ . '/Cache');
self::assertTrue(is_dir(__DIR__ . '/Cache'));
self::assertTrue($cache->flushAll());
self::assertEquals(50, $cache->getThreshold());
self::assertEquals(null, $cache->get('test'));
if (file_exists(__DIR__ . '/Cache')) {
rmdir(__DIR__ . '/Cache');
}
}
public function testGetSet()
{
if (file_exists(__DIR__ . '/Cache')) {
rmdir(__DIR__ . '/Cache');
}
$cache = new FileCache(__DIR__ . '/Cache');
$cache->set('key1', 'testVal');
self::assertEquals('testVal', $cache->get('key1'));
$cache->set('key2', false);
self::assertEquals(false, $cache->get('key2'));
$cache->set('key3', null);
self::assertEquals(null, $cache->get('key3'));
$cache->set('key4', 4);
self::assertEquals(4, $cache->get('key4'));
$cache->set('key5', 5.12);
self::assertEquals(5.12, $cache->get('key5'));
$cache->set('key6', ['asdf', 1, true, 2.3]);
self::assertEquals(['asdf', 1, true, 2.3], $cache->get('key6'));
$cache->replace('key4', 5);
self::assertEquals(5, $cache->get('key4'));
$cache->delete('key4');
self::assertEquals(null, $cache->get('key4'));
$cache->flushAll();
self::assertEquals(null, $cache->get('key5'));
if (file_exists(__DIR__ . '/Cache')) {
rmdir(__DIR__ . '/Cache');
}
}
}

View File

@ -11,9 +11,9 @@
* @link http://website.orange-management.de
*/
namespace phpOMS\tests\DataStorage\Cache;
namespace phpOMS\tests\DataStorage\Cache\Connection;
use phpOMS\DataStorage\Cache\NullCache;
use phpOMS\DataStorage\Cache\Connection\NullCache;
class NullCacheTest extends \PHPUnit\Framework\TestCase
{