1pub mod types;
8pub mod storage;
9pub mod query;
10pub mod index;
11pub mod transaction;
12pub mod persistence;
13
14pub use types::{DbValue, DataType, Column, TableSchema, SchemaError, DbError, DbResult};
15pub use storage::{MemoryEngine, PersistedEngine, StorageEngine, Row, RowId};
16pub use query::{QueryBuilder, UpdateBuilder, DeleteBuilder, Order, JoinType, FilterExpr};
17pub use transaction::Transaction;
18
19use std::sync::{Arc, RwLock};
20use std::path::Path;
21
22pub enum DatabaseEngine {
24 Memory(Arc<RwLock<MemoryEngine>>),
26 Persisted(Arc<RwLock<PersistedEngine>>),
28}
29
30pub struct Database {
34 engine: DatabaseEngine,
35}
36
37impl Database {
38 pub fn new() -> Self {
40 Database {
41 engine: DatabaseEngine::Memory(Arc::new(RwLock::new(MemoryEngine::new()))),
42 }
43 }
44
45 pub fn open(path: &Path) -> DbResult<Self> {
47 let engine = PersistedEngine::open(path)?;
48 Ok(Database {
49 engine: DatabaseEngine::Persisted(Arc::new(RwLock::new(engine))),
50 })
51 }
52
53 pub fn create(path: &Path) -> DbResult<Self> {
55 let engine = PersistedEngine::create(path)?;
56 Ok(Database {
57 engine: DatabaseEngine::Persisted(Arc::new(RwLock::new(engine))),
58 })
59 }
60
61 pub fn create_table(&self, name: &str, columns: Vec<Column>) -> DbResult<()> {
63 let schema = TableSchema::new(name, columns);
64 match &self.engine {
65 DatabaseEngine::Memory(engine) => {
66 let mut e = engine.write().unwrap();
67 e.create_table(schema)
68 }
69 DatabaseEngine::Persisted(engine) => {
70 let mut e = engine.write().unwrap();
71 e.create_table(schema)
72 }
73 }
74 }
75
76 pub fn drop_table(&self, name: &str) -> DbResult<()> {
78 match &self.engine {
79 DatabaseEngine::Memory(engine) => {
80 let mut e = engine.write().unwrap();
81 e.drop_table(name)
82 }
83 DatabaseEngine::Persisted(engine) => {
84 let mut e = engine.write().unwrap();
85 e.drop_table(name)
86 }
87 }
88 }
89
90 pub fn has_table(&self, name: &str) -> bool {
92 match &self.engine {
93 DatabaseEngine::Memory(engine) => {
94 let e = engine.read().unwrap();
95 e.has_table(name)
96 }
97 DatabaseEngine::Persisted(engine) => {
98 let e = engine.read().unwrap();
99 e.has_table(name)
100 }
101 }
102 }
103
104 pub fn insert(&self, table: &str, values: Vec<(&str, DbValue)>) -> DbResult<RowId> {
106 match &self.engine {
107 DatabaseEngine::Memory(engine) => {
108 let mut e = engine.write().unwrap();
109 Self::insert_with_schema(&mut *e, table, values)
110 }
111 DatabaseEngine::Persisted(engine) => {
112 let mut e = engine.write().unwrap();
113 Self::insert_with_schema(&mut *e, table, values)
114 }
115 }
116 }
117
118 fn insert_with_schema<E: StorageEngine>(
120 engine: &mut E,
121 table: &str,
122 values: Vec<(&str, DbValue)>,
123 ) -> DbResult<RowId> {
124 let schema = engine.get_schema(table)?.clone();
126
127 let mut row = Row::new();
129 for (name, value) in values {
130 row.insert(name.to_string(), value);
131 }
132
133 schema.fill_defaults(&mut row);
135
136 let values_ref: Vec<(String, DbValue)> = row.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
138 schema.validate(&values_ref)?;
139
140 engine.insert(table, row)
141 }
142
143 pub fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
145 match &self.engine {
146 DatabaseEngine::Memory(engine) => {
147 let e = engine.read().unwrap();
148 e.get(table, row_id)
149 }
150 DatabaseEngine::Persisted(engine) => {
151 let e = engine.read().unwrap();
152 e.get(table, row_id)
153 }
154 }
155 }
156
157 pub fn query(&self, table: &str) -> QueryBuilder {
162 match &self.engine {
163 DatabaseEngine::Memory(engine) => {
164 QueryBuilder::new(table.to_string(), Arc::clone(engine))
165 }
166 DatabaseEngine::Persisted(engine) => {
167 let e = engine.read().unwrap();
169 QueryBuilder::new(table.to_string(), e.inner_arc())
170 }
171 }
172 }
173
174 pub fn update(&self, table: &str) -> UpdateBuilder {
179 match &self.engine {
180 DatabaseEngine::Memory(engine) => {
181 UpdateBuilder::new(table.to_string(), Arc::clone(engine))
182 }
183 DatabaseEngine::Persisted(engine) => {
184 let e = engine.read().unwrap();
186 UpdateBuilder::new(table.to_string(), e.inner_arc())
187 }
188 }
189 }
190
191 pub fn delete(&self, table: &str) -> DeleteBuilder {
196 match &self.engine {
197 DatabaseEngine::Memory(engine) => {
198 DeleteBuilder::new(table.to_string(), Arc::clone(engine))
199 }
200 DatabaseEngine::Persisted(engine) => {
201 let e = engine.read().unwrap();
203 DeleteBuilder::new(table.to_string(), e.inner_arc())
204 }
205 }
206 }
207
208 pub fn transaction<F, T>(&self, f: F) -> DbResult<T>
214 where
215 F: FnOnce(&mut Transaction<'_>) -> DbResult<T>,
216 {
217 match &self.engine {
218 DatabaseEngine::Memory(engine) => {
219 let mut e = engine.write().unwrap();
220 let mut tx = Transaction::new(&mut *e as &mut dyn StorageEngine);
222 let result = f(&mut tx)?;
223 tx.commit()?;
224 Ok(result)
225 }
226 DatabaseEngine::Persisted(engine) => {
227 let mut e = engine.write().unwrap();
228 let mut tx = Transaction::new(&mut *e as &mut dyn StorageEngine);
230 let result = f(&mut tx)?;
231 tx.commit()?;
232 Ok(result)
233 }
234 }
235 }
236
237 pub fn create_index(&self, table: &str, column: &str) -> DbResult<()> {
239 match &self.engine {
240 DatabaseEngine::Memory(engine) => {
241 let mut e = engine.write().unwrap();
242 e.create_index(table, column)
243 }
244 DatabaseEngine::Persisted(engine) => {
245 let mut e = engine.write().unwrap();
246 e.create_index(table, column)
247 }
248 }
249 }
250
251 pub fn create_composite_index(&self, table: &str, columns: &[&str]) -> DbResult<()> {
253 match &self.engine {
254 DatabaseEngine::Memory(engine) => {
255 let mut e = engine.write().unwrap();
256 e.create_composite_index(table, columns)
257 }
258 DatabaseEngine::Persisted(engine) => {
259 let mut e = engine.write().unwrap();
260 e.create_composite_index(table, columns)
261 }
262 }
263 }
264
265 pub fn create_unique_index(&self, table: &str, columns: &[&str]) -> DbResult<()> {
267 match &self.engine {
268 DatabaseEngine::Memory(engine) => {
269 let mut e = engine.write().unwrap();
270 e.create_unique_index(table, columns)
271 }
272 DatabaseEngine::Persisted(engine) => {
273 let mut e = engine.write().unwrap();
274 e.create_unique_index(table, columns)
275 }
276 }
277 }
278
279 pub fn drop_index(&self, table: &str, column: &str) -> DbResult<bool> {
281 match &self.engine {
282 DatabaseEngine::Memory(engine) => {
283 let mut e = engine.write().unwrap();
284 e.drop_index(table, column)
285 }
286 DatabaseEngine::Persisted(engine) => {
287 let mut e = engine.write().unwrap();
288 e.drop_index(table, column)
289 }
290 }
291 }
292
293 pub fn drop_composite_index(&self, table: &str, columns: &[&str]) -> DbResult<bool> {
295 match &self.engine {
296 DatabaseEngine::Memory(engine) => {
297 let mut e = engine.write().unwrap();
298 e.drop_composite_index(table, columns)
299 }
300 DatabaseEngine::Persisted(engine) => {
301 let mut e = engine.write().unwrap();
302 e.drop_composite_index(table, columns)
303 }
304 }
305 }
306
307 pub fn has_index(&self, table: &str, column: &str) -> bool {
309 match &self.engine {
310 DatabaseEngine::Memory(engine) => {
311 let e = engine.read().unwrap();
312 e.has_index(table, column)
313 }
314 DatabaseEngine::Persisted(engine) => {
315 let e = engine.read().unwrap();
316 e.has_index(table, column)
317 }
318 }
319 }
320
321 pub fn has_composite_index(&self, table: &str, columns: &[&str]) -> bool {
323 match &self.engine {
324 DatabaseEngine::Memory(engine) => {
325 let e = engine.read().unwrap();
326 e.has_composite_index(table, columns)
327 }
328 DatabaseEngine::Persisted(engine) => {
329 let e = engine.read().unwrap();
330 e.has_composite_index(table, columns)
331 }
332 }
333 }
334}
335
336impl Default for Database {
337 fn default() -> Self {
338 Self::new()
339 }
340}
341
342#[cfg(test)]
343mod tests {
344 use super::*;
345
346 #[test]
347 fn test_create_table() {
348 let db = Database::new();
349 let columns = vec![
350 Column::new("id", DataType::integer()).primary_key(),
351 Column::new("name", DataType::text()),
352 Column::new("age", DataType::integer()),
353 ];
354
355 assert!(db.create_table("users", columns).is_ok());
356 assert!(db.has_table("users"));
357 }
358
359 #[test]
360 fn test_insert_and_query() {
361 let db = Database::new();
362 let columns = vec![
363 Column::new("id", DataType::integer()).primary_key(),
364 Column::new("name", DataType::text()),
365 Column::new("age", DataType::integer()),
366 ];
367 db.create_table("users", columns).unwrap();
368
369 db.insert("users", vec![
370 ("id", DbValue::integer(1)),
371 ("name", DbValue::text("Alice")),
372 ("age", DbValue::integer(25)),
373 ]).unwrap();
374
375 db.insert("users", vec![
376 ("id", DbValue::integer(2)),
377 ("name", DbValue::text("Bob")),
378 ("age", DbValue::integer(30)),
379 ]).unwrap();
380
381 match &db.engine {
383 DatabaseEngine::Memory(engine) => {
384 let e = engine.read().unwrap();
385 let rows = e.scan("users").unwrap();
386 assert_eq!(rows.len(), 2);
387 }
388 _ => {}
389 }
390 }
391
392 #[test]
393 fn test_transaction_basic() {
394 let db = Database::new();
395 db.create_table("users", vec![
396 Column::new("id", DataType::integer()),
397 Column::new("name", DataType::text()),
398 ]).unwrap();
399
400 let result = db.transaction(|tx| {
401 tx.insert("users", vec![("id", DbValue::integer(1)), ("name", DbValue::text("Alice"))])?;
402 tx.insert("users", vec![("id", DbValue::integer(2)), ("name", DbValue::text("Bob"))])?;
403 Ok(())
404 });
405
406 assert!(result.is_ok());
407
408 match &db.engine {
410 DatabaseEngine::Memory(engine) => {
411 let e = engine.read().unwrap();
412 let rows = e.scan("users").unwrap();
413 assert_eq!(rows.len(), 2);
414 }
415 _ => {}
416 }
417 }
418
419 #[test]
420 fn test_transaction_rollback() {
421 let db = Database::new();
422 db.create_table("users", vec![
423 Column::new("id", DataType::integer()),
424 Column::new("name", DataType::text()),
425 ]).unwrap();
426
427 db.insert("users", vec![
429 ("id", DbValue::integer(1)),
430 ("name", DbValue::text("Alice")),
431 ]).unwrap();
432
433 let result = db.transaction(|tx| {
435 tx.insert("users", vec![("id", DbValue::integer(2)), ("name", DbValue::text("Bob"))])?;
436 tx.rollback()?;
438 Ok(())
439 });
440
441 assert!(result.is_ok());
442
443 match &db.engine {
445 DatabaseEngine::Memory(engine) => {
446 let e = engine.read().unwrap();
447 let rows = e.scan("users").unwrap();
448 assert_eq!(rows.len(), 1);
449 assert_eq!(rows[0].1.get("name").unwrap().as_text(), Some("Alice"));
450 }
451 _ => {}
452 }
453 }
454
455 #[test]
456 fn test_insert_with_default_values() {
457 let db = Database::new();
458 let columns = vec![
459 Column::new("id", DataType::integer()).primary_key(),
460 Column::new("name", DataType::text()).not_null(),
461 Column::new("status", DataType::text()).default(DbValue::text("active")),
462 Column::new("age", DataType::integer()).default(DbValue::integer(0)),
463 Column::new("active", DataType::boolean()).default(DbValue::boolean(true)),
464 ];
465 db.create_table("users", columns).unwrap();
466
467 db.insert("users", vec![
469 ("id", DbValue::integer(1)),
470 ("name", DbValue::text("Alice")),
471 ]).unwrap();
472
473 let row = db.query("users").eq("id", DbValue::integer(1)).execute().unwrap();
475 assert_eq!(row.len(), 1);
476 assert_eq!(row[0].get("status").unwrap().as_text(), Some("active"));
477 assert_eq!(row[0].get("age").unwrap().as_integer(), Some(0));
478 assert_eq!(row[0].get("active").unwrap().as_boolean(), Some(true));
479 }
480
481 #[test]
482 fn test_transaction_insert_with_default_values() {
483 let db = Database::new();
484 let columns = vec![
485 Column::new("id", DataType::integer()).primary_key(),
486 Column::new("name", DataType::text()).not_null(),
487 Column::new("status", DataType::text()).default(DbValue::text("active")),
488 ];
489 db.create_table("users", columns).unwrap();
490
491 db.transaction(|tx| {
493 tx.insert("users", vec![
494 ("id", DbValue::integer(1)),
495 ("name", DbValue::text("Alice")),
496 ])?;
497 Ok(())
498 }).unwrap();
499
500 let row = db.query("users").eq("id", DbValue::integer(1)).execute().unwrap();
502 assert_eq!(row.len(), 1);
503 assert_eq!(row[0].get("status").unwrap().as_text(), Some("active"));
504 }
505}