diff --git a/extensions/completion/src/lib.rs b/extensions/completion/src/lib.rs index 53358c23c..94f8b4689 100644 --- a/extensions/completion/src/lib.rs +++ b/extensions/completion/src/lib.rs @@ -79,18 +79,6 @@ impl VTabModule for CompletionVTab { Ok(CompletionCursor::default()) } - fn column(cursor: &Self::VCursor, idx: u32) -> Result { - 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() } } diff --git a/extensions/core/README.md b/extensions/core/README.md index 0e4246f37..2b3bce4b9 100644 --- a/extensions/core/README.md +++ b/extensions/core/README.md @@ -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 { - 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 { let row = &self.rows[self.index]; if (idx as usize) < row.len() { diff --git a/extensions/core/src/vtabs.rs b/extensions/core/src/vtabs.rs index de5794c6e..a456c4d12 100644 --- a/extensions/core/src/vtabs.rs +++ b/extensions/core/src/vtabs.rs @@ -98,9 +98,6 @@ pub trait VTabModule: 'static { args: &[Value], idx_info: Option<(&str, i32)>, ) -> ResultCode; - fn column(cursor: &Self::VCursor, idx: u32) -> Result; - 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(()) } diff --git a/extensions/series/src/lib.rs b/extensions/series/src/lib.rs index 21d3a89fa..c5ee979da 100644 --- a/extensions/series/src/lib.rs +++ b/extensions/series/src/lib.rs @@ -79,18 +79,6 @@ impl VTabModule for GenerateSeriesVTab { ResultCode::OK } - - fn column(cursor: &Self::VCursor, idx: u32) -> Result { - 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!( diff --git a/extensions/tests/src/lib.rs b/extensions/tests/src/lib.rs index 5c6495595..f5138fad8 100644 --- a/extensions/tests/src/lib.rs +++ b/extensions/tests/src/lib.rs @@ -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 { - 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 { - ::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 { - ::eof(self) + self.index.is_some_and(|s| s >= self.rows.len()) || self.index.is_none() } fn next(&mut self) -> ResultCode { - ::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 } } diff --git a/macros/src/ext/vtab_derive.rs b/macros/src/ext/vtab_derive.rs index 0dd67ca0d..d096f2f94 100644 --- a/macros/src/ext/vtab_derive.rs +++ b/macros/src/ext/vtab_derive.rs @@ -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] diff --git a/macros/src/lib.rs b/macros/src/lib.rs index e173d47ba..154dfb63c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -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) /// }