mirror of
https://github.com/isar/rusqlite.git
synced 2024-12-01 23:21:38 +08:00
Doc
This commit is contained in:
parent
45624dc60b
commit
fe64d51422
@ -1,4 +1,5 @@
|
|||||||
//! Array Virtual Table
|
//! Array Virtual Table.
|
||||||
|
//!
|
||||||
//! Port of [carray](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/carray.c) C extension.
|
//! Port of [carray](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/carray.c) C extension.
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::os::raw::{c_char, c_int, c_void};
|
use std::os::raw::{c_char, c_int, c_void};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! CSV Virtual Table
|
//! CSV Virtual Table.
|
||||||
|
//!
|
||||||
//! Port of [csv](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/csv.c) C extension.
|
//! Port of [csv](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/csv.c) C extension.
|
||||||
extern crate csv;
|
extern crate csv;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
//! Create virtual tables.
|
//! Create virtual tables.
|
||||||
//! (See http://sqlite.org/vtab.html)
|
//!
|
||||||
|
//! Follow these steps to create your own virtual table:
|
||||||
|
//! 1. Write implemenation of `VTab` and `VTabCursor` traits.
|
||||||
|
//! 2. Create an instance of the `Module` structure specialized for `VTab` impl. from step 1.
|
||||||
|
//! 3. Register your `Module` structure using `Connection.create_module`.
|
||||||
|
//! 4. Run a `CREATE VIRTUAL TABLE` command that specifies the new module in the `USING` clause.
|
||||||
|
//!
|
||||||
|
//! (See [SQLite doc](http://sqlite.org/vtab.html))
|
||||||
use std::borrow::Cow::{self, Borrowed, Owned};
|
use std::borrow::Cow::{self, Borrowed, Owned};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -48,6 +55,9 @@ use {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 module
|
||||||
|
///
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/c3ref/module.html))
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Module<T: VTab> {
|
pub struct Module<T: VTab> {
|
||||||
base: ffi::sqlite3_module,
|
base: ffi::sqlite3_module,
|
||||||
@ -57,6 +67,8 @@ pub struct Module<T: VTab> {
|
|||||||
unsafe impl<T: VTab> Sync for Module<T> {}
|
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).
|
||||||
pub fn simple_module<T: VTab>() -> Module<T> {
|
pub fn simple_module<T: VTab>() -> 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.
|
||||||
@ -92,6 +104,8 @@ 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).
|
||||||
pub fn eponymous_only_module<T: VTab>() -> Module<T> {
|
pub fn eponymous_only_module<T: VTab>() -> 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
|
||||||
@ -143,6 +157,18 @@ impl VTabConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Virtual table instance trait.
|
/// Virtual table instance trait.
|
||||||
|
///
|
||||||
|
/// Implementations must be like:
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// #[repr(C)]
|
||||||
|
/// struct MyTab {
|
||||||
|
/// /// Base class. Must be first
|
||||||
|
/// base: ffi::sqlite3_vtab,
|
||||||
|
/// /* Virtual table implementations will typically add additional fields */
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html))
|
||||||
pub trait VTab: Sized {
|
pub trait VTab: Sized {
|
||||||
type Aux;
|
type Aux;
|
||||||
type Cursor: VTabCursor;
|
type Cursor: VTabCursor;
|
||||||
@ -150,6 +176,7 @@ 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.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcreate_method))
|
||||||
fn create(
|
fn create(
|
||||||
db: &mut VTabConnection,
|
db: &mut VTabConnection,
|
||||||
aux: Option<&Self::Aux>,
|
aux: Option<&Self::Aux>,
|
||||||
@ -162,14 +189,17 @@ pub trait VTab: Sized {
|
|||||||
|
|
||||||
/// 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))
|
||||||
fn connect(
|
fn connect(
|
||||||
db: &mut VTabConnection,
|
db: &mut VTabConnection,
|
||||||
aux: Option<&Self::Aux>,
|
aux: Option<&Self::Aux>,
|
||||||
args: &[&[u8]],
|
args: &[&[u8]],
|
||||||
) -> Result<(String, Self)>;
|
) -> Result<(String, Self)>;
|
||||||
/// Determine the best way to access the virtual table.
|
/// Determine the best way to access the virtual table.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xbestindex_method))
|
||||||
fn best_index(&self, info: &mut IndexInfo) -> Result<()>;
|
fn best_index(&self, info: &mut IndexInfo) -> Result<()>;
|
||||||
/// 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))
|
||||||
fn open(&self) -> Result<Self::Cursor>;
|
fn open(&self) -> Result<Self::Cursor>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +216,13 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pass information into and receive the reply from the `VTab.best_index` method.
|
||||||
|
///
|
||||||
|
/// (See [SQLite doc](http://sqlite.org/c3ref/index_info.html))
|
||||||
pub struct IndexInfo(*mut ffi::sqlite3_index_info);
|
pub struct IndexInfo(*mut ffi::sqlite3_index_info);
|
||||||
|
|
||||||
impl IndexInfo {
|
impl IndexInfo {
|
||||||
|
/// Record WHERE clause constraints.
|
||||||
pub fn constraints(&self) -> IndexConstraintIter {
|
pub fn constraints(&self) -> IndexConstraintIter {
|
||||||
let constraints =
|
let constraints =
|
||||||
unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
|
unsafe { slice::from_raw_parts((*self.0).aConstraint, (*self.0).nConstraint as usize) };
|
||||||
@ -197,6 +231,7 @@ impl IndexInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about the ORDER BY clause.
|
||||||
pub fn order_bys(&self) -> OrderByIter {
|
pub fn order_bys(&self) -> OrderByIter {
|
||||||
let order_bys =
|
let order_bys =
|
||||||
unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
|
unsafe { slice::from_raw_parts((*self.0).aOrderBy, (*self.0).nOrderBy as usize) };
|
||||||
@ -210,7 +245,6 @@ impl IndexInfo {
|
|||||||
unsafe { (*self.0).nOrderBy as usize }
|
unsafe { (*self.0).nOrderBy as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if `argv_index` > 0, constraint is part of argv to xFilter
|
|
||||||
pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage {
|
pub fn constraint_usage(&mut self, constraint_idx: usize) -> IndexConstraintUsage {
|
||||||
let constraint_usages = unsafe {
|
let constraint_usages = unsafe {
|
||||||
slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
|
slice::from_raw_parts_mut((*self.0).aConstraintUsage, (*self.0).nConstraint as usize)
|
||||||
@ -262,6 +296,7 @@ impl<'a> Iterator for IndexConstraintIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// WHERE clause constraint
|
||||||
pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint);
|
pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint);
|
||||||
|
|
||||||
impl<'a> IndexConstraint<'a> {
|
impl<'a> IndexConstraint<'a> {
|
||||||
@ -279,10 +314,11 @@ impl<'a> IndexConstraint<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about what parameters to pass to `VTabCursor.filter`.
|
||||||
pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage);
|
pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage);
|
||||||
|
|
||||||
impl<'a> IndexConstraintUsage<'a> {
|
impl<'a> IndexConstraintUsage<'a> {
|
||||||
/// if `argv_index` > 0, constraint is part of argv to xFilter
|
/// if `argv_index` > 0, constraint is part of argv to `VTabCursor.filter`
|
||||||
pub fn set_argv_index(&mut self, argv_index: c_int) {
|
pub fn set_argv_index(&mut self, argv_index: c_int) {
|
||||||
self.0.argvIndex = argv_index;
|
self.0.argvIndex = argv_index;
|
||||||
}
|
}
|
||||||
@ -308,6 +344,7 @@ impl<'a> Iterator for OrderByIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A column of the ORDER BY clause.
|
||||||
pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby);
|
pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby);
|
||||||
|
|
||||||
impl<'a> OrderBy<'a> {
|
impl<'a> OrderBy<'a> {
|
||||||
@ -322,23 +359,41 @@ impl<'a> OrderBy<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Virtual table cursor trait.
|
/// Virtual table cursor trait.
|
||||||
|
///
|
||||||
|
/// Implementations must be like:
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// #[repr(C)]
|
||||||
|
/// struct MyTabCursor {
|
||||||
|
/// /// Base class. Must be first
|
||||||
|
/// base: ffi::sqlite3_vtab_cursor,
|
||||||
|
/// /* Virtual table implementations will typically add additional fields */
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/c3ref/vtab_cursor.html))
|
||||||
pub trait VTabCursor: Sized {
|
pub trait VTabCursor: Sized {
|
||||||
type Table: VTab;
|
type Table: VTab;
|
||||||
/// Begin a search of a virtual table.
|
/// Begin a search of a virtual table.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xfilter_method))
|
||||||
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<()>;
|
||||||
/// Advance cursor to the next row of a result set initiated by `filter`.
|
/// Advance cursor to the next row of a result set initiated by `filter`.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method))
|
||||||
fn next(&mut self) -> Result<()>;
|
fn next(&mut self) -> Result<()>;
|
||||||
/// Must return `false` if the cursor currently points to a valid row of data,
|
/// Must return `false` if the cursor currently points to a valid row of data,
|
||||||
/// or `true` otherwise.
|
/// or `true` otherwise.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xeof_method))
|
||||||
fn eof(&self) -> bool;
|
fn eof(&self) -> bool;
|
||||||
/// Find the value for the `i`-th column of the current row.
|
/// Find the value for the `i`-th column of the current row.
|
||||||
/// `i` is zero-based so the first column is numbered 0.
|
/// `i` is zero-based so the first column is numbered 0.
|
||||||
/// May return its result back to SQLite using one of the specified `ctx`.
|
/// May return its result back to SQLite using one of the specified `ctx`.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xcolumn_method))
|
||||||
fn column(&self, ctx: &mut Context, i: c_int) -> Result<()>;
|
fn column(&self, ctx: &mut Context, i: c_int) -> Result<()>;
|
||||||
/// Return the rowid of row that the cursor is currently pointing at.
|
/// Return the rowid of row that the cursor is currently pointing at.
|
||||||
|
/// (See [SQLite doc](https://sqlite.org/vtab.html#the_xrowid_method))
|
||||||
fn rowid(&self) -> Result<i64>;
|
fn rowid(&self) -> Result<i64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Context is used by `VTabCursor.column`` to specify the cell value.
|
||||||
pub struct Context(*mut ffi::sqlite3_context);
|
pub struct Context(*mut ffi::sqlite3_context);
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
@ -349,6 +404,7 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wrapper to `VTabCursor.filter` arguments, the values requested by `VTab.best_index`.
|
||||||
pub struct Values<'a> {
|
pub struct Values<'a> {
|
||||||
args: &'a [*mut ffi::sqlite3_value],
|
args: &'a [*mut ffi::sqlite3_value],
|
||||||
}
|
}
|
||||||
@ -426,15 +482,15 @@ impl<'a> Iterator for ValueIter<'a> {
|
|||||||
|
|
||||||
impl Connection {
|
impl Connection {
|
||||||
/// Register a virtual table implementation.
|
/// Register a virtual table implementation.
|
||||||
|
///
|
||||||
|
/// 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<T: VTab>(
|
||||||
&self,
|
&self,
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
module: &Module<T>,
|
module: &Module<T>,
|
||||||
aux: Option<T::Aux>,
|
aux: Option<T::Aux>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.db
|
self.db.borrow_mut().create_module(module_name, module, aux)
|
||||||
.borrow_mut()
|
|
||||||
.create_module(module_name, module, aux)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,7 +830,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Virtual table cursors can set an error message by assigning a string to `zErrMsg`.
|
/// Virtual table cursors can set an error message by assigning a string to `zErrMsg`.
|
||||||
pub unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int {
|
unsafe fn cursor_error<T>(cursor: *mut ffi::sqlite3_vtab_cursor, result: Result<T>) -> c_int {
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => ffi::SQLITE_OK,
|
Ok(_) => ffi::SQLITE_OK,
|
||||||
@ -834,7 +890,7 @@ unsafe fn result_error<T>(ctx: *mut ffi::sqlite3_context, result: Result<T>) ->
|
|||||||
|
|
||||||
// Space to hold this error message string must be obtained
|
// Space to hold this error message string must be obtained
|
||||||
// from an SQLite memory allocation function.
|
// from an SQLite memory allocation function.
|
||||||
pub fn mprintf(err_msg: &str) -> *mut c_char {
|
fn mprintf(err_msg: &str) -> *mut c_char {
|
||||||
let c_format = CString::new("%s").unwrap();
|
let c_format = CString::new("%s").unwrap();
|
||||||
let c_err = CString::new(err_msg).unwrap();
|
let c_err = CString::new(err_msg).unwrap();
|
||||||
unsafe { ffi::sqlite3_mprintf(c_format.as_ptr(), c_err.as_ptr()) }
|
unsafe { ffi::sqlite3_mprintf(c_format.as_ptr(), c_err.as_ptr()) }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
//! generate series virtual table.
|
//! generate series virtual table.
|
||||||
|
//!
|
||||||
//! Port of C [generate series "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c).
|
//! Port of C [generate series "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c).
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
Loading…
Reference in New Issue
Block a user