goxoy_key_value/
key_value.rs

1use std::collections::HashMap;
2use rusqlite::Connection;
3
4#[derive(Debug)]
5pub struct KeyValueDb {
6    pub list:HashMap<String,String>,
7    pub db_open:bool,
8    pub record_loaded:bool,
9    pub db_obj:Connection,
10    pub db_path:String,
11}
12
13impl KeyValueDb {
14    pub fn new(db_name:&str) -> Self {
15        let mut full_path=String::from(db_name);
16        full_path.push_str(".db");
17        let create_table=match std::fs::metadata(full_path.clone()) {
18            Ok(_) => false,
19            Err(_) => true
20        };
21        let db_conn:Connection = Connection::open(full_path.clone()).unwrap();
22        if create_table==true{
23            let _db_result=db_conn.execute("CREATE TABLE kv_list ( key TEXT NOT NULL PRIMARY KEY, value TEXT NOT NULL )", ()).unwrap();
24        }
25        KeyValueDb{
26            list:HashMap::new(),
27            db_open:true,
28            record_loaded:false,
29            db_obj:db_conn,
30            db_path:full_path.clone(),
31        }
32    }
33    pub fn load_records(&mut self){
34        if self.db_open==true && self.record_loaded==false {
35            let stmt = self.db_obj.prepare("SELECT * FROM kv_list");
36            if stmt.is_ok(){
37                let mut stmt=stmt.unwrap();
38                stmt.query_map(
39                    (), 
40                    |row| {
41                        let key_result:String=row.get(0).unwrap();
42                        let value_result:String=row.get(1).unwrap();
43                        Ok((key_result,value_result))
44                    }
45                ).into_iter().for_each(|person| {
46                    person.for_each(|s|{
47                        let (key_result,value_result)=s.unwrap();
48                        self.list.insert(key_result, value_result);
49                    });
50                });
51            }
52            self.record_loaded=true;
53        }
54    }
55    
56    pub fn set_value(&mut self,key:&str,value:&str) -> bool {
57        if self.db_open==false {
58            return false;
59        }
60        self.load_records();
61        if self.list.contains_key(key){
62            let update_result=self.db_obj .execute("UPDATE kv_list SET value=?1 WHERE key=?2",&[&value, &key]);
63            if update_result.is_ok(){
64                if update_result.unwrap()>0{
65                    self.list.insert(String::from(key),String::from(value));
66                    return true;
67                }
68            }
69        }else{
70            let insert_result=self.db_obj .execute("INSERT INTO kv_list (key, value) VALUES (?1, ?2)",&[&key, &value]);
71            if insert_result.is_ok(){
72                if insert_result.unwrap()>0{
73                    self.list.insert(String::from(key),String::from(value));
74                    return true;
75                }
76            }
77        }
78        false
79    }
80    pub fn get_value(&mut self,key:&str) -> Option<String> {
81        if self.list.contains_key(key){
82            let value_str=self.list.get(key);
83            Some(String::from(value_str.unwrap()))
84        }else{
85            None
86        }
87    }
88
89    pub fn delete(&mut self,key:&str) ->bool {
90        if self.db_open==false {
91            return false;
92        }
93        self.load_records();
94        let insert_result=self.db_obj .execute("DELETE FROM kv_list WHERE key = ?1",&[&key]);
95        if insert_result.is_ok(){
96            if insert_result.unwrap()>0{
97                self.list.remove(&key.to_string());
98                return true;
99            }
100        }
101        false
102    }
103
104    pub fn flush(&mut self) -> bool{
105        self.close();
106        if std::fs::metadata(&self.db_path).is_ok(){
107            if std::fs::remove_file(&self.db_path).is_ok(){
108                return true;
109            }
110        }
111        false
112    }
113    pub fn close(&mut self){
114        if self.db_open==true {
115            self.db_obj=Connection::open_in_memory().unwrap();
116            self.db_open=false;
117            self.list.clear();
118            self.record_loaded=false;
119        }
120    }
121}
122
123#[test]
124fn full_test() {
125    // cargo test  --lib full_test -- --nocapture
126    let since_the_epoch = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH);
127    if since_the_epoch.is_ok(){
128        let tmp_db_name=since_the_epoch.unwrap().as_micros().to_string();
129        let mut kv_obj=KeyValueDb::new(&tmp_db_name);
130        kv_obj.set_value("tmp_key", "tmp_value");
131        let mut record_founded=false;
132        let tmp_value=kv_obj.get_value("tmp_key");
133        if tmp_value.is_some(){   
134            if tmp_value.unwrap().eq("tmp_value"){
135                record_founded=true;
136            }
137        }
138        kv_obj.flush();
139        if record_founded==true{
140            assert!(true)
141        }else{
142            assert!(false)
143        }
144    }else{
145        assert!(false)
146    }
147}