Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/static-analysis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ on:
branches: [ main, develop ]

jobs:
php-cs-fixer:
name: PHP-CS-Fixer
php-code-sniffer:
name: PHP Code Sniffer
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
/clover.xml
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ services:
- '@Macpaw\SchemaContextBundle\Service\BaggageSchemaResolver'
```

Decorate predis client with symfony-bundles/redis-bundle:

```yaml
# config/services.yaml

services:
Macpaw\RedisSchemaBundle\Redis\RedisClientAdapter:
decorates: SymfonyBundles\RedisBundle\Redis\ClientInterface
arguments:
- '@.inner'
- '@Macpaw\SchemaContextBundle\Service\BaggageSchemaResolver'
```

## Usage
Anywhere you use Symfony cache services (injected via CacheInterface or AdapterInterface), your keys will automatically be prefixed based on the current schema.
For example:
Expand Down Expand Up @@ -76,4 +89,3 @@ Feel free to open issues and submit pull requests.

## License
This bundle is released under the MIT license.

8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@
},
"require": {
"php": ">=8.3",
"macpaw/schema-context-bundle": "^1.1",
"macpaw/schema-context-bundle": "^2.0",
"symfony/cache": "^6.4|^7.0"
},
"require-dev": {
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.0",
"squizlabs/php_codesniffer": "3.7.*"
"squizlabs/php_codesniffer": "3.7.*",
"symfony-bundles/redis-bundle": "^3.1"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"suggest": {
"symfony-bundles/redis-bundle": "For predis client key decarations with schema prefix"
},
"scripts": {
"composer-validate": [
"composer validate"
Expand Down
108 changes: 108 additions & 0 deletions src/Redis/RedisClientAdapter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

declare(strict_types=1);

namespace Macpaw\RedisSchemaBundle\Redis;

use Macpaw\SchemaContextBundle\Service\BaggageSchemaResolver;
use Predis\Command\CommandInterface;
use Predis\Command\FactoryInterface;
use Predis\Configuration\OptionsInterface;
use Predis\Connection\ConnectionInterface;
use SymfonyBundles\RedisBundle\Redis\ClientInterface;

class RedisClientAdapter implements ClientInterface
Comment thread
zakhar-huzenko marked this conversation as resolved.
Resolved
{
public function __construct(
private BaggageSchemaResolver $resolver,
private ClientInterface $decorated,
/**
* Method names that should be prefixed with the schema which not present in interfaces
* like a hmget, hset, etc.
*
* @var array<array-key, string>
*/
private readonly array $decoratedCallMethods = [],
) {
}

public function pop(string $key): ?string
{
return $this->decorated->pop($this->prefixKey($key));
}

public function push(string $key, ...$values): int
{
return $this->decorated->push($this->prefixKey($key), ...$values);
}

public function count(string $key): int
{
return $this->decorated->count($this->prefixKey($key));
}

public function remove(string $key): int
{
return $this->decorated->remove($this->prefixKey($key));
}

public function getCommandFactory(): FactoryInterface
{
return $this->decorated->getCommandFactory();
}

public function getOptions(): OptionsInterface
{
return $this->decorated->getOptions();
}

public function connect(): void
{
$this->decorated->connect();
}

public function disconnect(): void
{
$this->decorated->disconnect();
}

public function getConnection(): ConnectionInterface
{
return $this->decorated->getConnection();
}

/**
* @param array<array-key, mixed> $arguments
*/
public function createCommand($method, $arguments = []): CommandInterface
{
return $this->decorated->createCommand($method, $arguments);
}

public function executeCommand(CommandInterface $command): mixed
{
return $this->decorated->executeCommand($command);
}

/**
* @param array<array-key, mixed> $arguments
*/
public function __call($method, $arguments): mixed
{
if (in_array($method, $this->decoratedCallMethods, true)) {
// Automatically prefix the first argument if it's a string
if (array_key_exists(0, $arguments) && is_scalar($arguments[0])) {
$arguments[0] = $this->prefixKey((string) $arguments[0]);
}
}

return $this->decorated->$method(...$arguments);
}

private function prefixKey(string $key): string
{
$schema = $this->resolver->getSchema();

return $schema === $this->resolver->getEnvironmentSchema() ? $key : $schema . '.' . $key;
}
}
18 changes: 10 additions & 8 deletions src/Redis/SchemaAwareRedisAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ public function __construct(
) {
}

private function prefixKey(string $key): string
{
$schema = $this->resolver->getSchema();

return $schema ? $schema . '.' . $key : $key;
}

public function clear(string $prefix = ''): bool
{
return $this->decorated->clear($prefix);
Expand Down Expand Up @@ -98,6 +91,15 @@ public function delete(string $key): bool

public function reset(): void
{
$this->decorated->clear($this->resolver->getSchema() ?? '');
$schema = $this->resolver->getSchema();

$this->decorated->clear($schema === $this->resolver->getEnvironmentSchema() ? '' : $schema);
}

private function prefixKey(string $key): string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: if SchemaAwarePRedisClient and SchemaAwareRedisAdapter are running at the same time, will they not duplicate the prefix?

{
$schema = $this->resolver->getSchema();

return $schema === $this->resolver->getEnvironmentSchema() ? $key : $schema . '.' . $key;
}
}
Loading
Loading