use wasm_dbms_api::prelude::{ColumnDef, DbmsResult, TableSchema, Value};
use wasm_dbms_memory::prelude::{MemoryAccess, TableReader};
use super::table::TableOverlay;
pub struct DatabaseOverlayReader<'a, T, MA>
where
T: TableSchema,
MA: MemoryAccess,
{
inserted_rows: Vec<Vec<(ColumnDef, Value)>>,
new_rows_cursor: usize,
table_overlay: &'a TableOverlay,
table_reader: TableReader<'a, T, MA>,
_marker: std::marker::PhantomData<T>,
}
impl<'a, T, MA> DatabaseOverlayReader<'a, T, MA>
where
T: TableSchema,
MA: MemoryAccess,
{
pub fn new(table_overlay: &'a TableOverlay, table_reader: TableReader<'a, T, MA>) -> Self {
let inserted_rows: Vec<_> = table_overlay.iter_inserted().collect();
Self {
inserted_rows,
new_rows_cursor: 0,
table_overlay,
table_reader,
_marker: std::marker::PhantomData,
}
}
pub fn try_next(&mut self) -> DbmsResult<Option<Vec<(ColumnDef, Value)>>> {
loop {
let next_base_row = self
.table_reader
.try_next()?
.map(|row| row.record.to_values());
let Some(next_row) = next_base_row.or_else(|| self.next_overlay_row()) else {
return Ok(None);
};
if let Some(patched) = self.table_overlay.patch_row(next_row) {
return Ok(Some(patched));
}
}
}
fn next_overlay_row(&mut self) -> Option<Vec<(ColumnDef, Value)>> {
let row = self.inserted_rows.get(self.new_rows_cursor)?.clone();
self.new_rows_cursor += 1;
Some(row)
}
}