mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-25 19:01:38 +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:
parent
48a15857fb
commit
2af75d1f13
@ -27,6 +27,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::{c_char, c_int, c_void};
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -72,9 +73,9 @@ struct ArrayTab {
|
|||||||
base: ffi::sqlite3_vtab,
|
base: ffi::sqlite3_vtab,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTab for ArrayTab {
|
unsafe impl<'vtab> VTab<'vtab> for ArrayTab {
|
||||||
type Aux = ();
|
type Aux = ();
|
||||||
type Cursor = ArrayTabCursor;
|
type Cursor = ArrayTabCursor<'vtab>;
|
||||||
|
|
||||||
fn connect(
|
fn connect(
|
||||||
_: &mut VTabConnection,
|
_: &mut VTabConnection,
|
||||||
@ -118,28 +119,30 @@ unsafe impl VTab for ArrayTab {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(&self) -> Result<ArrayTabCursor> {
|
fn open(&'vtab self) -> Result<ArrayTabCursor<'vtab>> {
|
||||||
Ok(ArrayTabCursor::new())
|
Ok(ArrayTabCursor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cursor for the Array virtual table
|
/// A cursor for the Array virtual table
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ArrayTabCursor {
|
struct ArrayTabCursor<'vtab> {
|
||||||
/// Base class. Must be first
|
/// Base class. Must be first
|
||||||
base: ffi::sqlite3_vtab_cursor,
|
base: ffi::sqlite3_vtab_cursor,
|
||||||
/// The rowid
|
/// The rowid
|
||||||
row_id: i64,
|
row_id: i64,
|
||||||
/// Pointer to the array of values ("pointer")
|
/// Pointer to the array of values ("pointer")
|
||||||
ptr: Option<Array>,
|
ptr: Option<Array>,
|
||||||
|
phantom: PhantomData<&'vtab ArrayTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ArrayTabCursor {
|
impl ArrayTabCursor<'_> {
|
||||||
fn new() -> ArrayTabCursor {
|
fn new<'vtab>() -> ArrayTabCursor<'vtab> {
|
||||||
ArrayTabCursor {
|
ArrayTabCursor {
|
||||||
base: ffi::sqlite3_vtab_cursor::default(),
|
base: ffi::sqlite3_vtab_cursor::default(),
|
||||||
row_id: 0,
|
row_id: 0,
|
||||||
ptr: None,
|
ptr: None,
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +153,7 @@ impl ArrayTabCursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl VTabCursor for ArrayTabCursor {
|
unsafe impl VTabCursor for ArrayTabCursor<'_> {
|
||||||
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
||||||
if idx_num > 0 {
|
if idx_num > 0 {
|
||||||
self.ptr = args.get_array(0)?;
|
self.ptr = args.get_array(0)?;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str;
|
use std::str;
|
||||||
@ -95,9 +96,9 @@ impl CSVTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTab for CSVTab {
|
unsafe impl<'vtab> VTab<'vtab> for CSVTab {
|
||||||
type Aux = ();
|
type Aux = ();
|
||||||
type Cursor = CSVTabCursor;
|
type Cursor = CSVTabCursor<'vtab>;
|
||||||
|
|
||||||
fn connect(
|
fn connect(
|
||||||
_: &mut VTabConnection,
|
_: &mut VTabConnection,
|
||||||
@ -258,16 +259,16 @@ unsafe impl VTab for CSVTab {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(&self) -> Result<CSVTabCursor> {
|
fn open(&'vtab self) -> Result<CSVTabCursor<'vtab>> {
|
||||||
Ok(CSVTabCursor::new(self.reader()?))
|
Ok(CSVTabCursor::new(self.reader()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateVTab 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<'vtab> {
|
||||||
/// Base class. Must be first
|
/// Base class. Must be first
|
||||||
base: ffi::sqlite3_vtab_cursor,
|
base: ffi::sqlite3_vtab_cursor,
|
||||||
/// The CSV reader object
|
/// The CSV reader object
|
||||||
@ -277,16 +278,18 @@ struct CSVTabCursor {
|
|||||||
/// Values of the current row
|
/// Values of the current row
|
||||||
cols: csv::StringRecord,
|
cols: csv::StringRecord,
|
||||||
eof: bool,
|
eof: bool,
|
||||||
|
phantom: PhantomData<&'vtab CSVTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CSVTabCursor {
|
impl CSVTabCursor<'_> {
|
||||||
fn new(reader: csv::Reader<File>) -> CSVTabCursor {
|
fn new<'vtab>(reader: csv::Reader<File>) -> CSVTabCursor<'vtab> {
|
||||||
CSVTabCursor {
|
CSVTabCursor {
|
||||||
base: ffi::sqlite3_vtab_cursor::default(),
|
base: ffi::sqlite3_vtab_cursor::default(),
|
||||||
reader,
|
reader,
|
||||||
row_number: 0,
|
row_number: 0,
|
||||||
cols: csv::StringRecord::new(),
|
cols: csv::StringRecord::new(),
|
||||||
eof: false,
|
eof: false,
|
||||||
|
phantom: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,7 +299,7 @@ impl CSVTabCursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTabCursor for CSVTabCursor {
|
unsafe impl VTabCursor for CSVTabCursor<'_> {
|
||||||
// Only a full table scan is supported. So `filter` simply rewinds to
|
// Only a full table scan is supported. So `filter` simply rewinds to
|
||||||
// the beginning.
|
// the beginning.
|
||||||
fn filter(
|
fn filter(
|
||||||
|
@ -61,13 +61,13 @@ use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};
|
|||||||
///
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Module<T: VTab> {
|
pub struct Module<'vtab, T: VTab<'vtab>> {
|
||||||
base: ffi::sqlite3_module,
|
base: ffi::sqlite3_module,
|
||||||
phantom: PhantomData<T>,
|
phantom: PhantomData<&'vtab T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: VTab> Send for Module<T> {}
|
unsafe impl<'vtab, T: VTab<'vtab>> Send for Module<'vtab, T> {}
|
||||||
unsafe impl<T: VTab> Sync for Module<T> {}
|
unsafe impl<'vtab, T: VTab<'vtab>> Sync for Module<'vtab, T> {}
|
||||||
|
|
||||||
union ModuleZeroHack {
|
union ModuleZeroHack {
|
||||||
bytes: [u8; std::mem::size_of::<ffi::sqlite3_module>()],
|
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.
|
/// `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).
|
/// 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
|
// 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.
|
||||||
&Module {
|
&Module {
|
||||||
@ -118,14 +118,14 @@ pub fn read_only_module<T: CreateVTab>() -> &'static Module<T> {
|
|||||||
xRollbackTo: None,
|
xRollbackTo: None,
|
||||||
..ZERO_MODULE
|
..ZERO_MODULE
|
||||||
},
|
},
|
||||||
phantom: PhantomData::<T>,
|
phantom: PhantomData::<&'vtab T>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `feature = "vtab"` Create an eponymous only virtual table implementation.
|
/// `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).
|
/// 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
|
// 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
|
// as the xConnect method For eponymous-only virtual tables, the xCreate
|
||||||
// method is NULL
|
// method is NULL
|
||||||
@ -157,7 +157,7 @@ pub fn eponymous_only_module<T: VTab>() -> &'static Module<T> {
|
|||||||
xRollbackTo: None,
|
xRollbackTo: None,
|
||||||
..ZERO_MODULE
|
..ZERO_MODULE
|
||||||
},
|
},
|
||||||
phantom: PhantomData::<T>,
|
phantom: PhantomData::<&'vtab T>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ impl VTabConnection {
|
|||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
|
/// (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`.
|
/// Client data passed to `Connection::create_module`.
|
||||||
type Aux;
|
type Aux;
|
||||||
/// Specific cursor implementation
|
/// Specific cursor implementation
|
||||||
@ -225,13 +225,13 @@ pub unsafe trait VTab: Sized {
|
|||||||
|
|
||||||
/// Create a new cursor used for accessing a virtual table.
|
/// Create a new cursor used for accessing a virtual table.
|
||||||
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xopen_method))
|
/// (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.
|
/// `feature = "vtab"` Non-eponymous virtual table instance trait.
|
||||||
///
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
|
/// (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
|
/// 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
|
/// TABLE statement. The `db` parameter is a pointer to the SQLite
|
||||||
/// database connection that is executing the CREATE VIRTUAL TABLE
|
/// database connection that is executing the CREATE VIRTUAL TABLE
|
||||||
@ -607,10 +607,10 @@ impl Connection {
|
|||||||
///
|
///
|
||||||
/// Step 3 of [Creating New Virtual Table
|
/// Step 3 of [Creating New Virtual Table
|
||||||
/// Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
|
/// 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,
|
&self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
module: &'static Module<T>,
|
module: &'static Module<'vtab, T>,
|
||||||
aux: Option<T::Aux>,
|
aux: Option<T::Aux>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.db.borrow_mut().create_module(module_name, module, aux)
|
self.db.borrow_mut().create_module(module_name, module, aux)
|
||||||
@ -618,10 +618,10 @@ impl Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InnerConnection {
|
impl InnerConnection {
|
||||||
fn create_module<T: VTab>(
|
fn create_module<'vtab, T: VTab<'vtab>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
module: &'static Module<T>,
|
module: &'static Module<'vtab, T>,
|
||||||
aux: Option<T::Aux>,
|
aux: Option<T::Aux>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let c_name = str_to_cstring(module_name)?;
|
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);
|
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,
|
db: *mut ffi::sqlite3,
|
||||||
aux: *mut c_void,
|
aux: *mut c_void,
|
||||||
argc: c_int,
|
argc: c_int,
|
||||||
@ -712,7 +712,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: CreateVTab,
|
T: CreateVTab<'vtab>,
|
||||||
{
|
{
|
||||||
use std::ffi::CStr;
|
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,
|
db: *mut ffi::sqlite3,
|
||||||
aux: *mut c_void,
|
aux: *mut c_void,
|
||||||
argc: c_int,
|
argc: c_int,
|
||||||
@ -764,7 +764,7 @@ unsafe extern "C" fn rust_connect<T>(
|
|||||||
err_msg: *mut *mut c_char,
|
err_msg: *mut *mut c_char,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: VTab,
|
T: VTab<'vtab>,
|
||||||
{
|
{
|
||||||
use std::ffi::CStr;
|
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,
|
vtab: *mut ffi::sqlite3_vtab,
|
||||||
info: *mut ffi::sqlite3_index_info,
|
info: *mut ffi::sqlite3_index_info,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: VTab,
|
T: VTab<'vtab>,
|
||||||
{
|
{
|
||||||
let vt = vtab as *mut T;
|
let vt = vtab as *mut T;
|
||||||
let mut idx_info = IndexInfo(info);
|
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
|
where
|
||||||
T: VTab,
|
T: VTab<'vtab>,
|
||||||
{
|
{
|
||||||
if vtab.is_null() {
|
if vtab.is_null() {
|
||||||
return ffi::SQLITE_OK;
|
return ffi::SQLITE_OK;
|
||||||
@ -843,9 +843,9 @@ where
|
|||||||
ffi::SQLITE_OK
|
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
|
where
|
||||||
T: CreateVTab,
|
T: CreateVTab<'vtab>,
|
||||||
{
|
{
|
||||||
if vtab.is_null() {
|
if vtab.is_null() {
|
||||||
return ffi::SQLITE_OK;
|
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,
|
vtab: *mut ffi::sqlite3_vtab,
|
||||||
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
|
pp_cursor: *mut *mut ffi::sqlite3_vtab_cursor,
|
||||||
) -> c_int
|
) -> c_int
|
||||||
where
|
where
|
||||||
T: VTab,
|
T: VTab<'vtab>,
|
||||||
{
|
{
|
||||||
let vt = vtab as *mut T;
|
let vt = vtab as *mut T;
|
||||||
match (*vt).open() {
|
match (*vt).open() {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
//! "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c):
|
//! "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c):
|
||||||
//! https://www.sqlite.org/series.html
|
//! https://www.sqlite.org/series.html
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
@ -49,9 +50,9 @@ struct SeriesTab {
|
|||||||
base: ffi::sqlite3_vtab,
|
base: ffi::sqlite3_vtab,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTab for SeriesTab {
|
unsafe impl<'vtab> VTab<'vtab> for SeriesTab {
|
||||||
type Aux = ();
|
type Aux = ();
|
||||||
type Cursor = SeriesTabCursor;
|
type Cursor = SeriesTabCursor<'vtab>;
|
||||||
|
|
||||||
fn connect(
|
fn connect(
|
||||||
_: &mut VTabConnection,
|
_: &mut VTabConnection,
|
||||||
@ -151,15 +152,14 @@ unsafe impl VTab for SeriesTab {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(&self) -> Result<SeriesTabCursor> {
|
fn open(&'vtab self) -> Result<SeriesTabCursor<'vtab>> {
|
||||||
Ok(SeriesTabCursor::new())
|
Ok(SeriesTabCursor::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cursor for the Series virtual table
|
/// A cursor for the Series virtual table
|
||||||
#[derive(Default)]
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct SeriesTabCursor {
|
struct SeriesTabCursor<'vtab> {
|
||||||
/// Base class. Must be first
|
/// Base class. Must be first
|
||||||
base: ffi::sqlite3_vtab_cursor,
|
base: ffi::sqlite3_vtab_cursor,
|
||||||
/// True to count down rather than up
|
/// True to count down rather than up
|
||||||
@ -174,14 +174,24 @@ struct SeriesTabCursor {
|
|||||||
max_value: i64,
|
max_value: i64,
|
||||||
/// Increment ("step")
|
/// Increment ("step")
|
||||||
step: i64,
|
step: i64,
|
||||||
|
phantom: PhantomData<&'vtab SeriesTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SeriesTabCursor {
|
impl SeriesTabCursor<'_> {
|
||||||
fn new() -> SeriesTabCursor {
|
fn new<'vtab>() -> SeriesTabCursor<'vtab> {
|
||||||
SeriesTabCursor::default()
|
SeriesTabCursor {
|
||||||
|
base: ffi::sqlite3_vtab_cursor::default(),
|
||||||
|
is_desc: false,
|
||||||
|
row_id: 0,
|
||||||
|
value: 0,
|
||||||
|
min_value: 0,
|
||||||
|
max_value: 0,
|
||||||
|
step: 0,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl VTabCursor for SeriesTabCursor {
|
unsafe impl VTabCursor for SeriesTabCursor<'_> {
|
||||||
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
fn filter(&mut self, idx_num: c_int, _idx_str: Option<&str>, args: &Values<'_>) -> Result<()> {
|
||||||
let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
|
let idx_num = QueryPlanFlags::from_bits_truncate(idx_num);
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -9,6 +9,7 @@ fn test_dummy_module() {
|
|||||||
VTabConnection, VTabCursor, Values,
|
VTabConnection, VTabCursor, Values,
|
||||||
};
|
};
|
||||||
use rusqlite::{version_number, Connection, Result};
|
use rusqlite::{version_number, Connection, Result};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
let module = eponymous_only_module::<DummyTab>();
|
let module = eponymous_only_module::<DummyTab>();
|
||||||
@ -19,9 +20,9 @@ fn test_dummy_module() {
|
|||||||
base: sqlite3_vtab,
|
base: sqlite3_vtab,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTab for DummyTab {
|
unsafe impl<'vtab> VTab<'vtab> for DummyTab {
|
||||||
type Aux = ();
|
type Aux = ();
|
||||||
type Cursor = DummyTabCursor;
|
type Cursor = DummyTabCursor<'vtab>;
|
||||||
|
|
||||||
fn connect(
|
fn connect(
|
||||||
_: &mut VTabConnection,
|
_: &mut VTabConnection,
|
||||||
@ -39,21 +40,22 @@ fn test_dummy_module() {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open(&self) -> Result<DummyTabCursor> {
|
fn open(&'vtab self) -> Result<DummyTabCursor<'vtab>> {
|
||||||
Ok(DummyTabCursor::default())
|
Ok(DummyTabCursor::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct DummyTabCursor {
|
struct DummyTabCursor<'vtab> {
|
||||||
/// Base class. Must be first
|
/// Base class. Must be first
|
||||||
base: sqlite3_vtab_cursor,
|
base: sqlite3_vtab_cursor,
|
||||||
/// The rowid
|
/// The rowid
|
||||||
row_id: i64,
|
row_id: i64,
|
||||||
|
phantom: PhantomData<&'vtab DummyTab>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VTabCursor for DummyTabCursor {
|
unsafe impl VTabCursor for DummyTabCursor<'_> {
|
||||||
fn filter(
|
fn filter(
|
||||||
&mut self,
|
&mut self,
|
||||||
_idx_num: c_int,
|
_idx_num: c_int,
|
||||||
|
Loading…
Reference in New Issue
Block a user