From 06060a3b927824fef25360db013342a04371d8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Gonz=C3=A1lez?= Date: Mon, 7 Oct 2024 12:41:42 -0600 Subject: [PATCH] enhancement: Support prefixes in Redis connections * Run tests targeting both phpredis and predis --- .github/workflows/run-tests.yml | 8 +++++++- .gitignore | 1 + src/Repositories/RedisRepository.php | 26 ++++++++++++++++++++++++-- tests/ModelQueryTest.php | 13 +++++++++++++ tests/TestCase.php | 8 -------- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index f2e6c326..898af06a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -15,8 +15,11 @@ jobs: os: [ ubuntu-latest ] php: [ 8.3, 8.2, 8.1 ] laravel: [ 11.*, 10.*, 9.* ] + redis-client: [ phpredis, redis ] dependency-version: [ prefer-stable ] include: + - redis-client: phpredis + php-extensions: redis - laravel: 11.* testbench: 9.* - laravel: 10.* @@ -36,7 +39,7 @@ jobs: - 6379:6379 options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3 - name: ${{ matrix.os }} - P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }} + name: ${{ matrix.os }} - P${{ matrix.php }} - L${{ matrix.laravel }} (${{ matrix.redis-client }}) - ${{ matrix.dependency-version }} steps: - name: Checkout code @@ -52,6 +55,7 @@ jobs: uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} + extensions: ${{ matrix.php-extensions }} - name: Install dependencies run: | @@ -60,3 +64,5 @@ jobs: - name: Execute tests run: vendor/bin/pest + env: + REDIS_CLIENT: ${{ matrix.redis-client }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f239481a..f23a2694 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ vendor composer.lock psalm.phar +.idea .php_cs.cache .phpunit.result.cache .php-cs-fixer.cache diff --git a/src/Repositories/RedisRepository.php b/src/Repositories/RedisRepository.php index da4ea3b5..4168a082 100644 --- a/src/Repositories/RedisRepository.php +++ b/src/Repositories/RedisRepository.php @@ -5,6 +5,9 @@ use Closure; use Generator; use Illuminate\Contracts\Redis\Connection; +use Illuminate\Redis\Connections\PhpRedisConnection; +use Illuminate\Redis\Connections\PredisConnection; +use Illuminate\Support\Str; class RedisRepository implements Repository { @@ -30,6 +33,16 @@ public function chunk(string $pattern, int $count): Generator { $cursor = null; + $prefix = match (true) { + $this->redis instanceof PhpRedisConnection => $this->redis->getOption($this->redis->client()::OPT_PREFIX), + $this->redis instanceof PredisConnection => $this->redis->getOptions()->prefix->getPrefix(), + default => null + }; + + if (filled($prefix)) { + $pattern = "{$prefix}{$pattern}"; + } + do { [$cursor, $keys] = $this->redis->scan($cursor, [ 'match' => $pattern, @@ -40,9 +53,18 @@ public function chunk(string $pattern, int $count): Generator return; } - if (! empty($keys)) { - yield $keys; + if (empty($keys)) { + continue; } + + if (filled($prefix)) { + $keys = array_map( + fn (string $key) => Str::after($key, $prefix), + $keys + ); + } + + yield $keys; } while ($cursor !== '0'); } diff --git a/tests/ModelQueryTest.php b/tests/ModelQueryTest.php index 29bb75af..6a243fb7 100644 --- a/tests/ModelQueryTest.php +++ b/tests/ModelQueryTest.php @@ -19,6 +19,19 @@ expect($found->getKey())->toBe($model->getKey()); }); +it('queries existing attributes', function () { + $model = ModelStub::create([ + 'name' => 'John Doe' + ]); + + $found = ModelStub::find($model->getKey()); + + expect($found)->is($model)->toBeTrue(); + expect($found->getKey())->toBe($model->getKey()); + + expect($found->name)->toBe($model->name); +}); + it('returns null when finding by null or empty key', function (?string $key) { ModelStub::create(); diff --git a/tests/TestCase.php b/tests/TestCase.php index 174658ad..acebd44a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -14,12 +14,4 @@ protected function getPackageProviders($app): array { return [ActiveRedisServiceProvider::class]; } - - /** - * Define environment setup. - */ - protected function defineEnvironment($app): void - { - $app['config']->set('database.redis.options.prefix', null); - } }