Skip to main content

regulus_db/
lib.rs

1//! Regulus DB - 轻量级嵌入式数据库
2//!
3//! 支持两种模式:
4//! - 内存模式:纯内存存储,快速但重启后数据丢失
5//! - 持久化模式:WAL 日志 + 快照,支持崩溃恢复
6
7pub 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
22/// 数据库引擎类型(用于统一 API)
23pub enum DatabaseEngine {
24    /// 内存模式
25    Memory(Arc<RwLock<MemoryEngine>>),
26    /// 持久化模式
27    Persisted(Arc<RwLock<PersistedEngine>>),
28}
29
30/// 数据库主结构
31///
32/// 使用 enum 包装两种引擎模式,提供统一的 API
33pub struct Database {
34    engine: DatabaseEngine,
35}
36
37impl Database {
38    /// 创建新的内存数据库实例
39    pub fn new() -> Self {
40        Database {
41            engine: DatabaseEngine::Memory(Arc::new(RwLock::new(MemoryEngine::new()))),
42        }
43    }
44
45    /// 打开持久化数据库
46    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    /// 创建新的持久化数据库(如果已存在则覆盖)
54    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    /// 创建表
62    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    /// 删除表
77    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    /// 检查表是否存在
91    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    /// 插入数据
105    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    /// 插入数据的通用实现
119    fn insert_with_schema<E: StorageEngine>(
120        engine: &mut E,
121        table: &str,
122        values: Vec<(&str, DbValue)>,
123    ) -> DbResult<RowId> {
124        // 获取 schema 验证列
125        let schema = engine.get_schema(table)?.clone();
126
127        // 构建行
128        let mut row = Row::new();
129        for (name, value) in values {
130            row.insert(name.to_string(), value);
131        }
132
133        // 填充默认值
134        schema.fill_defaults(&mut row);
135
136        // 验证 schema
137        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    /// 根据 row_id 获取单行
144    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    /// 查询构建器
158    ///
159    /// 内存模式:返回完整的 QueryBuilder,支持所有功能
160    /// 持久化模式:同样支持 QueryBuilder(通过内部 MemoryEngine 的 Arc)
161    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                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
168                let e = engine.read().unwrap();
169                QueryBuilder::new(table.to_string(), e.inner_arc())
170            }
171        }
172    }
173
174    /// 更新构建器
175    ///
176    /// 内存模式:返回完整的 UpdateBuilder,支持所有功能
177    /// 持久化模式:同样支持 UpdateBuilder(通过内部 MemoryEngine 的 Arc)
178    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                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
185                let e = engine.read().unwrap();
186                UpdateBuilder::new(table.to_string(), e.inner_arc())
187            }
188        }
189    }
190
191    /// 删除构建器
192    ///
193    /// 内存模式:返回完整的 DeleteBuilder,支持所有功能
194    /// 持久化模式:同样支持 DeleteBuilder(通过内部 MemoryEngine 的 Arc)
195    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                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
202                let e = engine.read().unwrap();
203                DeleteBuilder::new(table.to_string(), e.inner_arc())
204            }
205        }
206    }
207
208    /// 执行事务
209    ///
210    /// 事务在两种模式下都支持:
211    /// - 内存模式:支持回滚(通过 WriteLog)
212    /// - 持久化模式:支持回滚 + WAL 日志标记
213    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                // 将 MemoryEngine 转换为 trait object
221                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                // PersistedEngine 也实现了 StorageEngine
229                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    /// 为表列创建索引(单列,向后兼容)
238    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    /// 创建复合索引
252    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    /// 创建唯一复合索引
266    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    /// 删除索引
280    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    /// 删除复合索引
294    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    /// 检查列是否有索引
308    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    /// 检查复合索引是否存在
322    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        // 使用 scan 验证
382        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        // 验证
409        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        // 先插入一条数据
428        db.insert("users", vec![
429            ("id", DbValue::integer(1)),
430            ("name", DbValue::text("Alice")),
431        ]).unwrap();
432
433        // 尝试事务插入后回滚
434        let result = db.transaction(|tx| {
435            tx.insert("users", vec![("id", DbValue::integer(2)), ("name", DbValue::text("Bob"))])?;
436            // 手动回滚
437            tx.rollback()?;
438            Ok(())
439        });
440
441        assert!(result.is_ok());
442
443        // 验证 Bob 没有被插入
444        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        // 只插入部分字段,依赖默认值
468        db.insert("users", vec![
469            ("id", DbValue::integer(1)),
470            ("name", DbValue::text("Alice")),
471        ]).unwrap();
472
473        // 验证默认值已填充
474        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        // 在事务中插入,依赖默认值
492        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        // 验证默认值已填充
501        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}