1use std::collections::HashMap;
2use std::hash::{Hash, Hasher};
3use std::time::Instant;
4use std::fs::File;
5use std::io::{self, Write, Read};
6use serde::{Serialize, Deserialize};
7
8
9#[derive(Clone, Debug, Serialize, Deserialize)]
10pub struct Column {
11 pub name: String,
12 pub data_type: DataType,
13}
14
15impl Column {
16 pub fn new(name: String, data_type: DataType) -> Self {
17 Column { name, data_type }
18 }
19}
20
21#[derive(Clone, Debug, Serialize, Deserialize)]
22pub enum DataType {
23 Integer,
24 String,
25 Float,
26 Boolean,
27}
28
29#[derive(Clone, Debug, Serialize, Deserialize)]
30pub struct Table {
31 name: String,
32 columns: Vec<Column>,
33 data: Vec<HashMap<String, Value>>,
34}
35
36
37#[derive(Clone, Debug, Serialize, Deserialize)]
38pub enum Value {
39 Integer(i64),
40 String(String),
41 Float(f64),
42 Boolean(bool),
43 Null,
44}
45
46pub struct Database {
47 tables: HashMap<String, Table>,
48}
49
50impl Database {
51 pub fn new() -> Self {
52 Database {
53 tables: HashMap::new(),
54 }
55 }
56 pub async fn save(&self, path: &str) -> io::Result<()> {
57 let start = Instant::now();
58 let encoded: Vec<u8> = bincode::serialize(&self.tables).unwrap();
59 let mut file = File::create(path)?;
60 file.write_all(&encoded)?;
61
62 println!("Database saved in {:?}", start.elapsed());
63 Ok(())
64 }
65
66 pub async fn load(&mut self, path: &str) -> io::Result<()> {
67 let start = Instant::now();
68 let mut file = File::open(path)?;
69 let mut buffer = Vec::new();
70 file.read_to_end(&mut buffer)?;
71
72 let tables: HashMap<String, Table> = bincode::deserialize(&buffer)
73 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?;
74
75 self.tables = tables;
76 println!("Database loaded in {:?}", start.elapsed());
77 Ok(())
78 }
79 pub fn create_table(&mut self, name: String, columns: Vec<Column>) -> Result<(), String> {
80 let start = Instant::now();
81 if self.tables.contains_key(&name) {
82 return Err(format!("Table {} already exists", name));
83 }
84 self.tables.insert(
85 name.clone(),
86 Table {
87 name,
88 columns,
89 data: Vec::new(),
90 },
91 );
92
93 println!("Table created in {:?}", start.elapsed());
94 Ok(())
95 }
96
97 pub fn insert(&mut self, table_name: &str, row: HashMap<String, Value>) -> Result<(), String> {
98 let start = Instant::now();
99 let table = self
100 .tables
101 .get_mut(table_name)
102 .ok_or_else(|| format!("Table {} not found", table_name))?;
103
104 for col in &table.columns {
105 if !row.contains_key(&col.name) {
106 return Err(format!("Missing column: {}", col.name));
107 }
108 }
109
110 table.data.push(row);
111
112 println!("Row inserted in {:?}", start.elapsed());
113 Ok(())
114 }
115
116 pub fn select(
117 &self,
118 table_name: &str,
119 conditions: Option<fn(&HashMap<String, Value>) -> bool>,
120 ) -> Result<Vec<&HashMap<String, Value>>, String> {
121 let start = Instant::now();
122 let table = self
123 .tables
124 .get(table_name)
125 .ok_or_else(|| format!("Table {} not found", table_name))?;
126
127 let results = match conditions {
128 Some(filter) => table.data.iter().filter(|row| filter(row)).collect(),
129 None => table.data.iter().collect(),
130 };
131
132 println!("Rows selected in {:?}", start.elapsed());
133 Ok(results)
134 }
135
136 pub fn update(
137 &mut self,
138 table_name: &str,
139 conditions: fn(&HashMap<String, Value>) -> bool,
140 update_fn: fn(&mut HashMap<String, Value>),
141 ) -> Result<usize, String> {
142 let table = self
143 .tables
144 .get_mut(table_name)
145 .ok_or_else(|| format!("Table {} not found", table_name))?;
146
147 let mut updated_count = 0;
148 for row in &mut table.data {
149 if conditions(row) {
150 update_fn(row);
151 updated_count += 1;
152 }
153 }
154
155 Ok(updated_count)
156 }
157
158 pub fn delete(
159 &mut self,
160 table_name: &str,
161 conditions: fn(&HashMap<String, Value>) -> bool,
162 ) -> Result<usize, String> {
163 let table = self
164 .tables
165 .get_mut(table_name)
166 .ok_or_else(|| format!("Table {} not found", table_name))?;
167
168 let initial_len = table.data.len();
169 table.data.retain(|row| !conditions(row));
170
171 Ok(initial_len - table.data.len())
172 }
173}