From 6789f8ae7a51c1232ce4d07ff968c5d36b3dd0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Mat=C4=9Bj=C4=8Dek?= Date: Mon, 3 Jun 2024 14:11:34 +0200 Subject: [PATCH] added PSR-16 adapter (#77) --- composer.json | 3 +- src/Bridges/Psr/PsrCacheAdapter.php | 116 ++++++++++++++++++ tests/Bridges.Psr/PsrCacheAdapter.get.phpt | 20 +++ .../PsrCacheAdapter.getMultiple.phpt | 30 +++++ tests/Bridges.Psr/PsrCacheAdapter.has.phpt | 19 +++ tests/Bridges.Psr/PsrCacheAdapter.set.phpt | 63 ++++++++++ .../PsrCacheAdapter.setMultiple.phpt | 68 ++++++++++ 7 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 src/Bridges/Psr/PsrCacheAdapter.php create mode 100644 tests/Bridges.Psr/PsrCacheAdapter.get.phpt create mode 100644 tests/Bridges.Psr/PsrCacheAdapter.getMultiple.phpt create mode 100644 tests/Bridges.Psr/PsrCacheAdapter.has.phpt create mode 100644 tests/Bridges.Psr/PsrCacheAdapter.set.phpt create mode 100644 tests/Bridges.Psr/PsrCacheAdapter.setMultiple.phpt diff --git a/composer.json b/composer.json index 11ea140..077ef06 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "nette/di": "^3.1 || ^4.0", "latte/latte": "^2.11 || ^3.0.12", "tracy/tracy": "^2.9", - "phpstan/phpstan": "^1.0" + "phpstan/phpstan": "^1.0", + "psr/simple-cache": "^2.0 || ^3.0" }, "conflict": { "latte/latte": ">=3.0.0 <3.0.12" diff --git a/src/Bridges/Psr/PsrCacheAdapter.php b/src/Bridges/Psr/PsrCacheAdapter.php new file mode 100644 index 0000000..e06ea06 --- /dev/null +++ b/src/Bridges/Psr/PsrCacheAdapter.php @@ -0,0 +1,116 @@ +storage->read($key) ?? $default; + } + + + public function set(string $key, mixed $value, null|int|DateInterval $ttl = null): bool + { + $dependencies = []; + if ($ttl !== null) { + $dependencies[Nette\Caching\Cache::Expire] = self::ttlToSeconds($ttl); + } + + $this->storage->write($key, $value, $dependencies); + + return true; + } + + + public function delete(string $key): bool + { + $this->storage->remove($key); + return true; + } + + + public function clear(): bool + { + $this->storage->clean([Nette\Caching\Cache::All => true]); + return true; + } + + + /** + * @return \Generator + */ + public function getMultiple(iterable $keys, mixed $default = null): \Generator + { + foreach ($keys as $name) { + yield $name => $this->get($name, $default); + } + } + + + /** + * @param iterable $values + */ + public function setMultiple(iterable $values, null|int|DateInterval $ttl = null): bool + { + $ttl = self::ttlToSeconds($ttl); + + foreach ($values as $key => $value) { + $this->set((string) $key, $value, $ttl); + } + + return true; + } + + + public function deleteMultiple(iterable $keys): bool + { + foreach ($keys as $value) { + $this->delete($value); + } + + return true; + } + + + public function has(string $key): bool + { + return $this->storage->read($key) !== null; + } + + + private static function ttlToSeconds(null|int|DateInterval $ttl = null): ?int + { + if ($ttl instanceof DateInterval) { + return self::dateIntervalToSeconds($ttl); + } + + return $ttl; + } + + + private static function dateIntervalToSeconds(DateInterval $dateInterval): int + { + $now = new \DateTimeImmutable; + $expiresAt = $now->add($dateInterval); + return $expiresAt->getTimestamp() - $now->getTimestamp(); + } +} diff --git a/tests/Bridges.Psr/PsrCacheAdapter.get.phpt b/tests/Bridges.Psr/PsrCacheAdapter.get.phpt new file mode 100644 index 0000000..eeea253 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.get.phpt @@ -0,0 +1,20 @@ +get('test')); +}); + +test('get with default', function () { + $cache = new PsrCacheAdapter(new DevNullStorage); + Assert::true($cache->get('test', true)); +}); diff --git a/tests/Bridges.Psr/PsrCacheAdapter.getMultiple.phpt b/tests/Bridges.Psr/PsrCacheAdapter.getMultiple.phpt new file mode 100644 index 0000000..f1751e6 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.getMultiple.phpt @@ -0,0 +1,30 @@ +getMultiple(['test', 'test1'])); + + Assert::same([ + 'test' => null, + 'test1' => null, + ], $x); +}); + +test('get multiple with default', function () { + $cache = new PsrCacheAdapter(new DevNullStorage); + $x = iterator_to_array($cache->getMultiple(['test', 'test1'], true)); + + Assert::same([ + 'test' => true, + 'test1' => true, + ], $x); +}); diff --git a/tests/Bridges.Psr/PsrCacheAdapter.has.phpt b/tests/Bridges.Psr/PsrCacheAdapter.has.phpt new file mode 100644 index 0000000..0893554 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.has.phpt @@ -0,0 +1,19 @@ +set('test1', '1'); + + Assert::true($cache->has('test1')); + Assert::false($cache->has('test2')); +}); diff --git a/tests/Bridges.Psr/PsrCacheAdapter.set.phpt b/tests/Bridges.Psr/PsrCacheAdapter.set.phpt new file mode 100644 index 0000000..4f6fa67 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.set.phpt @@ -0,0 +1,63 @@ +set('test', '1'); + Assert::same([ + 'data' => '1', + 'dependencies' => [], + ], $storage->read('test')); +}); + +test('set ttl int', function () { + $storage = new TestStorage; + $cache = new PsrCacheAdapter($storage); + + $cache->set('test', '2', 1); + Assert::same([ + 'data' => '2', + 'dependencies' => [ + Caching\Cache::Expire => 1, + ], + ], $storage->read('test')); +}); + +test('set ttl DateInterval', function () { + $storage = new TestStorage; + $cache = new PsrCacheAdapter($storage); + + $cache->set('test', '3', new DateInterval('P3Y6M4DT12H30M5S')); + Assert::same([ + 'data' => '3', + 'dependencies' => [ + Caching\Cache::Expire => 110_813_405, + ], + ], $storage->read('test')); + + $cache->set('test', '4', (new DateTime('1978-01-23 05:06:07'))->diff(new DateTime('1986-12-30 07:08:09'))); + Assert::same([ + 'data' => '4', + 'dependencies' => [ + Caching\Cache::Expire => 281_930_522, + ], + ], $storage->read('test')); + + $cache->set('test', '5', (new DateTime('1986-12-30 07:08:09'))->diff(new DateTime('1978-01-23 05:06:07'))); + Assert::same([ + 'data' => '5', + 'dependencies' => [ + Caching\Cache::Expire => -282_103_322, + ], + ], $storage->read('test')); +}); diff --git a/tests/Bridges.Psr/PsrCacheAdapter.setMultiple.phpt b/tests/Bridges.Psr/PsrCacheAdapter.setMultiple.phpt new file mode 100644 index 0000000..3c6e9b8 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.setMultiple.phpt @@ -0,0 +1,68 @@ +setMultiple(['test1' => '1', 'test2' => '2']); + + Assert::same([ + 'data' => '1', + 'dependencies' => [], + ], $storage->read('test1')); + Assert::same([ + 'data' => '2', + 'dependencies' => [], + ], $storage->read('test2')); +}); + +test('set multiple ttl int', function () { + $storage = new TestStorage; + $cache = new PsrCacheAdapter($storage); + + $cache->setMultiple(['test1' => '1', 'test2' => '2'], 1); + + Assert::same([ + 'data' => '1', + 'dependencies' => [ + Caching\Cache::Expire => 1, + ], + ], $storage->read('test1')); + + Assert::same([ + 'data' => '2', + 'dependencies' => [ + Caching\Cache::Expire => 1, + ], + ], $storage->read('test2')); +}); + +test('set multiple ttl DateInterval', function () { + $storage = new TestStorage; + $cache = new PsrCacheAdapter($storage); + + $cache->setMultiple(['test1' => '1', 'test2' => '2'], new DateInterval('P3Y6M4DT12H30M5S')); + Assert::same([ + 'data' => '1', + 'dependencies' => [ + Caching\Cache::Expire => 110_813_405, + ], + ], $storage->read('test1')); + + Assert::same([ + 'data' => '2', + 'dependencies' => [ + Caching\Cache::Expire => 110_813_405, + ], + ], $storage->read('test2')); +});