diff --git a/composer.json b/composer.json index 0c623ca..56bac76 100644 --- a/composer.json +++ b/composer.json @@ -1,39 +1,40 @@ { - "name": "w7/rangine-cache-model", - "description": "对Laravel框架的Model扩展缓存支持", - "type": "library", - "license": "Apache-2.0", - "authors": [ - { - "name": "RenChao", - "email": "donknap@gmail.com" - } - ], - "require": { - "php": "7.*", - "illuminate/database": "~5.8", - "illuminate/cache": "~5.8", - "illuminate/contracts": "~5.8", - "psr/simple-cache" : "*" - }, - "require-dev": { - "symfony/thanks": "^1.0", - "phpunit/phpunit": "^7.2" - }, - "autoload": { + "name": "w7/rangine-cache-model", + "description": "对Model扩展缓存支持", + "type": "library", + "license": "Apache-2.0", + "authors": [ + { + "name": "GordenSong", + "email": "94581976@qq.com" + } + ], + "require": { + "php": "7.*", + "genealabs/laravel-model-caching": "^0.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^7.2", + "w7/php-cs-fixer": "^1.0" + }, + "autoload": { + "psr-4": { + "W7\\CacheModel\\": "src/" + }, "classmap": [ - - ], - "psr-4": { - "W7\\Laravel\\CacheModel\\": "src/" - }, - "files": [ - "src/helper.php" - ] - }, + "src/Traits/Buildable.php" + ] + }, "autoload-dev": { - "psr-4": { - "W7\\Laravel\\CacheModel\\Tests\\": "tests/" - } - } + "psr-4": { + "W7\\CacheModel\\Tests\\": "tests/" + } + }, + "extra": { + "rangine": { + "providers": [ + "W7\\CacheModel\\CacheModelProvider" + ] + } + } } diff --git a/config/model-cache.php b/config/model-cache.php new file mode 100644 index 0000000..dbd9637 --- /dev/null +++ b/config/model-cache.php @@ -0,0 +1,21 @@ + + * + * document http://s.w7.cc/index.php?c=wiki&do=view&id=317&list=2284 + * + * visited https://www.rangine.com/ for more details + */ + +return [ + 'cache-prefix' => '', + + 'enabled' => true, + + 'use-database-keying' => true, + + 'channel' => '' +]; diff --git a/src/CacheModelProvider.php b/src/CacheModelProvider.php new file mode 100644 index 0000000..9994ab0 --- /dev/null +++ b/src/CacheModelProvider.php @@ -0,0 +1,83 @@ + + * + * document http://s.w7.cc/index.php?c=wiki&do=view&id=317&list=2284 + * + * visited https://www.rangine.com/ for more details + */ + +namespace W7\CacheModel; + +use Illuminate\Cache\CacheManager; +use Illuminate\Container\Container; +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Events\TransactionCommitted; +use Illuminate\Database\Events\TransactionRolledBack; +use W7\Core\Provider\ProviderAbstract; +use Illuminate\Config\Repository; +use W7\CacheModel\Store\CacheStore; + +class CacheModelProvider extends ProviderAbstract { + public function register() { + $this->publishConfig('model-cache.php'); + $this->registerConfig('model-cache.php', 'model-cache'); + $this->registerCommand('model:cache'); + + Container::getInstance()->singleton('config', function () { + $config = $this->config->getUserConfig('model-cache'); + $config['store'] = 'icache'; + + return new Repository([ + 'laravel-model-caching' => $config, + 'cache.stores.icache' => [ + 'driver' => 'icache' + ]]); + }); + Container::getInstance()->singleton('db', function () { + return idb(); + }); + Container::getInstance()->singleton('cache', function ($app) { + return new CacheManager($app); + }); + } + + public function boot() { + $config = $this->config->getUserConfig('model-cache'); + Container::getInstance()->make('cache')->extend('icache', function ($app) use ($config) { + return Container::getInstance()->make('cache')->repository( + new CacheStore( + $config['cache-prefix'], + $config['channel'] + ) + ); + }); + + //放在boot的原因是在boot执行的时候,数据库需要的条件才会准备好 + $this->registerListener(); + } + + private function registerListener() { + //处理在事物中使用缓存问题 + Model::getEventDispatcher()->listen(TransactionCommitted::class, function (TransactionCommitted $instance) { + if ($instance->connection->transactionLevel() !== 0) { + return false; + } + $callbacks = $instance->connection->transCallback; + $instance->connection->transCallback = []; + foreach ((array)$callbacks as $callback) { + is_callable($callback) && $callback(); + } + }); + Model::getEventDispatcher()->listen(TransactionRolledBack::class, function (TransactionRolledBack $instance) { + if ($instance->connection->transactionLevel() !== 0) { + return false; + } + + $instance->connection->transCallback = []; + }); + } +} diff --git a/src/Caches/BatchCache.php b/src/Caches/BatchCache.php deleted file mode 100644 index f11d589..0000000 --- a/src/Caches/BatchCache.php +++ /dev/null @@ -1,187 +0,0 @@ -cache = $cache; - $this->namespace = $namespace; - } - - protected function getCache() - { - return $this->cache; - } - - /** - * @param string $key - * @return string - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function getCacheKey($key) - { - return Tag::getCacheKey($key, $this->namespace); - } - - /** - * @param $key - * @return string - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function getSizeCacheKey($key) - { - return $this->getCacheKey("{$key}:size"); - } - - /** - * @param $key - * @param $index - * @return string - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function getIndexCacheKey($key, $index) - { - return $this->getCacheKey("{$key}:{$index}"); - } - - /** - * @param string $key - * @return int - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function getSize($key) - { - $sizeCacheKey = $this->getSizeCacheKey($key); - - return $this->getCache()->get($sizeCacheKey); - } - - /** - * @param $key - * @param $value - * @param $ttl - * @throws InvalidArgumentException - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function setSize($key, $value, $ttl) - { - $sizeCacheKey = $this->getSizeCacheKey($key); - - $this->getCache()->set($sizeCacheKey, $value, $ttl); - } - - /** - * @param $key - * @param $i - * @param $item - * @param $ttl - * @throws InvalidArgumentException - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function setItem($key, $i, $item, $ttl) - { - $indexCacheKey = $this->getIndexCacheKey($key, $i); - - $this->getCache()->set($indexCacheKey, $item, $ttl); - } - - /** - * @param $key - * @param $index - * @return mixed - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function getItem($key, $index) - { - $indexCacheKey = $this->getIndexCacheKey($key, $index); - - return $this->getCache()->get($indexCacheKey); - } - - /** - * @param string $key - * @param array $array - * @param int|null $ttl - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function set($key, $array, $ttl = null) - { - $size = count($array); - - $this->setSize($key, $size, $ttl); - - $cache = $this->getCache(); - foreach ($array as $index => $item) { - $cacheKey = $this->getIndexCacheKey($key, $index); - - $cache->set($cacheKey, $item, $ttl); - } - } - - /** - * @param $key - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function flush($key) - { - $this->setSize($key, 0, 0); - } - - /** - * 返回值为 false, 数据损坏 - * @param $key - * @return bool|Collection|array - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function get($key) - { - $cacheValue = []; - - $size = $this->getSize($key); - if (empty($size)) { - return null; - } - - $realSize = 0; - for ($i = 0; $i < $size; $i++) { - $cacheItemKey = $this->getIndexCacheKey($key, $i); - $cacheItemValue = $this->getCache()->get($cacheItemKey); - if (empty($cacheItemValue)) { - continue; - } - $realSize++; - $cacheValue[] = $cacheItemValue; - } - - if ($realSize != $size) { - return false; - } - - return $cacheValue; - } - - /** - * @param $key - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function delete($key) - { - $this->getCache()->del($this->getSizeCacheKey($key)); - } -} \ No newline at end of file diff --git a/src/Caches/Cache.php b/src/Caches/Cache.php deleted file mode 100644 index 0b64546..0000000 --- a/src/Caches/Cache.php +++ /dev/null @@ -1,263 +0,0 @@ -set($key, $testObj, 1); - $get = static::$cacheInterfaceSingleton->get($key); - - static::$needSerialize = !is_object($get); - - static::$cacheInterfaceSingleton->delete($key); - } - - return static::$needSerialize; - } - - /** - * @return bool - */ - public static function isImplemented() - { - return !empty(static::$cacheInterfaceSingleton); - } - - /** - * @return CacheInterface - * @throws InvalidArgumentException - */ - public static function getCacheResolver() - { - if (!static::$cacheInterfaceSingleton instanceof CacheInterface) { - throw new InvalidArgumentException('使用 Model Cache 必须先调用 \W7\Laravel\CacheModel\Caches\Cache::setCacheResolver($cache)'); - } - return static::$cacheInterfaceSingleton; - } - - /** - * @var static - */ - private static $singleton; - - /** - * 获取单例 - * @return Cache - */ - public static function singleton() - { - return static::$singleton ?? (static::$singleton = new static()); - } - - /** - * @return CacheInterface - * @throws InvalidArgumentException - */ - public function getCache() - { - return static::getCacheResolver(); - } - - /** - * Serialize the value. - * - * @param mixed $value - * @return mixed - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function serialize($value) - { - if (!static::needSerialize()) { - return $value; - } - return serialize($value); - } - - /** - * Unserialize the value. - * - * @param mixed $value - * @return mixed - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function unserialize($value) - { - if (!static::needSerialize()) { - return $value; - } - return unserialize($value); - } - - protected function isValidData($var) - { - return is_numeric($var) || is_object($var) || is_null($var); - } - - /** - * @param $key - * @param $value - * @param null $ttl - * @throws InvalidArgumentException - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function set($key, $value, $ttl = null) - { - $value = $this->serialize($value); - - $this->getCache()->set($key, $value, $ttl ?? static::FOREVER); - } - - /** - * @param $key - * @return mixed - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function get($key) - { - $value = $this->getCache()->get($key); - - $value = $this->unserialize($value); - - // jd($key, $value); - - if ($this->isValidData($value)) { - return $value; - } else { - return null; - } - } - - /** - * 没有模型也可能有缓存,防止缓存击穿 - * @param string $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function has($key) - { - return $this->getCache()->has($key); - } - - /** - * @param string $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function del($key) - { - return $this->getCache()->delete($key); - } - - /** - * 清空当前表的缓存 - * @param string $namespace - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function flush($namespace = '') - { - Tag::flush($namespace); - } - - /** - * @param string $key - * @param stdClass|null $model - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function setModel($key, $model) - { - $model = $model ?? static::NULL; - - $this->set($key, $model); - } - - /** - * 获取缓存中键为 $key 的记录 - * @param $key - * @return stdClass|null - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function getModel($key) - { - $model = $this->get($key); - if ($model === static::NULL) { - $model = null; - } - return $model; - } - - /** - * @param string $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function delModel($key) - { - return $this->del($key); - } - - /** - * 缓存中是否存在主键为 key 的记录 - * @param $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function hasModel($key) - { - $model = $this->getModel($key); - - return !empty($model); - } -} \ No newline at end of file diff --git a/src/Caches/Tag.php b/src/Caches/Tag.php deleted file mode 100644 index e1678a3..0000000 --- a/src/Caches/Tag.php +++ /dev/null @@ -1,117 +0,0 @@ -del(static::getRootNamespace($namespace)); - } - - private static function getRootNamespace($namespace) - { - return join(':', [static::PREFIX, $namespace]); - } - - /** - * 获取缓存的键值 - * @param $key - * @param $namespace - * @return string - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public static function getCacheKey($key, $namespace) - { - $namespace = static::getRootNamespace($namespace); - - $pieces = explode(':', $namespace); - - $cacheKey = static::getPrefix($pieces) . ':' . $key; - - return $cacheKey; - } - - /** - * a:b:c:d - * - * a => k1 - * a:b => k2 - * a:b:c => k3 - * - * a:b:c:N => (a:b:c):N => k3:N => cache get - * - * @param $pieces - * @return mixed - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public static function getPrefix($pieces) - { - // $cache = Cache::singleton(); - $cache = Cache::getCacheResolver(); - - $length = count($pieces); - for ($i = 0; $i < $length; $i++) { - $key = Tag::joinPieces($pieces, $i + 1); - $value = $cache->get($key); - - if (empty($value)) { - // 'a:b' - $pre_key = Tag::joinPieces($pieces, $i);// 'a' - $pre_value = $cache->get($pre_key) ?? '';// 'a' => value - - $suffix = $pieces[$i];// 'b' - - $value = static::hash($pre_value, $suffix); - $cache->set($key, $value, Cache::FOREVER); - } - } - - return $cache->get(join(':', $pieces)); - } - - /** - * 前 n 个元素用 ':' 拼接 - * @param $pieces - * @param $n - * @return string - */ - private static function joinPieces($pieces, $n) - { - $length = count($pieces); - $array = []; - for ($i = 0; $i < $n && $n >= 0 && $n <= $length; $i++) { - $array[] = $pieces[$i]; - } - return join(':', $array); - } - - /** - * @param mixed ...$contents - * @return string - */ - private static function hash(...$contents) - { - $params = func_get_args(); - $params[] = str_random(8); - - return md5(uniqid(join(':', $params))); - } -} \ No newline at end of file diff --git a/src/Command/ClearCommand.php b/src/Command/ClearCommand.php new file mode 100644 index 0000000..e72c5b3 --- /dev/null +++ b/src/Command/ClearCommand.php @@ -0,0 +1,96 @@ + + * + * document http://s.w7.cc/index.php?c=wiki&do=view&id=317&list=2284 + * + * visited https://www.rangine.com/ for more details + */ + +namespace W7\CacheModel\Command; + +use Illuminate\Container\Container; +use Illuminate\Support\Collection; +use Symfony\Component\Console\Input\InputOption; +use W7\Console\Command\CommandAbstract; + +class ClearCommand extends CommandAbstract { + protected $description = 'Flush cache for a given model. If no model is given, entire model-cache is flushed.'; + + protected function configure() { + $this->addOption('--model', null, InputOption::VALUE_REQUIRED, 'model full name'); + } + + protected function handle($options) { + $option = $options['model']; + + go(function () use ($option) { + if (!$option) { + if ($this->output->confirm('clear all model cache?')) { + return $this->flushEntireCache(); + } + $this->output->error("option model Can't be empty"); + return false; + } + + return $this->flushModelCache($option); + }); + } + + protected function flushEntireCache() : int { + $config = Container::getInstance() + ->make('config') + ->get('laravel-model-caching.store'); + + Container::getInstance() + ->make('cache') + ->store($config) + ->flush(); + + $this->output->info('✔︎ Entire model cache has been flushed.'); + + return 0; + } + + protected function flushModelCache(string $option) : int { + $model = new $option; + $usesCachableTrait = $this->getAllTraitsUsedByClass($option) + ->contains("GeneaLabs\LaravelModelCaching\Traits\Cachable"); + + if (! $usesCachableTrait) { + $this->output->error("'{$option}' is not an instance of CachedModel."); + $this->output->warning('Only CachedModel instances can be flushed.'); + + return 1; + } + + $model->flushCache(); + $this->output->info("✔︎ Cache for model '{$option}' has been flushed."); + + return 0; + } + + /** @SuppressWarnings(PHPMD.BooleanArgumentFlag) */ + protected function getAllTraitsUsedByClass( + string $classname, + bool $autoload = true + ) : Collection { + $traits = collect(); + + if (class_exists($classname, $autoload)) { + $traits = collect(class_uses($classname, $autoload)); + } + + $parentClass = get_parent_class($classname); + + if ($parentClass) { + $traits = $traits + ->merge($this->getAllTraitsUsedByClass($parentClass, $autoload)); + } + + return $traits; + } +} diff --git a/src/EloquentBuilder.php b/src/EloquentBuilder.php deleted file mode 100644 index d6e22d7..0000000 --- a/src/EloquentBuilder.php +++ /dev/null @@ -1,82 +0,0 @@ -cacheModel = $cacheModel; - } - - /** - * @return Model - */ - public function getCacheModel() - { - return $this->cacheModel; - } - - public function needCache() - { - if (!empty($this->cacheModel)) { - return $this->getCacheModel()->needCache(); - } - return false; - } - - /** - * @var BatchCache - */ - protected $batchCache = null; - - public function __construct(QueryBuilder $query) - { - parent::__construct($query); - - $this->batchCache = new BatchCache(Cache::singleton()); - } - - /** - * @param $cacheKey - * @param null $ttl - * @param array $columns - * @return \Illuminate\Database\Eloquent\Collection - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheGet($cacheKey, $ttl = null, $columns = ['*']) - { - $builder = $this->applyScopes(); - - $models = $this->batchCache->get($cacheKey); - if (empty($models)) { - if (count($models = $builder->getModels($columns)) > 0) { - $models = $builder->eagerLoadRelations($models); - - $this->batchCache->set($cacheKey, $models, $ttl); - } - } - - return $builder->getModel()->newCollection($models); - } -} \ No newline at end of file diff --git a/src/Exceptions/CacheKeyNotExistsException.php b/src/Exceptions/CacheKeyNotExistsException.php deleted file mode 100644 index f6f2301..0000000 --- a/src/Exceptions/CacheKeyNotExistsException.php +++ /dev/null @@ -1,16 +0,0 @@ -useCache && Cache::isImplemented(); - } - - /** - * 获取表的缓存命名空间 - * @return string - */ - public function getCacheModelNamespace() - { - return ($this->getConnectionName() ?: 'default') . ':' . $this->getTable(); - } - - /** - * 清空表的缓存 - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public static function flush() - { - Tag::flush((new static())->getCacheModelNamespace()); - } - - /** - * 清空某个键的缓存,所有的键都在 batch_cache 名称空间下 - * @param $key - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public static function BatchFlush($key) - { - $batchCache = new BatchCache(Cache::singleton()); - $batchCache->flush($key); - } - - - /** - * @param \Illuminate\Database\Query\Builder $query - * @return Builder|EloquentBuilder|static - */ - public function newEloquentBuilder($query) - { - $builder = new EloquentBuilder($query); - $builder->setCacheModel($this); - - return $builder; - } - - /** - * @return \Illuminate\Database\Query\Builder|QueryBuilder - */ - protected function newBaseQueryBuilder() - { - $connection = $this->getConnection(); - $grammar = $connection->getQueryGrammar(); - $processor = $connection->getPostProcessor(); - - $queryBuilder = new QueryBuilder($connection, $grammar, $processor); - $queryBuilder->setCacheModel($this); - - return $queryBuilder; - } -} \ No newline at end of file diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php deleted file mode 100644 index 9f967b4..0000000 --- a/src/QueryBuilder.php +++ /dev/null @@ -1,306 +0,0 @@ -cacheModel = $cacheModel; - } - - /** - * @return Model - */ - public function getCacheModel() - { - return $this->cacheModel; - } - - public function needCache() - { - if (!empty($this->cacheModel)) { - return $this->getCacheModel()->needCache(); - } - return false; - } - - /** - * @return Cache - */ - public function getCacheResolver() - { - return Cache::singleton(); - } - - /** - * @param $key - * @param $model - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheSetModel($key, $model) - { - $key = $this->getCacheKey($key); - - $this->getCacheResolver()->setModel($key, $model); - } - - /** - * @param $key - * @return \stdClass|null - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheGetModel($key) - { - $key = $this->getCacheKey($key); - - return $this->getCacheResolver()->getModel($key); - } - - /** - * @param $key - * @return \stdClass|null - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheDelModel($key) - { - $key = $this->getCacheKey($key); - - return $this->getCacheResolver()->getModel($key); - } - - /** - * @param $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheHasModel($key) - { - $key = $this->getCacheKey($key); - - return $this->getCacheResolver()->hasModel($key); - } - - /** - * @param $key - * @return bool - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function cacheHasKey($key) - { - $key = $this->getCacheKey($key); - - return $this->getCacheResolver()->has($key); - } - - /** - * 获取缓存的键 - * @param $key - * @return string - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function getCacheKey($key) - { - $cacheKey = Tag::getCacheKey($key, $this->getCacheModel()->getCacheModelNamespace()); - if (Cache::needSerialize()) { - $cacheKey = unserialize($cacheKey); - } - return $cacheKey; - } - - /** - * @param array $values - * @param null $sequence - * @return int - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function insertGetId(array $values, $sequence = null) - { - try { - $id = parent::insertGetId($values, $sequence); - return $id; - } finally { - if ($this->needCache() && !empty($id)) { - $this->cacheDelModel($id); - } - } - } - - /** - * @param null $id - * @return int - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function delete($id = null) - { - try { - return parent::delete($id); - } finally { - if ($this->getCacheModel()->exists && $this->needCache()) { - $this->cacheDelModel($id ?? $this->getCacheModel()->getKey()); - } - } - } - - /** - * @param array $values - * @return int - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - public function update(array $values) - { - try { - return parent::update($values); - } finally { - if ($this->getCacheModel()->exists && $this->needCache()) { - $this->cacheDelModel($this->cacheModel->getKey()); - } - } - } - - /** - * 是否未定义列名 - * @return bool - */ - protected function isColumnsUndefined() - { - return $this->columns == ['*']; - } - - /** - * Model::query()->find($id); - * @return bool - */ - protected function isFindOneQuery() - { - if (count($this->wheres) == 1 && ($current = current($this->wheres))) { - return $current['type'] == 'Basic' - && $current['column'] == $this->cacheModel->getQualifiedKeyName() - && $current['operator'] == '=' - // && !empty($current['value']) - && $current['boolean'] == 'and'; - } - return false; - } - - /** - * Model::query()->find($ids); - * @return bool - */ - protected function isFindManyQuery() - { - if (count($this->wheres) == 1 && ($current = current($this->wheres))) { - return $current['type'] == 'In' - && $current['column'] == $this->cacheModel->getQualifiedKeyName() - && is_array($current['values']) - && $current['boolean'] == 'and'; - } - return false; - } - - /** - * 获取查询主键 - * - * @return \Illuminate\Support\Collection - */ - protected function getFindQueryPrimaryKeyValues() - { - $current = current($this->wheres); - if ($this->isFindOneQuery()) { - $ids = [$current['value']]; - } else { - $ids = $current['values']; - } - return collect($ids); - } - - protected function isFindQuery() - { - return $this->isFindOneQuery() || $this->isFindManyQuery(); - } - - protected function cacheFindFirst() - { - return $this->isFindQuery() - && $this->isColumnsUndefined() - && $this->needCache(); - } - - /** - * @return array - * @throws \Psr\SimpleCache\InvalidArgumentException - */ - protected function runSelect() - { - $cacheFindFirst = $this->cacheFindFirst(); - if ($cacheFindFirst) { - - $ids = $this->getFindQueryPrimaryKeyValues(); - - try { - $ids->each(function ($id) { - if (!$this->cacheHasKey($id)) { - throw new CacheKeyNotExistsException('cache missing'); - } - }); - - $rows = $ids->map(function ($id) { - return $this->cacheGetModel($id); - })->filter(function ($row) { - return !empty($row); - }); - - if ($rows->count() > 0) { - return $rows->toArray(); - } else { - return null; - } - } catch (CacheKeyNotExistsException $e) { - // 防止缓存击穿 - // jd($e->getMessage()); - $e->getMessage(); - } - } - - $rows = $this->connection->select( - $this->toSql(), $this->getBindings(), !$this->useWritePdo - ); - - if ($cacheFindFirst) { - $primaryKey = $this->getCacheModel()->getKeyName(); - foreach ($rows as $row) { - $this->cacheSetModel($row->{$primaryKey}, $row); - } - if (!empty($ids)) { - $ids->each(function ($id) { - if (!$this->cacheHasKey($id)) { - $this->cacheSetModel($id, null); - } - }); - } - } - - return $rows; - } - - -} \ No newline at end of file diff --git a/src/Store/CacheStore.php b/src/Store/CacheStore.php new file mode 100644 index 0000000..1c8aa4d --- /dev/null +++ b/src/Store/CacheStore.php @@ -0,0 +1,278 @@ + + * + * document http://s.w7.cc/index.php?c=wiki&do=view&id=317&list=2284 + * + * visited https://www.rangine.com/ for more details + */ + +namespace W7\CacheModel\Store; + +use Illuminate\Cache\RedisTaggedCache; +use Illuminate\Cache\TaggableStore; +use Illuminate\Cache\TagSet; + +class CacheStore extends TaggableStore { + protected $prefix; + protected $connection; + + /** + * Create a new store. + * + * @param string $prefix + * @param string $connection + * @return void + */ + public function __construct($prefix = '', $connection = 'default') { + if (empty($connection)) { + $connection = 'default'; + } + $this->setPrefix($prefix); + $this->setConnection($connection); + } + + /** + * Retrieve an item from the cache by key. + * + * @param string|array $key + * @return mixed + */ + public function get($key) { + return $this->connection()->get($this->prefix.$key); + } + + /** + * Retrieve multiple items from the cache by key. + * + * Items not found in the cache will have a null value. + * + * @param array $keys + * @return array + */ + public function many(array $keys) { + $values = $this->connection()->getMultiple(array_map(function ($key) { + return $this->prefix.$key; + }, $keys)); + + return $values; + } + + /** + * Store an item in the cache for a given number of seconds. + * + * @param string $key + * @param mixed $value + * @param int $seconds + * @return bool + */ + public function put($key, $value, $seconds) { + return (bool) $this->connection()->setex( + $this->prefix.$key, + (int) max(1, $seconds), + $this->serialize($value) + ); + } + + /** + * Store multiple items in the cache for a given number of seconds. + * + * @param array $values + * @param int $seconds + * @return bool + */ + public function putMany(array $values, $seconds) { + $this->connection()->multi(); + + $manyResult = null; + + foreach ($values as $key => $value) { + $result = $this->put($key, $value, $seconds); + + $manyResult = is_null($manyResult) ? $result : $result && $manyResult; + } + + $this->connection()->exec(); + + return $manyResult ?: false; + } + + /** + * Store an item in the cache if the key doesn't exist. + * + * @param string $key + * @param mixed $value + * @param int $seconds + * @return bool + */ + public function add($key, $value, $seconds) { + $lua = "return redis.call('exists',KEYS[1])<1 and redis.call('setex',KEYS[1],ARGV[2],ARGV[1])"; + + return (bool) $this->connection()->eval( + $lua, + 1, + $this->prefix.$key, + $this->serialize($value), + (int) max(1, $seconds) + ); + } + + /** + * Increment the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function increment($key, $value = 1) { + return $this->connection()->incrby($this->prefix.$key, $value); + } + + /** + * Decrement the value of an item in the cache. + * + * @param string $key + * @param mixed $value + * @return int + */ + public function decrement($key, $value = 1) { + return $this->connection()->decrby($this->prefix.$key, $value); + } + + /** + * Store an item in the cache indefinitely. + * + * @param string $key + * @param mixed $value + * @return bool + */ + public function forever($key, $value) { + return (bool) $this->connection()->set($this->prefix.$key, $value); + } + + /** + * Get a lock instance. + * + * @param string $name + * @param int $seconds + * @param string|null $owner + * @return \Illuminate\Contracts\Cache\Lock + */ + public function lock($name, $seconds = 0, $owner = null) { + } + + /** + * Restore a lock instance using the owner identifier. + * + * @param string $name + * @param string $owner + * @return \Illuminate\Contracts\Cache\Lock + */ + public function restoreLock($name, $owner) { + return $this->lock($name, 0, $owner); + } + + /** + * Remove an item from the cache. + * + * @param string $key + * @return bool + */ + public function forget($key) { + return (bool) $this->connection()->del($this->prefix.$key); + } + + /** + * Remove all items from the cache. + * + * @return bool + */ + public function flush() { + $this->connection()->clear(); + + return true; + } + + /** + * Begin executing a new tags operation. + * + * @param array|mixed $names + * @return \Illuminate\Cache\RedisTaggedCache + */ + public function tags($names) { + return new RedisTaggedCache( + $this, + new TagSet($this, is_array($names) ? $names : func_get_args()) + ); + } + + /** + * Get the Redis connection instance. + * + * @return \Predis\ClientInterface + */ + public function connection() { + return icache()->channel($this->connection); + } + + /** + * Set the connection name to be used. + * + * @param string $connection + * @return void + */ + public function setConnection($connection) { + $this->connection = $connection; + } + + /** + * Get the Redis database instance. + * + * @return \Illuminate\Contracts\Redis\Factory + */ + public function getRedis() { + return icache(); + } + + /** + * Get the cache key prefix. + * + * @return string + */ + public function getPrefix() { + return $this->prefix; + } + + /** + * Set the cache key prefix. + * + * @param string $prefix + * @return void + */ + public function setPrefix($prefix) { + $this->prefix = ! empty($prefix) ? $prefix.':' : ''; + } + + /** + * Serialize the value. + * + * @param mixed $value + * @return mixed + */ + protected function serialize($value) { + return is_numeric($value) ? $value : serialize($value); + } + + /** + * Unserialize the value. + * + * @param mixed $value + * @return mixed + */ + protected function unserialize($value) { + return is_numeric($value) ? $value : unserialize($value); + } +} diff --git a/src/Traits/Buildable.php b/src/Traits/Buildable.php new file mode 100644 index 0000000..e56b399 --- /dev/null +++ b/src/Traits/Buildable.php @@ -0,0 +1,324 @@ + + * + * document http://s.w7.cc/index.php?c=wiki&do=view&id=317&list=2284 + * + * visited https://www.rangine.com/ for more details + */ + +namespace GeneaLabs\LaravelModelCaching\Traits; + +use Illuminate\Container\Container; + +trait Buildable { + public function avg($column) { + if (! $this->isCachable()) { + return parent::avg($column); + } + + $cacheKey = $this->makeCacheKey(['*'], null, "-avg_{$column}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function count($columns = '*') { + if (! $this->isCachable()) { + return parent::count($columns); + } + + $cacheKey = $this->makeCacheKey([$columns], null, '-count'); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + /** + * @SuppressWarnings(PHPMD.ShortVariable) + */ + public function find($id, $columns = ['*']) { + if (! $this->isCachable()) { + return parent::find($id, $columns); + } + + $idKey = collect($id) + ->implode('_'); + $preStr = is_array($id) + ? 'find_list' + : 'find'; + $columns = collect($columns)->toArray(); + $cacheKey = $this->makeCacheKey($columns, null, "-{$preStr}_{$idKey}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function first($columns = ['*']) { + if (! $this->isCachable()) { + return parent::first($columns); + } + + $columns = collect($columns)->toArray(); + $cacheKey = $this->makeCacheKey($columns, null, '-first'); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function get($columns = ['*']) { + if (! $this->isCachable()) { + return parent::get($columns); + } + + $columns = collect($columns)->toArray(); + $cacheKey = $this->makeCacheKey($columns); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function inRandomOrder($seed = '') { + $this->isCachable = false; + + return parent::inRandomOrder($seed); + } + + public function max($column) { + if (! $this->isCachable()) { + return parent::max($column); + } + + $cacheKey = $this->makeCacheKey(['*'], null, "-max_{$column}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function min($column) { + if (! $this->isCachable()) { + return parent::min($column); + } + + $cacheKey = $this->makeCacheKey(['*'], null, "-min_{$column}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function paginate( + $perPage = null, + $columns = ['*'], + $pageName = 'page', + $page = null + ) { + if (! $this->isCachable()) { + return parent::paginate($perPage, $columns, $pageName, $page); + } + + $page = Container::getInstance() + ->make('request') + ->input($pageName) + ?: $page + ?: 1; + + if (is_array($page)) { + $page = $this->recursiveImplodeWithKey($page); + } + $columns = collect($columns)->toArray(); + $cacheKey = $this->makeCacheKey($columns, null, "-paginate_by_{$perPage}_{$pageName}_{$page}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + protected function recursiveImplodeWithKey(array $items, string $glue = '_') : string { + $result = ''; + + foreach ($items as $key => $value) { + $result .= $glue . $key . $glue . $value; + } + + return $result; + } + + public function pluck($column, $key = null) { + if (! $this->isCachable()) { + return parent::pluck($column, $key); + } + + $keyDifferentiator = "-pluck_{$column}" . ($key ? "_{$key}" : ''); + $cacheKey = $this->makeCacheKey([$column], null, $keyDifferentiator); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function sum($column) { + if (! $this->isCachable()) { + return parent::sum($column); + } + + $cacheKey = $this->makeCacheKey(['*'], null, "-sum_{$column}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function value($column) { + if (! $this->isCachable()) { + return parent::value($column); + } + + $cacheKey = $this->makeCacheKey(['*'], null, "-value_{$column}"); + + return $this->cachedValue(func_get_args(), $cacheKey); + } + + public function cachedValue(array $arguments, string $cacheKey) { + $method = debug_backtrace()[1]['function']; + $cacheTags = $this->makeCacheTags(); + $hashedCacheKey = sha1($cacheKey); + $result = $this->retrieveCachedValue( + $arguments, + $cacheKey, + $cacheTags, + $hashedCacheKey, + $method + ); + + return $this->preventHashCollision( + $result, + $arguments, + $cacheKey, + $cacheTags, + $hashedCacheKey, + $method + ); + } + + protected function preventHashCollision( + array $result, + array $arguments, + string $cacheKey, + array $cacheTags, + string $hashedCacheKey, + string $method + ) { + if ($result['key'] === $cacheKey) { + return $result['value']; + } + + $this->cache() + ->tags($cacheTags) + ->forget($hashedCacheKey); + + return $this->retrieveCachedValue( + $arguments, + $cacheKey, + $cacheTags, + $hashedCacheKey, + $method + ); + } + + protected function retrieveCachedValue( + array $arguments, + string $cacheKey, + array $cacheTags, + string $hashedCacheKey, + string $method + ) { + if (property_exists($this, 'model')) { + $this->checkCooldownAndRemoveIfExpired($this->model); + } + + if (method_exists($this, 'getModel')) { + $this->checkCooldownAndRemoveIfExpired($this->getModel()); + } + + return $this->cache($cacheTags) + ->rememberForever( + $hashedCacheKey, + function () use ($arguments, $cacheKey, $method) { + return [ + 'key' => $cacheKey, + 'value' => parent::{$method}(...$arguments), + ]; + } + ); + } + + public function delete() { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->cache($this->makeCacheTags()) + ->flush(); + }; + } else { + $this->cache($this->makeCacheTags()) + ->flush(); + } + + return parent::delete(); + } + + public function insert(array $values) { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->checkCooldownAndFlushAfterPersisting($this->model); + }; + } else { + $this->checkCooldownAndFlushAfterPersisting($this->model); + } + + return parent::insert($values); + } + + public function increment($column, $amount = 1, array $extra = []) { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->cache($this->makeCacheTags()) + ->flush(); + }; + } else { + $this->cache($this->makeCacheTags()) + ->flush(); + } + + return parent::decrement($column, $amount, $extra); + } + + public function decrement($column, $amount = 1, array $extra = []) { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->cache($this->makeCacheTags()) + ->flush(); + }; + } else { + $this->cache($this->makeCacheTags()) + ->flush(); + } + + return parent::decrement($column, $amount, $extra); + } + + public function update(array $values) { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->checkCooldownAndFlushAfterPersisting($this->model); + }; + } else { + $this->checkCooldownAndFlushAfterPersisting($this->model); + } + + return parent::update($values); + } + + public function forceDelete() { + if ($this->getConnection()->transactionLevel() > 0) { + $this->getConnection()->transCallback[] = function () { + $this->cache($this->makeCacheTags()) + ->flush(); + }; + } else { + $this->cache($this->makeCacheTags()) + ->flush(); + } + + return parent::forceDelete(); + } +} diff --git a/src/helper.php b/src/helper.php deleted file mode 100644 index 61cdda3..0000000 --- a/src/helper.php +++ /dev/null @@ -1,67 +0,0 @@ -make($abstract, $parameters); - } -} - -if (!function_exists('jd')) { - function jd(...$vars) - { - $option = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE; - $traces = debug_backtrace(); - - $args = [ - "{$traces[0]['file']}:{$traces[0]['line']}", - ]; - foreach ($vars as $var) { - if ($var instanceof \Illuminate\Database\Eloquent\Model || - $var instanceof \Illuminate\Database\Eloquent\Collection) { - $args[] = $var->toJson($option); - } else { - $args[] = json_encode($var, $option); - } - } - dd(...$args); - } -} - -if (!function_exists('ll')) { - /** - * 不退出打印 - * @param $var - * @param array ...$moreVars - */ - function ll($var, ...$moreVars) - { - $traces = debug_backtrace(); - - VarDumper::dump("{$traces[0]['file']}:{$traces[0]['line']}"); - VarDumper::dump($var); - foreach ($moreVars as $v) { - VarDumper::dump($v); - } - } -} \ No newline at end of file diff --git a/tests/Models/App.php b/tests/Models/App.php deleted file mode 100644 index 2f4e2bc..0000000 --- a/tests/Models/App.php +++ /dev/null @@ -1,21 +0,0 @@ -hasOne(MemberCount::class, 'uid', 'uid'); - } - - public function apps() - { - return $this->hasMany(App::class, 'uid', 'uid'); - } -} \ No newline at end of file diff --git a/tests/Models/MemberCount.php b/tests/Models/MemberCount.php deleted file mode 100644 index 84646ef..0000000 --- a/tests/Models/MemberCount.php +++ /dev/null @@ -1,23 +0,0 @@ -hasOne(MemberCount::class, 'uid', 'uid'); - } - - public function apps() - { - return $this->hasMany(App::class, 'uid', 'uid'); - } -} \ No newline at end of file diff --git a/tests/Models/Text.php b/tests/Models/Text.php deleted file mode 100644 index e314b45..0000000 --- a/tests/Models/Text.php +++ /dev/null @@ -1,18 +0,0 @@ -hasOne(MemberCount::class, 'uid', 'uid'); - } -} \ No newline at end of file diff --git a/tests/OriginModels/MemberCount.php b/tests/OriginModels/MemberCount.php deleted file mode 100644 index 7dc378a..0000000 --- a/tests/OriginModels/MemberCount.php +++ /dev/null @@ -1,21 +0,0 @@ -container(); - $this->db($container); - - ini_set('date.timezone', 'Asia/Shanghai'); - } - - protected function container() - { - $container = Container::getInstance(); - Facade::setFacadeApplication($container); - $config = [ - 'app' => [ - 'local_test' => false, - ], - - 'services' => [ - 'uc' => [ - //'key' => 'HSIjQgVTWpcia9Mz1iDdMdHHijomUeUPOny3EnX4fSrgE5WBTbQLO01A1gec2i', - 'key' => 'ddejcV9K0Bbbdrdi8e6R6ueY6n8r0Tbn5g9J9g4c1B5m8mcZ0Ndc4Zfp4p51f94f', - 'api' => 'http://bbs.w7.cc/uc_server', -// 'key' => 'ddejcV9K0Bbbdrdi8e6R6ueY6n8r0Tbn5g9J9g4c1B5m8mcZ0Ndc4Zfp4p51f94f', -// 'api' => 'http://127.0.0.1:8888/uc_server', - 'appid' => 2, - ], - ], - - 'cache' => [ - 'default' => env('CACHE_DRIVER', 'redis'), - 'stores' => [ - 'redis' => [ - 'driver' => 'redis', - 'connection' => 'default', - ], - ], - ], - - 'database' => [ - 'redis' => [ - 'client' => 'predis', - 'default' => [ - 'host' => env('REDIS_HOST', '127.0.0.1'), - 'password' => env('REDIS_PASSWORD', null), - 'port' => env('REDIS_PORT', 6379), - 'database' => 0, - 'read_write_timeout' => 0,//new - 'persistent' => 1, - ], - ], - ], - ]; - - $container['config'] = new Repository($config); - $container['config']['app.env'] = 'testing'; - - $container['events'] = new Dispatcher(); - - return $container; - } - - protected function db(Container $container) - { - $manager = new Manager($container); - $manager->setAsGlobal(); - - // 本地数据库 - $manager->addConnection([ - 'driver' => 'mysql', - 'host' => '172.16.1.13', - 'database' => 'we7_addons', - 'username' => 'root', - 'password' => '123456', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => 'ims_', - ]); - - $manager->addConnection([ - 'driver' => 'mysql', - 'host' => '172.16.1.13', - 'database' => 'we7_addons', - 'username' => 'root', - 'password' => '123456', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => 'ims_', - ], '13'); - - $manager->addConnection([ - 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'we7_prox', - 'username' => 'root', - 'password' => 'root', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => 'ims_', - ], 'local'); - - $manager->addConnection([ - 'driver' => 'mysql', - 'host' => 'localhost', - 'database' => 'we7_prox', - 'username' => 'root', - 'password' => 'root', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => 'ims_', - ], 'prox'); - - $manager->addConnection([ - 'driver' => 'mysql', - 'host' => '172.16.1.13', - 'database' => 'we7_discuz_gbk', - 'username' => 'root', - 'password' => '123456', - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', - 'prefix' => 'pre_', - - ], 'bbs'); - $manager->bootEloquent(); - - $container['app'] = $container; - $container->singleton('db', function () use ($manager) { - return $manager->getDatabaseManager(); - }); - - $container->singleton('cache', function ($app) { - return new CacheManager($app); - }); - - $container->singleton('cache.store', function ($app) { - return $app['cache']->driver(); - }); - - $container->singleton('redis', function ($app) { - $config = $app->make('config')->get('database.redis'); - - return new RedisManager(Arr::pull($config, 'client', 'predis'), $config); - }); - - $container->bind('redis.connection', function ($app) { - return $app['redis']->connection(); - }); - - // $event = new Dispatcher($container); - // $manager->setEventDispatcher($event); - - Manager::listen(function ($query, $bindings = null, $time = null, $connectionName = null) { - if ($query instanceof \Illuminate\Database\Events\QueryExecuted) { - $bindings = $query->bindings; - $time = $query->time; - $connection = $query->connection; - $query = $query->sql; - echo $query . PHP_EOL; - } - }); - - } -} \ No newline at end of file diff --git a/tests/TestModel.php b/tests/TestModel.php deleted file mode 100644 index 9cb5fa2..0000000 --- a/tests/TestModel.php +++ /dev/null @@ -1,322 +0,0 @@ -set('a', 123); - jd($cache->get('a')); - } - - public function testImpl() - { - $obj = new \stdClass(); - $obj->name = 'js'; - - $cache = \W7\Laravel\CacheModel\Caches\Cache::getCacheResolver(); - $cache->set('a', $obj, 10); - - jd($cache->get('a')); - } - - public function testCache() - { - // $key = '384942644ebcd01d369fc1194b4d7362:1'; - - $obj = new \stdClass(); - $obj->name = 'js';; - - $key = 'aa'; - - $value = $obj; - - $cache = \W7\Laravel\CacheModel\Caches\Cache::singleton(); - $cache->set($key, $value); - - $model = $cache->get($key); - jd($model); - } - - public function testTag() - { - $tag = new Tag(); - $key = Tag::getCacheKey(1, 'default:members'); - jd($key); - } - - public function testSave() - { - $text = new Text(); - $text->content = time().''; - $text->save(); - - jd($text); - } - - public function testA() - { - jd(join(':', [])); - } - - public function testFind() - { - // Member::flush(); - - $uid =2; - $user = Member::query()->find($uid); - $user = Member::query()->find($uid); - jd($user); - } - - - public function testFinds() - { - // Member::flush(); - - $uid = [1, 2, 5]; - Member::query()->find($uid); - $users = Member::query()->find($uid); - - jd($users); - } - - public function testMObile() - { - $uid = [1, 2, 5]; - MemberCount::query()->find($uid); - $membercount = MemberCount::query()->find($uid); - - jd($membercount); - } - - public function testFindsColumns() - { - $uid = [1, 2, 5]; - $columns = ['uid', 'username']; - Member::query()->find($uid, $columns); - $users = Member::query()->find($uid, $columns); - jd($users); - } - - public function testInsert() - { - $data = [ - 'uid' => 111, - 'username' => 'abc123', - 'password' => 'pwd111', - 'salt' => '123', - 'encrypt' => '123', - ]; - Member::query()->insert($data); - - Member::query()->find(111); - Member::query()->find(111); - jd(); - } - - public function testFlush() - { - ll('find'); - Member::query()->find(1); - ll('flush'); - Member::flush(); - ll('find'); - Member::query()->find(1); - ll('find'); - Member::query()->find(1); - } - - /** - */ - public function testSelect() - { - Member::flush(); - echo 'select query run once', PHP_EOL; - Member::query()->find(1); - Member::query()->find(1); - echo PHP_EOL; - - Member::flush(); - echo 'select query run twice', PHP_EOL; - Member::query()->find([1, 5], ['uid', 'username']); - Member::query()->find([1, 5], ['uid', 'username']); - echo PHP_EOL; - - Member::flush(); - echo 'select query run once', PHP_EOL; - Member::query()->find([1, 5]); - Member::query()->find([1, 5]); - echo PHP_EOL; - - Member::flush(); - echo 'select query run twice', PHP_EOL; - Member::query()->find([1, 2, 3, 4, 5], ['uid'])->keyBy('uid'); - Member::query()->find([1, 2, 3, 4, 5], ['uid'])->keyBy('uid'); - echo PHP_EOL; - - Member::flush(); - echo 'select query run once', PHP_EOL; - Member::query()->find([1, 2, 3, 4, 5])->keyBy('uid'); - Member::query()->find([1, 2, 3, 4, 5])->keyBy('uid'); - echo PHP_EOL; - - Member::flush(); - echo 'select query run 3 times', PHP_EOL; - Member::query()->find([1, 2, 3, 4, 5], ['uid'])->keyBy('uid'); - Member::query()->find([1, 2, 3, 4, 5], ['uid'])->keyBy('uid'); - Member::query()->find([1, 2, 3, 4, 5])->keyBy('uid'); - Member::query()->find([1, 2, 3, 4, 5])->keyBy('uid'); - $this->assertTrue(true); - } - - /** - */ - public function testSelectModelExist() - { - $uid = 123456; - - $user = Member::query()->find($uid); - $this->assertTrue(!empty($user)); - - echo "member find {$uid} again", PHP_EOL; - $user = Member::query()->find($uid); - $this->assertTrue(!empty($user)); - } - - /** - */ - public function testUpdate() - { - $uid = 1; - - /** - * @var $user Member - */ - $user = Member::query()->find($uid); - $this->assertTrue(!empty($user)); - - $user->invite_code = rand(1, 100000); - $user->save(); - - Member::query()->find($uid); - Member::query()->find($uid); - } - - public function testCreate() - { - $uid = 250050; - DB::table('members')->where('uid', $uid)->delete(); - - Member::query()->find($uid); - - Member::query()->forceCreate([ - 'uid' => 250050, - 'username' => 'cache_model', - 'password' => str_random(8), - 'salt' => str_random(6), - 'encrypt' => str_random(8), - ]); - } - - public function testInsertGetId() - { - $uid = 250050; - - $user = Member::query()->find($uid); - if (!empty($user)) { - $user->delete(); - } - - $value = [ - 'uid' => $uid, - 'username' => 'cache_model', - 'password' => str_random(8), - 'salt' => str_random(6), - 'encrypt' => str_random(8), - ]; - $id = Member::query()->insertGetId($value); - jd('iiid', $id); - } - - private function createUser() - { - $user = Member::query()->forceCreate([ - 'uid' => 250050, - 'username' => 'cache_model', - 'password' => str_random(8), - 'salt' => str_random(6), - 'encrypt' => str_random(8), - ]); - - return $user; - } - - - // public function testInsert() - // { - // $user = Member::query()->newModelInstance([ - // 'uid' => 250050, - // 'username' => 'cache_model', - // 'password' => str_random(8), - // 'salt' => str_random(6), - // 'encrypt' => str_random(8), - // ]); - // $user->save(); - // } - - public function testLL() - { - ll('a', 'b'); - } - - - public function testWith() - { - // Member::cacheFlushAll(); - $uid = 1; - $user = Member::query()->with(['apps'])->find($uid); - } - - public function testFlushAll() - { - Member::query()->find(1); - MemberCount::query()->find(1); - - MemberCount::flush(); - - echo 'select query twice', PHP_EOL; - - Member::query()->find(1); - MemberCount::query()->find(1); - - Member::query()->find(1); - MemberCount::query()->find(1); - } -} \ No newline at end of file diff --git a/tests/TestSerialize.php b/tests/TestSerialize.php deleted file mode 100644 index 1af1d53..0000000 --- a/tests/TestSerialize.php +++ /dev/null @@ -1,29 +0,0 @@ -connect('127.0.0.1', 6379); - echo "Connection to server sucessfully"; - //存储数据到列表中 - $redis->lpush("tutorial-list", "Redis"); - $redis->lpush("tutorial-list", "Mongodb"); - $redis->lpush("tutorial-list", "Mysql"); - // 获取存储的数据并输出 - $arList = $redis->lrange("tutorial-list", 0 ,5); - echo "Stored string in redis"; - print_r($arList); - } -} \ No newline at end of file diff --git a/tests/TestTag.php b/tests/TestTag.php deleted file mode 100644 index 1b43d36..0000000 --- a/tests/TestTag.php +++ /dev/null @@ -1,86 +0,0 @@ -each(function ($value, $index) { - ll($index, $value); - }); - } - - /** - * @throws InvalidArgumentException - */ - public function testBatchCache() - { - $cache_key = 'members_3'; - // $members = Member::query()->take(3)->get(); - // - $cache = new BatchCache(\W7\Laravel\CacheModel\Caches\Cache::singleton()); - // $cache->set($cache_key, $members); - - dd($cache->get($cache_key)); - - } - - public function testGet() - { - // $members = Member::query()->take(3)->get(); - $members = Member::query()->where('uid', '<', 10)->with('memberCount')->cacheGet('aaa', 1); - - jd($members->keyBy('uid')); - } - - /** - * @throws InvalidArgumentException - */ - public function testFlush() - { - \W7\Laravel\CacheModel\Caches\Cache::singleton()->getCache()->clear();; - // Member::batchFlush('aaa');; - } -} \ No newline at end of file