feat(dal): RedisCacheService - работа с Hash объектами
This commit is contained in:
@@ -1,17 +1,26 @@
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using StackExchange.Redis;
|
||||
using System.Text.Json;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace PARR.DAL.Cache.Services.Base
|
||||
{
|
||||
internal class RedisCacheService : IRedisCacheService
|
||||
{
|
||||
private readonly IDistributedCache cache;
|
||||
private readonly IDatabase redis;
|
||||
|
||||
public RedisCacheService(IDistributedCache cache)
|
||||
public RedisCacheService(
|
||||
IDistributedCache cache,
|
||||
IConnectionMultiplexer connectionMultiplexer
|
||||
)
|
||||
{
|
||||
this.cache = cache;
|
||||
this.redis = connectionMultiplexer.GetDatabase();
|
||||
}
|
||||
|
||||
#region Распределенный кэш IDistributedCache
|
||||
|
||||
public async Task<T?> GetCachedDataAsync<T>(string key)
|
||||
{
|
||||
var jsonData = await cache.GetStringAsync(key);
|
||||
@@ -69,6 +78,85 @@ namespace PARR.DAL.Cache.Services.Base
|
||||
cache.Remove(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Нативные операции Redis, Redis Hash
|
||||
|
||||
public async Task SetHashFieldAsync<T>(string hashKey, string field, T value, TimeSpan? ttl = null)
|
||||
{
|
||||
// меняет одно поле в Hash
|
||||
|
||||
var jsonData = JsonSerializer.Serialize(value);
|
||||
|
||||
// true - поля не было, создалось новое. false - поле было, обновили значение
|
||||
var result = await redis.HashSetAsync(hashKey, field, jsonData);
|
||||
|
||||
// если указан ttl, обновим для всего Hash
|
||||
// если не указан и ранее был создан hashKey, оставит его ttl; а если hashKey не было, то создаст его БЕССРОЧНЫМ!!!
|
||||
if (ttl.HasValue)
|
||||
await SetHashTtlAsync(hashKey, ttl.Value);
|
||||
}
|
||||
|
||||
public async Task<T?> GetHashFieldAsync<T>(string hashKey, string field)
|
||||
{
|
||||
// получить значение поля из Hash
|
||||
var value = await redis.HashGetAsync(hashKey, field);
|
||||
|
||||
if (value.IsNullOrEmpty)
|
||||
return default;
|
||||
|
||||
return JsonSerializer.Deserialize<T>(value);
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, T>> GetAllHashFieldsAsync<T>(string hashKey)
|
||||
{
|
||||
// получить все записи из Hash
|
||||
var objs = await redis.HashGetAllAsync(hashKey);
|
||||
|
||||
if (objs.Length == 0)
|
||||
return new Dictionary<string, T>();
|
||||
|
||||
var result = objs.ToDictionary(
|
||||
t => t.Name.ToString(),
|
||||
t => JsonSerializer.Deserialize<T>(t.Value)
|
||||
);
|
||||
|
||||
return result!;
|
||||
}
|
||||
|
||||
public async Task DeleteHashFieldAsync(string hashKey, string field)
|
||||
{
|
||||
// удалить запись из Hash
|
||||
await redis.HashDeleteAsync(hashKey, field);
|
||||
}
|
||||
|
||||
public async Task<bool> HashFieldExistsAsync(string hashKey, string field)
|
||||
{
|
||||
// есть ли запись в Hash
|
||||
return await redis.HashExistsAsync(hashKey, field);
|
||||
}
|
||||
|
||||
public async Task DeleteHashAsync(string hashKey)
|
||||
{
|
||||
// удалить весь Hash
|
||||
await redis.KeyDeleteAsync(hashKey);
|
||||
}
|
||||
|
||||
public async Task<long> GetHashLengthAsync(string hashKey)
|
||||
{
|
||||
// кол-во записей в hash
|
||||
return await redis.HashLengthAsync(hashKey);
|
||||
}
|
||||
|
||||
public async Task SetHashTtlAsync(string hashKey, TimeSpan ttl)
|
||||
{
|
||||
// Установить ttl для Hash
|
||||
await redis.KeyExpireAsync(hashKey, ttl);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
public string GetKey(string[] keyParts, bool isUseHash = false)
|
||||
{
|
||||
@@ -91,5 +179,7 @@ namespace PARR.DAL.Cache.Services.Base
|
||||
return keyStr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user