Introduce VTab and VTabCursor traits.

This commit is contained in:
gwenn 2016-02-10 18:15:46 +01:00
parent 30d1464e93
commit 1e6e8115bb
3 changed files with 29 additions and 7 deletions

View File

@ -7,7 +7,7 @@ use libc;
use {Connection, Error, Result}; use {Connection, Error, Result};
use ffi; use ffi;
use types::Null; use types::Null;
use vtab::declare_vtab; use vtab::{declare_vtab, VTab, VTabCursor};
use self::csv::Reader; use self::csv::Reader;
@ -31,7 +31,7 @@ struct CSVTab {
cols: Vec<String>, cols: Vec<String>,
} }
impl CSVTab { impl VTab<CSVTabCursor> for CSVTab {
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void, aux: *mut libc::c_void,
argc: libc::c_int, argc: libc::c_int,
@ -76,7 +76,9 @@ impl CSVTabCursor {
row_number: 0, row_number: 0,
} }
} }
}
impl VTabCursor<CSVTab> for CSVTabCursor {
fn vtab(&self) -> &mut CSVTab { fn vtab(&self) -> &mut CSVTab {
unsafe { &mut *(self.base.pVtab as *mut CSVTab) } unsafe { &mut *(self.base.pVtab as *mut CSVTab) }
} }

View File

@ -7,7 +7,7 @@ use libc;
use {Connection, Error, Result}; use {Connection, Error, Result};
use ffi; use ffi;
use vtab::declare_vtab; use vtab::{declare_vtab, VTab, VTabCursor};
pub fn create_int_array(conn: &Connection, name: &str) -> Result<Rc<RefCell<Vec<i64>>>> { pub fn create_int_array(conn: &Connection, name: &str) -> Result<Rc<RefCell<Vec<i64>>>> {
let array = Rc::new(RefCell::new(Vec::new())); let array = Rc::new(RefCell::new(Vec::new()));
@ -24,7 +24,7 @@ pub fn drop_int_array(conn: &Connection, name: &str) -> Result<()> {
fn escape_quote(identifier: String) -> String { fn escape_quote(identifier: String) -> String {
if identifier.contains('"') { if identifier.contains('"') {
// escape quote by doubling them // escape quote by doubling them
identifier.replace('"', "\"\"") identifier.replace("\"", "\"\"")
} else { } else {
identifier identifier
} }
@ -43,7 +43,7 @@ struct IntArrayVTab {
array: *const Rc<RefCell<Vec<i64>>>, array: *const Rc<RefCell<Vec<i64>>>,
} }
impl IntArrayVTab { impl VTab<IntArrayVTabCursor> for IntArrayVTab {
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void, aux: *mut libc::c_void,
_argc: libc::c_int, _argc: libc::c_int,
@ -80,11 +80,12 @@ impl IntArrayVTabCursor {
i: 0, i: 0,
} }
} }
}
impl VTabCursor<IntArrayVTab> for IntArrayVTabCursor {
fn vtab(&self) -> &mut IntArrayVTab { fn vtab(&self) -> &mut IntArrayVTab {
unsafe { &mut *(self.base.pVtab as *mut IntArrayVTab) } unsafe { &mut *(self.base.pVtab as *mut IntArrayVTab) }
} }
fn filter(&mut self) -> Result<()> { fn filter(&mut self) -> Result<()> {
self.i = 0; self.i = 0;
Ok(()) Ok(())

View File

@ -37,6 +37,25 @@ use ffi;
// \-> if not eof { cursor.column or xrowid } else { cursor.xclose } // \-> if not eof { cursor.column or xrowid } else { cursor.xclose }
// //
pub trait VTab<C: VTabCursor<Self>>: Sized {
fn create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void,
_argc: libc::c_int,
_argv: *const *const libc::c_char)
-> Result<Self>;
fn best_index(&self, _info: *mut ffi::sqlite3_index_info);
fn open(&self) -> Result<C>;
}
pub trait VTabCursor<V: VTab<Self>>: Sized {
fn vtab(&self) -> &mut V;
fn filter(&mut self) -> Result<()>;
fn next(&mut self) -> Result<()>;
fn eof(&self) -> bool;
fn column(&self, ctx: *mut ffi::sqlite3_context, _i: libc::c_int) -> Result<()>;
fn rowid(&self) -> Result<i64>;
}
impl Connection { impl Connection {
/// Register a virtual table implementation. /// Register a virtual table implementation.
pub fn create_module<A>(&self, pub fn create_module<A>(&self,
@ -261,7 +280,7 @@ pub unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor,
} }
} }
unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) { pub unsafe fn set_err_msg(vtab: *mut ffi::sqlite3_vtab, err_msg: &str) {
if !(*vtab).zErrMsg.is_null() { if !(*vtab).zErrMsg.is_null() {
ffi::sqlite3_free((*vtab).zErrMsg as *mut libc::c_void); ffi::sqlite3_free((*vtab).zErrMsg as *mut libc::c_void);
} }