Skip to main content

regulus_db/storage/
engine.rs

1use crate::types::{DbValue, TableSchema, DbResult, DbError, SchemaError};
2use crate::index::IndexManager;
3use crate::index::manager::IndexMeta;
4use crate::index::btree::BTreeIndex;
5use indexmap::IndexMap;
6use std::collections::HashMap;
7use serde::{Serialize, Deserialize};
8
9/// 行 ID 类型
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub struct RowId(pub u64);
12
13impl RowId {
14    pub fn new(id: u64) -> Self {
15        RowId(id)
16    }
17}
18
19/// 行数据 - 使用 IndexMap 保持列顺序
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Row(pub IndexMap<String, DbValue>);
22
23impl Row {
24    pub fn new() -> Self {
25        Row(IndexMap::new())
26    }
27
28    pub fn len(&self) -> usize {
29        self.0.len()
30    }
31
32    pub fn is_empty(&self) -> bool {
33        self.0.is_empty()
34    }
35
36    pub fn iter(&self) -> impl Iterator<Item = (&String, &DbValue)> {
37        self.0.iter()
38    }
39
40    pub fn insert(&mut self, key: String, value: DbValue) -> Option<DbValue> {
41        self.0.insert(key, value)
42    }
43
44    pub fn get(&self, key: &str) -> Option<&DbValue> {
45        self.0.get(key)
46    }
47
48    pub fn get_mut(&mut self, key: &str) -> Option<&mut DbValue> {
49        self.0.get_mut(key)
50    }
51
52    pub fn contains_key(&self, key: &str) -> bool {
53        self.0.contains_key(key)
54    }
55
56    pub fn remove(&mut self, key: &str) -> Option<DbValue> {
57        self.0.shift_remove(key)
58    }
59}
60
61impl std::ops::Deref for Row {
62    type Target = IndexMap<String, DbValue>;
63
64    fn deref(&self) -> &Self::Target {
65        &self.0
66    }
67}
68
69impl std::ops::DerefMut for Row {
70    fn deref_mut(&mut self) -> &mut Self::Target {
71        &mut self.0
72    }
73}
74
75impl IntoIterator for Row {
76    type Item = (String, DbValue);
77    type IntoIter = indexmap::map::IntoIter<String, DbValue>;
78
79    fn into_iter(self) -> Self::IntoIter {
80        self.0.into_iter()
81    }
82}
83
84impl<'a> IntoIterator for &'a Row {
85    type Item = (&'a String, &'a DbValue);
86    type IntoIter = indexmap::map::Iter<'a, String, DbValue>;
87
88    fn into_iter(self) -> Self::IntoIter {
89        self.0.iter()
90    }
91}
92
93impl<'a> IntoIterator for &'a mut Row {
94    type Item = (&'a String, &'a mut DbValue);
95    type IntoIter = indexmap::map::IterMut<'a, String, DbValue>;
96
97    fn into_iter(self) -> Self::IntoIter {
98        self.0.iter_mut()
99    }
100}
101
102impl FromIterator<(String, DbValue)> for Row {
103    fn from_iter<T: IntoIterator<Item = (String, DbValue)>>(iter: T) -> Self {
104        Row(iter.into_iter().collect())
105    }
106}
107
108/// 表数据容器
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct Table {
111    pub schema: TableSchema,
112    pub rows: HashMap<RowId, Row>,
113    pub next_row_id: u64,
114}
115
116impl Table {
117    pub fn new(schema: TableSchema) -> Self {
118        Table {
119            schema,
120            rows: HashMap::new(),
121            next_row_id: 0,
122        }
123    }
124
125    pub fn insert(&mut self, row: Row) -> RowId {
126        let row_id = RowId(self.next_row_id);
127        self.next_row_id += 1;
128        self.rows.insert(row_id, row);
129        row_id
130    }
131
132    pub fn get(&self, row_id: RowId) -> Option<&Row> {
133        self.rows.get(&row_id)
134    }
135
136    pub fn get_mut(&mut self, row_id: RowId) -> Option<&mut Row> {
137        self.rows.get_mut(&row_id)
138    }
139
140    pub fn remove(&mut self, row_id: RowId) -> Option<Row> {
141        self.rows.remove(&row_id)
142    }
143
144    pub fn iter(&self) -> impl Iterator<Item = (RowId, &Row)> {
145        self.rows.iter().map(|(k, v)| (*k, v))
146    }
147
148    pub fn iter_mut(&mut self) -> impl Iterator<Item = (RowId, &mut Row)> {
149        self.rows.iter_mut().map(|(k, v)| (*k, v))
150    }
151}
152
153/// 存储引擎 trait
154pub trait StorageEngine {
155    /// 创建表
156    fn create_table(&mut self, schema: TableSchema) -> DbResult<()>;
157
158    /// 删除表
159    fn drop_table(&mut self, name: &str) -> DbResult<()>;
160
161    /// 检查表是否存在
162    fn has_table(&self, name: &str) -> bool;
163
164    /// 获取表 schema(返回克隆,支持锁守卫场景)
165    fn get_schema(&self, name: &str) -> DbResult<TableSchema>;
166
167    /// 插入行
168    fn insert(&mut self, table: &str, row: Row) -> DbResult<RowId>;
169
170    /// 获取行(返回克隆,支持锁守卫场景)
171    fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>>;
172
173    /// 更新行
174    fn update(&mut self, table: &str, row_id: RowId, values: Row) -> DbResult<()>;
175
176    /// 删除行
177    fn delete(&mut self, table: &str, row_id: RowId) -> DbResult<Option<Row>>;
178
179    /// 扫描全表(返回克隆,支持锁守卫场景)
180    fn scan(&self, table: &str) -> DbResult<Vec<(RowId, Row)>>;
181}
182
183/// 内存存储引擎实现
184pub struct MemoryEngine {
185    tables: HashMap<String, Table>,
186    /// 索引管理器
187    indexes: IndexManager,
188}
189
190impl MemoryEngine {
191    pub fn new() -> Self {
192        MemoryEngine {
193            tables: HashMap::new(),
194            indexes: IndexManager::new(),
195        }
196    }
197
198    /// 为表列创建索引(单列,向后兼容)
199    pub fn create_index(&mut self, table: &str, column: &str) -> DbResult<()> {
200        self.create_composite_index(table, &[column])
201    }
202
203    /// 为表列创建复合索引
204    pub fn create_composite_index(&mut self, table: &str, columns: &[&str]) -> DbResult<()> {
205        // 检查表是否存在
206        if !self.has_table(table) {
207            return Err(DbError::TableNotFound(table.to_string()));
208        }
209
210        // 检查列是否存在
211        let schema = self.get_schema(table)?;
212        for &column in columns {
213            if !schema.columns.iter().any(|c| c.name == column) {
214                return Err(DbError::SchemaError(SchemaError::UnknownColumn {
215                    table: table.to_string(),
216                    column: column.to_string(),
217                }));
218            }
219        }
220
221        // 创建索引
222        self.indexes.create_index(table, columns);
223
224        // 构建索引:扫描现有数据
225        if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
226            if let Some(tbl) = self.tables.get(table) {
227                for (row_id, row) in tbl.iter() {
228                    let mut composite_key = Vec::new();
229                    for &column in columns {
230                        if let Some(value) = row.get(column) {
231                            composite_key.push(value.clone());
232                        } else {
233                            composite_key.push(DbValue::Null);
234                        }
235                    }
236                    index.insert_composite(composite_key, row_id);
237                }
238            }
239        }
240
241        Ok(())
242    }
243
244    /// 创建唯一复合索引
245    pub fn create_unique_index(&mut self, table: &str, columns: &[&str]) -> DbResult<()> {
246        // 检查表是否存在
247        if !self.has_table(table) {
248            return Err(DbError::TableNotFound(table.to_string()));
249        }
250
251        // 检查列是否存在
252        let schema = self.get_schema(table)?;
253        for &column in columns {
254            if !schema.columns.iter().any(|c| c.name == column) {
255                return Err(DbError::SchemaError(SchemaError::UnknownColumn {
256                    table: table.to_string(),
257                    column: column.to_string(),
258                }));
259            }
260        }
261
262        // 创建唯一索引
263        self.indexes.create_unique_index(table, columns);
264
265        // 构建索引:扫描现有数据
266        if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
267            if let Some(tbl) = self.tables.get(table) {
268                for (row_id, row) in tbl.iter() {
269                    let mut composite_key = Vec::new();
270                    for &column in columns {
271                        if let Some(value) = row.get(column) {
272                            composite_key.push(value.clone());
273                        } else {
274                            composite_key.push(DbValue::Null);
275                        }
276                    }
277                    index.insert_composite(composite_key, row_id);
278                }
279            }
280        }
281
282        Ok(())
283    }
284
285    /// 删除索引
286    pub fn drop_index(&mut self, table: &str, column: &str) -> DbResult<bool> {
287        Ok(self.indexes.drop_index(table, &[column]))
288    }
289
290    /// 删除复合索引
291    pub fn drop_composite_index(&mut self, table: &str, columns: &[&str]) -> DbResult<bool> {
292        Ok(self.indexes.drop_index(table, columns))
293    }
294
295    /// 检查列是否有索引
296    pub fn has_index(&self, table: &str, column: &str) -> bool {
297        self.indexes.has_index(table, column)
298    }
299
300    /// 检查复合索引是否存在
301    pub fn has_composite_index(&self, table: &str, columns: &[&str]) -> bool {
302        self.indexes.has_composite_index(table, columns)
303    }
304
305    /// 获取索引(不可变引用,单列)
306    pub fn get_index(&self, table: &str, column: &str) -> Option<&crate::index::BTreeIndex> {
307        self.indexes.get_index(table, column)
308    }
309
310    /// 获取复合索引(不可变引用)
311    pub fn get_composite_index(&self, table: &str, columns: &[&str]) -> Option<&crate::index::BTreeIndex> {
312        self.indexes.get_composite_index(table, columns)
313    }
314
315    /// 获取索引(可变引用,单列)
316    pub fn get_index_mut(&mut self, table: &str, column: &str) -> Option<&mut crate::index::BTreeIndex> {
317        self.indexes.get_index_mut(table, column)
318    }
319
320    /// 获取复合索引(可变引用)
321    pub fn get_composite_index_mut(&mut self, table: &str, columns: &[&str]) -> Option<&mut crate::index::BTreeIndex> {
322        self.indexes.get_composite_index_mut(table, columns)
323    }
324
325    /// 删除表的所有索引
326    pub fn drop_table_indexes(&mut self, table: &str) {
327        self.indexes.drop_table_indexes(table);
328    }
329
330    /// 获取表的行数
331    pub fn get_row_count(&self, table: &str) -> DbResult<usize> {
332        self.tables.get(table)
333            .map(|t| t.rows.len())
334            .ok_or_else(|| DbError::TableNotFound(table.to_string()))
335    }
336
337    /// 从索引中删除键值对(用于 delete 操作,单列)
338    pub fn remove_from_index(&mut self, table: &str, column: &str, key: &DbValue, row_id: RowId) {
339        if let Some(index) = self.indexes.get_index_mut(table, column) {
340            index.remove(key, row_id);
341        }
342    }
343
344    /// 从复合索引中删除键值对
345    pub fn remove_from_composite_index(&mut self, table: &str, columns: &[&str], key: &[DbValue], row_id: RowId) {
346        if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
347            index.remove_composite(key, row_id);
348        }
349    }
350
351    /// 向索引添加键值对(用于 insert 操作,单列)
352    pub fn add_to_index(&mut self, table: &str, column: &str, key: DbValue, row_id: RowId) {
353        if let Some(index) = self.indexes.get_index_mut(table, column) {
354            index.insert(key, row_id);
355        }
356    }
357
358    /// 向复合索引添加键值对
359    pub fn add_to_composite_index(&mut self, table: &str, columns: &[&str], key: Vec<DbValue>, row_id: RowId) {
360        if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
361            index.insert_composite(key, row_id);
362        }
363    }
364
365    /// 查找最佳索引
366    pub fn find_best_index(&self, table: &str, filter_columns: &[&str]) -> Option<(&IndexMeta, &BTreeIndex)> {
367        self.indexes.find_best_index(table, filter_columns)
368    }
369
370    /// 序列化引擎数据(用于快照)
371    pub fn serialize(&self) -> Result<SerializableEngineData, String> {
372        let tables: HashMap<String, Table> = self.tables.clone();
373        Ok(SerializableEngineData { tables })
374    }
375
376    /// 从序列化数据恢复(用于快照加载)
377    pub fn deserialize(data: SerializableEngineData) -> Self {
378        MemoryEngine {
379            tables: data.tables,
380            indexes: IndexManager::new(),
381        }
382    }
383
384    /// 为恢复创建新的 MemoryEngine(内部使用)
385    #[doc(hidden)]
386    pub fn new_for_restore() -> Self {
387        MemoryEngine {
388            tables: HashMap::new(),
389            indexes: IndexManager::new(),
390        }
391    }
392
393    /// 恢复时插入行(跳过 WAL)
394    #[doc(hidden)]
395    pub fn insert_restored(&mut self, table: &str, row_id: RowId, row: Row) -> DbResult<()> {
396        let tbl = self
397            .tables
398            .get_mut(table)
399            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
400
401        tbl.rows.insert(row_id, row);
402        Ok(())
403    }
404}
405
406/// 可序列化的引擎数据
407#[derive(Debug, Clone, Serialize, Deserialize)]
408pub struct SerializableEngineData {
409    pub tables: HashMap<String, Table>,
410}
411
412impl Default for MemoryEngine {
413    fn default() -> Self {
414        Self::new()
415    }
416}
417
418impl StorageEngine for MemoryEngine {
419    fn create_table(&mut self, schema: TableSchema) -> DbResult<()> {
420        if self.tables.contains_key(&schema.name) {
421            return Err(DbError::TableAlreadyExists(schema.name.clone()));
422        }
423        self.tables.insert(schema.name.clone(), Table::new(schema));
424        Ok(())
425    }
426
427    fn drop_table(&mut self, name: &str) -> DbResult<()> {
428        self.tables
429            .remove(name)
430            .ok_or_else(|| DbError::TableNotFound(name.to_string()))?;
431        // 删除表的所有索引
432        self.drop_table_indexes(name);
433        Ok(())
434    }
435
436    fn has_table(&self, name: &str) -> bool {
437        self.tables.contains_key(name)
438    }
439
440    fn get_schema(&self, name: &str) -> DbResult<TableSchema> {
441        self.tables
442            .get(name)
443            .ok_or_else(|| DbError::TableNotFound(name.to_string()))
444            .map(|table| table.schema.clone())
445    }
446
447    fn insert(&mut self, table: &str, row: Row) -> DbResult<RowId> {
448        let tbl = self
449            .tables
450            .get_mut(table)
451            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
452
453        // 验证 schema
454        let values: Vec<(String, DbValue)> = row.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
455        tbl.schema.validate(&values)?;
456
457        // 先获取需要索引的列和值(在插入之前)
458        let index_metas: Vec<&IndexMeta> = self.indexes.get_table_indexes(table);
459
460        // 收集单列索引条目
461        let index_entries: Vec<(String, DbValue)> = index_metas.iter()
462            .filter(|m| m.columns.len() == 1)
463            .flat_map(|m| m.columns.iter())
464            .filter_map(|column| row.get(column).map(|v| (column.clone(), v.clone())))
465            .collect();
466
467        // 收集复合索引条目(存储列名而不是引用)
468        let composite_index_entries: Vec<(Vec<String>, Vec<DbValue>)> = index_metas.iter()
469            .filter(|m| m.columns.len() > 1)
470            .filter_map(|meta| {
471                let key: Vec<DbValue> = meta.columns.iter()
472                    .filter_map(|col| row.get(col).cloned())
473                    .collect();
474                if key.len() == meta.columns.len() {
475                    Some((meta.columns.clone(), key))
476                } else {
477                    None
478                }
479            })
480            .collect();
481
482        drop(index_metas); // 提前释放借用
483
484        let row_id = tbl.insert(row);
485
486        // 更新单列索引
487        for (column, value) in index_entries {
488            self.add_to_index(table, &column, value, row_id);
489        }
490
491        // 更新复合索引
492        for (columns, key) in composite_index_entries {
493            let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
494            self.add_to_composite_index(table, &columns_ref, key, row_id);
495        }
496
497        Ok(row_id)
498    }
499
500    fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
501        let tbl = self
502            .tables
503            .get(table)
504            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
505        Ok(tbl.get(row_id).cloned())
506    }
507
508    fn update(&mut self, table: &str, row_id: RowId, values: Row) -> DbResult<()> {
509        // 获取旧值(用于从索引中删除)
510        let old_row_data: Option<Row> = {
511            let tbl = self.tables.get(table)
512                .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
513            tbl.get(row_id).cloned()
514        };
515
516        // 验证 schema 并更新行
517        let tbl = self.tables.get_mut(table)
518            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
519        let values_ref: Vec<(String, DbValue)> = values.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
520        tbl.schema.validate(&values_ref)?;
521
522        let row = tbl.get_mut(row_id).ok_or_else(|| DbError::RowNotFound)?;
523        for (key, value) in values {
524            row.insert(key, value);
525        }
526
527        // 获取新值(用于添加到索引)
528        let new_row_data: Option<Row> = {
529            let tbl = self.tables.get(table)
530                .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
531            tbl.get(row_id).cloned()
532        };
533
534        // 提取索引元数据信息(避免借用冲突)
535        // 单列索引:列名列表
536        let single_index_columns: Vec<String> = self.indexes.get_table_indexes(table)
537            .into_iter()
538            .filter(|m| m.columns.len() == 1)
539            .filter_map(|m| m.columns.first().cloned())
540            .collect();
541
542        // 复合索引:(列名列表,is_unique)
543        let composite_index_infos: Vec<(Vec<String>, bool)> = self.indexes.get_table_indexes(table)
544            .into_iter()
545            .filter(|m| m.columns.len() > 1)
546            .map(|m| (m.columns.clone(), m.is_unique))
547            .collect();
548
549        // 更新索引:先删除旧值
550        if let Some(ref old_row) = old_row_data {
551            // 删除单列索引
552            for col in &single_index_columns {
553                if let Some(value) = old_row.get(col) {
554                    self.remove_from_index(table, col, value, row_id);
555                }
556            }
557
558            // 删除复合索引
559            for (columns, _is_unique) in &composite_index_infos {
560                let key: Vec<DbValue> = columns.iter()
561                    .filter_map(|col| old_row.get(col).cloned())
562                    .collect();
563                if key.len() == columns.len() {
564                    let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
565                    self.remove_from_composite_index(table, &columns_ref, &key, row_id);
566                }
567            }
568        }
569
570        // 添加新值到索引
571        if let Some(ref new_row) = new_row_data {
572            // 添加单列索引
573            for col in &single_index_columns {
574                if let Some(value) = new_row.get(col) {
575                    self.add_to_index(table, col, value.clone(), row_id);
576                }
577            }
578
579            // 添加复合索引
580            for (columns, _is_unique) in &composite_index_infos {
581                let key: Vec<DbValue> = columns.iter()
582                    .filter_map(|col| new_row.get(col).cloned())
583                    .collect();
584                if key.len() == columns.len() {
585                    let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
586                    self.add_to_composite_index(table, &columns_ref, key, row_id);
587                }
588            }
589        }
590
591        Ok(())
592    }
593
594    fn delete(&mut self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
595        // 获取要删除的行数据
596        let row_data = {
597            let tbl = self.tables.get(table)
598                .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
599            tbl.get(row_id).cloned()
600        };
601
602        // 提取索引元数据信息(避免借用冲突)
603        // 单列索引:列名列表
604        let single_index_columns: Vec<String> = self.indexes.get_table_indexes(table)
605            .into_iter()
606            .filter(|m| m.columns.len() == 1)
607            .filter_map(|m| m.columns.first().cloned())
608            .collect();
609
610        // 复合索引:列名列表
611        let composite_index_infos: Vec<Vec<String>> = self.indexes.get_table_indexes(table)
612            .into_iter()
613            .filter(|m| m.columns.len() > 1)
614            .map(|m| m.columns.clone())
615            .collect();
616
617        // 从索引中删除
618        if let Some(ref row_data) = row_data {
619            // 删除单列索引
620            for col in &single_index_columns {
621                if let Some(value) = row_data.get(col) {
622                    self.remove_from_index(table, col, value, row_id);
623                }
624            }
625
626            // 删除复合索引
627            for columns in &composite_index_infos {
628                let key: Vec<DbValue> = columns.iter()
629                    .filter_map(|col| row_data.get(col).cloned())
630                    .collect();
631                if key.len() == columns.len() {
632                    let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
633                    self.remove_from_composite_index(table, &columns_ref, &key, row_id);
634                }
635            }
636        }
637
638        // 删除行
639        let tbl = self.tables.get_mut(table)
640            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
641        Ok(tbl.remove(row_id))
642    }
643
644    fn scan(&self, table: &str) -> DbResult<Vec<(RowId, Row)>> {
645        let tbl = self
646            .tables
647            .get(table)
648            .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
649        Ok(tbl.iter().map(|(k, v)| (k, v.clone())).collect())
650    }
651}
652
653#[cfg(test)]
654mod tests {
655    use super::*;
656    use crate::types::{DataType, Column};
657
658    fn create_test_schema() -> TableSchema {
659        TableSchema::new(
660            "users",
661            vec![
662                Column::new("id", DataType::integer()).primary_key(),
663                Column::new("name", DataType::text()),
664                Column::new("age", DataType::integer()),
665            ],
666        )
667    }
668
669    fn create_test_row() -> Row {
670        let mut row = Row::new();
671        row.insert("id".to_string(), DbValue::integer(1));
672        row.insert("name".to_string(), DbValue::text("Alice"));
673        row.insert("age".to_string(), DbValue::integer(25));
674        row
675    }
676
677    #[test]
678    fn test_create_table() {
679        let mut engine = MemoryEngine::new();
680        let schema = create_test_schema();
681
682        assert!(engine.create_table(schema).is_ok());
683        assert!(engine.has_table("users"));
684
685        // 重复创建应该失败
686        let schema2 = create_test_schema();
687        assert!(matches!(
688            engine.create_table(schema2),
689            Err(DbError::TableAlreadyExists(_))
690        ));
691    }
692
693    #[test]
694    fn test_insert_and_get() {
695        let mut engine = MemoryEngine::new();
696        engine.create_table(create_test_schema()).unwrap();
697
698        let row = create_test_row();
699        let row_id = engine.insert("users", row).unwrap();
700
701        let retrieved = engine.get("users", row_id).unwrap().unwrap();
702        assert_eq!(retrieved.get("name").unwrap().as_text(), Some("Alice"));
703    }
704
705    #[test]
706    fn test_update() {
707        let mut engine = MemoryEngine::new();
708        engine.create_table(create_test_schema()).unwrap();
709
710        let row = create_test_row();
711        let row_id = engine.insert("users", row).unwrap();
712
713        let mut update_values = Row::new();
714        update_values.insert("age".to_string(), DbValue::integer(26));
715
716        engine.update("users", row_id, update_values).unwrap();
717
718        let retrieved = engine.get("users", row_id).unwrap().unwrap();
719        assert_eq!(retrieved.get("age").unwrap().as_integer(), Some(26));
720    }
721
722    #[test]
723    fn test_delete() {
724        let mut engine = MemoryEngine::new();
725        engine.create_table(create_test_schema()).unwrap();
726
727        let row = create_test_row();
728        let row_id = engine.insert("users", row).unwrap();
729
730        let deleted = engine.delete("users", row_id).unwrap().unwrap();
731        assert_eq!(deleted.get("name").unwrap().as_text(), Some("Alice"));
732
733        assert!(engine.get("users", row_id).unwrap().is_none());
734    }
735
736    #[test]
737    fn test_scan() {
738        let mut engine = MemoryEngine::new();
739        engine.create_table(create_test_schema()).unwrap();
740
741        for i in 0..3 {
742            let mut row = Row::new();
743            row.insert("id".to_string(), DbValue::integer(i));
744            row.insert("name".to_string(), DbValue::text(format!("User{}", i)));
745            row.insert("age".to_string(), DbValue::integer(20 + i));
746            engine.insert("users", row).unwrap();
747        }
748
749        let rows = engine.scan("users").unwrap();
750        assert_eq!(rows.len(), 3);
751    }
752}