Introduce init_module! macro to create sqlite_module

This commit is contained in:
gwenn 2016-02-02 21:16:10 +01:00
parent f749d24ac1
commit f261e8f7eb
2 changed files with 90 additions and 76 deletions

View File

@ -89,7 +89,7 @@ mod error;
#[cfg(feature = "backup")]pub mod backup; #[cfg(feature = "backup")]pub mod backup;
#[cfg(feature = "functions")] pub mod functions; #[cfg(feature = "functions")] pub mod functions;
#[cfg(feature = "blob")] pub mod blob; #[cfg(feature = "blob")] pub mod blob;
#[cfg(all(feature = "vtab", feature = "functions"))] pub mod vtab; #[cfg(all(feature = "vtab", feature = "functions"))]pub mod vtab;
/// Old name for `Result`. `SqliteResult` is deprecated. /// Old name for `Result`. `SqliteResult` is deprecated.
pub type SqliteResult<T> = Result<T>; pub type SqliteResult<T> = Result<T>;

View File

@ -99,20 +99,28 @@ fn escape_quote(identifier: String) -> String {
} }
} }
static INT_ARRAY_MODULE: ffi::sqlite3_module = ffi::sqlite3_module { #[macro_export]
macro_rules! init_module {
($module_name: ident, $vtab: ident, $cursor: ty,
$create: ident, $best_index: ident, $destroy: ident,
$open: ident, $close: ident,
$filter: ident, $next: ident, $eof: ident,
$column: ident, $rowid: ident) => {
static $module_name: ffi::sqlite3_module = ffi::sqlite3_module {
iVersion: 1, iVersion: 1,
xCreate: Some(x_create), xCreate: Some($create),
xConnect: Some(x_create), /* A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method */ xConnect: Some($create), /* A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method */
xBestIndex: Some(x_best_index), xBestIndex: Some($best_index),
xDisconnect: Some(x_destroy), xDisconnect: Some($destroy),
xDestroy: Some(x_destroy), xDestroy: Some($destroy),
xOpen: Some(x_open), xOpen: Some($open),
xClose: Some(x_close), xClose: Some($close),
xFilter: Some(x_filter), xFilter: Some($filter),
xNext: Some(x_next), xNext: Some($next),
xEof: Some(x_eof), xEof: Some($eof),
xColumn: Some(x_column), xColumn: Some($column),
xRowid: Some(x_rowid), xRowid: Some($rowid),
xUpdate: None, // TODO xUpdate: None, // TODO
xBegin: None, xBegin: None,
xSync: None, xSync: None,
@ -125,16 +133,16 @@ static INT_ARRAY_MODULE: ffi::sqlite3_module = ffi::sqlite3_module {
xRollbackTo: None, xRollbackTo: None,
}; };
unsafe extern "C" fn x_create(db: *mut ffi::sqlite3, unsafe extern "C" fn $create(db: *mut ffi::sqlite3,
aux: *mut libc::c_void, aux: *mut libc::c_void,
argc: libc::c_int, argc: libc::c_int,
argv: *const *const libc::c_char, argv: *const *const libc::c_char,
pp_vtab: *mut *mut ffi::sqlite3_vtab, pp_vtab: *mut *mut ffi::sqlite3_vtab,
err_msg: *mut *mut libc::c_char) err_msg: *mut *mut libc::c_char)
-> libc::c_int { -> libc::c_int {
match IntArrayVTab::create(db, aux, argc, argv) { match $vtab::create(db, aux, argc, argv) {
Ok(vtab) => { Ok(vtab) => {
let boxed_vtab: *mut IntArrayVTab = Box::into_raw(Box::new(vtab)); let boxed_vtab: *mut $vtab = 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
} }
@ -154,12 +162,73 @@ unsafe extern "C" fn x_create(db: *mut ffi::sqlite3,
} }
} }
} }
unsafe extern "C" fn $best_index(vtab: *mut ffi::sqlite3_vtab,
unsafe extern "C" fn x_destroy(vtab: *mut ffi::sqlite3_vtab) -> libc::c_int { info: *mut ffi::sqlite3_index_info)
let vtab = vtab as *mut IntArrayVTab; -> libc::c_int {
let _: Box<IntArrayVTab> = Box::from_raw(mem::transmute(vtab)); let vtab = vtab as *mut $vtab;
(*vtab).best_index(info);
ffi::SQLITE_OK ffi::SQLITE_OK
} }
unsafe extern "C" fn $destroy(vtab: *mut ffi::sqlite3_vtab) -> libc::c_int {
let vtab = vtab as *mut $vtab;
let _: Box<$vtab> = Box::from_raw(mem::transmute(vtab));
ffi::SQLITE_OK
}
unsafe extern "C" fn $open(vtab: *mut ffi::sqlite3_vtab,
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor)
-> libc::c_int {
let vtab = vtab as *mut $vtab;
let cursor = (*vtab).open();
let boxed_cursor: *mut $cursor = Box::into_raw(Box::new(cursor));
*pp_cursor = boxed_cursor as *mut ffi::sqlite3_vtab_cursor;
ffi::SQLITE_OK
}
unsafe extern "C" fn $close(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut $cursor;
let _: Box<$cursor> = Box::from_raw(mem::transmute(cursor));
ffi::SQLITE_OK
}
unsafe extern "C" fn $filter(cursor: *mut ffi::sqlite3_vtab_cursor,
_idx_num: libc::c_int,
_idx_str: *const libc::c_char,
_argc: libc::c_int,
_argv: *mut *mut ffi::sqlite3_value)
-> libc::c_int {
let cursor = cursor as *mut $cursor;
(*cursor).filter()
}
unsafe extern "C" fn $next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut $cursor;
(*cursor).next()
}
unsafe extern "C" fn $eof(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut $cursor;
(*cursor).eof() as libc::c_int
}
unsafe extern "C" fn $column(cursor: *mut ffi::sqlite3_vtab_cursor,
ctx: *mut ffi::sqlite3_context,
i: libc::c_int)
-> libc::c_int {
let cursor = cursor as *mut $cursor;
(*cursor).column(ctx, i)
}
unsafe extern "C" fn $rowid(cursor: *mut ffi::sqlite3_vtab_cursor,
p_rowid: *mut ffi::sqlite3_int64)
-> libc::c_int {
let cursor = cursor as *mut $cursor;
*p_rowid = (*cursor).rowid();
ffi::SQLITE_OK
}
}
}
init_module!(INT_ARRAY_MODULE, IntArrayVTab, IntArrayVTabCursor,
int_array_create, int_array_best_index, int_array_destroy,
int_array_open, int_array_close,
int_array_filter, int_array_next, int_array_eof,
int_array_column, int_array_rowid);
#[repr(C)] #[repr(C)]
struct IntArrayVTab { struct IntArrayVTab {
@ -210,29 +279,6 @@ impl IntArrayVTab {
} }
} }
unsafe extern "C" fn x_best_index(vtab: *mut ffi::sqlite3_vtab,
info: *mut ffi::sqlite3_index_info)
-> libc::c_int {
let vtab = vtab as *mut IntArrayVTab;
(*vtab).best_index(info);
ffi::SQLITE_OK
}
unsafe extern "C" fn x_open(vtab: *mut ffi::sqlite3_vtab,
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor)
-> libc::c_int {
let vtab = vtab as *mut IntArrayVTab;
let cursor = (*vtab).open();
let boxed_cursor: *mut IntArrayVTabCursor = Box::into_raw(Box::new(cursor));
*pp_cursor = boxed_cursor as *mut ffi::sqlite3_vtab_cursor;
ffi::SQLITE_OK
}
unsafe extern "C" fn x_close(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
let _: Box<IntArrayVTabCursor> = Box::from_raw(mem::transmute(cursor));
ffi::SQLITE_OK
}
#[repr(C)] #[repr(C)]
struct IntArrayVTabCursor { struct IntArrayVTabCursor {
/// Base class /// Base class
@ -281,38 +327,6 @@ impl IntArrayVTabCursor {
} }
} }
unsafe extern "C" fn x_filter(cursor: *mut ffi::sqlite3_vtab_cursor,
_idx_num: libc::c_int,
_idx_str: *const libc::c_char,
_argc: libc::c_int,
_argv: *mut *mut ffi::sqlite3_value)
-> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
(*cursor).filter()
}
unsafe extern "C" fn x_next(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
(*cursor).next()
}
unsafe extern "C" fn x_eof(cursor: *mut ffi::sqlite3_vtab_cursor) -> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
(*cursor).eof() as libc::c_int
}
unsafe extern "C" fn x_column(cursor: *mut ffi::sqlite3_vtab_cursor,
ctx: *mut ffi::sqlite3_context,
i: libc::c_int)
-> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
(*cursor).column(ctx, i)
}
unsafe extern "C" fn x_rowid(cursor: *mut ffi::sqlite3_vtab_cursor,
p_rowid: *mut ffi::sqlite3_int64)
-> libc::c_int {
let cursor = cursor as *mut IntArrayVTabCursor;
*p_rowid = (*cursor).rowid();
ffi::SQLITE_OK
}
unsafe fn result_error(ctx: *mut ffi::sqlite3_context, err: Error) -> libc::c_int { unsafe fn result_error(ctx: *mut ffi::sqlite3_context, err: Error) -> libc::c_int {
match err { match err {
Error::SqliteFailure(err, s) => { Error::SqliteFailure(err, s) => {