Implement table cursor

This commit is contained in:
niku 2023-08-13 13:14:53 +02:00
parent 9eab0248c4
commit c4ce04d700
3 changed files with 52 additions and 9 deletions

40
src/cursor.rs Normal file
View File

@ -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;
}
}
}

View File

@ -1,3 +1,4 @@
pub mod cursor;
pub mod layout; pub mod layout;
pub mod pager; pub mod pager;
pub mod row; pub mod row;

View File

@ -1,4 +1,5 @@
use crate::{ use crate::{
cursor::Cursor,
layout::{ROW_SIZE, TABLE_MAX_ROWS}, layout::{ROW_SIZE, TABLE_MAX_ROWS},
row::{Row, RowBytes}, row::{Row, RowBytes},
table::Table, table::Table,
@ -6,8 +7,6 @@ use crate::{
use anyhow::Result; use anyhow::Result;
use thiserror::Error; use thiserror::Error;
type FilteredRows = Vec<Row>;
#[derive(Debug)] #[derive(Debug)]
pub enum StatementType { pub enum StatementType {
Insert(Box<Row>), Insert(Box<Row>),
@ -73,22 +72,25 @@ pub fn execute_insert(row: Row, table: &mut Table) -> Result<()> {
return Err(ExecutionError::TableFull.into()); return Err(ExecutionError::TableFull.into());
} }
let cursor = Cursor::at_table_end(table);
let bytes: RowBytes = row.into(); 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.page(page_num)?;
// let page = table.pager.pages[page_num].as_mut().unwrap();
page[offset..offset + ROW_SIZE].copy_from_slice(&bytes); page[offset..offset + ROW_SIZE].copy_from_slice(&bytes);
table.row_count += 1; table.row_count += 1;
Ok(()) Ok(())
} }
pub fn execute_select(table: &mut Table) -> Result<FilteredRows> { pub fn execute_select(table: &mut Table) -> Result<Vec<Row>> {
let mut rows: FilteredRows = vec![]; let mut rows: Vec<Row> = vec![];
for i in 0..table.row_count { let mut cursor = Cursor::at_table_start(table);
let (page_num, offset) = table.row_slot(i); while !cursor.end_of_table {
let page = table.pager.page(page_num)?; let (page_num, offset) = cursor.position();
let page = cursor.table.pager.page(page_num)?;
let row: RowBytes = page[offset..offset + ROW_SIZE].try_into()?; let row: RowBytes = page[offset..offset + ROW_SIZE].try_into()?;
rows.push(row.into()); rows.push(row.into());
cursor.advance();
} }
Ok(rows) Ok(rows)