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, DbError, DbResult};
15pub use storage::{MemoryEngine, PersistedEngine, StorageEngine, Row, RowId};
16pub use query::{QueryBuilder, UpdateBuilder, DeleteBuilder, Order, JoinType};
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        // 验证 schema
134        let values_ref: Vec<(String, DbValue)> = row.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
135        schema.validate(&values_ref)?;
136
137        engine.insert(table, row)
138    }
139
140    /// 根据 row_id 获取单行
141    pub fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
142        match &self.engine {
143            DatabaseEngine::Memory(engine) => {
144                let e = engine.read().unwrap();
145                e.get(table, row_id)
146            }
147            DatabaseEngine::Persisted(engine) => {
148                let e = engine.read().unwrap();
149                e.get(table, row_id)
150            }
151        }
152    }
153
154    /// 查询构建器
155    ///
156    /// 内存模式:返回完整的 QueryBuilder,支持所有功能
157    /// 持久化模式:同样支持 QueryBuilder(通过内部 MemoryEngine 的 Arc)
158    pub fn query(&self, table: &str) -> QueryBuilder {
159        match &self.engine {
160            DatabaseEngine::Memory(engine) => {
161                QueryBuilder::new(table.to_string(), Arc::clone(engine))
162            }
163            DatabaseEngine::Persisted(engine) => {
164                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
165                let e = engine.read().unwrap();
166                QueryBuilder::new(table.to_string(), e.inner_arc())
167            }
168        }
169    }
170
171    /// 更新构建器
172    ///
173    /// 内存模式:返回完整的 UpdateBuilder,支持所有功能
174    /// 持久化模式:同样支持 UpdateBuilder(通过内部 MemoryEngine 的 Arc)
175    pub fn update(&self, table: &str) -> UpdateBuilder {
176        match &self.engine {
177            DatabaseEngine::Memory(engine) => {
178                UpdateBuilder::new(table.to_string(), Arc::clone(engine))
179            }
180            DatabaseEngine::Persisted(engine) => {
181                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
182                let e = engine.read().unwrap();
183                UpdateBuilder::new(table.to_string(), e.inner_arc())
184            }
185        }
186    }
187
188    /// 删除构建器
189    ///
190    /// 内存模式:返回完整的 DeleteBuilder,支持所有功能
191    /// 持久化模式:同样支持 DeleteBuilder(通过内部 MemoryEngine 的 Arc)
192    pub fn delete(&self, table: &str) -> DeleteBuilder {
193        match &self.engine {
194            DatabaseEngine::Memory(engine) => {
195                DeleteBuilder::new(table.to_string(), Arc::clone(engine))
196            }
197            DatabaseEngine::Persisted(engine) => {
198                // 持久化模式:使用 PersistedEngine 内部的 MemoryEngine Arc
199                let e = engine.read().unwrap();
200                DeleteBuilder::new(table.to_string(), e.inner_arc())
201            }
202        }
203    }
204
205    /// 执行事务
206    ///
207    /// 事务在两种模式下都支持:
208    /// - 内存模式:支持回滚(通过 WriteLog)
209    /// - 持久化模式:支持回滚 + WAL 日志标记
210    pub fn transaction<F, T>(&self, f: F) -> DbResult<T>
211    where
212        F: FnOnce(&mut Transaction<'_>) -> DbResult<T>,
213    {
214        match &self.engine {
215            DatabaseEngine::Memory(engine) => {
216                let mut e = engine.write().unwrap();
217                // 将 MemoryEngine 转换为 trait object
218                let mut tx = Transaction::new(&mut *e as &mut dyn StorageEngine);
219                let result = f(&mut tx)?;
220                tx.commit()?;
221                Ok(result)
222            }
223            DatabaseEngine::Persisted(engine) => {
224                let mut e = engine.write().unwrap();
225                // PersistedEngine 也实现了 StorageEngine
226                let mut tx = Transaction::new(&mut *e as &mut dyn StorageEngine);
227                let result = f(&mut tx)?;
228                tx.commit()?;
229                Ok(result)
230            }
231        }
232    }
233
234    /// 为表列创建索引(单列,向后兼容)
235    pub fn create_index(&self, table: &str, column: &str) -> DbResult<()> {
236        match &self.engine {
237            DatabaseEngine::Memory(engine) => {
238                let mut e = engine.write().unwrap();
239                e.create_index(table, column)
240            }
241            DatabaseEngine::Persisted(engine) => {
242                let mut e = engine.write().unwrap();
243                e.create_index(table, column)
244            }
245        }
246    }
247
248    /// 创建复合索引
249    pub fn create_composite_index(&self, table: &str, columns: &[&str]) -> DbResult<()> {
250        match &self.engine {
251            DatabaseEngine::Memory(engine) => {
252                let mut e = engine.write().unwrap();
253                e.create_composite_index(table, columns)
254            }
255            DatabaseEngine::Persisted(engine) => {
256                let mut e = engine.write().unwrap();
257                e.create_composite_index(table, columns)
258            }
259        }
260    }
261
262    /// 创建唯一复合索引
263    pub fn create_unique_index(&self, table: &str, columns: &[&str]) -> DbResult<()> {
264        match &self.engine {
265            DatabaseEngine::Memory(engine) => {
266                let mut e = engine.write().unwrap();
267                e.create_unique_index(table, columns)
268            }
269            DatabaseEngine::Persisted(engine) => {
270                let mut e = engine.write().unwrap();
271                e.create_unique_index(table, columns)
272            }
273        }
274    }
275
276    /// 删除索引
277    pub fn drop_index(&self, table: &str, column: &str) -> DbResult<bool> {
278        match &self.engine {
279            DatabaseEngine::Memory(engine) => {
280                let mut e = engine.write().unwrap();
281                e.drop_index(table, column)
282            }
283            DatabaseEngine::Persisted(engine) => {
284                let mut e = engine.write().unwrap();
285                e.drop_index(table, column)
286            }
287        }
288    }
289
290    /// 删除复合索引
291    pub fn drop_composite_index(&self, table: &str, columns: &[&str]) -> DbResult<bool> {
292        match &self.engine {
293            DatabaseEngine::Memory(engine) => {
294                let mut e = engine.write().unwrap();
295                e.drop_composite_index(table, columns)
296            }
297            DatabaseEngine::Persisted(engine) => {
298                let mut e = engine.write().unwrap();
299                e.drop_composite_index(table, columns)
300            }
301        }
302    }
303
304    /// 检查列是否有索引
305    pub fn has_index(&self, table: &str, column: &str) -> bool {
306        match &self.engine {
307            DatabaseEngine::Memory(engine) => {
308                let e = engine.read().unwrap();
309                e.has_index(table, column)
310            }
311            DatabaseEngine::Persisted(engine) => {
312                let e = engine.read().unwrap();
313                e.has_index(table, column)
314            }
315        }
316    }
317
318    /// 检查复合索引是否存在
319    pub fn has_composite_index(&self, table: &str, columns: &[&str]) -> bool {
320        match &self.engine {
321            DatabaseEngine::Memory(engine) => {
322                let e = engine.read().unwrap();
323                e.has_composite_index(table, columns)
324            }
325            DatabaseEngine::Persisted(engine) => {
326                let e = engine.read().unwrap();
327                e.has_composite_index(table, columns)
328            }
329        }
330    }
331}
332
333impl Default for Database {
334    fn default() -> Self {
335        Self::new()
336    }
337}
338
339#[cfg(test)]
340mod tests {
341    use super::*;
342
343    #[test]
344    fn test_create_table() {
345        let db = Database::new();
346        let columns = vec![
347            Column::new("id", DataType::integer()).primary_key(),
348            Column::new("name", DataType::text()),
349            Column::new("age", DataType::integer()),
350        ];
351
352        assert!(db.create_table("users", columns).is_ok());
353        assert!(db.has_table("users"));
354    }
355
356    #[test]
357    fn test_insert_and_query() {
358        let db = Database::new();
359        let columns = vec![
360            Column::new("id", DataType::integer()).primary_key(),
361            Column::new("name", DataType::text()),
362            Column::new("age", DataType::integer()),
363        ];
364        db.create_table("users", columns).unwrap();
365
366        db.insert("users", vec![
367            ("id", DbValue::integer(1)),
368            ("name", DbValue::text("Alice")),
369            ("age", DbValue::integer(25)),
370        ]).unwrap();
371
372        db.insert("users", vec![
373            ("id", DbValue::integer(2)),
374            ("name", DbValue::text("Bob")),
375            ("age", DbValue::integer(30)),
376        ]).unwrap();
377
378        // 使用 scan 验证
379        match &db.engine {
380            DatabaseEngine::Memory(engine) => {
381                let e = engine.read().unwrap();
382                let rows = e.scan("users").unwrap();
383                assert_eq!(rows.len(), 2);
384            }
385            _ => {}
386        }
387    }
388
389    #[test]
390    fn test_transaction_basic() {
391        let db = Database::new();
392        db.create_table("users", vec![
393            Column::new("id", DataType::integer()),
394            Column::new("name", DataType::text()),
395        ]).unwrap();
396
397        let result = db.transaction(|tx| {
398            tx.insert("users", vec![("id", DbValue::integer(1)), ("name", DbValue::text("Alice"))])?;
399            tx.insert("users", vec![("id", DbValue::integer(2)), ("name", DbValue::text("Bob"))])?;
400            Ok(())
401        });
402
403        assert!(result.is_ok());
404
405        // 验证
406        match &db.engine {
407            DatabaseEngine::Memory(engine) => {
408                let e = engine.read().unwrap();
409                let rows = e.scan("users").unwrap();
410                assert_eq!(rows.len(), 2);
411            }
412            _ => {}
413        }
414    }
415
416    #[test]
417    fn test_transaction_rollback() {
418        let db = Database::new();
419        db.create_table("users", vec![
420            Column::new("id", DataType::integer()),
421            Column::new("name", DataType::text()),
422        ]).unwrap();
423
424        // 先插入一条数据
425        db.insert("users", vec![
426            ("id", DbValue::integer(1)),
427            ("name", DbValue::text("Alice")),
428        ]).unwrap();
429
430        // 尝试事务插入后回滚
431        let result = db.transaction(|tx| {
432            tx.insert("users", vec![("id", DbValue::integer(2)), ("name", DbValue::text("Bob"))])?;
433            // 手动回滚
434            tx.rollback()?;
435            Ok(())
436        });
437
438        assert!(result.is_ok());
439
440        // 验证 Bob 没有被插入
441        match &db.engine {
442            DatabaseEngine::Memory(engine) => {
443                let e = engine.read().unwrap();
444                let rows = e.scan("users").unwrap();
445                assert_eq!(rows.len(), 1);
446                assert_eq!(rows[0].1.get("name").unwrap().as_text(), Some("Alice"));
447            }
448            _ => {}
449        }
450    }
451}