From b82a155429997f5f2e64a332dcaa4467151be847 Mon Sep 17 00:00:00 2001 From: gwenn Date: Sun, 22 Jul 2018 09:51:06 +0200 Subject: [PATCH] Introduces CreateVTab for non-eponymous VTab --- src/vtab/csvtab.rs | 6 ++++-- src/vtab/mod.rs | 48 ++++++++++++++++++++++++++-------------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/vtab/csvtab.rs b/src/vtab/csvtab.rs index b4a4145..387e6c7 100644 --- a/src/vtab/csvtab.rs +++ b/src/vtab/csvtab.rs @@ -11,8 +11,8 @@ use std::str; use ffi; use types::Null; use vtab::{ - dequote, escape_double_quote, parse_boolean, read_only_module, Context, IndexInfo, Module, - VTab, VTabConnection, VTabCursor, Values, + dequote, escape_double_quote, parse_boolean, read_only_module, Context, CreateVTab, IndexInfo, + Module, VTab, VTabConnection, VTabCursor, Values, }; use {Connection, Error, Result}; @@ -249,6 +249,8 @@ impl VTab for CSVTab { } } +impl CreateVTab for CSVTab {} + /// A cursor for the CSV virtual table #[repr(C)] struct CSVTabCursor { diff --git a/src/vtab/mod.rs b/src/vtab/mod.rs index 8bffb65..5d16c98 100644 --- a/src/vtab/mod.rs +++ b/src/vtab/mod.rs @@ -70,7 +70,7 @@ unsafe impl Sync for Module {} /// 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). -pub fn read_only_module(version: c_int) -> Module { +pub fn read_only_module(version: c_int) -> Module { // 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. let ffi_module = ffi::sqlite3_module { @@ -178,11 +178,33 @@ pub trait VTab: Sized { type Aux; 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; +} + +/// 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. /// The `db` parameter is a pointer to the SQLite database connection that is executing /// 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)) fn create( db: &mut VTabConnection, @@ -194,27 +216,11 @@ pub trait VTab: Sized { /// 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)) fn destroy(&self) -> Result<()> { 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; } bitflags! { @@ -609,7 +615,7 @@ unsafe extern "C" fn rust_create( err_msg: *mut *mut c_char, ) -> c_int where - T: VTab, + T: CreateVTab, { use std::error::Error as StdError; use std::ffi::CStr; @@ -747,7 +753,7 @@ where unsafe extern "C" fn rust_destroy(vtab: *mut ffi::sqlite3_vtab) -> c_int where - T: VTab, + T: CreateVTab, { use std::error::Error as StdError; if vtab.is_null() {