Skip to content

Commit

Permalink
first idea
Browse files Browse the repository at this point in the history
  • Loading branch information
EriBloo committed Oct 11, 2024
1 parent f5fa794 commit 26a352b
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/CacheObjectsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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));
});
}
}
37 changes: 37 additions & 0 deletions src/Concerns/CacheObjectActions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace EriBloo\CacheObjects\Concerns;

use EriBloo\CacheObjects\Contracts\CacheObjectDriver;

/**
* @template TValue
*/
trait CacheObjectActions
{
/**
* @param TValue $value
*/
public function store(mixed $value): bool
{
/** @var CacheObjectDriver $driver */
$driver = app()
->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);
}
}
27 changes: 27 additions & 0 deletions src/Contracts/CacheObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace EriBloo\CacheObjects\Contracts;

use Carbon\CarbonInterval;

/**
* @template TValue
*/
interface CacheObject
{
public function key(): string;

public function ttl(): CarbonInterval;

/**
* @param TValue $value
*/
public function store(mixed $value): bool;

/**
* @return TValue
*/
public function retrieve(): mixed;
}
31 changes: 31 additions & 0 deletions src/Contracts/CacheObjectDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace EriBloo\CacheObjects\Contracts;

interface CacheObjectDriver
{
/**
* @template TValue
*
* @param TValue $value
* @param CacheObject<TValue> $cacheObject
*/
public function set(mixed $value, CacheObject $cacheObject): bool;

/**
* @template TValue
*
* @param CacheObject<TValue> $cacheObject
* @return TValue|null
*/
public function get(CacheObject $cacheObject): mixed;

/**
* @template TValue
*
* @param CacheObject<TValue> $cacheObject
*/
public function delete(CacheObject $cacheObject): bool;
}
77 changes: 77 additions & 0 deletions src/Drivers/LaravelDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

declare(strict_types=1);

namespace EriBloo\CacheObjects\Drivers;

use EriBloo\CacheObjects\Contracts\CacheObject;
use EriBloo\CacheObjects\Contracts\CacheObjectDriver;
use Illuminate\Contracts\Cache\Store;

final class LaravelDriver implements CacheObjectDriver
{
public function __construct(
private readonly Store $repository,
) {}

public function set(mixed $value, CacheObject $cacheObject): bool
{
$key = $this->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<TValue> $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<TValue> $cacheObject
*/
private function prepareTtl(CacheObject $cacheObject): int
{
return (int) $cacheObject->ttl()
->totalSeconds;
}
}
18 changes: 18 additions & 0 deletions tests/CacheObjectTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

use EriBloo\CacheObjects\Tests\Fixtures\BasicCacheObject;

use function PHPUnit\Framework\assertEquals;

it('stores basic cache object', function () {
// prepare
$obj = new BasicCacheObject('key');

// execute
$obj->store('test');

// assert
assertEquals('test', $obj->retrieve());
});
32 changes: 32 additions & 0 deletions tests/Fixtures/BasicCacheObject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace EriBloo\CacheObjects\Tests\Fixtures;

use Carbon\CarbonInterval;
use EriBloo\CacheObjects\Concerns\CacheObjectActions;
use EriBloo\CacheObjects\Contracts\CacheObject;

/**
* @implements CacheObject<string>
*/
final readonly class BasicCacheObject implements CacheObject
{
/** @use CacheObjectActions<string> */
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);
}
}
9 changes: 9 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
Expand Down

0 comments on commit 26a352b

Please sign in to comment.