goxoy_key_value/
key_value.rs1use 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 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}