From 0816a7b598e39db55c13a745865a4c8e6925ec62 Mon Sep 17 00:00:00 2001 From: Peter Gallagher Date: Thu, 22 Aug 2024 15:44:10 +0100 Subject: [PATCH] Add redis database support A redis connection string can have a database number after the port, seperated by a slash. Currently if you try and this in the redis server strings it is not passed in to the client so you can only use database 0. This gets the path and removes the `/` and casts it to an int as all redis dbs are integers. If the path is not a valid numeric it will set it to 0 which is the current behaviour. --- src/Cache/RedisFactory.php | 13 ++++++++++++- test/Cache/RedisFactoryTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/Cache/RedisFactory.php b/src/Cache/RedisFactory.php index 3f9ca15..c0c4971 100644 --- a/src/Cache/RedisFactory.php +++ b/src/Cache/RedisFactory.php @@ -50,8 +50,9 @@ private function normalizeServer(string $server): array $parsedServer = parse_url(trim($server)); if (! is_array($parsedServer)) { throw new InvalidArgumentException(sprintf( - 'Provided server "%s" is not a valid URL with format schema://[[username]:password@]host:port', + 'Provided server "%s" is not a valid URL with format %s', $server, + 'schema://[[username]:password@]host:port/[database]', )); } @@ -73,6 +74,16 @@ private function normalizeServer(string $server): array $parsedServer['password'] = urldecode($pass); } + $database = $parsedServer['path'] ?? null; + unset($parsedServer['path']); + + if ($database !== null) { + /** + * @todo Validate this is an integer and throw an exception if not for the next major version release + */ + $parsedServer['database'] = (int) trim($database, '/'); + } + return $parsedServer; } diff --git a/test/Cache/RedisFactoryTest.php b/test/Cache/RedisFactoryTest.php index c72e302..d06120e 100644 --- a/test/Cache/RedisFactoryTest.php +++ b/test/Cache/RedisFactoryTest.php @@ -157,4 +157,29 @@ public static function provideServersWithCredentials(): iterable 'servers' => ['rediss://1.1.1.1:6379'], ], null, null, SSL::OPTIONS]; } + + #[Test, DataProvider('provideServersWithDatabases')] + public function databaseConfigurationIsApplied( + array $redisConfig, + ?int $expectedDatabase, + ): void { + $this->container->expects($this->once())->method('get')->with('config')->willReturn([ + 'cache' => ['redis' => $redisConfig], + ]); + + $client = ($this->factory)($this->container); + $conn = $client->getConnection(); + + self::assertEquals($expectedDatabase, $conn->getParameters()->database); // @phpstan-ignore-line + } + + public static function provideServersWithDatabases(): iterable + { + yield 'no database' => [[ + 'servers' => ['tcp://1.1.1.1:6379'], + ], null]; + yield 'database' => [[ + 'servers' => ['tcp://1.1.1.1:6379/5'], + ], 5]; + } }