mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 17:05:36 +01:00
Add a Cursor trait and use it
We need an abstract cursor trait to implement a sorter, for example.
This commit is contained in:
@@ -18,8 +18,7 @@ impl Database {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn exec(&self, _sql: &str) {
|
||||
}
|
||||
pub fn exec(&self, _sql: &str) {}
|
||||
}
|
||||
|
||||
pub struct IO {}
|
||||
|
||||
103
core/btree.rs
103
core/btree.rs
@@ -1,6 +1,6 @@
|
||||
use crate::pager::Pager;
|
||||
use crate::sqlite3_ondisk::{BTreeCell, TableInteriorCell, TableLeafCell};
|
||||
use crate::types::OwnedRecord;
|
||||
use crate::types::{Cursor, CursorResult, OwnedRecord};
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -32,12 +32,7 @@ impl MemPage {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum CursorResult<T> {
|
||||
Ok(T),
|
||||
IO,
|
||||
}
|
||||
|
||||
pub struct Cursor {
|
||||
pub struct BTreeCursor {
|
||||
pager: Rc<Pager>,
|
||||
root_page: usize,
|
||||
page: RefCell<Option<Rc<MemPage>>>,
|
||||
@@ -45,7 +40,7 @@ pub struct Cursor {
|
||||
record: RefCell<Option<OwnedRecord>>,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
impl BTreeCursor {
|
||||
pub fn new(pager: Rc<Pager>, root_page: usize) -> Self {
|
||||
Self {
|
||||
pager,
|
||||
@@ -56,51 +51,6 @@ impl Cursor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.page.borrow().is_none()
|
||||
}
|
||||
|
||||
pub fn rewind(&mut self) -> Result<CursorResult<()>> {
|
||||
let mem_page = MemPage::new(None, self.root_page, 0);
|
||||
self.page.replace(Some(Rc::new(mem_page)));
|
||||
match self.get_next_record()? {
|
||||
CursorResult::Ok((rowid, next)) => {
|
||||
self.rowid.replace(rowid);
|
||||
self.record.replace(next);
|
||||
Ok(CursorResult::Ok(()))
|
||||
}
|
||||
CursorResult::IO => Ok(CursorResult::IO),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> Result<CursorResult<()>> {
|
||||
match self.get_next_record()? {
|
||||
CursorResult::Ok((rowid, next)) => {
|
||||
self.rowid.replace(rowid);
|
||||
self.record.replace(next);
|
||||
Ok(CursorResult::Ok(()))
|
||||
}
|
||||
CursorResult::IO => Ok(CursorResult::IO),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wait_for_completion(&mut self) -> Result<()> {
|
||||
// TODO: Wait for pager I/O to complete
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn rowid(&self) -> Result<Ref<Option<u64>>> {
|
||||
Ok(self.rowid.borrow())
|
||||
}
|
||||
|
||||
pub fn record(&self) -> Result<Ref<Option<OwnedRecord>>> {
|
||||
Ok(self.record.borrow())
|
||||
}
|
||||
|
||||
pub fn has_record(&self) -> bool {
|
||||
self.record.borrow().is_some()
|
||||
}
|
||||
|
||||
fn get_next_record(&mut self) -> Result<CursorResult<(Option<u64>, Option<OwnedRecord>)>> {
|
||||
loop {
|
||||
let mem_page = {
|
||||
@@ -155,3 +105,50 @@ impl Cursor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cursor for BTreeCursor {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.page.borrow().is_none()
|
||||
}
|
||||
|
||||
fn rewind(&mut self) -> Result<CursorResult<()>> {
|
||||
let mem_page = MemPage::new(None, self.root_page, 0);
|
||||
self.page.replace(Some(Rc::new(mem_page)));
|
||||
match self.get_next_record()? {
|
||||
CursorResult::Ok((rowid, next)) => {
|
||||
self.rowid.replace(rowid);
|
||||
self.record.replace(next);
|
||||
Ok(CursorResult::Ok(()))
|
||||
}
|
||||
CursorResult::IO => Ok(CursorResult::IO),
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> Result<CursorResult<()>> {
|
||||
match self.get_next_record()? {
|
||||
CursorResult::Ok((rowid, next)) => {
|
||||
self.rowid.replace(rowid);
|
||||
self.record.replace(next);
|
||||
Ok(CursorResult::Ok(()))
|
||||
}
|
||||
CursorResult::IO => Ok(CursorResult::IO),
|
||||
}
|
||||
}
|
||||
|
||||
fn wait_for_completion(&mut self) -> Result<()> {
|
||||
// TODO: Wait for pager I/O to complete
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rowid(&self) -> Result<Ref<Option<u64>>> {
|
||||
Ok(self.rowid.borrow())
|
||||
}
|
||||
|
||||
fn record(&self) -> Result<Ref<Option<OwnedRecord>>> {
|
||||
Ok(self.record.borrow())
|
||||
}
|
||||
|
||||
fn has_record(&self) -> bool {
|
||||
self.record.borrow().is_some()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,9 +95,7 @@ fn create_table(tbl_name: QualifiedName, body: CreateTableBody, root_page: usize
|
||||
|| type_name.contains("TEXT")
|
||||
{
|
||||
Type::Text
|
||||
} else if type_name.contains("BLOB")
|
||||
|| type_name.is_empty()
|
||||
{
|
||||
} else if type_name.contains("BLOB") || type_name.is_empty() {
|
||||
Type::Blob
|
||||
} else if type_name.contains("REAL")
|
||||
|| type_name.contains("FLOA")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::rc::Rc;
|
||||
use std::{cell::Ref, rc::Rc};
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -74,3 +74,18 @@ impl OwnedRecord {
|
||||
Self { values }
|
||||
}
|
||||
}
|
||||
|
||||
pub enum CursorResult<T> {
|
||||
Ok(T),
|
||||
IO,
|
||||
}
|
||||
|
||||
pub trait Cursor {
|
||||
fn is_empty(&self) -> bool;
|
||||
fn rewind(&mut self) -> Result<CursorResult<()>>;
|
||||
fn next(&mut self) -> Result<CursorResult<()>>;
|
||||
fn wait_for_completion(&mut self) -> Result<()>;
|
||||
fn rowid(&self) -> Result<Ref<Option<u64>>>;
|
||||
fn record(&self) -> Result<Ref<Option<OwnedRecord>>>;
|
||||
fn has_record(&self) -> bool;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::btree::{Cursor, CursorResult};
|
||||
use crate::btree::BTreeCursor;
|
||||
use crate::pager::Pager;
|
||||
use crate::types::{OwnedValue, Record};
|
||||
use crate::types::{Cursor, CursorResult, OwnedValue, Record};
|
||||
|
||||
use anyhow::Result;
|
||||
use std::cell::RefCell;
|
||||
@@ -153,7 +153,7 @@ pub enum StepResult<'a> {
|
||||
/// The program state describes the environment in which the program executes.
|
||||
pub struct ProgramState {
|
||||
pub pc: usize,
|
||||
cursors: RefCell<BTreeMap<usize, Cursor>>,
|
||||
cursors: RefCell<BTreeMap<usize, Box<dyn Cursor>>>,
|
||||
registers: Vec<OwnedValue>,
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ impl Program {
|
||||
cursor_id,
|
||||
root_page,
|
||||
} => {
|
||||
let cursor = Cursor::new(pager.clone(), *root_page);
|
||||
let cursor = Box::new(BTreeCursor::new(pager.clone(), *root_page));
|
||||
cursors.insert(*cursor_id, cursor);
|
||||
state.pc += 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user