Alice_DBMS/
json_engine.rs1use std::fs;
24use std::io::{self, Read, Write};
25use std::env;
26use std::path::{PathBuf, Path};
27use serde_json::{json, Value, Result as JsonResult};
28
29use log::{info, error, trace};
30use simplelog::*;
31
32use uuid::Uuid;
33use chrono::Local;
34
35const ROOT_DIR: &str = "Alice-Database-Data";
36const ADB_DATA_DIR: &str = "ADB_Data";
37const JSON_ENGINE_DIR: &str = "json_engine";
38
39
40#[derive(Debug, Clone)]
44pub struct Document {
45 pub name: String,
46 pub path: PathBuf,
47 pub json_value: Option<Value>,
48}
49
50#[derive(Debug, Clone)]
54pub struct Collection {
55 pub name: String,
56 pub documents: Vec<Document>,
57}
58
59impl Collection {
60 pub fn get_document(&self, name: &str) -> Option<&Document> {
62 self.documents.iter().find(|doc| doc.name == name)
63 }
64
65 pub fn get_document_mut(&mut self, name: &str) -> Option<&mut Document> {
74 self.documents.iter_mut().find(|doc| doc.name == name)
75 }
76
77 pub fn add_document(&mut self, name: &str, content: &str) -> io::Result<()> {
79 let collection_path = Path::new(&self.path()).join(&self.name);
80 fs::create_dir_all(&collection_path)?;
81
82 let doc_path = collection_path.join(&name.clone()); let mut file = fs::File::create(&doc_path)?;
85 file.write_all(content.as_bytes())?;
86
87 let new_document = Document {
89 name: name.to_string(),
90 path: doc_path.clone(),
91 json_value: parse_json_data(content).ok(),
92 };
93 self.documents.push(new_document);
94 Ok(())
95 }
96
97 pub fn delete_document(&mut self, name: &str) -> io::Result<()> {
99 if let Some(doc) = self.documents.iter().find(|doc| doc.name == name) {
100 fs::remove_file(&doc.path)?;
101 self.documents.retain(|doc| doc.name != name);
102 Ok(())
103 } else {
104 Err(io::Error::new(io::ErrorKind::NotFound, "Document not found"))
105 }
106 }
107
108 fn path(&self) -> PathBuf {
109 let home_dir = env::home_dir().expect("Failed to get home directory");
110 home_dir.join(ROOT_DIR).join(ADB_DATA_DIR).join(JSON_ENGINE_DIR)
111 }
112}
113
114#[derive(Debug, Clone)]
116pub struct JSONEngine {
117 collections: Vec<Collection>,
118}
119
120impl JSONEngine {
121 pub fn new(root: &Path, ) -> Self {
129 let collections = get_exists_collections(root);
130 JSONEngine { collections }
131 }
132
133
134 pub fn get_collection_mut(&mut self, name: &str) -> Option<&mut Collection> {
142 self.collections.iter_mut().find(|col| col.name == name)
143 }
144
145 pub fn add_collection(&mut self, name: &str) -> Option<&mut Collection> {
153 let collection_path = Path::new(&self.root_path()).join(name);
154 fs::create_dir_all(&collection_path).ok()?; let new_collection = Collection {
157 name: name.to_string(),
158 documents: vec![],
159 };
160
161 self.collections.push(new_collection);
162 self.collections.last_mut() }
164
165 pub fn get_collection(&self, name: &str) -> Option<&Collection> {
173 self.collections.iter().find(|col| col.name == name)
174 }
175
176 pub fn get_document(&self, collection_name: &str, document_name: &str) -> Option<&Document> {
185 self.get_collection(collection_name)?.get_document(document_name)
186 }
187
188 fn root_path(&self) -> PathBuf {
189 let home_dir = env::home_dir().expect("Failed to get home directory");
190 home_dir.join(ROOT_DIR).join(ADB_DATA_DIR).join(JSON_ENGINE_DIR)
191 }
192}
193
194impl Document {
195 pub fn update_rows(&mut self, key: &str, value: &Value) -> io::Result<()> {
204 if let Some(json_value) = &mut self.json_value {
205 if let Some(obj) = json_value.as_object_mut() {
206 obj.insert(key.to_string(), value.clone());
207 let updated_content = serde_json::to_string_pretty(json_value)?;
208 let mut file = fs::File::create(&self.path)?;
209 file.write_all(updated_content.as_bytes())?;
210 Ok(())
211 } else {
212 Err(io::Error::new(io::ErrorKind::InvalidData, "JSON is not an object"))
213 }
214 } else {
215 Err(io::Error::new(io::ErrorKind::InvalidData, "Document does not contain valid JSON"))
216 }
217 }
218
219 pub fn delete_rows(&mut self, key: &str) -> io::Result<()> {
227 if let Some(json_value) = &mut self.json_value {
228 if let Some(obj) = json_value.as_object_mut() {
229 obj.remove(key);
230 let updated_content = serde_json::to_string_pretty(json_value)?;
231 let mut file = fs::File::create(&self.path)?;
232 file.write_all(updated_content.as_bytes())?;
233 Ok(())
234 } else {
235 Err(io::Error::new(io::ErrorKind::InvalidData, "JSON is not an object"))
236 }
237 } else {
238 Err(io::Error::new(io::ErrorKind::InvalidData, "Document does not contain valid JSON"))
239 }
240 }
241
242 pub fn update_nested_field(&mut self, parent_key: &str, key: &str, value: &Value) -> io::Result<()> {
252 if let Some(json_value) = &mut self.json_value {
253 if let Some(parent) = json_value.get_mut(parent_key) {
254 if let Some(obj) = parent.as_object_mut() {
255 obj.insert(key.to_string(), value.clone());
256 let updated_content = serde_json::to_string_pretty(json_value)?;
257 let mut file = fs::File::create(&self.path)?;
258 file.write_all(updated_content.as_bytes())?;
259 Ok(())
260 } else {
261 Err(io::Error::new(io::ErrorKind::InvalidData, "Parent key is not an object"))
262 }
263 } else {
264 Err(io::Error::new(io::ErrorKind::NotFound, "Parent key not found"))
265 }
266 } else {
267 Err(io::Error::new(io::ErrorKind::InvalidData, "Document does not contain valid JSON"))
268 }
269 }
270}
271
272fn get_documents_in_collection(path: &Path) -> Vec<Document> {
274 let entries = fs::read_dir(path).unwrap();
275 let mut documents: Vec<Document> = vec![];
276
277 for entry in entries {
278 let entry = entry.unwrap();
279 let entry_path = entry.path();
280 if entry_path.is_file() {
281 let name = entry_path.file_name().unwrap().to_string_lossy().into_owned();
282 let data = read_file_data(&entry_path).unwrap_or_default();
283 let json_value = parse_json_data(&data).ok();
284 let document = Document {
285 name,
286 path: entry_path.clone(),
287 json_value,
288 };
289 documents.push(document);
290 }
291 }
292 documents
293}
294
295fn read_file_data(path: &Path) -> io::Result<String> {
296 let mut file = fs::File::open(path)?;
297 let mut contents = String::new();
298 file.read_to_string(&mut contents)?;
299 Ok(contents)
300}
301
302fn parse_json_data(data: &str) -> JsonResult<Value> {
303 serde_json::from_str(data)
304}
305
306fn get_exists_collections(path: &Path) -> Vec<Collection> {
307 let mut collections: Vec<Collection> = vec![];
308
309 if path.exists() && path.is_dir() {
310 let entries = fs::read_dir(path).unwrap();
311
312 for entry in entries {
313 let entry = entry.unwrap();
314 let entry_path = entry.path();
315
316 if entry_path.is_dir() {
317 let documents = get_documents_in_collection(&entry_path);
318 let collection_name = entry_path.file_name().unwrap().to_string_lossy().into_owned();
319 let collection = Collection {
320 name: collection_name,
321 documents,
322 };
323 collections.push(collection);
324 }
325 }
326 } else {
327 error!("The specified path does not exist or is not a directory: {:?}", path);
328 }
329
330 collections
331}
332
333impl JSONEngine {
335 pub fn get_document_mut(&mut self, collection_name: &str, document_name: &str) -> Option<&mut Document> {
336 self.get_collection_mut(collection_name)?.documents.iter_mut().find(|doc| doc.name == document_name)
337 }
338}
339