This commit is contained in:
Hassan Abedi 2026-04-10 16:07:26 +02:00
parent dff8adebfa
commit f0d22976c7

View File

@ -0,0 +1,72 @@
//! An in-memory table store backed by hash maps.
use std::collections::HashMap;
use crate::relational::{ResultSet, Row, Schema};
use super::{DataSource, ExecutionError};
/// A simple in-memory data source backed by named tables of rows.
///
/// Unlike [`Instance`](crate::chase::Instance), which stores chase-level atoms,
/// `TableStore` holds typed relational rows directly. This makes it useful for
/// testing and for scenarios where data does not originate from the chase engine.
#[derive(Debug, Clone, Default)]
pub struct TableStore {
tables: HashMap<String, (Schema, Vec<Row>)>,
}
impl TableStore {
/// Create an empty table store.
pub fn new() -> Self {
Self::default()
}
/// Register a table with its schema and initial rows.
pub fn insert(&mut self, name: impl Into<String>, schema: Schema, rows: Vec<Row>) {
self.tables.insert(name.into(), (schema, rows));
}
}
impl DataSource for TableStore {
fn scan(&self, table: &str, schema: &Schema) -> Result<ResultSet, ExecutionError> {
match self.tables.get(table) {
Some((_, rows)) => Ok(ResultSet::new(schema.clone(), rows.clone())),
None => Ok(ResultSet::new(schema.clone(), Vec::new())),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::relational::{DataType, Field, Value};
#[test]
fn scans_registered_table() {
let schema = Schema::new(vec![
Field::new("name", DataType::Text, false),
Field::new("age", DataType::Integer, false),
]);
let rows = vec![
Row::new(vec![Value::text("alice"), Value::Integer(30)]),
Row::new(vec![Value::text("bob"), Value::Integer(25)]),
];
let mut store = TableStore::new();
store.insert("people", schema.clone(), rows);
let result = store.scan("people", &schema).unwrap();
assert_eq!(result.rows().len(), 2);
assert_eq!(result.schema().fields()[0].name(), "name");
}
#[test]
fn returns_empty_for_missing_table() {
let store = TableStore::new();
let schema = Schema::new(vec![]);
let result = store.scan("missing", &schema).unwrap();
assert_eq!(result.rows().len(), 0);
}
}