use crate::types::{
CacheConfig, DataValue, IdType, QueryCondition, QueryConditionGroup, QueryConditionGroupWithConfig, QueryConditionWithConfig, QueryOptions,
SortDirection,
};
use rat_logger::debug;
use std::vec::Vec;
use super::cache_manager::{CACHE_KEY_PREFIX, CacheManager};
impl CacheManager {
pub(crate) fn generate_cache_key(&self, table: &str, id: &IdType, operation: &str) -> String {
let id_str = match id {
IdType::Number(n) => n.to_string(),
IdType::String(s) => s.clone(),
};
format!("{}:{}:{}:{}", CACHE_KEY_PREFIX, table, operation, id_str)
}
pub fn generate_query_cache_key(
&self,
table: &str,
conditions: &[QueryConditionWithConfig],
options: &QueryOptions,
) -> String {
let query_signature = self.build_query_signature(options);
let conditions_signature = self.build_conditions_signature(conditions);
let key = format!(
"{}:{}:query:{}:{}:{}",
CACHE_KEY_PREFIX, table, conditions_signature, query_signature, self.config.version
);
debug!("生成查询缓存键: table={}, key={}", table, key);
key
}
pub fn generate_condition_groups_with_config_cache_key(
&self,
table: &str,
condition_groups: &[QueryConditionGroupWithConfig],
options: &QueryOptions,
) -> String {
let query_signature = self.build_query_signature(options);
let groups_signature = self.build_condition_groups_with_config_signature(condition_groups);
let key = format!(
"{}:{}:groups:{}:{}",
CACHE_KEY_PREFIX, table, groups_signature, query_signature
);
debug!("生成条件组合查询缓存键(完整版): table={}, key={}", table, key);
key
}
pub fn generate_condition_groups_cache_key(
&self,
table: &str,
condition_groups: &[QueryConditionGroup],
options: &QueryOptions,
) -> String {
let query_signature = self.build_query_signature(options);
let groups_signature = self.build_condition_groups_signature(condition_groups);
let key = format!(
"{}:{}:groups:{}:{}",
CACHE_KEY_PREFIX, table, groups_signature, query_signature
);
debug!("生成条件组合查询缓存键: table={}, key={}", table, key);
key
}
fn build_query_signature(&self, options: &QueryOptions) -> String {
let mut parts = Vec::new();
if let Some(pagination) = &options.pagination {
parts.push(format!("p{}_{}", pagination.skip, pagination.limit));
}
if !options.sort.is_empty() {
let sort_str = options
.sort
.iter()
.map(|s| {
format!(
"{}{}",
s.field,
match s.direction {
SortDirection::Asc => "a",
SortDirection::Desc => "d",
}
)
})
.collect::<Vec<_>>()
.join(",");
parts.push(format!("s{}", sort_str));
}
if !options.fields.is_empty() {
let proj_str = options.fields.join(",");
parts.push(format!("f{}", proj_str));
}
if parts.is_empty() {
"default".to_string()
} else {
parts.join("_")
}
}
fn build_conditions_signature(&self, conditions: &[QueryConditionWithConfig]) -> String {
if conditions.is_empty() {
return "no_cond".to_string();
}
let mut signature = String::new();
for (i, condition) in conditions.iter().enumerate() {
if i > 0 {
signature.push('_');
}
signature.push_str(&format!(
"{}{:?}{}",
condition.field,
condition.operator,
match &condition.value {
DataValue::String(s) => s.clone(), DataValue::Int(n) => n.to_string(),
DataValue::Float(f) => f.to_string(),
DataValue::Bool(b) => b.to_string(),
_ => "val".to_string(),
}
));
}
signature
}
fn build_condition_groups_with_config_signature(&self, condition_groups: &[QueryConditionGroupWithConfig]) -> String {
if condition_groups.is_empty() {
return "no_groups".to_string();
}
let mut signature = String::new();
for (i, group) in condition_groups.iter().enumerate() {
if i > 0 {
signature.push('_');
}
match group {
QueryConditionGroupWithConfig::Single(condition) => {
signature.push_str(&format!(
"s{}{:?}{}{}",
condition.field,
condition.operator,
if condition.case_insensitive { "ci" } else { "cs" },
match &condition.value {
DataValue::String(s) => s.clone(),
DataValue::Int(n) => n.to_string(),
DataValue::Float(f) => f.to_string(),
DataValue::Bool(b) => b.to_string(),
_ => "val".to_string(),
}
));
}
QueryConditionGroupWithConfig::GroupWithConfig {
conditions,
operator,
} => {
signature.push_str(&format!("g{:?}_", operator));
for (j, condition) in conditions.iter().enumerate() {
if j > 0 {
signature.push('|');
}
match condition {
QueryConditionGroupWithConfig::Single(cond) => {
signature.push_str(&format!(
"{}{:?}{}{}",
cond.field,
cond.operator,
if cond.case_insensitive { "ci" } else { "cs" },
match &cond.value {
DataValue::String(s) => s.clone(),
DataValue::Int(n) => n.to_string(),
DataValue::Float(f) => f.to_string(),
DataValue::Bool(b) => b.to_string(),
_ => "val".to_string(),
}
));
}
QueryConditionGroupWithConfig::GroupWithConfig { .. } => {
signature.push_str("nested");
}
}
}
}
}
}
signature
}
fn build_condition_groups_signature(&self, condition_groups: &[QueryConditionGroup]) -> String {
if condition_groups.is_empty() {
return "no_groups".to_string();
}
let mut signature = String::new();
for (i, group) in condition_groups.iter().enumerate() {
if i > 0 {
signature.push('_');
}
match group {
QueryConditionGroup::Single(condition) => {
signature.push_str(&format!(
"s{}{:?}{}",
condition.field,
condition.operator,
match &condition.value {
DataValue::String(s) => s.clone(), DataValue::Int(n) => n.to_string(),
DataValue::Float(f) => f.to_string(),
DataValue::Bool(b) => b.to_string(),
_ => "val".to_string(),
}
));
}
QueryConditionGroup::Group {
conditions,
operator,
} => {
signature.push_str(&format!("g{:?}_", operator));
for (j, condition) in conditions.iter().enumerate() {
if j > 0 {
signature.push('|');
}
match condition {
QueryConditionGroup::Single(cond) => {
signature.push_str(&format!(
"{}{:?}{}",
cond.field,
cond.operator,
match &cond.value {
DataValue::String(s) => s.clone(),
DataValue::Int(n) => n.to_string(),
DataValue::Float(f) => f.to_string(),
DataValue::Bool(b) => b.to_string(),
_ => "val".to_string(),
}
));
}
QueryConditionGroup::Group { .. } => {
signature.push_str("nested");
}
}
}
}
}
}
signature
}
}