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#[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#[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#[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 pub next_autoincrement: i64,
115}
116
117impl Table {
118 pub fn new(schema: TableSchema) -> Self {
119 Table {
120 schema,
121 rows: HashMap::new(),
122 next_row_id: 0,
123 next_autoincrement: 1,
124 }
125 }
126
127 pub fn insert(&mut self, row: Row) -> RowId {
128 let row_id = RowId(self.next_row_id);
129 self.next_row_id += 1;
130 self.rows.insert(row_id, row);
131 row_id
132 }
133
134 pub fn get(&self, row_id: RowId) -> Option<&Row> {
135 self.rows.get(&row_id)
136 }
137
138 pub fn get_mut(&mut self, row_id: RowId) -> Option<&mut Row> {
139 self.rows.get_mut(&row_id)
140 }
141
142 pub fn remove(&mut self, row_id: RowId) -> Option<Row> {
143 self.rows.remove(&row_id)
144 }
145
146 pub fn iter(&self) -> impl Iterator<Item = (RowId, &Row)> {
147 self.rows.iter().map(|(k, v)| (*k, v))
148 }
149
150 pub fn iter_mut(&mut self) -> impl Iterator<Item = (RowId, &mut Row)> {
151 self.rows.iter_mut().map(|(k, v)| (*k, v))
152 }
153}
154
155pub trait StorageEngine {
157 fn create_table(&mut self, schema: TableSchema) -> DbResult<()>;
159
160 fn drop_table(&mut self, name: &str) -> DbResult<()>;
162
163 fn has_table(&self, name: &str) -> bool;
165
166 fn get_schema(&self, name: &str) -> DbResult<TableSchema>;
168
169 fn insert(&mut self, table: &str, row: Row) -> DbResult<RowId>;
171
172 fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>>;
174
175 fn update(&mut self, table: &str, row_id: RowId, values: Row) -> DbResult<()>;
177
178 fn delete(&mut self, table: &str, row_id: RowId) -> DbResult<Option<Row>>;
180
181 fn scan(&self, table: &str) -> DbResult<Vec<(RowId, Row)>>;
183}
184
185pub struct MemoryEngine {
187 tables: HashMap<String, Table>,
188 indexes: IndexManager,
190}
191
192impl MemoryEngine {
193 pub fn new() -> Self {
194 MemoryEngine {
195 tables: HashMap::new(),
196 indexes: IndexManager::new(),
197 }
198 }
199
200 pub fn create_index(&mut self, table: &str, column: &str) -> DbResult<()> {
202 self.create_composite_index(table, &[column])
203 }
204
205 pub fn create_composite_index(&mut self, table: &str, columns: &[&str]) -> DbResult<()> {
207 if !self.has_table(table) {
209 return Err(DbError::TableNotFound(table.to_string()));
210 }
211
212 let schema = self.get_schema(table)?;
214 for &column in columns {
215 if !schema.columns.iter().any(|c| c.name == column) {
216 return Err(DbError::SchemaError(SchemaError::UnknownColumn {
217 table: table.to_string(),
218 column: column.to_string(),
219 }));
220 }
221 }
222
223 self.indexes.create_index(table, columns);
225
226 if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
228 if let Some(tbl) = self.tables.get(table) {
229 for (row_id, row) in tbl.iter() {
230 let mut composite_key = Vec::new();
231 for &column in columns {
232 if let Some(value) = row.get(column) {
233 composite_key.push(value.clone());
234 } else {
235 composite_key.push(DbValue::Null);
236 }
237 }
238 index.insert_composite(composite_key, row_id);
239 }
240 }
241 }
242
243 Ok(())
244 }
245
246 pub fn create_unique_index(&mut self, table: &str, columns: &[&str]) -> DbResult<()> {
248 if !self.has_table(table) {
250 return Err(DbError::TableNotFound(table.to_string()));
251 }
252
253 let schema = self.get_schema(table)?;
255 for &column in columns {
256 if !schema.columns.iter().any(|c| c.name == column) {
257 return Err(DbError::SchemaError(SchemaError::UnknownColumn {
258 table: table.to_string(),
259 column: column.to_string(),
260 }));
261 }
262 }
263
264 self.indexes.create_unique_index(table, columns);
266
267 if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
269 if let Some(tbl) = self.tables.get(table) {
270 for (row_id, row) in tbl.iter() {
271 let mut composite_key = Vec::new();
272 for &column in columns {
273 if let Some(value) = row.get(column) {
274 composite_key.push(value.clone());
275 } else {
276 composite_key.push(DbValue::Null);
277 }
278 }
279 index.insert_composite(composite_key, row_id);
280 }
281 }
282 }
283
284 Ok(())
285 }
286
287 pub fn drop_index(&mut self, table: &str, column: &str) -> DbResult<bool> {
289 Ok(self.indexes.drop_index(table, &[column]))
290 }
291
292 pub fn drop_composite_index(&mut self, table: &str, columns: &[&str]) -> DbResult<bool> {
294 Ok(self.indexes.drop_index(table, columns))
295 }
296
297 pub fn has_index(&self, table: &str, column: &str) -> bool {
299 self.indexes.has_index(table, column)
300 }
301
302 pub fn has_composite_index(&self, table: &str, columns: &[&str]) -> bool {
304 self.indexes.has_composite_index(table, columns)
305 }
306
307 pub fn get_index(&self, table: &str, column: &str) -> Option<&crate::index::BTreeIndex> {
309 self.indexes.get_index(table, column)
310 }
311
312 pub fn get_composite_index(&self, table: &str, columns: &[&str]) -> Option<&crate::index::BTreeIndex> {
314 self.indexes.get_composite_index(table, columns)
315 }
316
317 pub fn get_index_mut(&mut self, table: &str, column: &str) -> Option<&mut crate::index::BTreeIndex> {
319 self.indexes.get_index_mut(table, column)
320 }
321
322 pub fn get_composite_index_mut(&mut self, table: &str, columns: &[&str]) -> Option<&mut crate::index::BTreeIndex> {
324 self.indexes.get_composite_index_mut(table, columns)
325 }
326
327 pub fn drop_table_indexes(&mut self, table: &str) {
329 self.indexes.drop_table_indexes(table);
330 }
331
332 pub fn get_row_count(&self, table: &str) -> DbResult<usize> {
334 self.tables.get(table)
335 .map(|t| t.rows.len())
336 .ok_or_else(|| DbError::TableNotFound(table.to_string()))
337 }
338
339 pub fn remove_from_index(&mut self, table: &str, column: &str, key: &DbValue, row_id: RowId) {
341 if let Some(index) = self.indexes.get_index_mut(table, column) {
342 index.remove(key, row_id);
343 }
344 }
345
346 pub fn remove_from_composite_index(&mut self, table: &str, columns: &[&str], key: &[DbValue], row_id: RowId) {
348 if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
349 index.remove_composite(key, row_id);
350 }
351 }
352
353 pub fn add_to_index(&mut self, table: &str, column: &str, key: DbValue, row_id: RowId) {
355 if let Some(index) = self.indexes.get_index_mut(table, column) {
356 index.insert(key, row_id);
357 }
358 }
359
360 pub fn add_to_composite_index(&mut self, table: &str, columns: &[&str], key: Vec<DbValue>, row_id: RowId) {
362 if let Some(index) = self.indexes.get_composite_index_mut(table, columns) {
363 index.insert_composite(key, row_id);
364 }
365 }
366
367 pub fn find_best_index(&self, table: &str, filter_columns: &[&str]) -> Option<(&IndexMeta, &BTreeIndex)> {
369 self.indexes.find_best_index(table, filter_columns)
370 }
371
372 pub fn serialize(&self) -> Result<SerializableEngineData, String> {
374 let tables: HashMap<String, Table> = self.tables.clone();
375 Ok(SerializableEngineData { tables })
376 }
377
378 pub fn deserialize(data: SerializableEngineData) -> Self {
380 MemoryEngine {
381 tables: data.tables,
382 indexes: IndexManager::new(),
383 }
384 }
385
386 #[doc(hidden)]
388 pub fn new_for_restore() -> Self {
389 MemoryEngine {
390 tables: HashMap::new(),
391 indexes: IndexManager::new(),
392 }
393 }
394
395 #[doc(hidden)]
397 pub fn insert_restored(&mut self, table: &str, row_id: RowId, row: Row) -> DbResult<()> {
398 let tbl = self
399 .tables
400 .get_mut(table)
401 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
402
403 tbl.rows.insert(row_id, row);
404 Ok(())
405 }
406}
407
408#[derive(Debug, Clone, Serialize, Deserialize)]
410pub struct SerializableEngineData {
411 pub tables: HashMap<String, Table>,
412}
413
414impl Default for MemoryEngine {
415 fn default() -> Self {
416 Self::new()
417 }
418}
419
420impl StorageEngine for MemoryEngine {
421 fn create_table(&mut self, schema: TableSchema) -> DbResult<()> {
422 if self.tables.contains_key(&schema.name) {
423 return Err(DbError::TableAlreadyExists(schema.name.clone()));
424 }
425 self.tables.insert(schema.name.clone(), Table::new(schema));
426 Ok(())
427 }
428
429 fn drop_table(&mut self, name: &str) -> DbResult<()> {
430 self.tables
431 .remove(name)
432 .ok_or_else(|| DbError::TableNotFound(name.to_string()))?;
433 self.drop_table_indexes(name);
435 Ok(())
436 }
437
438 fn has_table(&self, name: &str) -> bool {
439 self.tables.contains_key(name)
440 }
441
442 fn get_schema(&self, name: &str) -> DbResult<TableSchema> {
443 self.tables
444 .get(name)
445 .ok_or_else(|| DbError::TableNotFound(name.to_string()))
446 .map(|table| table.schema.clone())
447 }
448
449 fn insert(&mut self, table: &str, mut row: Row) -> DbResult<RowId> {
450 let tbl = self
451 .tables
452 .get_mut(table)
453 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
454
455 if let Some(auto_col) = tbl.schema.auto_increment_column() {
457 if !row.contains_key(&auto_col.name) {
458 let next_val = tbl.next_autoincrement;
460 row.insert(auto_col.name.clone(), DbValue::integer(next_val));
461 tbl.next_autoincrement = next_val + 1;
462 } else {
463 if let Some(DbValue::Integer(user_val)) = row.get(&auto_col.name) {
465 tbl.next_autoincrement = tbl.next_autoincrement.max(*user_val + 1);
466 }
467 }
468 }
469
470 tbl.schema.fill_defaults(&mut row);
472
473 let values: Vec<(String, DbValue)> = row.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
475 tbl.schema.validate(&values)?;
476
477 for column in &tbl.schema.columns {
479 if let Some(value) = row.get(&column.name) {
480 if column.primary_key {
482 for (_, existing_row) in tbl.iter() {
483 if let Some(existing_val) = existing_row.get(&column.name) {
484 if existing_val == value {
485 return Err(DbError::SchemaError(SchemaError::PrimaryKeyViolation {
486 table: table.to_string(),
487 column: column.name.clone(),
488 }));
489 }
490 }
491 }
492 }
493 if column.unique && !column.primary_key {
495 for (_, existing_row) in tbl.iter() {
496 if let Some(existing_val) = existing_row.get(&column.name) {
497 if existing_val == value {
498 return Err(DbError::SchemaError(SchemaError::UniqueViolation {
499 table: table.to_string(),
500 column: column.name.clone(),
501 }));
502 }
503 }
504 }
505 }
506 }
507 }
508
509 let index_metas: Vec<&IndexMeta> = self.indexes.get_table_indexes(table);
511
512 let index_entries: Vec<(String, DbValue)> = index_metas.iter()
514 .filter(|m| m.columns.len() == 1)
515 .flat_map(|m| m.columns.iter())
516 .filter_map(|column| row.get(column).map(|v| (column.clone(), v.clone())))
517 .collect();
518
519 let composite_index_entries: Vec<(Vec<String>, Vec<DbValue>)> = index_metas.iter()
521 .filter(|m| m.columns.len() > 1)
522 .filter_map(|meta| {
523 let key: Vec<DbValue> = meta.columns.iter()
524 .filter_map(|col| row.get(col).cloned())
525 .collect();
526 if key.len() == meta.columns.len() {
527 Some((meta.columns.clone(), key))
528 } else {
529 None
530 }
531 })
532 .collect();
533
534 drop(index_metas); let row_id = tbl.insert(row);
537
538 for (column, value) in index_entries {
540 self.add_to_index(table, &column, value, row_id);
541 }
542
543 for (columns, key) in composite_index_entries {
545 let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
546 self.add_to_composite_index(table, &columns_ref, key, row_id);
547 }
548
549 Ok(row_id)
550 }
551
552 fn get(&self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
553 let tbl = self
554 .tables
555 .get(table)
556 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
557 Ok(tbl.get(row_id).cloned())
558 }
559
560 fn update(&mut self, table: &str, row_id: RowId, values: Row) -> DbResult<()> {
561 let old_row_data: Option<Row> = {
563 let tbl = self.tables.get(table)
564 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
565 tbl.get(row_id).cloned()
566 };
567
568 let tbl = self.tables.get_mut(table)
570 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
571 let values_ref: Vec<(String, DbValue)> = values.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
572 tbl.schema.validate(&values_ref)?;
573
574 let row = tbl.get_mut(row_id).ok_or_else(|| DbError::RowNotFound)?;
575 for (key, value) in values {
576 row.insert(key, value);
577 }
578
579 let new_row_data: Option<Row> = {
581 let tbl = self.tables.get(table)
582 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
583 tbl.get(row_id).cloned()
584 };
585
586 let single_index_columns: Vec<String> = self.indexes.get_table_indexes(table)
589 .into_iter()
590 .filter(|m| m.columns.len() == 1)
591 .filter_map(|m| m.columns.first().cloned())
592 .collect();
593
594 let composite_index_infos: Vec<(Vec<String>, bool)> = self.indexes.get_table_indexes(table)
596 .into_iter()
597 .filter(|m| m.columns.len() > 1)
598 .map(|m| (m.columns.clone(), m.is_unique))
599 .collect();
600
601 if let Some(ref old_row) = old_row_data {
603 for col in &single_index_columns {
605 if let Some(value) = old_row.get(col) {
606 self.remove_from_index(table, col, value, row_id);
607 }
608 }
609
610 for (columns, _is_unique) in &composite_index_infos {
612 let key: Vec<DbValue> = columns.iter()
613 .filter_map(|col| old_row.get(col).cloned())
614 .collect();
615 if key.len() == columns.len() {
616 let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
617 self.remove_from_composite_index(table, &columns_ref, &key, row_id);
618 }
619 }
620 }
621
622 if let Some(ref new_row) = new_row_data {
624 for col in &single_index_columns {
626 if let Some(value) = new_row.get(col) {
627 self.add_to_index(table, col, value.clone(), row_id);
628 }
629 }
630
631 for (columns, _is_unique) in &composite_index_infos {
633 let key: Vec<DbValue> = columns.iter()
634 .filter_map(|col| new_row.get(col).cloned())
635 .collect();
636 if key.len() == columns.len() {
637 let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
638 self.add_to_composite_index(table, &columns_ref, key, row_id);
639 }
640 }
641 }
642
643 Ok(())
644 }
645
646 fn delete(&mut self, table: &str, row_id: RowId) -> DbResult<Option<Row>> {
647 let row_data = {
649 let tbl = self.tables.get(table)
650 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
651 tbl.get(row_id).cloned()
652 };
653
654 let single_index_columns: Vec<String> = self.indexes.get_table_indexes(table)
657 .into_iter()
658 .filter(|m| m.columns.len() == 1)
659 .filter_map(|m| m.columns.first().cloned())
660 .collect();
661
662 let composite_index_infos: Vec<Vec<String>> = self.indexes.get_table_indexes(table)
664 .into_iter()
665 .filter(|m| m.columns.len() > 1)
666 .map(|m| m.columns.clone())
667 .collect();
668
669 if let Some(ref row_data) = row_data {
671 for col in &single_index_columns {
673 if let Some(value) = row_data.get(col) {
674 self.remove_from_index(table, col, value, row_id);
675 }
676 }
677
678 for columns in &composite_index_infos {
680 let key: Vec<DbValue> = columns.iter()
681 .filter_map(|col| row_data.get(col).cloned())
682 .collect();
683 if key.len() == columns.len() {
684 let columns_ref: Vec<&str> = columns.iter().map(|s| s.as_str()).collect();
685 self.remove_from_composite_index(table, &columns_ref, &key, row_id);
686 }
687 }
688 }
689
690 let tbl = self.tables.get_mut(table)
692 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
693 Ok(tbl.remove(row_id))
694 }
695
696 fn scan(&self, table: &str) -> DbResult<Vec<(RowId, Row)>> {
697 let tbl = self
698 .tables
699 .get(table)
700 .ok_or_else(|| DbError::TableNotFound(table.to_string()))?;
701 Ok(tbl.iter().map(|(k, v)| (k, v.clone())).collect())
702 }
703}
704
705#[cfg(test)]
706mod tests {
707 use super::*;
708 use crate::types::{DataType, Column};
709
710 fn create_test_schema() -> TableSchema {
711 TableSchema::new(
712 "users",
713 vec![
714 Column::new("id", DataType::integer()).primary_key(),
715 Column::new("name", DataType::text()),
716 Column::new("age", DataType::integer()),
717 ],
718 )
719 }
720
721 fn create_test_row() -> Row {
722 let mut row = Row::new();
723 row.insert("id".to_string(), DbValue::integer(1));
724 row.insert("name".to_string(), DbValue::text("Alice"));
725 row.insert("age".to_string(), DbValue::integer(25));
726 row
727 }
728
729 #[test]
730 fn test_create_table() {
731 let mut engine = MemoryEngine::new();
732 let schema = create_test_schema();
733
734 assert!(engine.create_table(schema).is_ok());
735 assert!(engine.has_table("users"));
736
737 let schema2 = create_test_schema();
739 assert!(matches!(
740 engine.create_table(schema2),
741 Err(DbError::TableAlreadyExists(_))
742 ));
743 }
744
745 #[test]
746 fn test_insert_and_get() {
747 let mut engine = MemoryEngine::new();
748 engine.create_table(create_test_schema()).unwrap();
749
750 let row = create_test_row();
751 let row_id = engine.insert("users", row).unwrap();
752
753 let retrieved = engine.get("users", row_id).unwrap().unwrap();
754 assert_eq!(retrieved.get("name").unwrap().as_text(), Some("Alice"));
755 }
756
757 #[test]
758 fn test_update() {
759 let mut engine = MemoryEngine::new();
760 engine.create_table(create_test_schema()).unwrap();
761
762 let row = create_test_row();
763 let row_id = engine.insert("users", row).unwrap();
764
765 let mut update_values = Row::new();
766 update_values.insert("age".to_string(), DbValue::integer(26));
767
768 engine.update("users", row_id, update_values).unwrap();
769
770 let retrieved = engine.get("users", row_id).unwrap().unwrap();
771 assert_eq!(retrieved.get("age").unwrap().as_integer(), Some(26));
772 }
773
774 #[test]
775 fn test_delete() {
776 let mut engine = MemoryEngine::new();
777 engine.create_table(create_test_schema()).unwrap();
778
779 let row = create_test_row();
780 let row_id = engine.insert("users", row).unwrap();
781
782 let deleted = engine.delete("users", row_id).unwrap().unwrap();
783 assert_eq!(deleted.get("name").unwrap().as_text(), Some("Alice"));
784
785 assert!(engine.get("users", row_id).unwrap().is_none());
786 }
787
788 #[test]
789 fn test_scan() {
790 let mut engine = MemoryEngine::new();
791 engine.create_table(create_test_schema()).unwrap();
792
793 for i in 0..3 {
794 let mut row = Row::new();
795 row.insert("id".to_string(), DbValue::integer(i));
796 row.insert("name".to_string(), DbValue::text(format!("User{}", i)));
797 row.insert("age".to_string(), DbValue::integer(20 + i));
798 engine.insert("users", row).unwrap();
799 }
800
801 let rows = engine.scan("users").unwrap();
802 assert_eq!(rows.len(), 3);
803 }
804
805 #[test]
806 fn test_insert_with_default_values() {
807 let mut engine = MemoryEngine::new();
808 let schema = TableSchema::new(
809 "users",
810 vec![
811 Column::new("id", DataType::integer()).primary_key(),
812 Column::new("name", DataType::text()).not_null(),
813 Column::new("status", DataType::text()).default(DbValue::text("active")),
814 Column::new("age", DataType::integer()).default(DbValue::integer(0)),
815 Column::new("active", DataType::boolean()).default(DbValue::boolean(true)),
816 ],
817 );
818 engine.create_table(schema).unwrap();
819
820 let mut row = Row::new();
822 row.insert("id".to_string(), DbValue::integer(1));
823 row.insert("name".to_string(), DbValue::text("Alice"));
824
825 let row_id = engine.insert("users", row).unwrap();
826
827 let retrieved = engine.get("users", row_id).unwrap().unwrap();
829 assert_eq!(retrieved.get("status").unwrap().as_text(), Some("active"));
830 assert_eq!(retrieved.get("age").unwrap().as_integer(), Some(0));
831 assert_eq!(retrieved.get("active").unwrap().as_boolean(), Some(true));
832 }
833
834 #[test]
835 fn test_insert_with_explicit_value_overrides_default() {
836 let mut engine = MemoryEngine::new();
837 let schema = TableSchema::new(
838 "users",
839 vec![
840 Column::new("id", DataType::integer()).primary_key(),
841 Column::new("name", DataType::text()).not_null(),
842 Column::new("status", DataType::text()).default(DbValue::text("active")),
843 ],
844 );
845 engine.create_table(schema).unwrap();
846
847 let mut row = Row::new();
849 row.insert("id".to_string(), DbValue::integer(1));
850 row.insert("name".to_string(), DbValue::text("Bob"));
851 row.insert("status".to_string(), DbValue::text("inactive"));
852
853 let row_id = engine.insert("users", row).unwrap();
854
855 let retrieved = engine.get("users", row_id).unwrap().unwrap();
857 assert_eq!(retrieved.get("status").unwrap().as_text(), Some("inactive"));
858 }
859}