Introduces CreateVTab for non-eponymous VTab

This commit is contained in:
gwenn 2018-07-22 09:51:06 +02:00
parent b93b005604
commit b82a155429
2 changed files with 31 additions and 23 deletions

View File

@ -11,8 +11,8 @@ use std::str;
use ffi; use ffi;
use types::Null; use types::Null;
use vtab::{ use vtab::{
dequote, escape_double_quote, parse_boolean, read_only_module, Context, IndexInfo, Module, dequote, escape_double_quote, parse_boolean, read_only_module, Context, CreateVTab, IndexInfo,
VTab, VTabConnection, VTabCursor, Values, Module, VTab, VTabConnection, VTabCursor, Values,
}; };
use {Connection, Error, Result}; use {Connection, Error, Result};
@ -249,6 +249,8 @@ impl VTab for CSVTab {
} }
} }
impl CreateVTab for CSVTab {}
/// A cursor for the CSV virtual table /// A cursor for the CSV virtual table
#[repr(C)] #[repr(C)]
struct CSVTabCursor { struct CSVTabCursor {

View File

@ -70,7 +70,7 @@ unsafe impl<T: VTab> Sync for Module<T> {}
/// Create a read-only virtual table implementation. /// Create a read-only virtual table implementation.
/// ///
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations). /// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
pub fn read_only_module<T: VTab>(version: c_int) -> Module<T> { pub fn read_only_module<T: CreateVTab>(version: c_int) -> Module<T> {
// 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.
let ffi_module = ffi::sqlite3_module { let ffi_module = ffi::sqlite3_module {
@ -178,11 +178,33 @@ pub trait VTab: Sized {
type Aux; type Aux;
type Cursor: VTabCursor; type Cursor: VTabCursor;
/// Establish a new connection to an existing virtual table.
///
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
fn connect(
db: &mut VTabConnection,
aux: Option<&Self::Aux>,
args: &[&[u8]],
) -> Result<(String, Self)>;
/// Determine the best way to access the virtual table.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xbestindex_method))
fn best_index(&self, info: &mut IndexInfo) -> Result<()>;
/// Create a new cursor used for accessing a virtual table.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xopen_method))
fn open(&self) -> Result<Self::Cursor>;
}
/// Non-eponymous virtual table instance trait.
///
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
pub trait CreateVTab: VTab {
/// 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.
/// ///
/// Unused by eponymous virtual table. Call `connect` by default. /// Call `connect` by default.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcreate_method)) /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcreate_method))
fn create( fn create(
db: &mut VTabConnection, db: &mut VTabConnection,
@ -194,27 +216,11 @@ pub trait VTab: Sized {
/// Destroy the underlying table implementation. This method undoes the work of `create`. /// Destroy the underlying table implementation. This method undoes the work of `create`.
/// ///
/// Unused by eponymous virtual table. Do nothing by default. /// Do nothing by default.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xdestroy_method)) /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xdestroy_method))
fn destroy(&self) -> Result<()> { fn destroy(&self) -> Result<()> {
Ok(()) Ok(())
} }
/// 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.
///
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
fn connect(
db: &mut VTabConnection,
aux: Option<&Self::Aux>,
args: &[&[u8]],
) -> Result<(String, Self)>;
/// Determine the best way to access the virtual table.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xbestindex_method))
fn best_index(&self, info: &mut IndexInfo) -> Result<()>;
/// Create a new cursor used for accessing a virtual table.
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xopen_method))
fn open(&self) -> Result<Self::Cursor>;
} }
bitflags! { bitflags! {
@ -609,7 +615,7 @@ unsafe extern "C" fn rust_create<T>(
err_msg: *mut *mut c_char, err_msg: *mut *mut c_char,
) -> c_int ) -> c_int
where where
T: VTab, T: CreateVTab,
{ {
use std::error::Error as StdError; use std::error::Error as StdError;
use std::ffi::CStr; use std::ffi::CStr;
@ -747,7 +753,7 @@ where
unsafe extern "C" fn rust_destroy<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int unsafe extern "C" fn rust_destroy<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
where where
T: VTab, T: CreateVTab,
{ {
use std::error::Error as StdError; use std::error::Error as StdError;
if vtab.is_null() { if vtab.is_null() {