mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 00:39:20 +08:00
Introduce macro to avoid code duplication
This commit is contained in:
parent
f04bec2fd5
commit
762321c15e
151
src/vtab/mod.rs
151
src/vtab/mod.rs
@ -97,36 +97,26 @@ const ZERO_MODULE: ffi::sqlite3_module = unsafe {
|
|||||||
.module
|
.module
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Create an modifiable virtual table implementation.
|
macro_rules! module {
|
||||||
///
|
($lt:lifetime, $vt:ty, $ct:ty, $xc:expr, $xd:expr, $xu:expr) => {
|
||||||
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
|
|
||||||
#[must_use]
|
|
||||||
pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T> {
|
|
||||||
#[allow(clippy::needless_update)]
|
#[allow(clippy::needless_update)]
|
||||||
&Module {
|
&Module {
|
||||||
base: ffi::sqlite3_module {
|
base: ffi::sqlite3_module {
|
||||||
|
// We don't use V3
|
||||||
iVersion: 2,
|
iVersion: 2,
|
||||||
xCreate: match T::KIND {
|
xCreate: $xc,
|
||||||
VTabKind::EponymousOnly => None,
|
xConnect: Some(rust_connect::<$vt>),
|
||||||
VTabKind::Eponymous => Some(rust_connect::<T>),
|
xBestIndex: Some(rust_best_index::<$vt>),
|
||||||
_ => Some(rust_create::<T>),
|
xDisconnect: Some(rust_disconnect::<$vt>),
|
||||||
},
|
xDestroy: $xd,
|
||||||
xConnect: Some(rust_connect::<T>),
|
xOpen: Some(rust_open::<$vt>),
|
||||||
xBestIndex: Some(rust_best_index::<T>),
|
xClose: Some(rust_close::<$ct>),
|
||||||
xDisconnect: Some(rust_disconnect::<T>),
|
xFilter: Some(rust_filter::<$ct>),
|
||||||
xDestroy: match T::KIND {
|
xNext: Some(rust_next::<$ct>),
|
||||||
VTabKind::EponymousOnly => None,
|
xEof: Some(rust_eof::<$ct>),
|
||||||
VTabKind::Eponymous => Some(rust_disconnect::<T>),
|
xColumn: Some(rust_column::<$ct>),
|
||||||
_ => Some(rust_destroy::<T>),
|
xRowid: Some(rust_rowid::<$ct>), // FIXME optional
|
||||||
},
|
xUpdate: $xu,
|
||||||
xOpen: Some(rust_open::<T>),
|
|
||||||
xClose: Some(rust_close::<T::Cursor>),
|
|
||||||
xFilter: Some(rust_filter::<T::Cursor>),
|
|
||||||
xNext: Some(rust_next::<T::Cursor>),
|
|
||||||
xEof: Some(rust_eof::<T::Cursor>),
|
|
||||||
xColumn: Some(rust_column::<T::Cursor>),
|
|
||||||
xRowid: Some(rust_rowid::<T::Cursor>),
|
|
||||||
xUpdate: Some(rust_update::<T>),
|
|
||||||
xBegin: None,
|
xBegin: None,
|
||||||
xSync: None,
|
xSync: None,
|
||||||
xCommit: None,
|
xCommit: None,
|
||||||
@ -138,7 +128,26 @@ pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T>
|
|||||||
xRollbackTo: None,
|
xRollbackTo: None,
|
||||||
..ZERO_MODULE
|
..ZERO_MODULE
|
||||||
},
|
},
|
||||||
phantom: PhantomData::<&'vtab T>,
|
phantom: PhantomData::<&$lt $vt>,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create an modifiable virtual table implementation.
|
||||||
|
///
|
||||||
|
/// Step 2 of [Creating New Virtual Table Implementations](https://sqlite.org/vtab.html#creating_new_virtual_table_implementations).
|
||||||
|
#[must_use]
|
||||||
|
pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T> {
|
||||||
|
match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => {
|
||||||
|
module!('vtab, T, T::Cursor, None, None, Some(rust_update::<T>))
|
||||||
|
}
|
||||||
|
VTabKind::Eponymous => {
|
||||||
|
module!('vtab, T, T::Cursor, Some(rust_connect::<T>), Some(rust_disconnect::<T>), Some(rust_update::<T>))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
module!('vtab, T, T::Cursor, Some(rust_create::<T>), Some(rust_destroy::<T>), Some(rust_update::<T>))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,46 +156,18 @@ pub fn update_module<'vtab, T: UpdateVTab<'vtab>>() -> &'static Module<'vtab, T>
|
|||||||
/// 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).
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab, 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
|
match T::KIND {
|
||||||
|
VTabKind::EponymousOnly => eponymous_only_module(),
|
||||||
|
VTabKind::Eponymous => {
|
||||||
|
// A virtual table is eponymous if its xCreate method is the exact same function
|
||||||
|
// as the xConnect method
|
||||||
|
module!('vtab, T, T::Cursor, Some(rust_connect::<T>), Some(rust_disconnect::<T>), None)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// The xConnect and xCreate methods may 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.
|
||||||
#[allow(clippy::needless_update)]
|
module!('vtab, T, T::Cursor, Some(rust_create::<T>), Some(rust_destroy::<T>), None)
|
||||||
&Module {
|
}
|
||||||
base: ffi::sqlite3_module {
|
|
||||||
// We don't use V3
|
|
||||||
iVersion: 2, // We don't use V2 or V3 features in read_only_module types
|
|
||||||
xCreate: match T::KIND {
|
|
||||||
VTabKind::EponymousOnly => None,
|
|
||||||
VTabKind::Eponymous => Some(rust_connect::<T>),
|
|
||||||
_ => Some(rust_create::<T>),
|
|
||||||
},
|
|
||||||
xConnect: Some(rust_connect::<T>),
|
|
||||||
xBestIndex: Some(rust_best_index::<T>),
|
|
||||||
xDisconnect: Some(rust_disconnect::<T>),
|
|
||||||
xDestroy: match T::KIND {
|
|
||||||
VTabKind::EponymousOnly => None,
|
|
||||||
VTabKind::Eponymous => Some(rust_disconnect::<T>),
|
|
||||||
_ => Some(rust_destroy::<T>),
|
|
||||||
},
|
|
||||||
xOpen: Some(rust_open::<T>),
|
|
||||||
xClose: Some(rust_close::<T::Cursor>),
|
|
||||||
xFilter: Some(rust_filter::<T::Cursor>),
|
|
||||||
xNext: Some(rust_next::<T::Cursor>),
|
|
||||||
xEof: Some(rust_eof::<T::Cursor>),
|
|
||||||
xColumn: Some(rust_column::<T::Cursor>),
|
|
||||||
xRowid: Some(rust_rowid::<T::Cursor>),
|
|
||||||
xUpdate: None,
|
|
||||||
xBegin: None,
|
|
||||||
xSync: None,
|
|
||||||
xCommit: None,
|
|
||||||
xRollback: None,
|
|
||||||
xFindFunction: None,
|
|
||||||
xRename: None,
|
|
||||||
xSavepoint: None,
|
|
||||||
xRelease: None,
|
|
||||||
xRollbackTo: None,
|
|
||||||
..ZERO_MODULE
|
|
||||||
},
|
|
||||||
phantom: PhantomData::<&'vtab T>,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,40 +176,8 @@ pub fn read_only_module<'vtab, T: CreateVTab<'vtab>>() -> &'static Module<'vtab,
|
|||||||
/// 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).
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn eponymous_only_module<'vtab, T: VTab<'vtab>>() -> &'static Module<'vtab, 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
|
// For eponymous-only virtual tables, the xCreate method is NULL
|
||||||
// as the xConnect method For eponymous-only virtual tables, the xCreate
|
module!('vtab, T, T::Cursor, None, None, None)
|
||||||
// method is NULL
|
|
||||||
#[allow(clippy::needless_update)]
|
|
||||||
&Module {
|
|
||||||
base: ffi::sqlite3_module {
|
|
||||||
// We don't use V3
|
|
||||||
iVersion: 2,
|
|
||||||
xCreate: None,
|
|
||||||
xConnect: Some(rust_connect::<T>),
|
|
||||||
xBestIndex: Some(rust_best_index::<T>),
|
|
||||||
xDisconnect: Some(rust_disconnect::<T>),
|
|
||||||
xDestroy: None,
|
|
||||||
xOpen: Some(rust_open::<T>),
|
|
||||||
xClose: Some(rust_close::<T::Cursor>),
|
|
||||||
xFilter: Some(rust_filter::<T::Cursor>),
|
|
||||||
xNext: Some(rust_next::<T::Cursor>),
|
|
||||||
xEof: Some(rust_eof::<T::Cursor>),
|
|
||||||
xColumn: Some(rust_column::<T::Cursor>),
|
|
||||||
xRowid: Some(rust_rowid::<T::Cursor>),
|
|
||||||
xUpdate: None,
|
|
||||||
xBegin: None,
|
|
||||||
xSync: None,
|
|
||||||
xCommit: None,
|
|
||||||
xRollback: None,
|
|
||||||
xFindFunction: None,
|
|
||||||
xRename: None,
|
|
||||||
xSavepoint: None,
|
|
||||||
xRelease: None,
|
|
||||||
xRollbackTo: None,
|
|
||||||
..ZERO_MODULE
|
|
||||||
},
|
|
||||||
phantom: PhantomData::<&'vtab T>,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Virtual table configuration options
|
/// Virtual table configuration options
|
||||||
@ -350,7 +299,7 @@ pub trait CreateVTab<'vtab>: VTab<'vtab> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Non-read-only virtual table instance trait.
|
/// Writable virtual table instance trait.
|
||||||
///
|
///
|
||||||
/// (See [SQLite doc](https://sqlite.org/vtab.html#xupdate))
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#xupdate))
|
||||||
pub trait UpdateVTab<'vtab>: CreateVTab<'vtab> {
|
pub trait UpdateVTab<'vtab>: CreateVTab<'vtab> {
|
||||||
|
Loading…
Reference in New Issue
Block a user