mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 00:39:20 +08:00
Updatable eponymous virtual table
This commit is contained in:
parent
3787f432a4
commit
f04bec2fd5
@ -31,7 +31,7 @@ use crate::ffi;
|
|||||||
use crate::types::Null;
|
use crate::types::Null;
|
||||||
use crate::vtab::{
|
use crate::vtab::{
|
||||||
dequote, escape_double_quote, parse_boolean, read_only_module, Context, CreateVTab, IndexInfo,
|
dequote, escape_double_quote, parse_boolean, read_only_module, Context, CreateVTab, IndexInfo,
|
||||||
VTab, VTabConfig, VTabConnection, VTabCursor, Values,
|
VTab, VTabConfig, VTabConnection, VTabCursor, VTabKind, Values,
|
||||||
};
|
};
|
||||||
use crate::{Connection, Error, Result};
|
use crate::{Connection, Error, Result};
|
||||||
|
|
||||||
@ -264,7 +264,9 @@ unsafe impl<'vtab> VTab<'vtab> for CsvTab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CreateVTab<'_> for CsvTab {}
|
impl CreateVTab<'_> for CsvTab {
|
||||||
|
const KIND: VTabKind = VTabKind::Default;
|
||||||
|
}
|
||||||
|
|
||||||
/// A cursor for the CSV virtual table
|
/// A cursor for the CSV virtual table
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -57,6 +57,19 @@ use crate::{str_to_cstring, Connection, Error, InnerConnection, Result};
|
|||||||
// ffi::sqlite3_vtab => VTab
|
// ffi::sqlite3_vtab => VTab
|
||||||
// ffi::sqlite3_vtab_cursor => VTabCursor
|
// ffi::sqlite3_vtab_cursor => VTabCursor
|
||||||
|
|
||||||
|
/// Virtual table kind
|
||||||
|
pub enum VTabKind {
|
||||||
|
/// Non-eponymous
|
||||||
|
Default,
|
||||||
|
/// [`create`](CreateVTab::create) == [`connect`](VTab::connect)
|
||||||
|
Eponymous,
|
||||||
|
/// No [`create`](CreateVTab::create) / [`destroy`](CreateVTab::destroy) or
|
||||||
|
/// not used
|
||||||
|
///
|
||||||
|
/// SQLite >= 3.9.0
|
||||||
|
EponymousOnly,
|
||||||
|
}
|
||||||
|
|
||||||
/// Virtual table module
|
/// Virtual table module
|
||||||
///
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
||||||
@ -93,11 +106,19 @@ pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T>
|
|||||||
&Module {
|
&Module {
|
||||||
base: ffi::sqlite3_module {
|
base: ffi::sqlite3_module {
|
||||||
iVersion: 2,
|
iVersion: 2,
|
||||||
xCreate: Some(rust_create::<T>),
|
xCreate: match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => None,
|
||||||
|
VTabKind::Eponymous => Some(rust_connect::<T>),
|
||||||
|
_ => 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_destroy::<T>),
|
xDestroy: match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => None,
|
||||||
|
VTabKind::Eponymous => Some(rust_disconnect::<T>),
|
||||||
|
_ => 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>),
|
||||||
@ -133,11 +154,19 @@ pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab,
|
|||||||
base: ffi::sqlite3_module {
|
base: ffi::sqlite3_module {
|
||||||
// We don't use V3
|
// We don't use V3
|
||||||
iVersion: 2, // We don't use V2 or V3 features in read_only_module types
|
iVersion: 2, // We don't use V2 or V3 features in read_only_module types
|
||||||
xCreate: Some(rust_create::<T>),
|
xCreate: match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => None,
|
||||||
|
VTabKind::Eponymous => Some(rust_connect::<T>),
|
||||||
|
_ => 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_destroy::<T>),
|
xDestroy: match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => None,
|
||||||
|
VTabKind::Eponymous => Some(rust_disconnect::<T>),
|
||||||
|
_ => 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>),
|
||||||
@ -247,7 +276,7 @@ impl VTabConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Virtual table instance trait.
|
/// Eponymous-only virtual table instance trait.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
@ -288,10 +317,14 @@ pub unsafe trait VTab<'vtab>: Sized {
|
|||||||
fn open(&'vtab self) -> Result<Self::Cursor>;
|
fn open(&'vtab self) -> Result<Self::Cursor>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Non-eponymous virtual table instance trait.
|
/// Read-only 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>: VTab<'vtab> {
|
pub trait CreateVTab<'vtab>: VTab<'vtab> {
|
||||||
|
/// For [`EponymousOnly`](VTabKind::EponymousOnly),
|
||||||
|
/// [`create`](CreateVTab::create) and [`destroy`](CreateVTab::destroy) are
|
||||||
|
/// not called
|
||||||
|
const KIND: VTabKind;
|
||||||
/// 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
|
||||||
@ -323,12 +356,14 @@ pub trait CreateVTab<'vtab>: VTab<'vtab> {
|
|||||||
pub trait UpdateVTab<'vtab>: CreateVTab<'vtab> {
|
pub trait UpdateVTab<'vtab>: CreateVTab<'vtab> {
|
||||||
/// Delete rowid or PK
|
/// Delete rowid or PK
|
||||||
fn delete(&mut self, arg: ValueRef<'_>) -> Result<()>;
|
fn delete(&mut self, arg: ValueRef<'_>) -> Result<()>;
|
||||||
/// Insert: args[0] == NULL: old rowid or PK, args[1]: new rowid or PK,
|
/// Insert: `args[0] == NULL: old rowid or PK, args[1]: new rowid or PK,
|
||||||
/// args[2]: ... Return the new rowid.
|
/// args[2]: ...`
|
||||||
|
///
|
||||||
|
/// Return the new rowid.
|
||||||
// TODO Make the distinction between argv[1] == NULL and argv[1] != NULL ?
|
// TODO Make the distinction between argv[1] == NULL and argv[1] != NULL ?
|
||||||
fn insert(&mut self, args: &Values<'_>) -> Result<i64>;
|
fn insert(&mut self, args: &Values<'_>) -> Result<i64>;
|
||||||
/// Update: args[0] != NULL: old rowid or PK, args[1]: new row id or PK,
|
/// Update: `args[0] != NULL: old rowid or PK, args[1]: new row id or PK,
|
||||||
/// args[2]: ...
|
/// args[2]: ...`
|
||||||
fn update(&mut self, args: &Values<'_>) -> Result<()>;
|
fn update(&mut self, args: &Values<'_>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user