use std::sync::Arc;
use redis::{FromRedisValue, RedisResult, ToRedisArgs};
use crate::database::config::{ REDIS_ASYNC_POOL};
pub struct RedisAsync;
impl RedisAsync {
fn pool() -> &'static Arc<deadpool_redis::Pool> {
REDIS_ASYNC_POOL.get().expect("Redis async pool not initialized")
}
pub async fn set<T: ToRedisArgs + Send + Sync>(key: &str, value: &T) -> RedisResult<()> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("SET").arg(key).arg(value).query_async(&mut *conn).await
}
pub async fn set_with_expiry<T: ToRedisArgs + Send + Sync>(key: &str, value: &T, expiry_seconds: u64) -> RedisResult<()> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("SET")
.arg(key)
.arg(value)
.arg("EX")
.arg(expiry_seconds)
.query_async(&mut *conn).await
}
pub async fn set_nx_ex<T: ToRedisArgs + Send + Sync>(key: &str, value: &T, expiry_seconds: u64) -> RedisResult<bool> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
let result: Option<String> = redis::cmd("SET")
.arg(key)
.arg(value)
.arg("NX")
.arg("EX")
.arg(expiry_seconds)
.query_async(&mut *conn).await?;
Ok(result == Some("OK".to_string()))
}
pub async fn get<T: FromRedisValue + Send>(key: &str) -> RedisResult<Option<T>> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("GET").arg(key).query_async(&mut *conn).await
}
pub async fn expire(key: &str, expiry_seconds: i64) -> RedisResult<bool> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
let result: i32 = redis::cmd("EXPIRE").arg(key).arg(expiry_seconds).query_async(&mut *conn).await?;
Ok(result == 1)
}
pub async fn exists(key: &str) -> RedisResult<bool> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
let exists: i32 = redis::cmd("EXISTS").arg(key).query_async(&mut *conn).await?;
Ok(exists == 1)
}
pub async fn del(key: &str) -> RedisResult<i32> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("DEL").arg(key).query_async(&mut *conn).await
}
pub async fn del_vec(keys: &[&str]) -> RedisResult<i32> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("DEL").arg(keys).query_async(&mut *conn).await
}
pub async fn ttl(key: &str) -> RedisResult<i64> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("TTL").arg(key).query_async(&mut *conn).await
}
pub async fn incr(key: &str) -> RedisResult<i64> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("INCR").arg(key).query_async(&mut *conn).await
}
pub async fn decr(key: &str) -> RedisResult<i64> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("DECR").arg(key).query_async(&mut *conn).await
}
pub async fn hset<K: ToRedisArgs + Send + Sync, V: ToRedisArgs + Send + Sync>(key: &str, field: K, value: V) -> RedisResult<()> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("HSET").arg(key).arg(field).arg(value).query_async(&mut *conn).await
}
pub async fn hget<T: FromRedisValue + Send>(key: &str, field: &str) -> RedisResult<Option<T>> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("HGET").arg(key).arg(field).query_async(&mut *conn).await
}
pub async fn lpush<T: ToRedisArgs + Send + Sync>(key: &str, value: T) -> RedisResult<i32> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("LPUSH").arg(key).arg(value).query_async(&mut *conn).await
}
pub async fn rpop(key: &str) -> RedisResult<Option<String>> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("RPOP").arg(key).query_async(&mut *conn).await
}
pub async fn xadd_maxlen<K: ToRedisArgs + Send + Sync, V: ToRedisArgs + Send + Sync>(
key: &str,
maxlen: usize,
field: K,
value: V,
) -> RedisResult<String> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("XADD")
.arg(key)
.arg("MAXLEN")
.arg("~")
.arg(maxlen)
.arg("*")
.arg(field)
.arg(value)
.query_async(&mut *conn)
.await
}
pub async fn xdel<ID: ToRedisArgs + Send + Sync>(key: &str, ids: &[&ID]) -> RedisResult<i32> {
let mut conn = Self::pool().get().await.map_err(|e| {
redis::RedisError::from((redis::ErrorKind::IoError, "Pool error", format!("{:?}", e)))
})?;
redis::cmd("XDEL").arg(key).arg(ids).query_async(&mut *conn).await
}
}