mirror of
https://github.com/isar/rusqlite.git
synced 2025-10-23 17:28:55 +08:00
VTabCursor lifetime should be bound to VTab lifetime
```c struct sqlite3_vtab_cursor { sqlite3_vtab *pVtab; /* Virtual table of this cursor */ ``` It seems that we need to introduce a lifetime on `VTab` trait to express such constraint: https://users.rust-lang.org/t/associated-type-with-lifetime-bound/7256 But there may be another/new way to do it.
This commit is contained in:
@@ -61,13 +61,13 @@ use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};
|
||||
///
|
||||
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
||||
#[repr(transparent)]
|
||||
pub struct Module<T: VTab> {
|
||||
pub struct Module<'vtab, T: VTab<'vtab>> {
|
||||
base: ffi::sqlite3_module,
|
||||
phantom: PhantomData<T>,
|
||||
phantom: PhantomData<&'vtab T>,
|
||||
}
|
||||
|
||||
unsafe impl<T: VTab> Send for Module<T> {}
|
||||
unsafe impl<T: VTab> Sync for Module<T> {}
|
||||
unsafe impl<'vtab, T: VTab<'vtab>> Send for Module<'vtab, T> {}
|
||||
unsafe impl<'vtab, T: VTab<'vtab>> Sync for Module<'vtab, T> {}
|
||||
|
||||
union ModuleZeroHack {
|
||||
bytes: [u8; std::mem::size_of::<ffi::sqlite3_module>()],
|
||||
@@ -87,7 +87,7 @@ const ZERO_MODULE: ffi::sqlite3_module = unsafe {
|
||||
/// `feature = "vtab"` 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<T: CreateVTab>() -> &'static Module<T> {
|
||||
pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab, T> {
|
||||
// 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.
|
||||
&Module {
|
||||
@@ -118,14 +118,14 @@ pub fn read_only_module<T: CreateVTab>() -> &'static Module<T> {
|
||||
xRollbackTo: None,
|
||||
..ZERO_MODULE
|
||||
},
|
||||
phantom: PhantomData::<T>,
|
||||
phantom: PhantomData::<&'vtab T>,
|
||||
}
|
||||
}
|
||||
|
||||
/// `feature = "vtab"` 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).
|
||||
pub fn eponymous_only_module<T: VTab>() -> &'static Module<T> {
|
||||
pub fn eponymous_only_module<'vtab, T: VTab<'vtab>>() -> &'static Module<'vtab, T> {
|
||||
// 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
|
||||
@@ -157,7 +157,7 @@ pub fn eponymous_only_module<T: VTab>() -> &'static Module<T> {
|
||||
xRollbackTo: None,
|
||||
..ZERO_MODULE
|
||||
},
|
||||
phantom: PhantomData::<T>,
|
||||
phantom: PhantomData::<&'vtab T>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ impl VTabConnection {
|
||||
/// ```
|
||||
///
|
||||
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
|
||||
pub unsafe trait VTab: Sized {
|
||||
pub unsafe trait VTab<'vtab>: Sized {
|
||||
/// Client data passed to `Connection::create_module`.
|
||||
type Aux;
|
||||
/// Specific cursor implementation
|
||||
@@ -225,13 +225,13 @@ pub unsafe trait VTab: Sized {
|
||||
|
||||
/// 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>;
|
||||
fn open(&'vtab self) -> Result<Self::Cursor>;
|
||||
}
|
||||
|
||||
/// `feature = "vtab"` Non-eponymous virtual table instance trait.
|
||||
///
|
||||
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
|
||||
pub trait CreateVTab: VTab {
|
||||
pub trait CreateVTab<'vtab>: VTab<'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
|
||||
@@ -607,10 +607,10 @@ impl Connection {
|
||||
///
|
||||
/// Step 3 of [Creating New Virtual Table
|
||||
/// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
|
||||
pub fn create_module<T: VTab>(
|
||||
pub fn create_module<'vtab, T: VTab<'vtab>>(
|
||||
&self,
|
||||
module_name: &str,
|
||||
module: &'static Module<T>,
|
||||
module: &'static Module<'vtab, T>,
|
||||
aux: Option<T::Aux>,
|
||||
) -> Result<()> {
|
||||
self.db.borrow_mut().create_module(module_name, module, aux)
|
||||
@@ -618,10 +618,10 @@ impl Connection {
|
||||
}
|
||||
|
||||
impl InnerConnection {
|
||||
fn create_module<T: VTab>(
|
||||
fn create_module<'vtab, T: VTab<'vtab>>(
|
||||
&mut self,
|
||||
module_name: &str,
|
||||
module: &'static Module<T>,
|
||||
module: &'static Module<'vtab, T>,
|
||||
aux: Option<T::Aux>,
|
||||
) -> Result<()> {
|
||||
let c_name = str_to_cstring(module_name)?;
|
||||
@@ -703,7 +703,7 @@ unsafe extern "C" fn free_boxed_value<T>(p: *mut c_void) {
|
||||
let _: Box<T> = Box::from_raw(p as *mut T);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_create<T>(
|
||||
unsafe extern "C" fn rust_create<'vtab, T>(
|
||||
db: *mut ffi::sqlite3,
|
||||
aux: *mut c_void,
|
||||
argc: c_int,
|
||||
@@ -712,7 +712,7 @@ unsafe extern "C" fn rust_create<T>(
|
||||
err_msg: *mut *mut c_char,
|
||||
) -> c_int
|
||||
where
|
||||
T: CreateVTab,
|
||||
T: CreateVTab<'vtab>,
|
||||
{
|
||||
use std::ffi::CStr;
|
||||
|
||||
@@ -755,7 +755,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_connect<T>(
|
||||
unsafe extern "C" fn rust_connect<'vtab, T>(
|
||||
db: *mut ffi::sqlite3,
|
||||
aux: *mut c_void,
|
||||
argc: c_int,
|
||||
@@ -764,7 +764,7 @@ unsafe extern "C" fn rust_connect<T>(
|
||||
err_msg: *mut *mut c_char,
|
||||
) -> c_int
|
||||
where
|
||||
T: VTab,
|
||||
T: VTab<'vtab>,
|
||||
{
|
||||
use std::ffi::CStr;
|
||||
|
||||
@@ -807,12 +807,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_best_index<T>(
|
||||
unsafe extern "C" fn rust_best_index<'vtab, T>(
|
||||
vtab: *mut ffi::sqlite3_vtab,
|
||||
info: *mut ffi::sqlite3_index_info,
|
||||
) -> c_int
|
||||
where
|
||||
T: VTab,
|
||||
T: VTab<'vtab>,
|
||||
{
|
||||
let vt = vtab as *mut T;
|
||||
let mut idx_info = IndexInfo(info);
|
||||
@@ -831,9 +831,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_disconnect<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
||||
unsafe extern "C" fn rust_disconnect<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
||||
where
|
||||
T: VTab,
|
||||
T: VTab<'vtab>,
|
||||
{
|
||||
if vtab.is_null() {
|
||||
return ffi::SQLITE_OK;
|
||||
@@ -843,9 +843,9 @@ where
|
||||
ffi::SQLITE_OK
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_destroy<T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
||||
unsafe extern "C" fn rust_destroy<'vtab, T>(vtab: *mut ffi::sqlite3_vtab) -> c_int
|
||||
where
|
||||
T: CreateVTab,
|
||||
T: CreateVTab<'vtab>,
|
||||
{
|
||||
if vtab.is_null() {
|
||||
return ffi::SQLITE_OK;
|
||||
@@ -869,12 +869,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn rust_open<T>(
|
||||
unsafe extern "C" fn rust_open<'vtab, T: 'vtab>(
|
||||
vtab: *mut ffi::sqlite3_vtab,
|
||||
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
|
||||
) -> c_int
|
||||
where
|
||||
T: VTab,
|
||||
T: VTab<'vtab>,
|
||||
{
|
||||
let vt = vtab as *mut T;
|
||||
match (*vt).open() {
|
||||
|
Reference in New Issue
Block a user