1mod collection;
6mod data_type;
7pub mod utils;
8pub use collection::Collection;
9pub use data_type::DataType;
10pub use data_type::FindOp; use std::fs;
12
13pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");
14
15pub struct InfuseDB {
16 pub path: String,
17 collections: Vec<Collection>,
18}
19
20impl InfuseDB {
21 pub fn new() -> Self {
22 InfuseDB {
23 path: "./default.mdb".to_string(),
24 collections: Vec::new(),
25 }
26 }
27
28 pub fn load(path: &str) -> Result<Self, &str> {
29 let mut collections = Vec::new();
30 let contents = fs::read_to_string(path);
31 if contents.is_err() {
32 return Err("Error reading file");
33 }
34 let contents = contents.unwrap();
35 let mut page = String::new();
36 for line in contents.lines() {
37 let line = line.trim();
38 let line = if line.ends_with('\n') {
39 line.strip_prefix('\n').unwrap()
40 } else {
41 line
42 };
43
44 if line.len() == 0 || line.starts_with("#") {
45 continue;
46 }
47 if line.starts_with('[') && line.ends_with(']') && page.len() != 0 {
48 collections.push(Collection::load(page.as_str()));
49 page = String::new();
50 }
51 page.push_str(line);
52 page.push('\n');
53 }
54 if !page.is_empty() {
55 collections.push(Collection::load(page.as_str()));
56 }
57
58 Ok(InfuseDB {
59 collections,
60 path: path.to_string(),
61 })
62 }
63
64 pub fn dump(&self) -> Result<(), &str> {
65 let mut result = String::new();
66 for collection in self.collections.iter() {
67 let page = collection.dump();
68 result.push_str(page.as_str());
69 result.push_str("\n");
70 }
71
72 let _ = fs::write(self.path.as_str(), result);
73 Ok(())
74 }
75
76 pub fn create_collection(&mut self, name: &str) -> Result<&mut Collection, &str> {
77 if self.collections.iter().any(|x| x.name == name) {
79 Err("Collection already exists")
80 } else {
81 let collection = Collection::new(name);
82 self.collections.push(collection);
83 return Ok(self.collections.last_mut().unwrap());
84 }
85 }
86
87 pub fn get_collection(&mut self, name: &str) -> Option<&mut Collection> {
88 let index = self
90 .collections
91 .iter()
92 .position(|x| x.name == name.to_string());
93 if index.is_none() {
94 return None;
95 }
96 let index = index.unwrap();
97 let c = self.collections.get_mut(index).unwrap();
98 return Some(c);
99 }
100
101 pub fn get_collection_list(&self) -> Vec<String> {
102 let mut collection_list: Vec<String> = Vec::new();
103 for collection in self.collections.iter() {
104 collection_list.push(collection.name.clone());
105 }
106 collection_list
107 }
108
109 pub fn remove_collection(&mut self, name: String) {
110 let index = self
111 .collections
112 .iter()
113 .position(|x| x.name == name)
114 .unwrap();
115 self.collections.remove(index);
116 }
117}
118
119#[cfg(test)]
121#[test]
122fn test_infusedb() {
123 let mut infusedb = InfuseDB::new();
124 let r1 = infusedb.create_collection("users").is_ok();
125 let r2 = infusedb.create_collection("posts").is_ok();
126 assert!(r1);
127 assert!(r2);
128 assert_eq!(infusedb.collections.len(), 2);
129 assert_eq!(infusedb.collections[0].name, "users");
130 assert_eq!(infusedb.collections[1].name, "posts");
131 assert_eq!(infusedb.get_collection("users").unwrap().name, "users");
132 assert_eq!(infusedb.get_collection("posts").unwrap().name, "posts");
133 assert_eq!(infusedb.get_collection_list().len(), 2);
134 infusedb.remove_collection("users".to_string());
135 assert_eq!(infusedb.collections.len(), 1);
136 infusedb.remove_collection("posts".to_string());
137 assert_eq!(infusedb.collections.len(), 0);
138}
139
140