diff --git a/composer.json b/composer.json index fddef60..be8a119 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,8 @@ "nette/di": "^3.1 || ^4.0", "latte/latte": "^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.12" diff --git a/src/Bridges/Psr/PsrCacheAdapter.php b/src/Bridges/Psr/PsrCacheAdapter.php new file mode 100644 index 0000000..f8400cd --- /dev/null +++ b/src/Bridges/Psr/PsrCacheAdapter.php @@ -0,0 +1,120 @@ +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): iterable + { + 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..5b2f9b6 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.get.phpt @@ -0,0 +1,19 @@ +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..3fffc05 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.getMultiple.phpt @@ -0,0 +1,29 @@ +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..806c987 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.has.phpt @@ -0,0 +1,18 @@ +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..147c11d --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.set.phpt @@ -0,0 +1,62 @@ +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_899_805, + ], + ], $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 => 282_016_922, + ], + ], $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_016_922, + ], + ], $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..2197b20 --- /dev/null +++ b/tests/Bridges.Psr/PsrCacheAdapter.setMultiple.phpt @@ -0,0 +1,67 @@ +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_899_805, + ], + ], $storage->read('test1')); + + Assert::same([ + 'data' => '2', + 'dependencies' => [ + Caching\Cache::Expire => 110_899_805, + ], + ], $storage->read('test2')); +}); diff --git a/tests/lock b/tests/lock new file mode 100644 index 0000000..e69de29