br_cache/
lib.rs

1use crate::redis::Redis;
2use json::{object, JsonValue};
3use serde::{Deserialize, Serialize};
4use std::collections::BTreeMap;
5use std::fs;
6use std::path::PathBuf;
7use std::sync::RwLock;
8use once_cell::sync::Lazy;
9
10mod redis;
11
12static GLOBAL_CONFIG: Lazy<RwLock<Config>> = Lazy::new(|| {
13    RwLock::new(Config::default())
14});
15
16#[derive(Clone)]
17pub enum Cache {
18    Redis(Redis),
19    None,
20}
21
22impl Cache {
23    /// 配置文件模式
24    pub fn new(config: Config) -> Self {
25        {
26            let mut data = GLOBAL_CONFIG.write().unwrap();
27            data.clone_from(&config);
28        }
29        let config = GLOBAL_CONFIG.read().unwrap();
30        let connection = config.connections.get(config.default.as_str()).unwrap().clone();
31        match connection.mode {
32            CacheMode::Redis => {
33                match Redis::connect(connection) {
34                    Ok(e) => Cache::Redis(e),
35                    Err(_) => Cache::None
36                }
37            }
38            CacheMode::None => Cache::None
39        }
40    }
41
42    /// 非配置文件模式
43    pub fn create(name: &str, connection: Connection) -> Self {
44        {
45            let mut data = GLOBAL_CONFIG.write().unwrap();
46            if !data.connections.contains_key(name) {
47                data.connections.insert(name.to_string(), connection);
48            }
49            data.default = name.to_string();
50        }
51        let config = GLOBAL_CONFIG.read().unwrap();
52        let connection = config.connections.get(config.default.as_str()).unwrap().clone();
53        match connection.mode {
54            CacheMode::Redis => {
55                match Redis::connect(connection) {
56                    Ok(e) => Cache::Redis(e),
57                    Err(_) => Cache::None
58                }
59            }
60            CacheMode::None => Cache::None
61        }
62    }
63    /// 获取通道列表
64    pub fn connections(&mut self) -> JsonValue {
65        let mut connections = vec![];
66        let data = GLOBAL_CONFIG.read().unwrap();
67        for (item, mut value) in data.connections.clone() {
68            if value.mode.str().is_empty() {
69                continue;
70            }
71            let mut t = value.json();
72            t["name"] = item.into();
73            connections.push(t);
74        }
75        connections.into()
76    }
77    /// 切换通道
78    pub fn connection(&mut self, name: &str) -> Self {
79        let mut data = GLOBAL_CONFIG.write().unwrap();
80        if data.connections.contains_key(name) {
81            if name == data.default {
82                return self.clone();
83            }
84            data.default = name.to_string();
85            let connection = data.connections.get(data.default.as_str()).unwrap().clone();
86            match connection.mode {
87                CacheMode::Redis => {
88                    match Redis::connect(connection) {
89                        Ok(e) => Cache::Redis(e),
90                        Err(_) => Cache::None
91                    }
92                }
93                CacheMode::None => Cache::None
94            }
95        } else {
96            Cache::None
97        }
98    }
99}
100
101
102impl CacheBase for Cache {
103    fn db(&mut self, db: i8) -> Result<&mut dyn CacheBase, String> {
104        match self {
105            Cache::Redis(e) => Ok(e.db(db)?),
106            Cache::None => Err("error".to_string()),
107        }
108    }
109
110    fn add(&mut self, key: &str, value: JsonValue, expiration_date: u64) -> Result<bool, String> {
111        let res = match self {
112            Cache::Redis(e) => e.add(key, value, expiration_date)?,
113            Cache::None => return Err("error".to_string()),
114        };
115        Ok(res)
116    }
117    fn get(&mut self, key: &str) -> Result<JsonValue, String> {
118        let res = match self {
119            Cache::Redis(e) => e.get(key)?,
120            Cache::None => return Err("error".to_string()),
121        };
122        Ok(res)
123    }
124    fn delete(&mut self, key: &str) -> Result<bool, String> {
125        let res = match self {
126            Cache::Redis(e) => e.delete(key)?,
127            Cache::None => return Err("error".to_string()),
128        };
129        Ok(res)
130    }
131
132    fn exists(&mut self, key: &str) -> Result<bool, String> {
133        let res = match self {
134            Cache::Redis(e) => e.exists(key)?,
135            Cache::None => return Err("error".to_string()),
136        };
137        Ok(res)
138    }
139
140    fn keys(&mut self, key: &str) -> Result<JsonValue, String> {
141        let res = match self {
142            Cache::Redis(e) => e.keys(key)?,
143            Cache::None => return Err("error".to_string()),
144        };
145        Ok(res)
146    }
147
148    fn set_add(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
149        let res = match self {
150            Cache::Redis(e) => e.set_add(key, value)?,
151            Cache::None => return Err("error".to_string()),
152        };
153        Ok(res)
154    }
155    fn set_get(&mut self, key: &str) -> Result<JsonValue, String> {
156        let res = match self {
157            Cache::Redis(e) => e.set_get(key)?,
158            Cache::None => return Err("error".to_string()),
159        };
160        Ok(res)
161    }
162
163    fn set_delete(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
164        let res = match self {
165            Cache::Redis(e) => e.set_delete(key, value)?,
166            Cache::None => return Err("error".to_string()),
167        };
168        Ok(res)
169    }
170
171    fn set_message_queue(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
172        match self {
173            Cache::Redis(e) => e.set_message_queue(key, value),
174            Cache::None => Err("error".to_string()),
175        }
176    }
177    fn get_message_queue(&mut self, key: &str) -> Result<JsonValue, String> {
178        match self {
179            Cache::Redis(e) => Ok(e.get_message_queue(key)?),
180            Cache::None => Err("error".to_string()),
181        }
182    }
183    fn set_object(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String> {
184        let res = match self {
185            Cache::Redis(e) => e.set_object(key, field, value)?,
186            Cache::None => return Err("error".to_string()),
187        };
188        Ok(res)
189    }
190    /// 获取哈希值
191    fn get_object(&mut self, key: &str) -> Result<JsonValue, String> {
192        let res = match self {
193            Cache::Redis(e) => e.get_object(key)?,
194            Cache::None => return Err("error".to_string()),
195        };
196        Ok(res)
197    }
198    /// 哈希-添加
199    fn add_hash(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String> {
200        let res = match self {
201            Cache::Redis(e) => e.add_hash(key, field, value)?,
202            Cache::None => return Err("error".to_string()),
203        };
204        Ok(res)
205    }
206    /// 哈希-获取指定字段的值
207    fn get_hash_field_value(&mut self, key: &str, field: &str) -> Result<JsonValue, String> {
208        let res = match self {
209            Cache::Redis(e) => e.get_hash_field_value(key, field)?,
210            Cache::None => return Err("error".to_string()),
211        };
212        Ok(res)
213    }
214    /// 哈希-获取所有字段
215    fn get_hash_fields(&mut self, key: &str) -> Result<JsonValue, String> {
216        let res = match self {
217            Cache::Redis(e) => e.get_hash_fields(key)?,
218            Cache::None => return Err("error".to_string()),
219        };
220        Ok(res)
221    }
222    /// 哈希-删除
223    fn delete_hash(&mut self, key: &str, field: &str) -> Result<bool, String> {
224        let res = match self {
225            Cache::Redis(e) => e.delete_hash(key, field)?,
226            Cache::None => return Err("error".to_string()),
227        };
228        Ok(res)
229    }
230    /// 哈希-获取所有值
231    fn get_hash_values(&mut self, key: &str) -> Result<JsonValue, String> {
232        let res = match self {
233            Cache::Redis(e) => e.get_hash_values(key)?,
234            Cache::None => return Err("error".to_string()),
235        };
236        Ok(res)
237    }
238}
239
240pub trait CacheBase {
241    /// 选择数据库
242    fn db(&mut self, db: i8) -> Result<&mut dyn CacheBase, String>;
243    /// 设置缓存
244    ///
245    /// * expiration_date 过期时间 s 秒
246    fn add(&mut self, key: &str, value: JsonValue, expiration_date: u64) -> Result<bool, String>;
247    /// 获取缓存
248    fn get(&mut self, key: &str) -> Result<JsonValue, String>;
249    /// 删除缓存
250    fn delete(&mut self, key: &str) -> Result<bool, String>;
251    /// exists 判断KEY是否存在
252    /// * key 键
253    fn exists(&mut self, key: &str) -> Result<bool, String>;
254    /// 查询 KEY
255    /// * key 键 格式 * 或 *#### 模糊查询
256    fn keys(&mut self, key: &str) -> Result<JsonValue, String>;
257
258    /// 集合 添加
259    fn set_add(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
260    /// 集合 获取
261    fn set_get(&mut self, key: &str) -> Result<JsonValue, String>;
262    /// 集合 删除
263    fn set_delete(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
264    /// 设置消息队列
265    fn set_message_queue(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
266    /// 获取消息队列
267    fn get_message_queue(&mut self, key: &str) -> Result<JsonValue, String>;
268    fn set_object(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String>;
269    /// 获取哈希值
270    fn get_object(&mut self, key: &str) -> Result<JsonValue, String>;
271    /// 添加哈希
272    fn add_hash(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String>;
273    /// 获取哈希指定key的字段值
274    fn get_hash_field_value(&mut self, key: &str, field: &str) -> Result<JsonValue, String>;
275    /// 获取key下所有的field
276    fn get_hash_fields(&mut self, key: &str) -> Result<JsonValue, String>;
277    /// 删除哈希指定key的字段
278    fn delete_hash(&mut self, key: &str, field: &str) -> Result<bool, String>;
279    /// 获取key下所有的value
280    fn get_hash_values(&mut self, key: &str) -> Result<JsonValue, String>;
281}
282
283#[derive(Clone, Debug, Deserialize, Serialize)]
284pub struct Config {
285    pub default: String,
286    pub connections: BTreeMap<String, Connection>,
287}
288
289impl Default for Config {
290    fn default() -> Self {
291        Self::new()
292    }
293}
294
295impl Config {
296    /// 创建配置
297    /// *config_file 配置文件地址
298    /// *path 是否显示包名
299    pub fn create(config_file: PathBuf, pkg_name: bool) -> Config {
300        #[derive(Clone, Debug, Deserialize, Serialize)]
301        pub struct ConfigNew {
302            pub br_cache: Config,
303        }
304        impl ConfigNew {
305            pub fn new() -> ConfigNew {
306                let mut connections = BTreeMap::new();
307                connections.insert("my_name".to_string(), Connection::default());
308                Self {
309                    br_cache: Config {
310                        default: "my_name".to_string(),
311                        connections,
312                    },
313                }
314            }
315        }
316        match fs::read_to_string(config_file.clone()) {
317            Ok(e) => {
318                if pkg_name {
319                    let data = ConfigNew::new();
320                    toml::from_str::<ConfigNew>(&e).unwrap_or_else(|_| {
321                        let toml = toml::to_string(&data).unwrap();
322                        let toml = format!("{e}\r\n{toml}");
323                        let _ = fs::write(config_file.to_str().unwrap(), toml);
324                        data
325                    }).br_cache
326                } else {
327                    Config::new()
328                }
329            }
330            Err(_) => {
331                if pkg_name {
332                    let data = ConfigNew::new();
333                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
334                    let toml = toml::to_string(&data).unwrap();
335                    let _ = fs::write(config_file.to_str().unwrap(), toml);
336                    data.br_cache
337                } else {
338                    let data = Config::new();
339                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
340                    let toml = toml::to_string(&data).unwrap();
341                    let _ = fs::write(config_file.to_str().unwrap(), toml);
342                    data
343                }
344            }
345        }
346    }
347    pub fn new() -> Config {
348        let mut connections = BTreeMap::new();
349        connections.insert("my_name".to_string(), Connection::default());
350        Self {
351            default: "my_name".to_string(),
352            connections,
353        }
354    }
355}
356
357#[derive(Clone, Debug, Serialize, Deserialize)]
358pub struct Connection {
359    pub mode: CacheMode,
360    pub hostname: String,
361    pub hostport: String,
362    pub userpass: String,
363}
364impl Default for Connection {
365    fn default() -> Self {
366        Self {
367            mode: CacheMode::Redis,
368            hostname: "127.0.0.1".to_string(),
369            hostport: "6379".to_string(),
370            userpass: "".to_string(),
371        }
372    }
373}
374impl Connection {
375    pub fn from(data: JsonValue) -> Connection {
376        Self {
377            mode: CacheMode::from(data["mode"].as_str().unwrap_or("")),
378            hostname: data["hostname"].to_string(),
379            hostport: data["hostport"].to_string(),
380            userpass: data["userpass"].to_string(),
381        }
382    }
383    pub fn json(&mut self) -> JsonValue {
384        let mut data = object! {};
385        data["mode"] = self.mode.str().into();
386        data["hostname"] = self.hostname.clone().into();
387        data["hostport"] = self.hostport.clone().into();
388        data["userpass"] = self.userpass.clone().into();
389        data
390    }
391}
392
393#[derive(Clone, Debug, Serialize, Deserialize)]
394pub enum CacheMode {
395    Redis,
396    None,
397}
398
399impl CacheMode {
400    pub fn str(&mut self) -> &'static str {
401        match self {
402            CacheMode::Redis => "redis",
403            CacheMode::None => ""
404        }
405    }
406    pub fn from(name: &str) -> Self {
407        match name {
408            "redis" => CacheMode::Redis,
409            _ => CacheMode::Redis,
410        }
411    }
412}