fbc_starter/cache/
cache_key_builder.rs1use super::cache_key::{CacheHashKey, CacheKey, ValueType};
28use std::time::Duration;
29
30pub trait CacheKeyBuilder {
31 fn get_prefix(&self) -> Option<&str> {
33 None
34 }
35
36 fn get_tenant(&self) -> Option<&str> {
39 None
40 }
41
42 fn set_tenant_id(&mut self, _tenant_id: u64) {}
44
45 fn get_modular(&self) -> Option<&str> {
47 None
48 }
49
50 fn get_table(&self) -> &str;
52
53 fn get_field(&self) -> Option<&str> {
55 None
56 }
57
58 fn get_value_type(&self) -> ValueType {
60 ValueType::Obj
61 }
62
63 fn get_expire(&self) -> Option<Duration> {
65 None
66 }
67
68 fn get_pattern(&self) -> String {
70 format!("*:{}:*", self.get_table())
71 }
72
73 fn key(&self, uniques: &[&dyn ToString]) -> CacheKey {
79 let key = self.build_key(uniques);
80 assert!(!key.is_empty(), "key 不能为空");
81 CacheKey::new(key, self.get_expire())
82 }
83
84 fn hash_field_key(&self, field: &dyn ToString, uniques: &[&dyn ToString]) -> CacheHashKey {
90 let key = self.build_key(uniques);
91 assert!(!key.is_empty(), "key 不能为空");
92 CacheHashKey::new(key, Some(field.to_string()), self.get_expire())
93 }
94
95 fn hash_key(&self, uniques: &[&dyn ToString]) -> CacheHashKey {
100 let key = self.build_key(uniques);
101 assert!(!key.is_empty(), "key 不能为空");
102 CacheHashKey::new(key, None, self.get_expire())
103 }
104
105 fn build_key(&self, uniques: &[&dyn ToString]) -> String {
109 let mut parts = Vec::new();
110
111 if let Some(prefix) = self.get_prefix() {
113 if !prefix.is_empty() {
114 parts.push(prefix.to_string());
115 }
116 }
117
118 if let Some(tenant) = self.get_tenant() {
120 if !tenant.is_empty() {
121 parts.push(tenant.to_string());
122 }
123 }
124
125 if let Some(modular) = self.get_modular() {
127 if !modular.is_empty() {
128 parts.push(modular.to_string());
129 }
130 }
131
132 let table = self.get_table();
134 assert!(!table.is_empty(), "缓存业务类型不能为空");
135 parts.push(table.to_string());
136
137 if let Some(field) = self.get_field() {
139 if !field.is_empty() {
140 parts.push(field.to_string());
141 }
142 }
143
144 parts.push(self.get_value_type().as_str().to_string());
146
147 for unique in uniques {
149 let value = unique.to_string();
150 if !value.is_empty() {
151 parts.push(value);
152 }
153 }
154
155 parts.join(":")
156 }
157}
158
159#[derive(Debug, Clone)]
163pub struct SimpleCacheKeyBuilder {
164 pub prefix: Option<String>,
165 pub tenant: Option<String>,
166 pub modular: Option<String>,
167 pub table: String,
168 pub field: Option<String>,
169 pub value_type: ValueType,
170 pub expire: Option<Duration>,
171}
172
173impl SimpleCacheKeyBuilder {
174 pub fn new(table: impl Into<String>) -> Self {
176 Self {
177 prefix: None,
178 tenant: None,
179 modular: None,
180 table: table.into(),
181 field: None,
182 value_type: ValueType::Obj,
183 expire: None,
184 }
185 }
186
187 pub fn with_prefix(mut self, prefix: impl Into<String>) -> Self {
189 self.prefix = Some(prefix.into());
190 self
191 }
192
193 pub fn with_tenant(mut self, tenant: impl Into<String>) -> Self {
195 self.tenant = Some(tenant.into());
196 self
197 }
198
199 pub fn with_modular(mut self, modular: impl Into<String>) -> Self {
201 self.modular = Some(modular.into());
202 self
203 }
204
205 pub fn with_field(mut self, field: impl Into<String>) -> Self {
207 self.field = Some(field.into());
208 self
209 }
210
211 pub fn with_value_type(mut self, value_type: ValueType) -> Self {
213 self.value_type = value_type;
214 self
215 }
216
217 pub fn with_expire(mut self, expire: Duration) -> Self {
219 self.expire = Some(expire);
220 self
221 }
222}
223
224impl CacheKeyBuilder for SimpleCacheKeyBuilder {
225 fn get_prefix(&self) -> Option<&str> {
226 self.prefix.as_deref()
227 }
228
229 fn get_tenant(&self) -> Option<&str> {
230 self.tenant.as_deref()
231 }
232
233 fn get_modular(&self) -> Option<&str> {
234 self.modular.as_deref()
235 }
236
237 fn get_table(&self) -> &str {
238 &self.table
239 }
240
241 fn get_field(&self) -> Option<&str> {
242 self.field.as_deref()
243 }
244
245 fn get_value_type(&self) -> ValueType {
246 self.value_type
247 }
248
249 fn get_expire(&self) -> Option<Duration> {
250 self.expire
251 }
252}
253
254#[cfg(test)]
255mod tests {
256 use super::*;
257
258 #[test]
259 fn test_simple_cache_key_builder() {
260 let builder = SimpleCacheKeyBuilder::new("user")
261 .with_prefix("dev")
262 .with_tenant("0000")
263 .with_modular("authority")
264 .with_field("id")
265 .with_value_type(ValueType::Obj);
266
267 let key = builder.key(&[&1u64]);
268 assert_eq!(key.key, "dev:0000:authority:user:id:obj:1");
269 }
270
271 #[test]
272 fn test_cache_key_without_optional_fields() {
273 let builder = SimpleCacheKeyBuilder::new("tenant");
274
275 let key = builder.key(&[&1u64]);
276 assert_eq!(key.key, "tenant:obj:1");
277 }
278
279 #[test]
280 fn test_hash_key() {
281 let builder = SimpleCacheKeyBuilder::new("user")
282 .with_tenant("0000")
283 .with_modular("authority");
284
285 let hash_key = builder.hash_field_key(&"name", &[&1u64]);
286 assert_eq!(hash_key.key, "0000:authority:user:obj:1");
287 assert_eq!(hash_key.field, Some("name".to_string()));
288 }
289
290 #[test]
291 fn test_multiple_uniques() {
292 let builder = SimpleCacheKeyBuilder::new("user.activity")
293 .with_tenant("0000")
294 .with_modular("authority")
295 .with_field("id.id")
296 .with_value_type(ValueType::Number);
297
298 let key = builder.key(&[&1u64, &3u64]);
299 assert_eq!(key.key, "0000:authority:user.activity:id.id:number:1:3");
300 }
301}