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