kv.rs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. use crate::kv::schema::{kv_table, kv_table::dsl, KV_SQL};
  2. use ::diesel::{query_dsl::*, ExpressionMethods};
  3. use diesel::{Connection, SqliteConnection};
  4. use lazy_static::lazy_static;
  5. use lib_sqlite::{DBConnection, Database, PoolConfig};
  6. use std::{collections::HashMap, path::Path, sync::RwLock};
  7. const DB_NAME: &str = "kv.db";
  8. lazy_static! {
  9. static ref KV_HOLDER: RwLock<KV> = RwLock::new(KV::new());
  10. }
  11. pub struct KV {
  12. database: Option<Database>,
  13. cache: HashMap<String, KeyValue>,
  14. }
  15. impl KV {
  16. fn new() -> Self {
  17. KV {
  18. database: None,
  19. cache: HashMap::new(),
  20. }
  21. }
  22. fn set(value: KeyValue) -> Result<(), String> {
  23. log::trace!("[KV]: set value: {:?}", value);
  24. update_cache(value.clone());
  25. let _ = diesel::replace_into(kv_table::table)
  26. .values(&value)
  27. .execute(&*(get_connection()?))
  28. .map_err(|e| format!("KV set error: {:?}", e))?;
  29. Ok(())
  30. }
  31. fn get(key: &str) -> Result<KeyValue, String> {
  32. if let Some(value) = read_cache(key) {
  33. return Ok(value);
  34. }
  35. let conn = get_connection()?;
  36. let value = dsl::kv_table
  37. .filter(kv_table::key.eq(key))
  38. .first::<KeyValue>(&*conn)
  39. .map_err(|e| format!("KV get error: {:?}", e))?;
  40. update_cache(value.clone());
  41. Ok(value)
  42. }
  43. #[allow(dead_code)]
  44. pub fn remove(key: &str) -> Result<(), String> {
  45. log::debug!("remove key: {}", key);
  46. match KV_HOLDER.write() {
  47. Ok(mut guard) => {
  48. guard.cache.remove(key);
  49. }
  50. Err(e) => log::error!("Require write lock failed: {:?}", e),
  51. };
  52. let conn = get_connection()?;
  53. let sql = dsl::kv_table.filter(kv_table::key.eq(key));
  54. let _ = diesel::delete(sql)
  55. .execute(&*conn)
  56. .map_err(|e| format!("KV remove error: {:?}", e))?;
  57. Ok(())
  58. }
  59. pub fn init(root: &str) -> Result<(), String> {
  60. if !Path::new(root).exists() {
  61. return Err(format!("Init KVStore failed. {} not exists", root));
  62. }
  63. let pool_config = PoolConfig::default();
  64. let database = Database::new(root, DB_NAME, pool_config).unwrap();
  65. let conn = database.get_connection().unwrap();
  66. SqliteConnection::execute(&*conn, KV_SQL).unwrap();
  67. let mut store = KV_HOLDER
  68. .write()
  69. .map_err(|e| format!("KVStore write failed: {:?}", e))?;
  70. store.database = Some(database);
  71. Ok(())
  72. }
  73. }
  74. fn read_cache(key: &str) -> Option<KeyValue> {
  75. match KV_HOLDER.read() {
  76. Ok(guard) => guard.cache.get(key).cloned(),
  77. Err(e) => {
  78. log::error!("Require read lock failed: {:?}", e);
  79. None
  80. }
  81. }
  82. }
  83. fn update_cache(value: KeyValue) {
  84. match KV_HOLDER.write() {
  85. Ok(mut guard) => {
  86. guard.cache.insert(value.key.clone(), value);
  87. }
  88. Err(e) => log::error!("Require write lock failed: {:?}", e),
  89. };
  90. }
  91. macro_rules! impl_get_func {
  92. (
  93. $func_name:ident,
  94. $get_method:ident=>$target:ident
  95. ) => {
  96. impl KV {
  97. #[allow(dead_code)]
  98. pub fn $func_name(k: &str) -> Option<$target> {
  99. match KV::get(k) {
  100. Ok(item) => item.$get_method,
  101. Err(_) => None,
  102. }
  103. }
  104. }
  105. };
  106. }
  107. macro_rules! impl_set_func {
  108. ($func_name:ident,$set_method:ident,$key_type:ident) => {
  109. impl KV {
  110. #[allow(dead_code)]
  111. pub fn $func_name(key: &str, value: $key_type) {
  112. let mut item = KeyValue::new(key);
  113. item.$set_method = Some(value);
  114. match KV::set(item) {
  115. Ok(_) => {}
  116. Err(e) => {
  117. log::error!("{:?}", e)
  118. }
  119. };
  120. }
  121. }
  122. };
  123. }
  124. impl_set_func!(set_str, str_value, String);
  125. impl_set_func!(set_bool, bool_value, bool);
  126. impl_set_func!(set_int, int_value, i64);
  127. impl_set_func!(set_float, float_value, f64);
  128. impl_get_func!(get_str,str_value=>String);
  129. impl_get_func!(get_int,int_value=>i64);
  130. impl_get_func!(get_float,float_value=>f64);
  131. impl_get_func!(get_bool,bool_value=>bool);
  132. fn get_connection() -> Result<DBConnection, String> {
  133. match KV_HOLDER.read() {
  134. Ok(store) => {
  135. let conn = store
  136. .database
  137. .as_ref()
  138. .expect("KVStore is not init")
  139. .get_connection()
  140. .map_err(|e| format!("KVStore error: {:?}", e))?;
  141. Ok(conn)
  142. }
  143. Err(e) => {
  144. let msg = format!("KVStore get connection failed: {:?}", e);
  145. log::error!("{:?}", msg);
  146. Err(msg)
  147. }
  148. }
  149. }
  150. #[derive(Clone, Debug, Default, Queryable, Identifiable, Insertable, AsChangeset)]
  151. #[table_name = "kv_table"]
  152. #[primary_key(key)]
  153. pub struct KeyValue {
  154. pub key: String,
  155. pub str_value: Option<String>,
  156. pub int_value: Option<i64>,
  157. pub float_value: Option<f64>,
  158. pub bool_value: Option<bool>,
  159. }
  160. impl KeyValue {
  161. pub fn new(key: &str) -> Self {
  162. KeyValue {
  163. key: key.to_string(),
  164. ..Default::default()
  165. }
  166. }
  167. }
  168. #[cfg(test)]
  169. mod tests {
  170. use crate::kv::KV;
  171. #[test]
  172. fn kv_store_test() {
  173. let dir = "./temp/";
  174. if !std::path::Path::new(dir).exists() {
  175. std::fs::create_dir_all(dir).unwrap();
  176. }
  177. KV::init(dir).unwrap();
  178. KV::set_str("1", "hello".to_string());
  179. assert_eq!(KV::get_str("1").unwrap(), "hello");
  180. assert_eq!(KV::get_str("2"), None);
  181. KV::set_bool("1", true);
  182. assert!(KV::get_bool("1").unwrap());
  183. assert_eq!(KV::get_bool("2"), None);
  184. }
  185. }