WIP
This commit is contained in:
parent
dff8adebfa
commit
f0d22976c7
72
src/execution/table_store.rs
Normal file
72
src/execution/table_store.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user