1use crate::engines::Engines;
24use uuid::Uuid;
25use std::path::{PathBuf, Path};
26use std::fs::File;
27use std::io::{self, BufRead};
28
29use crate::json_engine::JSONEngine;
30use crate::log_engine::LOGEngine;
31
32use std::collections::HashMap;
33use crate::command_executor::IMPestParser;
34use pest_derive::Parser;
35use pest::Parser;
36use crate::command_executor::Rule;
37
38macro_rules! adbprint {
39 ($($arg:tt)*) => {
40 println!("[ INSTANCE MANAGER ]=: {}", format!($($arg)*));
41 };
42}
43
44#[derive(Debug, Clone)]
45pub struct Instance {
46 pub name: String,
47 pub engine: Engines,
48}
49
50#[derive(Debug, Clone, Default)]
51pub struct InstanceManager {
52 pub name: String,
53 pub instances: Vec<Instance>,
54 pub root_path: PathBuf,
55 pub authenticated_apps: HashMap<String, String>,
56}
57
58impl InstanceManager {
59 pub fn new(root_path: &PathBuf) -> Self {
60 let name = Uuid::new_v4().to_string();
61 Self {
62 name,
63 instances: vec![],
64 root_path: root_path.to_owned(),
65 authenticated_apps: HashMap::new(),
66 }
67 }
68
69 pub fn create_instance(&mut self, engine_type: &str, name: &str) -> Result<String, Box<dyn std::error::Error>> {
70 let new_name = name.to_string();
71 let engine = match engine_type {
72 "json_engine" => Engines::JSONEngine(JSONEngine::new(&self.root_path)),
73 "log_engine" => Engines::LOGEngine(LOGEngine::new(&self.root_path)),
74 _ => {
75 println!("Engine not found.");
76 return Err(Box::new(std::io::Error::new(
77 std::io::ErrorKind::InvalidInput, "Engine type not found")));
78 }
79 };
80 let instance = Instance { engine, name: new_name.clone() };
81 self.instances.push(instance);
82 Ok(new_name)
83 }
84
85 pub fn get_instance(&self, instance_name: &str) -> Option<&Instance> {
86 self.instances.iter().find(|i| i.name == instance_name)
87 }
88
89 pub fn get_mutable_engine(&mut self, instance_name: &str) -> Option<&mut Engines> {
90 self.instances.iter_mut().find(|instance| instance.name == instance_name)
91 .map(|instance| &mut instance.engine)
92 }
93
94 pub fn sign_up(&mut self, app_name: String) -> String {
95 let key = Uuid::new_v4().to_string();
96 self.authenticated_apps.insert(app_name, key.clone());
97 key
98 }
99
100 pub fn get_all_apps(&self) {
101 adbprint!("{:#?}", self.authenticated_apps);
102 }
103
104 pub fn execute_cmd(&mut self, command: &str) -> Result<(), Box<dyn std::error::Error>> {
105 match IMPestParser::parse(Rule::sql_statements, command) {
106 Ok(pairs) => {
107 for pair in pairs {
108 for inner_pair in pair.into_inner() {
109 match inner_pair.as_rule() {
110 Rule::create_instance => {
111 let inner = inner_pair.into_inner().as_str().split(" ENGINE ").collect::<Vec<_>>();
112 let instance_id = self.create_instance(inner[1], inner[0]);
113 match instance_id {
114 Ok(message) => adbprint!("NEW INSTANCE ID: {}", message),
115 Err(e) => adbprint!("{:#?}", e),
116 }
117 },
118 Rule::get_instance => {
119 let inner = inner_pair.into_inner().as_str();
120 adbprint!("{:#?}", self.get_instance(inner));
121 },
122 Rule::get_instances => {
123 adbprint!("{:#?}", self.instances);
124 },
125 Rule::print_addbms => {
126 adbprint!("{:#?}", self);
127 },
128 Rule::supported_engines => {
129 adbprint!("LOGEngine (log_engine)\nJSONEngine (json_engine)");
130 },
131 Rule::create_collection => {
132 let inner = inner_pair.into_inner().as_str().split(" INSTANCE WITH NAME ").collect::<Vec<_>>();
133 if let Some(engine) = self.get_mutable_engine(inner[0]) {
134 match engine {
135 Engines::JSONEngine(json_engine) => {
136 json_engine.add_collection(inner[1]); },
138 Engines::LOGEngine(log_engine) => {
139 log_engine.add_collection(inner[1]); },
141 }
143 } else {
144 adbprint!("Instance not found: {}", inner[0]);
145 }
146 }
147
148 Rule::create_document => {
149 let inner = inner_pair.into_inner().as_str().split(" INSTANCE IN COLLECTION ").collect::<Vec<_>>();
150 let inner_two = inner[1].split(" WITH NAME ").collect::<Vec<_>>();
151
152 if let Some(engine) = self.get_mutable_engine(inner[0]) {
153 match engine {
154 Engines::JSONEngine(json_engine) => {
155 if let Some(collection) = json_engine.get_collection_mut(inner_two[0]) {
156 collection.add_document(inner_two[1], "");
157 adbprint!("DOCUMENT {} CREATED IN {}.{} C.I", inner_two[1], inner_two[0], inner[0]);
158 } else {
159 adbprint!("Collection not found in JSONEngine: {}", inner_two[0]);
160 }
161 },
162 Engines::LOGEngine(log_engine) => {
163 if let Some(collection) = log_engine.get_collection_mut(inner_two[0]) {
164 collection.add_document(inner_two[1], "");
165 adbprint!("DOCUMENT {} CREATED IN {}.{} C.I", inner_two[1], inner_two[0], inner[0]);
166 } else {
167 adbprint!("Collection not found in LOGEngine: {}", inner_two[0]);
168 }
169 },
170 }
171 } else {
172 adbprint!("Instance not found: {}", inner[0]);
173 }
174 },
175 _ => unreachable!("I don't know this command"),
176 }
177 }
178 }
179 Ok(())
180 }
181 Err(e) => {
182 adbprint!("Error parsing command: {}", e);
183 Err(Box::new(e))
184 }
185 }
186 }
187
188 pub fn wrapped_execute_cmd(&mut self, command: &str) -> Result<(), Box<dyn std::error::Error>> {
189 self.execute_cmd(command)
190 .map_err(|e| { adbprint!("Error! {}", e); e })
191 }
192
193 pub fn execute_decl_file<P>(&mut self, filename: P) -> Result<(), io::Error>
194 where
195 P: AsRef<Path>,
196 {
197 let file = File::open(filename)?;
198 let reader = io::BufReader::new(file);
199
200 for line in reader.lines() {
201 if let Err(e) = self.wrapped_execute_cmd(&line?.replace("\n", "")) {
202 adbprint!("Failed to execute line: {}", e);
203 }
204 }
205 Ok(())
206 }
207}