use super::client::RedisBackend;
use super::error::map_redis_error;
use crate::error::{OxCacheError, OxCacheResult};
use crate::security;
use std::time::Duration;
impl RedisBackend {
pub async fn set_many_pipeline(&self, items: &[(&str, Vec<u8>)], ttl: Option<Duration>) -> OxCacheResult<()> {
if items.is_empty() {
return Ok(());
}
for (key, _) in items {
security::validate_redis_key(key)?;
}
if let Some(ttl) = ttl {
let secs = ttl.as_secs();
if secs == 0 {
return Err(OxCacheError::InvalidInput(
"TTL must be at least 1 second for Redis SETEX; sub-second TTL is truncated to 0".to_string(),
));
}
}
let mut conn = self.conn();
let mut pipe = redis::pipe();
for (key, value) in items {
if let Some(ttl) = ttl {
pipe.cmd("SETEX").arg(key).arg(ttl.as_secs()).arg(value.as_slice());
} else {
pipe.cmd("SET").arg(key).arg(value.as_slice());
}
}
pipe.query_async::<()>(&mut conn).await.map_err(map_redis_error)?;
Ok(())
}
pub async fn get_many_pipeline(&self, keys: &[&str]) -> OxCacheResult<Vec<Option<Vec<u8>>>> {
if keys.is_empty() {
return Ok(vec![]);
}
for key in keys {
security::validate_redis_key(key)?;
}
let mut conn = self.conn();
let mut pipe = redis::pipe();
for key in keys {
pipe.cmd("GET").arg(key);
}
let results: Vec<Option<Vec<u8>>> = pipe.query_async(&mut conn).await.map_err(map_redis_error)?;
Ok(results)
}
pub async fn delete_many_pipeline(&self, keys: &[&str]) -> OxCacheResult<()> {
if keys.is_empty() {
return Ok(());
}
for key in keys {
security::validate_redis_key(key)?;
}
let mut conn = self.conn();
let mut pipe = redis::pipe();
for key in keys {
pipe.cmd("DEL").arg(key);
}
pipe.query_async::<()>(&mut conn).await.map_err(map_redis_error)?;
Ok(())
}
}