Change VTabCursor::filter signature

This commit is contained in:
gwenn 2016-08-13 13:55:30 +02:00
parent 0a19cbd16a
commit 8f079819f7
8 changed files with 51 additions and 50 deletions

View File

@ -90,11 +90,7 @@ impl Connection {
table.as_ptr(), table.as_ptr(),
column.as_ptr(), column.as_ptr(),
row, row,
if read_only { if read_only { 0 } else { 1 },
0
} else {
1
},
&mut blob) &mut blob)
}; };
c.decode_result(rc).map(|_| { c.decode_result(rc).map(|_| {

View File

@ -202,7 +202,7 @@ impl<'a> ValueRef<'a> {
ValueRef::Blob(from_raw_parts(blob as *const u8, len as usize)) ValueRef::Blob(from_raw_parts(blob as *const u8, len as usize))
} }
_ => unreachable!("sqlite3_value_type returned invalid value") _ => unreachable!("sqlite3_value_type returned invalid value"),
} }
} }
} }
@ -239,7 +239,7 @@ impl<'a> Context<'a> {
let value = unsafe { ValueRef::from_value(arg) }; let value = unsafe { ValueRef::from_value(arg) };
FromSql::column_result(value).map_err(|err| match err { FromSql::column_result(value).map_err(|err| match err {
Error::InvalidColumnType => Error::InvalidFunctionParameterType, Error::InvalidColumnType => Error::InvalidFunctionParameterType,
_ => err _ => err,
}) })
} }
@ -266,11 +266,7 @@ impl<'a> Context<'a> {
/// types must be identical. /// types must be identical.
pub unsafe fn get_aux<T>(&self, arg: c_int) -> Option<&T> { pub unsafe fn get_aux<T>(&self, arg: c_int) -> Option<&T> {
let p = ffi::sqlite3_get_auxdata(self.ctx, arg) as *mut T; let p = ffi::sqlite3_get_auxdata(self.ctx, arg) as *mut T;
if p.is_null() { if p.is_null() { None } else { Some(&*p) }
None
} else {
Some(&*p)
}
} }
} }

View File

@ -93,12 +93,18 @@ mod named_params;
mod error; mod error;
mod convenient; mod convenient;
mod raw_statement; mod raw_statement;
#[cfg(feature = "load_extension")]mod load_extension_guard; #[cfg(feature = "load_extension")]
#[cfg(feature = "trace")]pub mod trace; mod load_extension_guard;
#[cfg(feature = "backup")]pub mod backup; #[cfg(feature = "trace")]
#[cfg(feature = "functions")]pub mod functions; pub mod trace;
#[cfg(feature = "blob")]pub mod blob; #[cfg(feature = "backup")]
#[cfg(all(feature = "vtab", feature = "functions"))]pub mod vtab; pub mod backup;
#[cfg(feature = "functions")]
pub mod functions;
#[cfg(feature = "blob")]
pub mod blob;
#[cfg(all(feature = "vtab", feature = "functions"))]
pub mod vtab;
// Number of cached prepared statements we'll hold on to. // Number of cached prepared statements we'll hold on to.
const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16; const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16;
@ -886,9 +892,7 @@ impl<'conn> Statement<'conn> {
for (i, p) in params.iter().enumerate() { for (i, p) in params.iter().enumerate() {
try!(unsafe { try!(unsafe {
self.conn.decode_result( self.conn.decode_result(p.bind_parameter(self.stmt.ptr(), (i + 1) as c_int))
p.bind_parameter(self.stmt.ptr(), (i + 1) as c_int)
)
}); });
} }
@ -1115,7 +1119,8 @@ impl<'a> ValueRef<'a> {
ffi::SQLITE_FLOAT => ValueRef::Real(ffi::sqlite3_column_double(raw, col)), ffi::SQLITE_FLOAT => ValueRef::Real(ffi::sqlite3_column_double(raw, col)),
ffi::SQLITE_TEXT => { ffi::SQLITE_TEXT => {
let text = ffi::sqlite3_column_text(raw, col); let text = ffi::sqlite3_column_text(raw, col);
assert!(!text.is_null(), "unexpected SQLITE_TEXT column type with NULL data"); assert!(!text.is_null(),
"unexpected SQLITE_TEXT column type with NULL data");
let s = CStr::from_ptr(text as *const c_char); let s = CStr::from_ptr(text as *const c_char);
// sqlite3_column_text returns UTF8 data, so our unwrap here should be fine. // sqlite3_column_text returns UTF8 data, so our unwrap here should be fine.
@ -1126,9 +1131,11 @@ impl<'a> ValueRef<'a> {
let blob = ffi::sqlite3_column_blob(raw, col); let blob = ffi::sqlite3_column_blob(raw, col);
let len = ffi::sqlite3_column_bytes(raw, col); let len = ffi::sqlite3_column_bytes(raw, col);
assert!(len >= 0, "unexpected negative return from sqlite3_column_bytes"); assert!(len >= 0,
"unexpected negative return from sqlite3_column_bytes");
if len > 0 { if len > 0 {
assert!(!blob.is_null(), "unexpected SQLITE_BLOB column type with NULL data"); assert!(!blob.is_null(),
"unexpected SQLITE_BLOB column type with NULL data");
ValueRef::Blob(from_raw_parts(blob as *const u8, len as usize)) ValueRef::Blob(from_raw_parts(blob as *const u8, len as usize))
} else { } else {
// The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. // The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
@ -1136,7 +1143,7 @@ impl<'a> ValueRef<'a> {
} }
} }
_ => unreachable!("sqlite3_column_type returned invalid value") _ => unreachable!("sqlite3_column_type returned invalid value"),
} }
} }
} }

View File

@ -204,9 +204,7 @@ impl<'conn> Statement<'conn> {
fn bind_parameters_named(&mut self, params: &[(&str, &ToSql)]) -> Result<()> { fn bind_parameters_named(&mut self, params: &[(&str, &ToSql)]) -> Result<()> {
for &(name, value) in params { for &(name, value) in params {
if let Some(i) = try!(self.parameter_index(name)) { if let Some(i) = try!(self.parameter_index(name)) {
try!(self.conn.decode_result(unsafe { try!(self.conn.decode_result(unsafe { value.bind_parameter(self.stmt.ptr(), i) }));
value.bind_parameter(self.stmt.ptr(), i)
}));
} else { } else {
return Err(Error::InvalidParameterName(name.into())); return Err(Error::InvalidParameterName(name.into()));
} }

View File

@ -21,10 +21,11 @@ impl ToSql for Value {
impl FromSql for Value { impl FromSql for Value {
fn column_result(value: ValueRef) -> Result<Self> { fn column_result(value: ValueRef) -> Result<Self> {
match value { match value {
ValueRef::Text(ref s) => serde_json::from_str(s), ValueRef::Text(ref s) => serde_json::from_str(s),
ValueRef::Blob(ref b) => serde_json::from_slice(b), ValueRef::Blob(ref b) => serde_json::from_slice(b),
_ => return Err(Error::InvalidColumnType), _ => return Err(Error::InvalidColumnType),
}.map_err(|err| Error::FromSqlConversionFailure(Box::new(err))) }
.map_err(|err| Error::FromSqlConversionFailure(Box::new(err)))
} }
} }

View File

@ -56,10 +56,7 @@ impl CSVTab {
} }
impl VTab<CSVTabCursor> for CSVTab { impl VTab<CSVTabCursor> for CSVTab {
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3, _aux: *mut libc::c_void, args: &[&[u8]]) -> Result<CSVTab> {
_aux: *mut libc::c_void,
args: &[&[u8]])
-> Result<CSVTab> {
if args.len() < 4 { if args.len() < 4 {
return Err(Error::ModuleError("no CSV file specified".to_owned())); return Err(Error::ModuleError("no CSV file specified".to_owned()));
} }
@ -173,8 +170,8 @@ impl VTabCursor<CSVTab> for CSVTabCursor {
fn filter(&mut self, fn filter(&mut self,
_idx_num: libc::c_int, _idx_num: libc::c_int,
_idx_str: *const libc::c_char, _idx_str: Option<&str>,
_args: &mut[*mut ffi::sqlite3_value]) _args: &mut [*mut ffi::sqlite3_value])
-> Result<()> { -> Result<()> {
{ {
let offset_first_row = self.vtab().offset_first_row; let offset_first_row = self.vtab().offset_first_row;
@ -196,7 +193,7 @@ impl VTabCursor<CSVTab> for CSVTabCursor {
} }
} }
self.row_number = self.row_number + 1; self.row_number += 1;
Ok(()) Ok(())
} }
fn eof(&self) -> bool { fn eof(&self) -> bool {

View File

@ -102,14 +102,14 @@ impl VTabCursor<IntArrayVTab> for IntArrayVTabCursor {
} }
fn filter(&mut self, fn filter(&mut self,
_idx_num: libc::c_int, _idx_num: libc::c_int,
_idx_str: *const libc::c_char, _idx_str: Option<&str>,
_args: &mut[*mut ffi::sqlite3_value]) _args: &mut [*mut ffi::sqlite3_value])
-> Result<()> { -> Result<()> {
self.i = 0; self.i = 0;
Ok(()) Ok(())
} }
fn next(&mut self) -> Result<()> { fn next(&mut self) -> Result<()> {
self.i = self.i + 1; self.i += 1;
Ok(()) Ok(())
} }
fn eof(&self) -> bool { fn eof(&self) -> bool {

View File

@ -42,10 +42,7 @@ use ffi;
pub trait VTab<C: VTabCursor<Self>>: Sized { pub trait VTab<C: VTabCursor<Self>>: Sized {
/// Create a new instance of a virtual table in response to a CREATE VIRTUAL TABLE statement. /// Create a new instance of a virtual table in response to a CREATE VIRTUAL TABLE statement.
/// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement. /// The `db` parameter is a pointer to the SQLite database connection that is executing the CREATE VIRTUAL TABLE statement.
fn create(db: *mut ffi::sqlite3, fn create(db: *mut ffi::sqlite3, aux: *mut libc::c_void, args: &[&[u8]]) -> Result<Self>;
aux: *mut libc::c_void,
args: &[&[u8]])
-> Result<Self>;
/// Determine the best way to access the virtual table. /// Determine the best way to access the virtual table.
fn best_index(&self, info: *mut ffi::sqlite3_index_info); fn best_index(&self, info: *mut ffi::sqlite3_index_info);
/// Create a new cursor used for accessing a virtual table. /// Create a new cursor used for accessing a virtual table.
@ -59,8 +56,8 @@ pub trait VTabCursor<V: VTab<Self>>: Sized {
/// Begin a search of a virtual table. /// Begin a search of a virtual table.
fn filter(&mut self, fn filter(&mut self,
idx_num: libc::c_int, idx_num: libc::c_int,
idx_str: *const libc::c_char, idx_str: Option<&str>,
args: &mut[*mut ffi::sqlite3_value]) args: &mut [*mut ffi::sqlite3_value])
-> Result<()>; -> Result<()>;
/// Advance cursor to the next row of a result set initiated by `filter`. /// Advance cursor to the next row of a result set initiated by `filter`.
fn next(&mut self) -> Result<()>; fn next(&mut self) -> Result<()>;
@ -258,11 +255,19 @@ unsafe extern "C" fn $filter(cursor: *mut ffi::sqlite3_vtab_cursor,
argc: libc::c_int, argc: libc::c_int,
argv: *mut *mut ffi::sqlite3_value) argv: *mut *mut ffi::sqlite3_value)
-> libc::c_int { -> libc::c_int {
use std::ffi::CStr;
use std::slice; use std::slice;
use std::str;
use vtab::cursor_error; use vtab::cursor_error;
let idx_name = if idx_str.is_null() {
None
} else {
let c_slice = CStr::from_ptr(idx_str).to_bytes();
Some(str::from_utf8_unchecked(c_slice))
};
let mut args = slice::from_raw_parts_mut(argv, argc as usize); let mut args = slice::from_raw_parts_mut(argv, argc as usize);
let cr = cursor as *mut $cursor; let cr = cursor as *mut $cursor;
cursor_error(cursor, (*cr).filter(idx_num, idx_str, &mut args)) cursor_error(cursor, (*cr).filter(idx_num, idx_name, &mut args))
} }
unsafe extern "C" fn $next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int { unsafe extern "C" fn $next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
use vtab::cursor_error; use vtab::cursor_error;
@ -365,4 +370,5 @@ pub fn mprintf(err_msg: &str) -> *mut ::libc::c_char {
} }
pub mod int_array; pub mod int_array;
#[cfg(feature = "csvtab")]pub mod csvtab; #[cfg(feature = "csvtab")]
pub mod csvtab;