From 26a352b882b62f324884281ea60ac775c4a0524f Mon Sep 17 00:00:00 2001 From: EriBloo <19932449+EriBloo@users.noreply.github.com> Date: Fri, 11 Oct 2024 07:52:12 +0000 Subject: [PATCH] first idea --- src/CacheObjectsServiceProvider.php | 8 +++ src/Concerns/CacheObjectActions.php | 37 ++++++++++++++ src/Contracts/CacheObject.php | 27 ++++++++++ src/Contracts/CacheObjectDriver.php | 31 ++++++++++++ src/Drivers/LaravelDriver.php | 77 +++++++++++++++++++++++++++++ tests/CacheObjectTest.php | 18 +++++++ tests/Fixtures/BasicCacheObject.php | 32 ++++++++++++ tests/TestCase.php | 9 ++++ 8 files changed, 239 insertions(+) create mode 100644 src/Concerns/CacheObjectActions.php create mode 100644 src/Contracts/CacheObject.php create mode 100644 src/Contracts/CacheObjectDriver.php create mode 100644 src/Drivers/LaravelDriver.php create mode 100644 tests/CacheObjectTest.php create mode 100644 tests/Fixtures/BasicCacheObject.php diff --git a/src/CacheObjectsServiceProvider.php b/src/CacheObjectsServiceProvider.php index 0ea38ec..d1041ea 100644 --- a/src/CacheObjectsServiceProvider.php +++ b/src/CacheObjectsServiceProvider.php @@ -4,6 +4,10 @@ namespace EriBloo\CacheObjects; +use EriBloo\CacheObjects\Contracts\CacheObjectDriver; +use EriBloo\CacheObjects\Drivers\LaravelDriver; +use Illuminate\Contracts\Cache\Store; +use Illuminate\Foundation\Application; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -19,5 +23,9 @@ public function configurePackage(Package $package): void $package ->name('laravel-cache-objects') ->hasConfigFile(); + + $this->app->scoped(CacheObjectDriver::class, function (Application $app) { + return new LaravelDriver($app->make(Store::class)); + }); } } diff --git a/src/Concerns/CacheObjectActions.php b/src/Concerns/CacheObjectActions.php new file mode 100644 index 0000000..f09f29c --- /dev/null +++ b/src/Concerns/CacheObjectActions.php @@ -0,0 +1,37 @@ +make(CacheObjectDriver::class); + + return $driver->set($value, $this); + } + + /** + * @return TValue|null + */ + public function retrieve(): mixed + { + /** @var CacheObjectDriver $driver */ + $driver = app() + ->make(CacheObjectDriver::class); + + return $driver->get($this); + } +} diff --git a/src/Contracts/CacheObject.php b/src/Contracts/CacheObject.php new file mode 100644 index 0000000..eb78ab2 --- /dev/null +++ b/src/Contracts/CacheObject.php @@ -0,0 +1,27 @@ + $cacheObject + */ + public function set(mixed $value, CacheObject $cacheObject): bool; + + /** + * @template TValue + * + * @param CacheObject $cacheObject + * @return TValue|null + */ + public function get(CacheObject $cacheObject): mixed; + + /** + * @template TValue + * + * @param CacheObject $cacheObject + */ + public function delete(CacheObject $cacheObject): bool; +} diff --git a/src/Drivers/LaravelDriver.php b/src/Drivers/LaravelDriver.php new file mode 100644 index 0000000..e2ec121 --- /dev/null +++ b/src/Drivers/LaravelDriver.php @@ -0,0 +1,77 @@ +prepareKey($cacheObject); + $value = $this->prepareValue($value); + $ttl = $this->prepareTtl($cacheObject); + + if ($ttl <= 0) { + return $this->repository->forever($key, $value); + } + + return $this->repository->put($key, $value, $ttl); + } + + public function get(CacheObject $cacheObject): mixed + { + $key = $this->prepareKey($cacheObject); + $value = $this->repository->get($key); + + if ($value === null) { + return null; + } + + return $this->prepareReturn($value); + } + + public function delete(CacheObject $cacheObject): bool + { + return $this->repository->forget($this->prepareKey($cacheObject)); + } + + /** + * @template TValue + * + * @param CacheObject $cacheObject + */ + private function prepareKey(CacheObject $cacheObject): string + { + return $cacheObject->key(); + } + + private function prepareValue(mixed $value): string + { + return serialize($value); + } + + private function prepareReturn(string $value): mixed + { + return unserialize($value); + } + + /** + * @template TValue + * + * @param CacheObject $cacheObject + */ + private function prepareTtl(CacheObject $cacheObject): int + { + return (int) $cacheObject->ttl() + ->totalSeconds; + } +} diff --git a/tests/CacheObjectTest.php b/tests/CacheObjectTest.php new file mode 100644 index 0000000..4567133 --- /dev/null +++ b/tests/CacheObjectTest.php @@ -0,0 +1,18 @@ +store('test'); + + // assert + assertEquals('test', $obj->retrieve()); +}); diff --git a/tests/Fixtures/BasicCacheObject.php b/tests/Fixtures/BasicCacheObject.php new file mode 100644 index 0000000..275a586 --- /dev/null +++ b/tests/Fixtures/BasicCacheObject.php @@ -0,0 +1,32 @@ + + */ +final readonly class BasicCacheObject implements CacheObject +{ + /** @use CacheObjectActions */ + use CacheObjectActions; + + public function __construct( + public string $value, + ) {} + + public function key(): string + { + return "basic-cache-object:{$this->value}"; + } + + public function ttl(): CarbonInterval + { + return CarbonInterval::seconds(0); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index ad8497d..5351f78 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,7 +4,11 @@ namespace EriBloo\CacheObjects\Tests; +use Cache; use EriBloo\CacheObjects\CacheObjectsServiceProvider; +use EriBloo\CacheObjects\Contracts\CacheObjectDriver; +use EriBloo\CacheObjects\Drivers\LaravelDriver; +use Illuminate\Cache\ArrayStore; use Illuminate\Database\Eloquent\Factories\Factory; use Orchestra\Testbench\TestCase as Orchestra; @@ -19,6 +23,11 @@ protected function setUp(): void $modelName, ) . 'Factory', ); + + $store = new ArrayStore; + $this->app?->instance('store', $store); + $this->app?->instance(CacheObjectDriver::class, new LaravelDriver($store)); + Cache::spy(); } protected function getPackageProviders($app)