You've already forked AstralRinth
forked from didirus/AstralRinth
Compiler improvements (#753)
* basic redis add * toml; reverted unnecessary changes * merge issues * increased test connections --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use super::models::DatabaseError;
|
||||
use deadpool_redis::{Config, Runtime};
|
||||
use redis::{cmd, FromRedisValue, ToRedisArgs};
|
||||
use itertools::Itertools;
|
||||
use redis::{cmd, Cmd};
|
||||
use std::fmt::Display;
|
||||
|
||||
const DEFAULT_EXPIRY: i64 = 1800; // 30 minutes
|
||||
@@ -11,6 +12,11 @@ pub struct RedisPool {
|
||||
meta_namespace: String,
|
||||
}
|
||||
|
||||
pub struct RedisConnection {
|
||||
pub connection: deadpool_redis::Connection,
|
||||
meta_namespace: String,
|
||||
}
|
||||
|
||||
impl RedisPool {
|
||||
// initiate a new redis pool
|
||||
// testing pool uses a hashmap to mimic redis behaviour for very small data sizes (ie: tests)
|
||||
@@ -35,32 +41,39 @@ impl RedisPool {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn set<T1, T2>(
|
||||
&self,
|
||||
pub async fn connect(&self) -> Result<RedisConnection, DatabaseError> {
|
||||
Ok(RedisConnection {
|
||||
connection: self.pool.get().await?,
|
||||
meta_namespace: self.meta_namespace.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl RedisConnection {
|
||||
pub async fn set(
|
||||
&mut self,
|
||||
namespace: &str,
|
||||
id: T1,
|
||||
data: T2,
|
||||
id: &str,
|
||||
data: &str,
|
||||
expiry: Option<i64>,
|
||||
) -> Result<(), DatabaseError>
|
||||
where
|
||||
T1: Display,
|
||||
T2: ToRedisArgs,
|
||||
{
|
||||
let mut redis_connection = self.pool.get().await?;
|
||||
|
||||
cmd("SET")
|
||||
.arg(format!("{}_{}:{}", self.meta_namespace, namespace, id))
|
||||
.arg(data)
|
||||
.arg("EX")
|
||||
.arg(expiry.unwrap_or(DEFAULT_EXPIRY))
|
||||
.query_async::<_, ()>(&mut redis_connection)
|
||||
.await?;
|
||||
|
||||
) -> Result<(), DatabaseError> {
|
||||
let mut cmd = cmd("SET");
|
||||
redis_args(
|
||||
&mut cmd,
|
||||
vec![
|
||||
format!("{}_{}:{}", self.meta_namespace, namespace, id),
|
||||
data.to_string(),
|
||||
"EX".to_string(),
|
||||
expiry.unwrap_or(DEFAULT_EXPIRY).to_string(),
|
||||
]
|
||||
.as_slice(),
|
||||
);
|
||||
redis_execute(&mut cmd, &mut self.connection).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn set_serialized_to_json<Id, D>(
|
||||
&self,
|
||||
&mut self,
|
||||
namespace: &str,
|
||||
id: Id,
|
||||
data: D,
|
||||
@@ -70,92 +83,116 @@ impl RedisPool {
|
||||
Id: Display,
|
||||
D: serde::Serialize,
|
||||
{
|
||||
self.set(namespace, id, serde_json::to_string(&data)?, expiry)
|
||||
.await
|
||||
self.set(
|
||||
namespace,
|
||||
&id.to_string(),
|
||||
&serde_json::to_string(&data)?,
|
||||
expiry,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get<R, Id>(&self, namespace: &str, id: Id) -> Result<Option<R>, DatabaseError>
|
||||
where
|
||||
Id: Display,
|
||||
R: FromRedisValue,
|
||||
{
|
||||
let mut redis_connection = self.pool.get().await?;
|
||||
|
||||
let res = cmd("GET")
|
||||
.arg(format!("{}_{}:{}", self.meta_namespace, namespace, id))
|
||||
.query_async::<_, Option<R>>(&mut redis_connection)
|
||||
.await?;
|
||||
pub async fn get(
|
||||
&mut self,
|
||||
namespace: &str,
|
||||
id: &str,
|
||||
) -> Result<Option<String>, DatabaseError> {
|
||||
let mut cmd = cmd("GET");
|
||||
redis_args(
|
||||
&mut cmd,
|
||||
vec![format!("{}_{}:{}", self.meta_namespace, namespace, id)].as_slice(),
|
||||
);
|
||||
let res = redis_execute(&mut cmd, &mut self.connection).await?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub async fn get_deserialized_from_json<R, Id>(
|
||||
&self,
|
||||
pub async fn get_deserialized_from_json<R>(
|
||||
&mut self,
|
||||
namespace: &str,
|
||||
id: Id,
|
||||
id: &str,
|
||||
) -> Result<Option<R>, DatabaseError>
|
||||
where
|
||||
Id: Display,
|
||||
R: for<'a> serde::Deserialize<'a>,
|
||||
{
|
||||
Ok(self
|
||||
.get::<String, Id>(namespace, id)
|
||||
.get(namespace, id)
|
||||
.await?
|
||||
.and_then(|x| serde_json::from_str(&x).ok()))
|
||||
}
|
||||
|
||||
pub async fn multi_get<R, T1>(
|
||||
&self,
|
||||
pub async fn multi_get<R>(
|
||||
&mut self,
|
||||
namespace: &str,
|
||||
ids: impl IntoIterator<Item = T1>,
|
||||
ids: impl IntoIterator<Item = impl Display>,
|
||||
) -> Result<Vec<Option<R>>, DatabaseError>
|
||||
where
|
||||
T1: Display,
|
||||
R: FromRedisValue,
|
||||
R: for<'a> serde::Deserialize<'a>,
|
||||
{
|
||||
let mut redis_connection = self.pool.get().await?;
|
||||
let res = cmd("MGET")
|
||||
.arg(
|
||||
ids.into_iter()
|
||||
.map(|x| format!("{}_{}:{}", self.meta_namespace, namespace, x))
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
.query_async::<_, Vec<Option<R>>>(&mut redis_connection)
|
||||
.await?;
|
||||
Ok(res)
|
||||
let mut cmd = cmd("MGET");
|
||||
|
||||
redis_args(
|
||||
&mut cmd,
|
||||
&ids.into_iter()
|
||||
.map(|x| format!("{}_{}:{}", self.meta_namespace, namespace, x))
|
||||
.collect_vec(),
|
||||
);
|
||||
let res: Vec<Option<String>> = redis_execute(&mut cmd, &mut self.connection).await?;
|
||||
Ok(res
|
||||
.into_iter()
|
||||
.map(|x| x.and_then(|x| serde_json::from_str(&x).ok()))
|
||||
.collect())
|
||||
}
|
||||
|
||||
pub async fn delete<T1>(&self, namespace: &str, id: T1) -> Result<(), DatabaseError>
|
||||
pub async fn delete<T1>(&mut self, namespace: &str, id: T1) -> Result<(), DatabaseError>
|
||||
where
|
||||
T1: Display,
|
||||
{
|
||||
let mut redis_connection = self.pool.get().await?;
|
||||
|
||||
cmd("DEL")
|
||||
.arg(format!("{}_{}:{}", self.meta_namespace, namespace, id))
|
||||
.query_async::<_, ()>(&mut redis_connection)
|
||||
.await?;
|
||||
|
||||
let mut cmd = cmd("DEL");
|
||||
redis_args(
|
||||
&mut cmd,
|
||||
vec![format!("{}_{}:{}", self.meta_namespace, namespace, id)].as_slice(),
|
||||
);
|
||||
redis_execute(&mut cmd, &mut self.connection).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_many(
|
||||
&self,
|
||||
&mut self,
|
||||
iter: impl IntoIterator<Item = (&str, Option<String>)>,
|
||||
) -> Result<(), DatabaseError> {
|
||||
let mut cmd = cmd("DEL");
|
||||
let mut any = false;
|
||||
for (namespace, id) in iter {
|
||||
if let Some(id) = id {
|
||||
cmd.arg(format!("{}_{}:{}", self.meta_namespace, namespace, id));
|
||||
redis_args(
|
||||
&mut cmd,
|
||||
[format!("{}_{}:{}", self.meta_namespace, namespace, id)].as_slice(),
|
||||
);
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
|
||||
if any {
|
||||
let mut redis_connection = self.pool.get().await?;
|
||||
cmd.query_async::<_, ()>(&mut redis_connection).await?;
|
||||
redis_execute(&mut cmd, &mut self.connection).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn redis_args(cmd: &mut Cmd, args: &[String]) {
|
||||
for arg in args {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn redis_execute<T>(
|
||||
cmd: &mut Cmd,
|
||||
redis: &mut deadpool_redis::Connection,
|
||||
) -> Result<T, deadpool_redis::PoolError>
|
||||
where
|
||||
T: redis::FromRedisValue,
|
||||
{
|
||||
let res = cmd.query_async::<_, T>(redis).await?;
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user