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    pub fn db(&mut self, db: i8) -> Result<&mut dyn CacheBase, String> {
100        match self {
101            Cache::Redis(e) => Ok(e.db(db)?),
102            Cache::None => Err("error".to_string()),
103        }
104    }
105
106    pub fn add(&mut self, key: &str, value: JsonValue, expiration_date: u64) -> Result<bool, String> {
107        let res = match self {
108            Cache::Redis(e) => e.add(key, value, expiration_date)?,
109            Cache::None => return Err("error".to_string()),
110        };
111        Ok(res)
112    }
113    pub fn get(&mut self, key: &str) -> Result<JsonValue, String> {
114        let res = match self {
115            Cache::Redis(e) => e.get(key)?,
116            Cache::None => return Err("error".to_string()),
117        };
118        Ok(res)
119    }
120    pub fn delete(&mut self, key: &str) -> Result<bool, String> {
121        let res = match self {
122            Cache::Redis(e) => e.delete(key)?,
123            Cache::None => return Err("error".to_string()),
124        };
125        Ok(res)
126    }
127
128    pub fn exists(&mut self, key: &str) -> Result<bool, String> {
129        let res = match self {
130            Cache::Redis(e) => e.exists(key)?,
131            Cache::None => return Err("error".to_string()),
132        };
133        Ok(res)
134    }
135
136    pub fn keys(&mut self, key: &str) -> Result<JsonValue, String> {
137        let res = match self {
138            Cache::Redis(e) => e.keys(key)?,
139            Cache::None => return Err("error".to_string()),
140        };
141        Ok(res)
142    }
143
144    pub fn set_add(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
145        let res = match self {
146            Cache::Redis(e) => e.set_add(key, value)?,
147            Cache::None => return Err("error".to_string()),
148        };
149        Ok(res)
150    }
151    pub fn set_get(&mut self, key: &str) -> Result<JsonValue, String> {
152        let res = match self {
153            Cache::Redis(e) => e.set_get(key)?,
154            Cache::None => return Err("error".to_string()),
155        };
156        Ok(res)
157    }
158
159    pub fn set_delete(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
160        let res = match self {
161            Cache::Redis(e) => e.set_delete(key, value)?,
162            Cache::None => return Err("error".to_string()),
163        };
164        Ok(res)
165    }
166
167    pub fn set_message_queue(&mut self, key: &str, value: JsonValue) -> Result<bool, String> {
168        match self {
169            Cache::Redis(e) => e.set_message_queue(key, value),
170            Cache::None => Err("error".to_string()),
171        }
172    }
173    pub fn get_message_queue(&mut self, key: &str) -> Result<JsonValue, String> {
174        match self {
175            Cache::Redis(e) => Ok(e.get_message_queue(key)?),
176            Cache::None => Err("error".to_string()),
177        }
178    }
179    pub fn set_object(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String> {
180        let res = match self {
181            Cache::Redis(e) => e.set_object(key, field, value)?,
182            Cache::None => return Err("error".to_string()),
183        };
184        Ok(res)
185    }
186    /// 获取哈希值
187    pub fn get_object(&mut self, key: &str) -> Result<JsonValue, String> {
188        let res = match self {
189            Cache::Redis(e) => e.get_object(key)?,
190            Cache::None => return Err("error".to_string()),
191        };
192        Ok(res)
193    }
194    /// 哈希-添加
195    pub fn add_hash(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String> {
196        let res = match self {
197            Cache::Redis(e) => e.add_hash(key, field, value)?,
198            Cache::None => return Err("error".to_string()),
199        };
200        Ok(res)
201    }
202    /// 哈希-获取指定字段的值
203    pub fn get_hash_field_value(&mut self, key: &str, field: &str) -> Result<JsonValue, String> {
204        let res = match self {
205            Cache::Redis(e) => e.get_hash_field_value(key, field)?,
206            Cache::None => return Err("error".to_string()),
207        };
208        Ok(res)
209    }
210    /// 哈希-获取所有字段
211    pub fn get_hash_fields(&mut self, key: &str) -> Result<JsonValue, String> {
212        let res = match self {
213            Cache::Redis(e) => e.get_hash_fields(key)?,
214            Cache::None => return Err("error".to_string()),
215        };
216        Ok(res)
217    }
218    /// 哈希-删除
219    pub fn delete_hash(&mut self, key: &str, field: &str) -> Result<bool, String> {
220        let res = match self {
221            Cache::Redis(e) => e.delete_hash(key, field)?,
222            Cache::None => return Err("error".to_string()),
223        };
224        Ok(res)
225    }
226    /// 哈希-获取所有值
227    pub fn get_hash_values(&mut self, key: &str) -> Result<JsonValue, String> {
228        let res = match self {
229            Cache::Redis(e) => e.get_hash_values(key)?,
230            Cache::None => return Err("error".to_string()),
231        };
232        Ok(res)
233    }
234}
235
236
237pub trait CacheBase {
238    /// 选择数据库
239    fn db(&mut self, db: i8) -> Result<&mut dyn CacheBase, String>;
240    /// 设置缓存
241    ///
242    /// * expiration_date 过期时间 s 秒
243    fn add(&mut self, key: &str, value: JsonValue, expiration_date: u64) -> Result<bool, String>;
244    /// 获取缓存
245    fn get(&mut self, key: &str) -> Result<JsonValue, String>;
246    /// 删除缓存
247    fn delete(&mut self, key: &str) -> Result<bool, String>;
248    /// exists 判断KEY是否存在
249    /// * key 键
250    fn exists(&mut self, key: &str) -> Result<bool, String>;
251    /// 查询 KEY
252    /// * key 键 格式 * 或 *#### 模糊查询
253    fn keys(&mut self, key: &str) -> Result<JsonValue, String>;
254
255    /// 集合 添加
256    fn set_add(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
257    /// 集合 获取
258    fn set_get(&mut self, key: &str) -> Result<JsonValue, String>;
259    /// 集合 删除
260    fn set_delete(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
261    /// 设置消息队列
262    fn set_message_queue(&mut self, key: &str, value: JsonValue) -> Result<bool, String>;
263    /// 获取消息队列
264    fn get_message_queue(&mut self, key: &str) -> Result<JsonValue, String>;
265    fn set_object(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String>;
266    /// 获取哈希值
267    fn get_object(&mut self, key: &str) -> Result<JsonValue, String>;
268    /// 添加哈希
269    fn add_hash(&mut self, key: &str, field: &str, value: JsonValue) -> Result<bool, String>;
270    /// 获取哈希指定key的字段值
271    fn get_hash_field_value(&mut self, key: &str, field: &str) -> Result<JsonValue, String>;
272    /// 获取key下所有的field
273    fn get_hash_fields(&mut self, key: &str) -> Result<JsonValue, String>;
274    /// 删除哈希指定key的字段
275    fn delete_hash(&mut self, key: &str, field: &str) -> Result<bool, String>;
276    /// 获取key下所有的value
277    fn get_hash_values(&mut self, key: &str) -> Result<JsonValue, String>;
278}
279
280#[derive(Clone, Debug, Deserialize, Serialize)]
281pub struct Config {
282    pub default: String,
283    pub connections: BTreeMap<String, Connection>,
284}
285
286impl Default for Config {
287    fn default() -> Self {
288        Self::new()
289    }
290}
291
292impl Config {
293    /// 创建配置
294    /// *config_file 配置文件地址
295    /// *path 是否显示包名
296    pub fn create(config_file: PathBuf, pkg_name: bool) -> Config {
297        #[derive(Clone, Debug, Deserialize, Serialize)]
298        pub struct ConfigNew {
299            pub br_cache: Config,
300        }
301        impl ConfigNew {
302            pub fn new() -> ConfigNew {
303                let mut connections = BTreeMap::new();
304                connections.insert("my_name".to_string(), Connection::default());
305                Self {
306                    br_cache: Config {
307                        default: "my_name".to_string(),
308                        connections,
309                    },
310                }
311            }
312        }
313        match fs::read_to_string(config_file.clone()) {
314            Ok(e) => {
315                if pkg_name {
316                    let data = ConfigNew::new();
317                    toml::from_str::<ConfigNew>(&e).unwrap_or_else(|_| {
318                        let toml = toml::to_string(&data).unwrap();
319                        let toml = format!("{e}\r\n{toml}");
320                        let _ = fs::write(config_file.to_str().unwrap(), toml);
321                        data
322                    }).br_cache
323                } else {
324                    Config::new()
325                }
326            }
327            Err(_) => {
328                if pkg_name {
329                    let data = ConfigNew::new();
330                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
331                    let toml = toml::to_string(&data).unwrap();
332                    let _ = fs::write(config_file.to_str().unwrap(), toml);
333                    data.br_cache
334                } else {
335                    let data = Config::new();
336                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
337                    let toml = toml::to_string(&data).unwrap();
338                    let _ = fs::write(config_file.to_str().unwrap(), toml);
339                    data
340                }
341            }
342        }
343    }
344    pub fn new() -> Config {
345        let mut connections = BTreeMap::new();
346        connections.insert("my_name".to_string(), Connection::default());
347        Self {
348            default: "my_name".to_string(),
349            connections,
350        }
351    }
352}
353
354#[derive(Clone, Debug, Serialize, Deserialize)]
355pub struct Connection {
356    pub mode: CacheMode,
357    pub hostname: String,
358    pub hostport: String,
359    pub userpass: String,
360}
361impl Default for Connection {
362    fn default() -> Self {
363        Self {
364            mode: CacheMode::Redis,
365            hostname: "127.0.0.1".to_string(),
366            hostport: "6379".to_string(),
367            userpass: "".to_string(),
368        }
369    }
370}
371impl Connection {
372    pub fn from(data: JsonValue) -> Connection {
373        Self {
374            mode: CacheMode::from(data["mode"].as_str().unwrap_or("")),
375            hostname: data["hostname"].to_string(),
376            hostport: data["hostport"].to_string(),
377            userpass: data["userpass"].to_string(),
378        }
379    }
380    pub fn json(&mut self) -> JsonValue {
381        let mut data = object! {};
382        data["mode"] = self.mode.str().into();
383        data["hostname"] = self.hostname.clone().into();
384        data["hostport"] = self.hostport.clone().into();
385        data["userpass"] = self.userpass.clone().into();
386        data
387    }
388}
389
390#[derive(Clone, Debug, Serialize, Deserialize)]
391pub enum CacheMode {
392    Redis,
393    None,
394}
395
396impl CacheMode {
397    pub fn str(&mut self) -> &'static str {
398        match self {
399            CacheMode::Redis => "redis",
400            CacheMode::None => ""
401        }
402    }
403    pub fn from(name: &str) -> Self {
404        match name {
405            "redis" => CacheMode::Redis,
406            _ => CacheMode::Redis,
407        }
408    }
409}