Introduce Aux associated type

This commit is contained in:
gwenn 2018-05-06 18:05:02 +02:00
parent 2e2b5c41f4
commit 58b8b4c95d
4 changed files with 23 additions and 8 deletions

View File

@ -34,6 +34,7 @@ pub fn load_module(conn: &Connection) -> Result<()> {
init_module!( init_module!(
CSV_MODULE, CSV_MODULE,
CSVTab, CSVTab,
(),
CSVTabCursor, CSVTabCursor,
csv_create, csv_create,
csv_connect, csv_connect,
@ -96,9 +97,10 @@ impl CSVTab {
} }
impl VTab for CSVTab { impl VTab for CSVTab {
type Aux = ();
type Cursor = CSVTabCursor; type Cursor = CSVTabCursor;
unsafe fn connect(db: *mut ffi::sqlite3, _aux: *mut c_void, args: &[&[u8]]) -> Result<CSVTab> { unsafe fn connect(db: *mut ffi::sqlite3, _aux: *mut (), 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()));
} }

View File

@ -43,6 +43,7 @@ pub fn drop_int_array(conn: &Connection, name: &str) -> Result<()> {
eponymous_module!( eponymous_module!(
INT_ARRAY_MODULE, INT_ARRAY_MODULE,
IntArrayVTab, IntArrayVTab,
Rc<RefCell<Vec<i64>>>,
IntArrayVTabCursor, IntArrayVTabCursor,
Some(int_array_connect), Some(int_array_connect),
int_array_connect, int_array_connect,
@ -66,11 +67,12 @@ struct IntArrayVTab {
} }
impl VTab for IntArrayVTab { impl VTab for IntArrayVTab {
type Aux = Rc<RefCell<Vec<i64>>>;
type Cursor = IntArrayVTabCursor; type Cursor = IntArrayVTabCursor;
unsafe fn connect( unsafe fn connect(
db: *mut ffi::sqlite3, db: *mut ffi::sqlite3,
aux: *mut c_void, aux: *mut Rc<RefCell<Vec<i64>>>,
_args: &[&[u8]], _args: &[&[u8]],
) -> Result<IntArrayVTab> { ) -> Result<IntArrayVTab> {
let array = aux as *const Rc<RefCell<Vec<i64>>>; let array = aux as *const Rc<RefCell<Vec<i64>>>;

View File

@ -42,16 +42,18 @@ use {str_to_cstring, Connection, Error, InnerConnection, Result};
/// Virtual table instance trait. /// Virtual table instance trait.
pub trait VTab: Sized { pub trait VTab: Sized {
type Aux;
type Cursor: VTabCursor; type Cursor: VTabCursor;
/// 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 `db` parameter is a pointer to the SQLite database connection that is executing
/// the CREATE VIRTUAL TABLE statement. /// the CREATE VIRTUAL TABLE statement.
unsafe fn create(db: *mut ffi::sqlite3, aux: *mut c_void, args: &[&[u8]]) -> Result<Self> { unsafe fn create(db: *mut ffi::sqlite3, aux: *mut Self::Aux, args: &[&[u8]]) -> Result<Self> {
Self::connect(db, aux, args) Self::connect(db, aux, args)
} }
/// Similar to `create`. The difference is that `connect` is called to establish a new connection /// Similar to `create`. The difference is that `connect` is called to establish a new connection
/// to an _existing_ virtual table whereas `create` is called to create a new virtual table from scratch. /// to an _existing_ virtual table whereas `create` is called to create a new virtual table from scratch.
unsafe fn connect(db: *mut ffi::sqlite3, aux: *mut c_void, args: &[&[u8]]) -> Result<Self>; unsafe fn connect(db: *mut ffi::sqlite3, aux: *mut Self::Aux, 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 IndexInfo) -> Result<()>; fn best_index(&self, info: &mut IndexInfo) -> Result<()>;
/// Create a new cursor used for accessing a virtual table. /// Create a new cursor used for accessing a virtual table.
@ -385,6 +387,7 @@ macro_rules! init_module {
( (
$module_name:ident, $module_name:ident,
$vtab:ident, $vtab:ident,
$aux:ty,
$cursor:ty, $cursor:ty,
$create:ident, $create:ident,
$connect:ident, $connect:ident,
@ -427,9 +430,10 @@ macro_rules! init_module {
// The xConnect and xCreate methods do the same thing, but they must be // The xConnect and xCreate methods do the same thing, but they must be
// different so that the virtual table is not an eponymous virtual table. // different so that the virtual table is not an eponymous virtual table.
create_or_connect!($vtab, $create, create); create_or_connect!($vtab, $aux, $create, create);
common_decl!( common_decl!(
$vtab, $vtab,
$aux,
$cursor, $cursor,
$connect, $connect,
$best_index, $best_index,
@ -451,6 +455,7 @@ macro_rules! eponymous_module {
( (
$module_name:ident, $module_name:ident,
$vtab:ident, $vtab:ident,
$aux:ty,
$cursor:ty, $cursor:ty,
$create:expr, $create:expr,
$connect:ident, $connect:ident,
@ -494,6 +499,7 @@ macro_rules! eponymous_module {
common_decl!( common_decl!(
$vtab, $vtab,
$aux,
$cursor, $cursor,
$connect, $connect,
$best_index, $best_index,
@ -511,7 +517,7 @@ macro_rules! eponymous_module {
} // eponymous_module macro end } // eponymous_module macro end
macro_rules! create_or_connect { macro_rules! create_or_connect {
($vtab:ident, $create_or_connect:ident, $vtab_func:ident) => { ($vtab:ident, $aux:ty, $create_or_connect:ident, $vtab_func:ident) => {
unsafe extern "C" fn $create_or_connect( unsafe extern "C" fn $create_or_connect(
db: *mut ffi::sqlite3, db: *mut ffi::sqlite3,
aux: *mut c_void, aux: *mut c_void,
@ -524,6 +530,8 @@ macro_rules! create_or_connect {
use std::ffi::CStr; use std::ffi::CStr;
use std::slice; use std::slice;
use vtab::mprintf; use vtab::mprintf;
let aux = aux as *mut $aux;
let args = slice::from_raw_parts(argv, argc as usize); let args = slice::from_raw_parts(argv, argc as usize);
let vec = args.iter() let vec = args.iter()
.map(|&cs| CStr::from_ptr(cs).to_bytes()) .map(|&cs| CStr::from_ptr(cs).to_bytes())
@ -552,6 +560,7 @@ macro_rules! create_or_connect {
macro_rules! common_decl { macro_rules! common_decl {
( (
$vtab:ident, $vtab:ident,
$aux:ty,
$cursor:ty, $cursor:ty,
$connect:ident, $connect:ident,
$best_index:ident, $best_index:ident,
@ -565,7 +574,7 @@ macro_rules! common_decl {
$column:ident, $column:ident,
$rowid:ident $rowid:ident
) => { ) => {
create_or_connect!($vtab, $connect, connect); create_or_connect!($vtab, $aux, $connect, connect);
unsafe extern "C" fn $best_index( unsafe extern "C" fn $best_index(
vtab: *mut ffi::sqlite3_vtab, vtab: *mut ffi::sqlite3_vtab,
info: *mut ffi::sqlite3_index_info, info: *mut ffi::sqlite3_index_info,

View File

@ -16,6 +16,7 @@ pub fn load_module(conn: &Connection) -> Result<()> {
eponymous_module!( eponymous_module!(
SERIES_MODULE, SERIES_MODULE,
SeriesTab, SeriesTab,
(),
SeriesTabCursor, SeriesTabCursor,
None, None,
series_connect, series_connect,
@ -61,11 +62,12 @@ struct SeriesTab {
} }
impl VTab for SeriesTab { impl VTab for SeriesTab {
type Aux = ();
type Cursor = SeriesTabCursor; type Cursor = SeriesTabCursor;
unsafe fn connect( unsafe fn connect(
db: *mut ffi::sqlite3, db: *mut ffi::sqlite3,
_aux: *mut c_void, _aux: *mut (),
_args: &[&[u8]], _args: &[&[u8]],
) -> Result<SeriesTab> { ) -> Result<SeriesTab> {
let vtab = SeriesTab { let vtab = SeriesTab {