1use log::{error, warn};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7use crate::{
8 edge::Edge, errors::GruPHstError, graphs_stats::GraphsStats, util::graphs_memory_watcher,
9 vertex::Vertex,
10};
11
12mod persistence;
13mod queries;
14mod stats;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct Graphs {
19 vault: HashMap<String, Vec<Edge>>,
21 label: String,
23 stats: GraphsStats,
25}
26
27impl Graphs {
28 pub fn init(label: &str) -> Self {
36 let mut vault: HashMap<String, Vec<Edge>> = HashMap::new();
37 vault.insert(String::from(label), vec![]);
38 Graphs {
39 label: String::from(label),
40 vault,
41 stats: GraphsStats::init(),
42 }
43 }
44
45 pub fn init_with(label: &str, vertex: &Edge) -> Self {
57 let mut graphs = Graphs::init(label);
58 graphs.add_edge(vertex, None);
59 graphs
60 }
61
62 pub fn insert(&mut self, name: &str) {
71 self.vault.insert(String::from(name), vec![]);
72 self.label = String::from(name);
73 graphs_memory_watcher(self);
74 }
75
76 pub fn insert_with(&mut self, name: &str, edge: &Edge) {
78 self.vault.insert(String::from(name), vec![]);
79 self.label = String::from(name);
80 self.add_edge(edge, Some(name));
81 graphs_memory_watcher(self);
82 }
83
84 pub fn get_label(&self) -> String {
86 self.label.clone()
87 }
88
89 pub fn set_label(&mut self, label: &str) {
91 self.label = label.to_string()
92 }
93
94 pub fn get_stats(&mut self) -> GraphsStats {
97 self.stats = GraphsStats::generate_stats(self);
98 self.stats.clone()
99 }
100
101 pub fn get_graphs_stats(&self) -> GraphsStats {
103 self.stats.clone()
104 }
105
106 pub fn get_vaults(&self) -> Result<HashMap<String, Vec<Edge>>, GruPHstError> {
107 let vaults = self.vault.clone();
108 if vaults.values().len() == 1 {
109 for val in vaults.values() {
110 if val.is_empty() {
111 return Err(GruPHstError::NoVaultOnGraphs);
112 }
113 }
114 Ok(vaults)
115 } else {
116 Ok(vaults)
117 }
118 }
119
120 pub fn add_edge(&mut self, edge: &Edge, vault_name: Option<&str>) {
127 let current_vault = self.select_vault_label(vault_name);
128 if let Some(e) = self.vault.get_mut(¤t_vault) {
129 e.push(edge.clone());
130 } else {
131 self.insert(¤t_vault);
132 let v = self.vault.get_mut(¤t_vault).unwrap();
133 v.push(edge.clone());
134 }
135 graphs_memory_watcher(self);
136 }
137
138 pub fn add_edges(&mut self, edges: &mut Vec<Edge>, vault_name: Option<&str>) {
145 let current_vault = self.select_vault_label(vault_name);
146 if let Some(e) = self.vault.get_mut(¤t_vault) {
147 e.append(edges);
148 } else {
149 self.insert(¤t_vault);
150 let v = self.vault.get_mut(¤t_vault).unwrap();
151 v.append(edges);
152 }
153 graphs_memory_watcher(self);
154 }
155
156 pub fn get_edges(&self, vault_name: Option<&str>) -> Result<Vec<Edge>, GruPHstError> {
159 Ok(self.select_vault(vault_name)?)
160 }
161
162 pub fn get_uniq_vertices(&self, vault_name: Option<&str>) -> Result<Vec<Vertex>, GruPHstError> {
164 let edges = self.select_vault(vault_name)?;
165 let mut vertices_map: HashMap<String, Vertex> = HashMap::new();
166 for edge in edges {
167 vertices_map.insert(edge.get_from_vertex().get_id(), edge.get_from_vertex());
168 vertices_map.insert(edge.get_to_vertex().get_id(), edge.get_to_vertex());
169 }
170 let uniq_vertices: Vec<Vertex> = vertices_map.into_values().collect();
171 Ok(uniq_vertices)
172 }
173
174 pub fn get_uniq_vertices_on_graphs(&self) -> Result<Vec<Vertex>, GruPHstError> {
176 let vaults = self.get_vaults()?;
177 let mut vertices_map: HashMap<String, Vertex> = HashMap::new();
178 for (_, edges) in vaults {
179 for edge in edges {
180 vertices_map.insert(edge.get_from_vertex().get_id(), edge.get_from_vertex());
181 vertices_map.insert(edge.get_to_vertex().get_id(), edge.get_to_vertex());
182 }
183 }
184 let uniq_vertices: Vec<Vertex> = vertices_map.into_values().collect();
185 Ok(uniq_vertices)
186 }
187
188 pub fn update_label(&mut self, label: &str) {
190 self.label = label.to_string();
191 }
192
193 pub fn delete_edge_by_id(
195 &mut self,
196 id: String,
197 vault_name: Option<&str>,
198 ) -> Result<(), GruPHstError> {
199 let edges = self.select_vault_mut(vault_name)?;
200 if let Some(index) = edges.iter().position(|edge| edge.get_id() == id) {
201 edges.remove(index);
202 graphs_memory_watcher(self);
203 Ok(())
204 } else {
205 error!("Edge [{}] to delete not found", id);
206 Err(GruPHstError::EdgeNotFound)
207 }
208 }
209
210 pub fn update_graph(
212 &mut self,
213 edge_to_update: &Edge,
214 vault_name: Option<&str>,
215 ) -> Result<(), GruPHstError> {
216 let edges: &mut Vec<Edge> = self.select_vault_mut(vault_name)?;
217 let index = edges
218 .iter()
219 .position(|vertex| vertex.get_id() == edge_to_update.get_id());
220 if index.is_some() {
221 let i = index.unwrap();
222 edges.remove(i);
223 edges.push(edge_to_update.clone());
224 graphs_memory_watcher(self);
225 Ok(())
226 } else {
227 #[rustfmt::skip]
228 error!("Edge to update with id: [{}] not found", edge_to_update.get_id());
229 Err(GruPHstError::EdgeNotFound)
230 }
231 }
232
233 fn select_vault_label(&self, vault_label: Option<&str>) -> String {
235 let mut current_vault = self.label.clone();
236 if let Some(vlt) = vault_label {
237 current_vault = vlt.to_string();
238 }
239 current_vault.to_string()
240 }
241
242 fn select_vault_not_exists_error(vault: String) -> GruPHstError {
243 warn!("Vault {} does not exists", vault);
244 GruPHstError::VaultNotExists(vault)
245 }
246
247 fn select_vault_mut(
248 &mut self,
249 vault_label: Option<&str>,
250 ) -> Result<&mut Vec<Edge>, GruPHstError> {
251 let vault = self.select_vault_label(vault_label);
252 if let Some(edges) = self.vault.get_mut(&vault) {
253 match edges.is_empty() {
254 false => Ok(edges),
255 true => Err(GruPHstError::VaultEmpty),
256 }
257 } else {
258 Err(Graphs::select_vault_not_exists_error(vault))
259 }
260 }
261
262 fn select_vault(&self, vault_label: Option<&str>) -> Result<Vec<Edge>, GruPHstError> {
263 let vault = self.select_vault_label(vault_label);
264 if let Some(edges) = self.vault.get(&vault) {
265 match edges.is_empty() {
266 false => Ok(edges.clone()),
267 true => Err(GruPHstError::VaultEmpty),
268 }
269 } else {
270 Err(Graphs::select_vault_not_exists_error(vault))
271 }
272 }
273
274 pub fn delete_vault(&mut self, graph_name: &str) -> Result<(), GruPHstError> {
287 match self.vault.remove(graph_name) {
288 Some(_) => Ok(()),
289 None => Err(GruPHstError::VaultNotExists(graph_name.to_string())),
290 }
291 }
292}