mirror of
https://github.com/isar/rusqlite.git
synced 2025-01-19 20:50:51 +08:00
Refactoring
Introduce VTab::destroy. Let implementation specify the iVersion. Rename simple_module into read_only_module.
This commit is contained in:
parent
849dbda5e8
commit
669663304e
@ -36,7 +36,7 @@ pub fn load_module(conn: &Connection) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref ARRAY_MODULE: Module<ArrayTab> = eponymous_only_module::<ArrayTab>();
|
static ref ARRAY_MODULE: Module<ArrayTab> = eponymous_only_module::<ArrayTab>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Column numbers
|
// Column numbers
|
||||||
|
@ -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, simple_module, Context, IndexInfo, Module, VTab,
|
dequote, escape_double_quote, parse_boolean, read_only_module, Context, IndexInfo, Module,
|
||||||
VTabConnection, VTabCursor, Values,
|
VTab, VTabConnection, VTabCursor, Values,
|
||||||
};
|
};
|
||||||
use {Connection, Error, Result};
|
use {Connection, Error, Result};
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ pub fn load_module(conn: &Connection) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CSV_MODULE: Module<CSVTab> = simple_module::<CSVTab>();
|
static ref CSV_MODULE: Module<CSVTab> = read_only_module::<CSVTab>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An instance of the CSV virtual table
|
/// An instance of the CSV virtual table
|
||||||
|
@ -70,16 +70,16 @@ 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 simple_module<T: VTab>() -> Module<T> {
|
pub fn read_only_module<T: VTab>(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 {
|
||||||
iVersion: 1,
|
iVersion: version,
|
||||||
xCreate: Some(rust_create::<T>),
|
xCreate: Some(rust_create::<T>),
|
||||||
xConnect: Some(rust_connect::<T>),
|
xConnect: Some(rust_connect::<T>),
|
||||||
xBestIndex: Some(rust_best_index::<T>),
|
xBestIndex: Some(rust_best_index::<T>),
|
||||||
xDisconnect: Some(rust_disconnect::<T>),
|
xDisconnect: Some(rust_disconnect::<T>),
|
||||||
xDestroy: Some(rust_disconnect::<T>), // TODO Validate: no rust_destroy
|
xDestroy: Some(rust_destroy::<T>),
|
||||||
xOpen: Some(rust_open::<T>),
|
xOpen: Some(rust_open::<T>),
|
||||||
xClose: Some(rust_close::<T::Cursor>),
|
xClose: Some(rust_close::<T::Cursor>),
|
||||||
xFilter: Some(rust_filter::<T::Cursor>),
|
xFilter: Some(rust_filter::<T::Cursor>),
|
||||||
@ -107,11 +107,11 @@ pub fn simple_module<T: VTab>() -> Module<T> {
|
|||||||
/// Create an eponymous only virtual table implementation.
|
/// Create an eponymous 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 eponymous_only_module<T: VTab>() -> Module<T> {
|
pub fn eponymous_only_module<T: VTab>(version: c_int) -> Module<T> {
|
||||||
// A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method
|
// A virtual table is eponymous if its xCreate method is the exact same function as the xConnect method
|
||||||
// For eponymous-only virtual tables, the xCreate method is NULL
|
// For eponymous-only virtual tables, the xCreate method is NULL
|
||||||
let ffi_module = ffi::sqlite3_module {
|
let ffi_module = ffi::sqlite3_module {
|
||||||
iVersion: 1,
|
iVersion: version,
|
||||||
xCreate: None,
|
xCreate: None,
|
||||||
xConnect: Some(rust_connect::<T>),
|
xConnect: Some(rust_connect::<T>),
|
||||||
xBestIndex: Some(rust_best_index::<T>),
|
xBestIndex: Some(rust_best_index::<T>),
|
||||||
@ -177,6 +177,8 @@ pub trait VTab: Sized {
|
|||||||
/// 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.
|
||||||
/// (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,
|
||||||
@ -186,10 +188,17 @@ pub trait VTab: Sized {
|
|||||||
Self::connect(db, aux, args)
|
Self::connect(db, aux, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Validate: no destroy
|
/// Destroy the underlying table implementation. This method undoes the work of `create`.
|
||||||
|
///
|
||||||
|
/// Unused by eponymous virtual table. 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
|
/// 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.
|
||||||
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xconnect_method))
|
||||||
fn connect(
|
fn connect(
|
||||||
db: &mut VTabConnection,
|
db: &mut VTabConnection,
|
||||||
@ -717,11 +726,41 @@ unsafe extern "C" fn rust_disconnect<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
|||||||
where
|
where
|
||||||
T: VTab,
|
T: VTab,
|
||||||
{
|
{
|
||||||
|
if vtab.is_null() {
|
||||||
|
return ffi::SQLITE_OK;
|
||||||
|
}
|
||||||
let vtab = vtab as *mut T;
|
let vtab = vtab as *mut T;
|
||||||
let _: Box<T> = Box::from_raw(vtab);
|
let _: Box<T> = Box::from_raw(vtab);
|
||||||
ffi::SQLITE_OK
|
ffi::SQLITE_OK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn rust_destroy<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
||||||
|
where
|
||||||
|
T: VTab,
|
||||||
|
{
|
||||||
|
use std::error::Error as StdError;
|
||||||
|
if vtab.is_null() {
|
||||||
|
return ffi::SQLITE_OK;
|
||||||
|
}
|
||||||
|
let vt = vtab as *mut T;
|
||||||
|
match (*vt).destroy() {
|
||||||
|
Ok(_) => {
|
||||||
|
let _: Box<T> = Box::from_raw(vt);
|
||||||
|
ffi::SQLITE_OK
|
||||||
|
}
|
||||||
|
Err(Error::SqliteFailure(err, s)) => {
|
||||||
|
if let Some(err_msg) = s {
|
||||||
|
set_err_msg(vtab, &err_msg);
|
||||||
|
}
|
||||||
|
err.extended_code
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
set_err_msg(vtab, err.description());
|
||||||
|
ffi::SQLITE_ERROR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn rust_open<T>(
|
unsafe extern "C" fn rust_open<T>(
|
||||||
vtab: *mut ffi::sqlite3_vtab,
|
vtab: *mut ffi::sqlite3_vtab,
|
||||||
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
|
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
|
||||||
|
@ -19,7 +19,7 @@ pub fn load_module(conn: &Connection) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref SERIES_MODULE: Module<SeriesTab> = eponymous_only_module::<SeriesTab>();
|
static ref SERIES_MODULE: Module<SeriesTab> = eponymous_only_module::<SeriesTab>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Column numbers
|
// Column numbers
|
||||||
|
@ -7,12 +7,13 @@ extern crate rusqlite;
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_dummy_module() {
|
fn test_dummy_module() {
|
||||||
use rusqlite::vtab::{
|
use rusqlite::vtab::{
|
||||||
eponymous_only_module, sqlite3_vtab, sqlite3_vtab_cursor, Context, IndexInfo, VTab, VTabConnection, VTabCursor, Values,
|
eponymous_only_module, sqlite3_vtab, sqlite3_vtab_cursor, Context, IndexInfo, VTab,
|
||||||
|
VTabConnection, VTabCursor, Values,
|
||||||
};
|
};
|
||||||
use rusqlite::{version_number, Connection, Result};
|
use rusqlite::{version_number, Connection, Result};
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
let module = eponymous_only_module::<DummyTab>();
|
let module = eponymous_only_module::<DummyTab>(1);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct DummyTab {
|
struct DummyTab {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user