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 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};
// http://sqlite.org/bindptr.html

View File

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

View File

@ -432,7 +432,9 @@ impl Connection {
module: &Module<T>,
aux: Option<T::Aux>,
) -> 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,
err_msg: *mut *mut c_char,
) -> c_int
where T: VTab {
where
T: VTab,
{
use std::error::Error as StdError;
use std::ffi::CStr;
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>
.collect::<Vec<_>>();
match T::create(&mut conn, aux.as_ref(), &vec[..]) {
Ok((sql, vtab)) => {
match ::std::ffi::CString::new(sql) {
Ok(c_sql) => {
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
if rc == ffi::SQLITE_OK {
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
ffi::SQLITE_OK
} else {
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
rc
}
}
Err(err) => {
Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
Ok(c_sql) => {
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
if rc == ffi::SQLITE_OK {
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
ffi::SQLITE_OK
} else {
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
rc
}
}
}
Err(err) => {
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
}
},
Err(Error::SqliteFailure(err, s)) => {
if let Some(s) = s {
*err_msg = mprintf(&s);
@ -583,7 +585,9 @@ unsafe extern "C" fn rust_connect<T>(
pp_vtab: *mut *mut ffi::sqlite3_vtab,
err_msg: *mut *mut c_char,
) -> c_int
where T: VTab {
where
T: VTab,
{
use std::error::Error as StdError;
use std::ffi::CStr;
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>
.collect::<Vec<_>>();
match T::connect(&mut conn, aux.as_ref(), &vec[..]) {
Ok((sql, vtab)) => {
match ::std::ffi::CString::new(sql) {
Ok(c_sql) => {
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
if rc == ffi::SQLITE_OK {
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
ffi::SQLITE_OK
} else {
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
rc
}
}
Err(err) => {
Ok((sql, vtab)) => match ::std::ffi::CString::new(sql) {
Ok(c_sql) => {
let rc = ffi::sqlite3_declare_vtab(db, c_sql.as_ptr());
if rc == ffi::SQLITE_OK {
let boxed_vtab: *mut T = Box::into_raw(Box::new(vtab));
*pp_vtab = boxed_vtab as *mut ffi::sqlite3_vtab;
ffi::SQLITE_OK
} else {
let err = error_from_sqlite_code(rc, None);
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
rc
}
}
}
Err(err) => {
*err_msg = mprintf(err.description());
ffi::SQLITE_ERROR
}
},
Err(Error::SqliteFailure(err, s)) => {
if let Some(s) = s {
*err_msg = mprintf(&s);
@ -633,7 +635,9 @@ unsafe extern "C" fn rust_best_index<T>(
vtab: *mut ffi::sqlite3_vtab,
info: *mut ffi::sqlite3_index_info,
) -> c_int
where T: VTab {
where
T: VTab,
{
use std::error::Error as StdError;
let vt = vtab as *mut T;
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
where T: VTab {
where
T: VTab,
{
let vtab = vtab as *mut T;
let _: Box<T> = Box::from_raw(vtab);
ffi::SQLITE_OK
@ -663,7 +669,9 @@ unsafe extern "C" fn rust_open<T>(
vtab: *mut ffi::sqlite3_vtab,
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
) -> c_int
where T: VTab {
where
T: VTab,
{
use std::error::Error as StdError;
let vt = vtab as *mut T;
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
where C: VTabCursor {
where
C: VTabCursor,
{
let cr = cursor as *mut C;
let _: Box<C> = Box::from_raw(cr);
ffi::SQLITE_OK
@ -699,7 +709,9 @@ unsafe extern "C" fn rust_filter<C>(
argc: c_int,
argv: *mut *mut ffi::sqlite3_value,
) -> c_int
where C: VTabCursor {
where
C: VTabCursor,
{
use std::ffi::CStr;
use std::slice;
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
where C: VTabCursor {
where
C: VTabCursor,
{
let cr = cursor as *mut C;
cursor_error(cursor, (*cr).next())
}
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;
(*cr).eof() as c_int
}
@ -732,7 +748,9 @@ unsafe extern "C" fn rust_column<C>(
ctx: *mut ffi::sqlite3_context,
i: c_int,
) -> c_int
where C: VTabCursor {
where
C: VTabCursor,
{
let cr = cursor as *mut C;
let mut ctxt = Context(ctx);
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,
p_rowid: *mut ffi::sqlite3_int64,
) -> c_int
where C: VTabCursor {
where
C: VTabCursor,
{
let cr = cursor as *mut C;
match (*cr).rowid() {
Ok(rowid) => {

View File

@ -5,7 +5,10 @@ use std::os::raw::c_int;
use ffi;
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};
/// Register the "generate_series" module.

View File

@ -1,14 +1,16 @@
//! Ensure Virtual tables can be declared outside `rusqlite` crate.
extern crate libsqlite3_sys as ffi;
#[cfg(feature = "vtab")]
extern crate rusqlite;
extern crate libsqlite3_sys as ffi;
#[cfg(feature = "vtab")]
#[test]
fn test_dummy_module() {
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 std::os::raw::c_int;
@ -83,7 +85,8 @@ fn test_dummy_module() {
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() };
if version < 3008012 {