Remove VTabModule methods delegating directly to VTabCursor

This commit is contained in:
Piotr Rzysko
2025-05-18 21:37:43 +02:00
parent c800de4304
commit ea0ec6a216
7 changed files with 42 additions and 103 deletions

View File

@@ -79,18 +79,6 @@ impl VTabModule for CompletionVTab {
Ok(CompletionCursor::default())
}
fn column(cursor: &Self::VCursor, idx: u32) -> Result<Value, ResultCode> {
cursor.column(idx)
}
fn next(cursor: &mut Self::VCursor) -> ResultCode {
cursor.next()
}
fn eof(cursor: &Self::VCursor) -> bool {
cursor.eof()
}
fn filter(cursor: &mut Self::VCursor, args: &[Value], _: Option<(&str, i32)>) -> ResultCode {
if args.is_empty() || args.len() > 2 {
return ResultCode::InvalidArgs;
@@ -122,7 +110,7 @@ impl VTabModule for CompletionVTab {
cursor.rowid = 0;
cursor.phase = CompletionPhase::Keywords;
Self::next(cursor)
cursor.next()
}
}

View File

@@ -215,26 +215,6 @@ impl VTabModule for CsvVTable {
ResultCode::OK
}
/// Return the value for the column at the given index in the current row.
fn column(cursor: &Self::VCursor, idx: u32) -> Result<Value, Self::Error> {
cursor.column(idx)
}
/// Next advances the cursor to the next row.
fn next(cursor: &mut Self::VCursor) -> ResultCode {
if cursor.index < cursor.rows.len() - 1 {
cursor.index += 1;
ResultCode::OK
} else {
ResultCode::EOF
}
}
/// Return true if the cursor is at the end.
fn eof(cursor: &Self::VCursor) -> bool {
cursor.index >= cursor.rows.len()
}
/// *Optional* methods for non-readonly tables
/// Update the value at rowid
@@ -263,14 +243,22 @@ struct CsvCursor {
impl VTabCursor for CsvCursor {
type Error = &'static str;
/// Next advances the cursor to the next row.
fn next(&mut self) -> ResultCode {
CsvCursor::next(self)
if self.index < self.rows.len() - 1 {
self.index += 1;
ResultCode::OK
} else {
ResultCode::EOF
}
}
/// Return true if the cursor is at the end.
fn eof(&self) -> bool {
self.index >= self.rows.len()
}
/// Return the value for the column at the given index in the current row.
fn column(&self, idx: u32) -> Result<Value, Self::Error> {
let row = &self.rows[self.index];
if (idx as usize) < row.len() {

View File

@@ -98,9 +98,6 @@ pub trait VTabModule: 'static {
args: &[Value],
idx_info: Option<(&str, i32)>,
) -> ResultCode;
fn column(cursor: &Self::VCursor, idx: u32) -> Result<Value, Self::Error>;
fn next(cursor: &mut Self::VCursor) -> ResultCode;
fn eof(cursor: &Self::VCursor) -> bool;
fn update(&mut self, _rowid: i64, _args: &[Value]) -> Result<(), Self::Error> {
Ok(())
}

View File

@@ -79,18 +79,6 @@ impl VTabModule for GenerateSeriesVTab {
ResultCode::OK
}
fn column(cursor: &Self::VCursor, idx: u32) -> Result<Value, Self::Error> {
cursor.column(idx)
}
fn next(cursor: &mut Self::VCursor) -> ResultCode {
cursor.next()
}
fn eof(cursor: &Self::VCursor) -> bool {
cursor.eof()
}
}
/// The cursor for iterating over the generated sequence
@@ -255,7 +243,7 @@ mod tests {
(series.stop - series.start) / series.step + 1
);
}
match GenerateSeriesVTab::next(&mut cursor) {
match cursor.next() {
ResultCode::OK => (),
ResultCode::EOF => break,
err => return Err(err),
@@ -559,9 +547,9 @@ mod tests {
GenerateSeriesVTab::filter(&mut cursor, &args, None);
let mut rowids = vec![];
while !GenerateSeriesVTab::eof(&cursor) {
while !cursor.eof() {
let cur_rowid = cursor.rowid();
match GenerateSeriesVTab::next(&mut cursor) {
match cursor.next() {
ResultCode::OK => rowids.push(cur_rowid),
ResultCode::EOF => break,
err => panic!(

View File

@@ -169,33 +169,6 @@ impl VTabModule for KVStoreVTab {
Ok(())
}
fn eof(cursor: &Self::VCursor) -> bool {
cursor.index.is_some_and(|s| s >= cursor.rows.len()) || cursor.index.is_none()
}
fn next(cursor: &mut Self::VCursor) -> ResultCode {
cursor.index = Some(cursor.index.unwrap_or(0) + 1);
if cursor.index.is_some_and(|c| c >= cursor.rows.len()) {
return ResultCode::EOF;
}
ResultCode::OK
}
fn column(cursor: &Self::VCursor, idx: u32) -> Result<Value, Self::Error> {
if cursor.index.is_some_and(|c| c >= cursor.rows.len()) {
return Err("cursor out of range".into());
}
if let Some((_, ref key, ref val)) = cursor.rows.get(cursor.index.unwrap_or(0)) {
match idx {
0 => Ok(Value::from_text(key.clone())), // key
1 => Ok(Value::from_text(val.clone())), // value
_ => Err("Invalid column".into()),
}
} else {
Err("Invalid Column".into())
}
}
fn destroy(&mut self) -> Result<(), Self::Error> {
println!("VDestroy called");
Ok(())
@@ -222,15 +195,30 @@ impl VTabCursor for KVStoreCursor {
}
fn column(&self, idx: u32) -> Result<Value, Self::Error> {
<KVStoreVTab as VTabModule>::column(self, idx)
if self.index.is_some_and(|c| c >= self.rows.len()) {
return Err("cursor out of range".into());
}
if let Some((_, ref key, ref val)) = self.rows.get(self.index.unwrap_or(0)) {
match idx {
0 => Ok(Value::from_text(key.clone())), // key
1 => Ok(Value::from_text(val.clone())), // value
_ => Err("Invalid column".into()),
}
} else {
Err("Invalid Column".into())
}
}
fn eof(&self) -> bool {
<KVStoreVTab as VTabModule>::eof(self)
self.index.is_some_and(|s| s >= self.rows.len()) || self.index.is_none()
}
fn next(&mut self) -> ResultCode {
<KVStoreVTab as VTabModule>::next(self)
self.index = Some(self.index.unwrap_or(0) + 1);
if self.index.is_some_and(|c| c >= self.rows.len()) {
return ResultCode::EOF;
}
ResultCode::OK
}
}

View File

@@ -89,7 +89,7 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
return ::limbo_ext::Value::error(::limbo_ext::ResultCode::Error);
}
let cursor = unsafe { &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor) };
match <#struct_name as ::limbo_ext::VTabModule>::column(cursor, idx) {
match <<#struct_name as ::limbo_ext::VTabModule>::VCursor as ::limbo_ext::VTabCursor>::column(cursor, idx) {
Ok(val) => val,
Err(e) => ::limbo_ext::Value::error_with_message(e.to_string())
}
@@ -103,7 +103,7 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
return ::limbo_ext::ResultCode::Error;
}
let cursor = &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor);
<#struct_name as ::limbo_ext::VTabModule>::next(cursor)
<<#struct_name as ::limbo_ext::VTabModule>::VCursor as ::limbo_ext::VTabCursor>::next(cursor)
}
#[no_mangle]
@@ -114,7 +114,7 @@ pub fn derive_vtab_module(input: TokenStream) -> TokenStream {
return true;
}
let cursor = &mut *(cursor as *mut <#struct_name as ::limbo_ext::VTabModule>::VCursor);
<#struct_name as ::limbo_ext::VTabModule>::eof(cursor)
<<#struct_name as ::limbo_ext::VTabModule>::VCursor as ::limbo_ext::VTabCursor>::eof(cursor)
}
#[no_mangle]

View File

@@ -264,23 +264,6 @@ pub fn derive_agg_func(input: TokenStream) -> TokenStream {
/// fn filter(_cursor: &mut Self::VCursor, _arg_count: i32, _args: &[Value]) -> ResultCode {
/// ResultCode::OK
/// }
/// /// Return the value for a given column index
/// fn column(cursor: &Self::VCursor, idx: u32) -> Value {
/// cursor.column(idx)
/// }
/// /// Move the cursor to the next row
/// fn next(cursor: &mut Self::VCursor) -> ResultCode {
/// if cursor.index < cursor.rows.len() - 1 {
/// cursor.index += 1;
/// ResultCode::OK
/// } else {
/// ResultCode::EOF
/// }
/// }
/// fn eof(cursor: &Self::VCursor) -> bool {
/// cursor.index >= cursor.rows.len()
/// }
///
/// /// **Optional** methods for non-readonly tables:
///
/// /// Update the row with the provided values, return the new rowid
@@ -317,12 +300,19 @@ pub fn derive_agg_func(input: TokenStream) -> TokenStream {
/// }
/// // Implement the VTabCursor trait for your virtual cursor
/// impl VTabCursor for CsvCursor {
/// /// Move the cursor to the next row
/// fn next(&mut self) -> ResultCode {
/// Self::next(self)
/// if self.index < self.rows.len() - 1 {
/// self.index += 1;
/// ResultCode::OK
/// } else {
/// ResultCode::EOF
/// }
/// }
/// fn eof(&self) -> bool {
/// self.index >= self.rows.len()
/// }
/// /// Return the value for a given column index
/// fn column(&self, idx: u32) -> Value {
/// self.column(idx)
/// }