Skip to content

Commit

Permalink
Refactored Store.php to implement the Cache\Store interface instead o…
Browse files Browse the repository at this point in the history
…f overriding DatabaseStore (#18)
  • Loading branch information
spont4e authored Apr 20, 2022
1 parent 8f05706 commit 836c1f0
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 74 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

A MongoDB cache driver for Laravel

| **Laravel<br/>Version** | **Package<br/>Version** | **Install using<br/>this command** |
|-------------------------|-------------------------|------------------------------------------------------|
| **Laravel<br/>Version** | **Package<br/>Version** | **Install using<br/>this command** |
|-------------------------|-------------------------|----------------------------------------------------|
| 5.7.x | 2.11.x | composer require 1ff/laravel-mongodb-cache:~2.11.0 |
| 5.8.x, 6.x | 2.12.x | composer require 1ff/laravel-mongodb-cache:~2.12.0 |
| 7.x | 3.x.x | composer require 1ff/laravel-mongodb-cache:^3.0 |
| 8.x | 4.x.x | composer require 1ff/laravel-mongodb-cache:^4.0 |
| 9.x | 5.x.x | Comming soon |
| 7.x | 3.x.x | composer require 1ff/laravel-mongodb-cache:^3.1 |
| 8.x | 4.x.x | composer require 1ff/laravel-mongodb-cache:^4.1 |
| 9.x | 5.x.x | Comming soon |

Installation
------------
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "1ff/laravel-mongodb-cache",
"description": "A mongodb cache driver for laravel",
"type": "library",
"version": "3.0.0",
"version": "3.1.0",
"require": {
"jenssegers/mongodb": "~3.7",
"illuminate/cache": "^7.0"
Expand All @@ -15,6 +15,10 @@
{
"name": "Vihren Ganev",
"email": "[email protected]"
},
{
"name": "1FF Team",
"homepage": "https://github.com/1FF"
}
],
"minimum-stability": "stable",
Expand Down
210 changes: 142 additions & 68 deletions src/Store.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,78 @@
namespace ForFit\Mongodb\Cache;

use Closure;
use Illuminate\Cache\DatabaseStore;
use Illuminate\Support\InteractsWithTime;
use Illuminate\Cache\RetrievesMultipleKeys;
use Illuminate\Database\ConnectionInterface;
use Illuminate\Contracts\Cache\Store as StoreInterface;
use Jenssegers\Mongodb\Query\Builder;
use MongoDB\BSON\UTCDateTime;
use MongoDB\Driver\Exception\BulkWriteException;

class Store extends DatabaseStore
class Store implements StoreInterface
{
use InteractsWithTime;
use RetrievesMultipleKeys;

/**
* Sets the tags to be used
* The database connection instance.
*
* @param array $tags
* @return MongoTaggedCache
* @var ConnectionInterface
*/
public function tags(array $tags)
protected $connection;

/**
* The name of the cache table.
*
* @var string
*/
protected $table;

/**
* A string that should be prepended to keys.
*
* @var string
*/
protected $prefix;

/**
* Create a new database store.
*
* @param ConnectionInterface $connection
* @param string $table
* @param string $prefix
* @return void
*/
public function __construct(ConnectionInterface $connection, string $table, string $prefix = '')
{
return new MongoTaggedCache($this, $tags);
$this->table = $table;
$this->prefix = $prefix;
$this->connection = $connection;
}

/**
* Retrieve an item from the cache by key.
*
* @param string $key
* @return mixed
* @inheritDoc
*/
public function get($key)
{
$cacheData = $this->table()->where('key', $this->getKeyWithPrefix($key))->first();

return $cacheData ? $this->decodeFromSaved($cacheData['value']) : null;
return $cacheData ? unserialize($cacheData['value']) : null;
}

/**
* Store an item in the cache for a given number of seconds.
*
* @param string $key
* @param mixed $value
* @param float|int $ttl
* @param array|null $tags
* @return bool
* @inheritDoc
*/
public function put($key, $value, $ttl, $tags = [])
public function put($key, $value, $seconds, $tags = [])
{
$expiration = ($this->getTime() + (int) $ttl) * 1000;
$expiration = ($this->currentTime() + (int)$seconds) * 1000;

try {
return (bool) $this->table()->where('key', $this->getKeyWithPrefix($key))->update(
return (bool)$this->table()->where('key', $this->getKeyWithPrefix($key))->update(
[
'value' => $this->encodeForSave($value),
'value' => serialize($value),
'expiration' => new UTCDateTime($expiration),
'tags' => $tags
'tags' => $tags,
],
['upsert' => true]
);
Expand All @@ -62,22 +85,70 @@ public function put($key, $value, $ttl, $tags = [])
}

/**
* Retrieve an item's expiration time from the cache by key.
*
* @param string $key
* @return mixed
* @inheritDoc
*/
public function getExpiration($key)
public function increment($key, $value = 1)
{
$cacheData = $this->table()->where('key', $this->getKeyWithPrefix($key))->first();
return $this->incrementOrDecrement($key, $value, function ($current, $value) {
return $current + $value;
});
}

if (!$cacheData) {
return null;
}
/**
* @inheritDoc
*/
public function decrement($key, $value = 1)
{
return $this->incrementOrDecrement($key, $value, function ($current, $value) {
return $current - $value;
});
}

$expirationSeconds = $cacheData['expiration']->toDateTime()->getTimestamp();
/**
* @inheritDoc
*/
public function forever($key, $value)
{
return $this->put($key, $value, 315360000);
}

return round(($expirationSeconds - time()) / 60);
/**
* @inheritDoc
*/
public function forget($key)
{
$this->table()->where('key', '=', $this->getPrefix() . $key)->delete();

return true;
}

/**
* @inheritDoc
*/
public function flush()
{
$this->table()->delete();

return true;
}

/**
* @inheritDoc
*/
public function getPrefix()
{
return $this->prefix;
}

/**
* Sets the tags to be used
*
* @param array $tags
* @return MongoTaggedCache
*/
public function tags(array $tags)
{
return new MongoTaggedCache($this, $tags);
}

/**
Expand All @@ -94,64 +165,67 @@ public function flushByTags(array $tags)
}

/**
* Increment or decrement an item in the cache.
* Retrieve an item's expiration time from the cache by key.
*
* @param string $key
* @param int $value
* @param Closure $callback
* @return int|bool
* @param string $key
* @return null|float|int
*/
protected function incrementOrDecrement($key, $value, Closure $callback)
public function getExpiration($key)
{
if (isset($this->connection->transaction)) {
return parent::incrementOrDecrement($key, $value, $callback);
}

$currentValue = $this->get($key);
$cacheData = $this->table()->where('key', $this->getKeyWithPrefix($key))->first();

if ($currentValue === null) {
return false;
if (empty($cacheData['expiration'])) {
return null;
}

$newValue = $callback($currentValue, $value);

if ($this->put($key, $newValue, $this->getExpiration($key))) {
return $newValue;
}
$expirationSeconds = $cacheData['expiration']->toDateTime()->getTimestamp();

return false;
return round(($expirationSeconds - $this->currentTime()) / 60);
}

/**
* Format the key to always search for
* Get a query builder for the cache table.
*
* @param string $key
* @return string
* @return Builder
*/
protected function getKeyWithPrefix(string $key)
protected function table()
{
return $this->getPrefix() . $key;
return $this->connection->table($this->table);
}

/**
* Encode data for save
* Format the key to always search for
*
* @param mixed $data
* @param string $key
* @return string
*/
protected function encodeForSave($data)
protected function getKeyWithPrefix(string $key)
{
return serialize($data);
return $this->getPrefix() . $key;
}

/**
* Decode data from save
* Increment or decrement an item in the cache.
*
* @param string $data
* @return mixed
* @param string $key
* @param int $value
* @param Closure $callback
* @return int|bool
*/
protected function decodeFromSaved($data)
protected function incrementOrDecrement($key, $value, Closure $callback)
{
return unserialize($data);
$currentValue = $this->get($key);

if ($currentValue === null) {
return false;
}

$newValue = $callback($currentValue, $value);

if ($this->put($key, $newValue, $this->getExpiration($key))) {
return $newValue;
}

return false;
}
}

0 comments on commit 836c1f0

Please sign in to comment.