diff --git a/src/vtab/csvtab.rs b/src/vtab/csvtab.rs index ebb6a7f..574e7d0 100644 --- a/src/vtab/csvtab.rs +++ b/src/vtab/csvtab.rs @@ -9,7 +9,7 @@ use libc; use {Connection, Error, Result}; use ffi; use types::Null; -use vtab::{declare_vtab, escape_double_quote, VTab, VTabCursor}; +use vtab::{declare_vtab, escape_double_quote, Context, VTab, VTabCursor}; /// Register the "csv" module. pub fn load_module(conn: &Connection) -> Result<()> { @@ -199,17 +199,16 @@ impl VTabCursor for CSVTabCursor { fn eof(&self) -> bool { self.eof } - fn column(&self, ctx: *mut ffi::sqlite3_context, col: libc::c_int) -> Result<()> { - use functions::ToResult; + fn column(&self, ctx: &mut Context, col: libc::c_int) -> Result<()> { if col < 0 || col as usize >= self.cols.len() { return Err(Error::ModuleError(format!("column index out of bounds: {}", col))); } if self.cols.is_empty() { - unsafe { Null.set_result(ctx) }; + ctx.set_result(&Null); return Ok(()); } // TODO Affinity - unsafe { self.cols[col as usize].set_result(ctx) }; + ctx.set_result(&self.cols[col as usize]); Ok(()) } fn rowid(&self) -> Result { diff --git a/src/vtab/int_array.rs b/src/vtab/int_array.rs index 4f043c8..8a575f0 100644 --- a/src/vtab/int_array.rs +++ b/src/vtab/int_array.rs @@ -7,7 +7,7 @@ use libc; use {Connection, Error, Result}; use ffi; -use vtab::{declare_vtab, escape_double_quote, VTab, VTabCursor}; +use vtab::{declare_vtab, escape_double_quote, Context, VTab, VTabCursor}; /// Create a specific instance of an intarray object. /// The new intarray object is returned. @@ -119,12 +119,11 @@ impl VTabCursor for IntArrayVTabCursor { self.i >= array.len() } } - fn column(&self, ctx: *mut ffi::sqlite3_context, _i: libc::c_int) -> Result<()> { - use functions::ToResult; + fn column(&self, ctx: &mut Context, _i: libc::c_int) -> Result<()> { let vtab = self.vtab(); unsafe { let array = (*vtab.array).borrow(); - array[self.i].set_result(ctx); + ctx.set_result(&array[self.i]); } Ok(()) } diff --git a/src/vtab/mod.rs b/src/vtab/mod.rs index c657651..8d7b99f 100644 --- a/src/vtab/mod.rs +++ b/src/vtab/mod.rs @@ -9,6 +9,7 @@ use libc; use {Connection, Error, Result, InnerConnection, str_to_cstring}; use error::error_from_sqlite_code; use ffi; +use functions::ToResult; // let conn: Connection = ...; // let mod: Module = ...; // VTab builder @@ -65,11 +66,21 @@ pub trait VTabCursor>: Sized { fn eof(&self) -> bool; /// Find the value for the `i`-th column of the current row. `i` is zero-based so the first column is numbered 0. /// May return its result back to SQLite using one of the specified `ctx`. - fn column(&self, ctx: *mut ffi::sqlite3_context, i: libc::c_int) -> Result<()>; + fn column(&self, ctx: &mut Context, i: libc::c_int) -> Result<()>; /// Return the rowid of row that the cursor is currently pointing at. fn rowid(&self) -> Result; } +pub struct Context(*mut ffi::sqlite3_context); + +impl Context { + pub fn set_result(&mut self, value: &ToResult) { + unsafe { + value.set_result(self.0); + } + } +} + impl Connection { /// Register a virtual table implementation. pub fn create_module(&self, @@ -282,9 +293,10 @@ unsafe extern "C" fn $column(cursor: *mut ffi::sqlite3_vtab_cursor, ctx: *mut ffi::sqlite3_context, i: libc::c_int) -> libc::c_int { - use vtab::result_error; + use vtab::{result_error, Context}; let cr = cursor as *mut $cursor; - result_error(ctx, (*cr).column(ctx, i)) + let mut ctxt = Context(ctx); + result_error(ctx, (*cr).column(&mut ctxt, i)) } unsafe extern "C" fn $rowid(cursor: *mut ffi::sqlite3_vtab_cursor, p_rowid: *mut ffi::sqlite3_int64)