diff --git a/src/cursor.rs b/src/cursor.rs new file mode 100644 index 0000000..8098a6b --- /dev/null +++ b/src/cursor.rs @@ -0,0 +1,40 @@ +use crate::table::Table; + +pub type Position = (usize, usize); + +pub struct Cursor<'a> { + pub table: &'a mut Table, + pub row_num: usize, + pub end_of_table: bool, +} + +impl<'a> Cursor<'a> { + pub fn at_table_start(table: &'a mut Table) -> Self { + let end_of_table = table.row_count == 0; + Self { + table, + row_num: 0, + end_of_table, + } + } + + pub fn at_table_end(table: &'a mut Table) -> Self { + let row_count = table.row_count; + Self { + table, + row_num: row_count, + end_of_table: true, + } + } + + pub fn position(&self) -> Position { + self.table.row_slot(self.row_num) + } + + pub fn advance(&mut self) { + self.row_num += 1; + if self.row_num >= self.table.row_count { + self.end_of_table = true; + } + } +} diff --git a/src/lib.rs b/src/lib.rs index ae2874a..67ad978 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod cursor; pub mod layout; pub mod pager; pub mod row; diff --git a/src/statement.rs b/src/statement.rs index 2e10c78..bb70136 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -1,4 +1,5 @@ use crate::{ + cursor::Cursor, layout::{ROW_SIZE, TABLE_MAX_ROWS}, row::{Row, RowBytes}, table::Table, @@ -6,8 +7,6 @@ use crate::{ use anyhow::Result; use thiserror::Error; -type FilteredRows = Vec; - #[derive(Debug)] pub enum StatementType { Insert(Box), @@ -73,22 +72,25 @@ pub fn execute_insert(row: Row, table: &mut Table) -> Result<()> { return Err(ExecutionError::TableFull.into()); } + let cursor = Cursor::at_table_end(table); let bytes: RowBytes = row.into(); - let (page_num, offset) = table.row_slot(table.row_count); + + let (page_num, offset) = cursor.position(); let page = table.pager.page(page_num)?; - // let page = table.pager.pages[page_num].as_mut().unwrap(); page[offset..offset + ROW_SIZE].copy_from_slice(&bytes); table.row_count += 1; Ok(()) } -pub fn execute_select(table: &mut Table) -> Result { - let mut rows: FilteredRows = vec![]; - for i in 0..table.row_count { - let (page_num, offset) = table.row_slot(i); - let page = table.pager.page(page_num)?; +pub fn execute_select(table: &mut Table) -> Result> { + let mut rows: Vec = vec![]; + let mut cursor = Cursor::at_table_start(table); + while !cursor.end_of_table { + let (page_num, offset) = cursor.position(); + let page = cursor.table.pager.page(page_num)?; let row: RowBytes = page[offset..offset + ROW_SIZE].try_into()?; rows.push(row.into()); + cursor.advance(); } Ok(rows)