index/src/Cache/Valkey/ValkeyBackend.php
2024-04-10 22:23:34 +00:00

87 lines
2.7 KiB
PHP

<?php
// ValkeyBackend.php
// Created: 2024-04-10
// Updated: 2024-04-10
namespace Index\Cache\Valkey;
use InvalidArgumentException;
use RuntimeException;
use Index\Cache\{ICacheBackend,ICacheProvider,ICacheProviderInfo};
use Index\Net\{EndPoint,UnixEndPoint};
/**
* Information about the Valkey backend.
*
* Also compatible with Redis and KeyDB.
*/
class ValkeyBackend implements ICacheBackend {
public function isAvailable(): bool {
return extension_loaded('redis');
}
/**
* Creates a Valkey cache provider.
*
* @param ValkeyProviderInfo $providerInfo Valkey provider info.
* @return ValkeyProvider Valkey provider instance.
*/
public function createProvider(ICacheProviderInfo $providerInfo): ICacheProvider {
if(!($providerInfo instanceof ValkeyProviderInfo))
throw new InvalidArgumentException('$providerInfo must by of type ValkeyProviderInfo');
return new ValkeyProvider($providerInfo);
}
/**
* @return ValkeyProviderInfo Valkey provider info instance.
*/
public function parseDsn(string|array $dsn): ICacheProviderInfo {
if(is_string($dsn)) {
$dsn = parse_url($dsn);
if($dsn === false)
throw new InvalidArgumentException('$dsn is not a valid uri.');
}
if(!isset($dsn['host']))
throw new InvalidArgumentException('Host is missing from DSN.');
$host = $dsn['host'];
$isUnix = $host === ':unix';
if(empty($dsn['user'])) {
$username = $password = '';
} else {
if(isset($dsn['pass'])) {
$username = $dsn['user'];
$password = $dsn['pass'];
} else {
$password = $dsn['user'];
$username = '';
}
}
if(!$isUnix) {
if(isset($dsn['port']))
$host .= ':' . $dsn['port'];
$endPoint = EndPoint::parse($host);
}
$prefix = str_replace('/', ':', ltrim($dsn['path'] ?? '', '/'));
parse_str(str_replace('+', '%2B', $dsn['query'] ?? ''), $query);
$unixPath = isset($query['socket']) && is_string($query['socket']) ? $query['socket'] : '';
$dbNumber = isset($query['db']) && is_string($query['db']) && ctype_digit($query['db']) ? (int)$query['db'] : 0;
$persist = isset($query['persist']);
if($isUnix) {
if(empty($unixPath))
throw new InvalidArgumentException('Unix socket path is missing from DSN.');
$endPoint = new UnixEndPoint($unixPath);
}
return new ValkeyProviderInfo($endPoint, $prefix, $persist, $username, $password, $dbNumber);
}
}