This commit is contained in:
gwenn 2018-07-14 19:21:03 +02:00
parent 0c371834aa
commit ed1bdc0e68
5 changed files with 82 additions and 53 deletions

View File

@ -6,7 +6,10 @@ use std::rc::Rc;
use ffi; use ffi;
use types::{ToSql, ToSqlOutput, Value}; use types::{ToSql, ToSqlOutput, Value};
use vtab::{eponymous_only_module, Context, IndexConstraintOp, IndexInfo, Module, VTab, VTabConnection, VTabCursor, Values}; use vtab::{
eponymous_only_module, Context, IndexConstraintOp, IndexInfo, Module, VTab, VTabConnection,
VTabCursor, Values,
};
use {Connection, Result}; use {Connection, Result};
// http://sqlite.org/bindptr.html // http://sqlite.org/bindptr.html

View File

@ -10,8 +10,8 @@ use std::str;
use ffi; use ffi;
use types::Null; use types::Null;
use vtab::{ use vtab::{
dequote, escape_double_quote, parse_boolean, simple_module, Context, IndexInfo, Module, VTab, VTabConnection, dequote, escape_double_quote, parse_boolean, simple_module, Context, IndexInfo, Module, VTab,
VTabCursor, Values, VTabConnection, VTabCursor, Values,
}; };
use {Connection, Error, Result}; use {Connection, Error, Result};

View File

@ -432,7 +432,9 @@ impl Connection {
module: &Module<T>, module: &Module<T>,
aux: Option<T::Aux>, aux: Option<T::Aux>,
) -> Result<()> { ) -> Result<()> {
self.db.borrow_mut().create_module::<T>(module_name, module, aux) self.db
.borrow_mut()
.create_module::<T>(module_name, module, aux)
} }
} }
@ -529,7 +531,9 @@ unsafe extern "C" fn rust_create<T>(
pp_vtab: *mut *mut ffi::sqlite3_vtab, pp_vtab: *mut *mut ffi::sqlite3_vtab,
err_msg: *mut *mut c_char, err_msg: *mut *mut c_char,
) -> c_int ) -> c_int
where T: VTab { where
T: VTab,
{
use std::error::Error as StdError; use std::error::Error as StdError;
use std::ffi::CStr; use std::ffi::CStr;
use std::slice; use std::slice;
@ -542,26 +546,24 @@ unsafe extern "C" fn rust_create<T>(
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error> .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
.collect::<Vec<_>>(); .collect::<Vec<_>>();
match T::create(&mut conn, aux.as_ref(), &vec[..]) { match T::create(&mut conn, aux.as_ref(), &vec[..]) {
Ok((sql, vtab)) => { Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
match ::std::ffi::CString::new(sql) { Ok(c_sql) => {
Ok(c_sql) => { let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr()); if rc == ffi::SQLITE_OK {
if rc == ffi::SQLITE_OK { let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab)); *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab; ffi::SQLITE_OK
ffi::SQLITE_OK } else {
} else { let err = error_from_sqlite_code(rc, None);
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
rc
}
}
Err(err) => {
*err_msg = mprintf(err.description()); *err_msg = mprintf(err.description());
ffi::SQLITE_ERROR rc
} }
} }
} Err(err) => {
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
}
},
Err(Error::SqliteFailure(err, s)) => { Err(Error::SqliteFailure(err, s)) => {
if let Some(s) = s { if let Some(s) = s {
*err_msg = mprintf(&s); *err_msg = mprintf(&s);
@ -583,7 +585,9 @@ unsafe extern "C" fn rust_connect<T>(
pp_vtab: *mut *mut ffi::sqlite3_vtab, pp_vtab: *mut *mut ffi::sqlite3_vtab,
err_msg: *mut *mut c_char, err_msg: *mut *mut c_char,
) -> c_int ) -> c_int
where T: VTab { where
T: VTab,
{
use std::error::Error as StdError; use std::error::Error as StdError;
use std::ffi::CStr; use std::ffi::CStr;
use std::slice; use std::slice;
@ -596,26 +600,24 @@ unsafe extern "C" fn rust_connect<T>(
.map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error> .map(|&cs| CStr::from_ptr(cs).to_bytes()) // FIXME .to_str() -> Result<&str, Utf8Error>
.collect::<Vec<_>>(); .collect::<Vec<_>>();
match T::connect(&mut conn, aux.as_ref(), &vec[..]) { match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
Ok((sql, vtab)) => { Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
match ::std::ffi::CString::new(sql) { Ok(c_sql) => {
Ok(c_sql) => { let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr()); if rc == ffi::SQLITE_OK {
if rc == ffi::SQLITE_OK { let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab)); *pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab; ffi::SQLITE_OK
ffi::SQLITE_OK } else {
} else { let err = error_from_sqlite_code(rc, None);
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
rc
}
}
Err(err) => {
*err_msg = mprintf(err.description()); *err_msg = mprintf(err.description());
ffi::SQLITE_ERROR rc
} }
} }
} Err(err) => {
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
}
},
Err(Error::SqliteFailure(err, s)) => { Err(Error::SqliteFailure(err, s)) => {
if let Some(s) = s { if let Some(s) = s {
*err_msg = mprintf(&s); *err_msg = mprintf(&s);
@ -633,7 +635,9 @@ unsafe extern "C" fn rust_best_index<T>(
vtab: *mut ffi::sqlite3_vtab, vtab: *mut ffi::sqlite3_vtab,
info: *mut ffi::sqlite3_index_info, info: *mut ffi::sqlite3_index_info,
) -> c_int ) -> c_int
where T: VTab { where
T: VTab,
{
use std::error::Error as StdError; use std::error::Error as StdError;
let vt = vtab as *mut T; let vt = vtab as *mut T;
let mut idx_info = IndexInfo(info); let mut idx_info = IndexInfo(info);
@ -653,7 +657,9 @@ unsafe extern "C" fn rust_best_index<T>(
} }
unsafe extern "C" fn rust_disconnect<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int unsafe extern "C" fn rust_disconnect<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where T: VTab { where
T: VTab,
{
let vtab = vtab as *mut T; let vtab = vtab as *mut T;
let _: Box<T> = Box::from_raw(vtab); let _: Box<T> = Box::from_raw(vtab);
ffi::SQLITE_OK ffi::SQLITE_OK
@ -663,7 +669,9 @@ unsafe extern "C" fn rust_open<T>(
vtab: *mut ffi::sqlite3_vtab, vtab: *mut ffi::sqlite3_vtab,
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor, pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
) -> c_int ) -> c_int
where T: VTab { where
T: VTab,
{
use std::error::Error as StdError; use std::error::Error as StdError;
let vt = vtab as *mut T; let vt = vtab as *mut T;
match (*vt).open() { match (*vt).open() {
@ -686,7 +694,9 @@ unsafe extern "C" fn rust_open<T>(
} }
unsafe extern "C" fn rust_close<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int unsafe extern "C" fn rust_close<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
let cr = cursor as *mut C; let cr = cursor as *mut C;
let _: Box<C> = Box::from_raw(cr); let _: Box<C> = Box::from_raw(cr);
ffi::SQLITE_OK ffi::SQLITE_OK
@ -699,7 +709,9 @@ unsafe extern "C" fn rust_filter<C>(
argc: c_int, argc: c_int,
argv: *mut *mut ffi::sqlite3_value, argv: *mut *mut ffi::sqlite3_value,
) -> c_int ) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
use std::ffi::CStr; use std::ffi::CStr;
use std::slice; use std::slice;
use std::str; use std::str;
@ -716,13 +728,17 @@ unsafe extern "C" fn rust_filter<C>(
} }
unsafe extern "C" fn rust_next<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int unsafe extern "C" fn rust_next<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
let cr = cursor as *mut C; let cr = cursor as *mut C;
cursor_error(cursor, (*cr).next()) cursor_error(cursor, (*cr).next())
} }
unsafe extern "C" fn rust_eof<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int unsafe extern "C" fn rust_eof<C>(cursor: *mut ffi::sqlite3_vtab_cursor) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
let cr = cursor as *mut C; let cr = cursor as *mut C;
(*cr).eof() as c_int (*cr).eof() as c_int
} }
@ -732,7 +748,9 @@ unsafe extern "C" fn rust_column<C>(
ctx: *mut ffi::sqlite3_context, ctx: *mut ffi::sqlite3_context,
i: c_int, i: c_int,
) -> c_int ) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
let cr = cursor as *mut C; let cr = cursor as *mut C;
let mut ctxt = Context(ctx); let mut ctxt = Context(ctx);
result_error(ctx, (*cr).column(&mut ctxt, i)) result_error(ctx, (*cr).column(&mut ctxt, i))
@ -742,7 +760,9 @@ unsafe extern "C" fn rust_rowid<C>(
cursor: *mut ffi::sqlite3_vtab_cursor, cursor: *mut ffi::sqlite3_vtab_cursor,
p_rowid: *mut ffi::sqlite3_int64, p_rowid: *mut ffi::sqlite3_int64,
) -> c_int ) -> c_int
where C: VTabCursor { where
C: VTabCursor,
{
let cr = cursor as *mut C; let cr = cursor as *mut C;
match (*cr).rowid() { match (*cr).rowid() {
Ok(rowid) => { Ok(rowid) => {

View File

@ -5,7 +5,10 @@ use std::os::raw::c_int;
use ffi; use ffi;
use types::Type; use types::Type;
use vtab::{eponymous_only_module, Context, IndexConstraintOp, IndexInfo, Module, VTab, VTabConnection, VTabCursor, Values}; use vtab::{
eponymous_only_module, Context, IndexConstraintOp, IndexInfo, Module, VTab, VTabConnection,
VTabCursor, Values,
};
use {Connection, Result}; use {Connection, Result};
/// Register the "generate_series" module. /// Register the "generate_series" module.

View File

@ -1,14 +1,16 @@
//! Ensure Virtual tables can be declared outside `rusqlite` crate. //! Ensure Virtual tables can be declared outside `rusqlite` crate.
extern crate libsqlite3_sys as ffi;
#[cfg(feature = "vtab")] #[cfg(feature = "vtab")]
extern crate rusqlite; extern crate rusqlite;
extern crate libsqlite3_sys as ffi;
#[cfg(feature = "vtab")] #[cfg(feature = "vtab")]
#[test] #[test]
fn test_dummy_module() { fn test_dummy_module() {
use ffi; use ffi;
use rusqlite::vtab::{eponymous_only_module, Context, IndexInfo, VTab, VTabConnection, VTabCursor, Values}; use rusqlite::vtab::{
eponymous_only_module, Context, IndexInfo, VTab, VTabConnection, VTabCursor, Values,
};
use rusqlite::{Connection, Result}; use rusqlite::{Connection, Result};
use std::os::raw::c_int; use std::os::raw::c_int;
@ -83,7 +85,8 @@ fn test_dummy_module() {
let db = Connection::open_in_memory().unwrap(); let db = Connection::open_in_memory().unwrap();
db.create_module::<DummyTab>("dummy", &module, None).unwrap(); db.create_module::<DummyTab>("dummy", &module, None)
.unwrap();
let version = unsafe { ffi::sqlite3_libversion_number() }; let version = unsafe { ffi::sqlite3_libversion_number() };
if version < 3008012 { if version < 3008012 {