use std::hash::{Hash, Hasher};
use std::time::Duration;
#[derive(Debug, Default)]
pub struct CacheKeyBuilder {
parts: Vec<String>,
}
impl CacheKeyBuilder {
pub fn new() -> Self {
Self { parts: Vec::new() }
}
pub fn table(mut self, table: &str) -> Self {
self.parts.push(format!("t:{}", table));
self
}
pub fn condition(mut self, column: &str, value: impl std::fmt::Display) -> Self {
self.parts.push(format!("{}={}", column, value));
self
}
pub fn order(mut self, column: &str, direction: &str) -> Self {
self.parts.push(format!("o:{}:{}", column, direction));
self
}
pub fn limit(mut self, limit: u64) -> Self {
self.parts.push(format!("l:{}", limit));
self
}
pub fn offset(mut self, offset: u64) -> Self {
self.parts.push(format!("off:{}", offset));
self
}
pub fn raw(mut self, part: &str) -> Self {
self.parts.push(part.to_string());
self
}
pub fn build(self) -> String {
self.parts.join(":")
}
pub fn build_hash(self) -> u64 {
use std::collections::hash_map::DefaultHasher;
let key = self.build();
let mut hasher = DefaultHasher::new();
key.hash(&mut hasher);
hasher.finish()
}
}
#[derive(Debug, Clone)]
pub struct CacheOptions {
pub key: Option<String>,
pub ttl: Duration,
pub tags: Vec<String>,
}
impl CacheOptions {
pub fn new(ttl: Duration) -> Self {
Self {
key: None,
ttl,
tags: Vec::new(),
}
}
pub fn with_key(mut self, key: &str) -> Self {
self.key = Some(key.to_string());
self
}
pub fn with_tag(mut self, tag: &str) -> Self {
self.tags.push(tag.to_string());
self
}
pub fn with_tags(mut self, tags: &[&str]) -> Self {
self.tags.extend(tags.iter().map(|s| s.to_string()));
self
}
}
#[derive(Debug, Clone)]
pub struct CacheWarmer {
queries: Vec<WarmQuery>,
}
#[derive(Debug, Clone)]
struct WarmQuery {
key: String,
sql: String,
ttl: Duration,
}
impl CacheWarmer {
pub fn new() -> Self {
Self {
queries: Vec::new(),
}
}
pub fn add_query(mut self, key: &str, sql: &str, ttl: Duration) -> Self {
self.queries.push(WarmQuery {
key: key.to_string(),
sql: sql.to_string(),
ttl,
});
self
}
pub fn query_count(&self) -> usize {
self.queries.len()
}
pub fn queries(&self) -> impl Iterator<Item = (&str, &str, Duration)> {
self.queries
.iter()
.map(|q| (q.key.as_str(), q.sql.as_str(), q.ttl))
}
}
impl Default for CacheWarmer {
fn default() -> Self {
Self::new()
}
}