mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 22:08:55 +08:00 
			
		
		
		
	Document which features are required, and add vtab usage examples (#669)
This commit is contained in:
		| @@ -1,6 +1,30 @@ | ||||
| //! Array Virtual Table. | ||||
| //! `feature = "array"` Array Virtual Table: https://www.sqlite.org/carray.html | ||||
| //! | ||||
| //! Note: `rarray`, not `carray` is the name of the table valued function we | ||||
| //! define. | ||||
| //! | ||||
| //! Port of [carray](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/carray.c) C extension. | ||||
| //! | ||||
| //! # Example | ||||
| //! | ||||
| //! ```rust,no_run | ||||
| //! # use rusqlite::{types::Value, Connection, Result, params}; | ||||
| //! # use std::rc::Rc; | ||||
| //! fn example(db: &Connection) -> Result<()> { | ||||
| //!     // Note: This should be done once (usually when opening the DB). | ||||
| //!     rusqlite::vtab::array::load_module(&db)?; | ||||
| //!     let v = [1i64, 2, 3, 4]; | ||||
| //!     // Note: A `Rc<Vec<Value>>` must be used as the parameter. | ||||
| //!     let values = Rc::new(v.iter().copied().map(Value::from).collect::<Vec<Value>>()); | ||||
| //!     let mut stmt = db.prepare("SELECT value from rarray(?);")?; | ||||
| //!     let rows = stmt.query_map(params![values], |row| row.get::<_, i64>(0))?; | ||||
| //!     for value in rows { | ||||
| //!         println!("{}", value?); | ||||
| //!     } | ||||
| //!     Ok(()) | ||||
| //! } | ||||
| //! ``` | ||||
|  | ||||
| use std::default::Default; | ||||
| use std::os::raw::{c_char, c_int, c_void}; | ||||
| use std::rc::Rc; | ||||
| @@ -29,7 +53,7 @@ impl ToSql for Array { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Register the "rarray" module. | ||||
| /// `feature = "array"` Register the "rarray" module. | ||||
| pub fn load_module(conn: &Connection) -> Result<()> { | ||||
|     let aux: Option<()> = None; | ||||
|     conn.create_module("rarray", &ARRAY_MODULE, aux) | ||||
|   | ||||
| @@ -1,6 +1,25 @@ | ||||
| //! CSV Virtual Table. | ||||
| //! `feature = "csvtab"` CSV Virtual Table: https://www.sqlite.org/csv.html | ||||
| //! | ||||
| //! Port of [csv](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/csv.c) C extension. | ||||
| //! | ||||
| //! # Example | ||||
| //! | ||||
| //! ```rust,no_run | ||||
| //! # use rusqlite::{Connection, Result}; | ||||
| //! fn example() -> Result<()> { | ||||
| //!     // Note: This should be done once (usually when opening the DB). | ||||
| //!     let db = Connection::open_in_memory()?; | ||||
| //!     rusqlite::vtab::csvtab::load_module(&db)?; | ||||
| //!     // Assum3e my_csv.csv | ||||
| //!     let schema = " | ||||
| //!         CREATE VIRTUAL TABLE my_csv_data | ||||
| //!         USING csv(filename = 'my_csv.csv') | ||||
| //!     "; | ||||
| //!     db.execute_batch(schema)?; | ||||
| //!     // Now the `my_csv_data` (virtual) table can be queried as normal... | ||||
| //!     Ok(()) | ||||
| //! } | ||||
| //! ``` | ||||
| use std::fs::File; | ||||
| use std::os::raw::c_int; | ||||
| use std::path::Path; | ||||
| @@ -15,7 +34,7 @@ use crate::vtab::{ | ||||
| }; | ||||
| use crate::{Connection, Error, Result}; | ||||
|  | ||||
| /// Register the "csv" module. | ||||
| /// `feature = "csvtab"` Register the "csv" module. | ||||
| /// ```sql | ||||
| /// CREATE VIRTUAL TABLE vtab USING csv( | ||||
| ///   filename=FILENAME -- Name of file containing CSV content | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| //! Create virtual tables. | ||||
| //! `feature = "vtab"` Create virtual tables. | ||||
| //! | ||||
| //! Follow these steps to create your own virtual table: | ||||
| //! 1. Write implemenation of `VTab` and `VTabCursor` traits. | ||||
| @@ -57,7 +57,7 @@ use crate::{str_to_cstring, Connection, Error, InnerConnection, Result}; | ||||
| // ffi::sqlite3_vtab => VTab | ||||
| // ffi::sqlite3_vtab_cursor => VTabCursor | ||||
|  | ||||
| /// Virtual table module | ||||
| /// `feature = "vtab"` Virtual table module | ||||
| /// | ||||
| /// (See [SQLite doc](https://sqlite.org/c3ref/module.html)) | ||||
| #[repr(C)] | ||||
| @@ -77,7 +77,7 @@ fn zeroed_module() -> ffi::sqlite3_module { | ||||
|     unsafe { std::mem::MaybeUninit::zeroed().assume_init() } | ||||
| } | ||||
|  | ||||
| /// 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). | ||||
| pub fn read_only_module<T: CreateVTab>(version: c_int) -> Module<T> { | ||||
| @@ -115,7 +115,7 @@ pub fn read_only_module<T: CreateVTab>(version: c_int) -> Module<T> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// 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). | ||||
| pub fn eponymous_only_module<T: VTab>(version: c_int) -> Module<T> { | ||||
| @@ -154,6 +154,7 @@ pub fn eponymous_only_module<T: VTab>(version: c_int) -> Module<T> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// `feature = "vtab"` | ||||
| pub struct VTabConnection(*mut ffi::sqlite3); | ||||
|  | ||||
| impl VTabConnection { | ||||
| @@ -179,7 +180,7 @@ impl VTabConnection { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Virtual table instance trait. | ||||
| /// `feature = "vtab"` Virtual table instance trait. | ||||
| /// | ||||
| /// Implementations must be like: | ||||
| /// ```rust,ignore | ||||
| @@ -214,7 +215,7 @@ pub trait VTab: Sized { | ||||
|     fn open(&self) -> Result<Self::Cursor>; | ||||
| } | ||||
|  | ||||
| /// Non-eponymous virtual table instance trait. | ||||
| /// `feature = "vtab"` Non-eponymous virtual table instance trait. | ||||
| /// | ||||
| /// (See [SQLite doc](https://sqlite.org/c3ref/vtab.html)) | ||||
| pub trait CreateVTab: VTab { | ||||
| @@ -243,7 +244,7 @@ pub trait CreateVTab: VTab { | ||||
|     } | ||||
| } | ||||
|  | ||||
| ///Index constraint operator. | ||||
| /// `feature = "vtab"` Index constraint operator. | ||||
| #[derive(Debug, PartialEq)] | ||||
| #[allow(non_snake_case, non_camel_case_types)] | ||||
| pub enum IndexConstraintOp { | ||||
| @@ -286,8 +287,8 @@ impl From<u8> for IndexConstraintOp { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Pass information into and receive the reply from the `VTab.best_index` | ||||
| /// method. | ||||
| /// `feature = "vtab"` 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); | ||||
| @@ -358,6 +359,7 @@ impl IndexInfo { | ||||
|     // TODO sqlite3_vtab_collation (http://sqlite.org/c3ref/vtab_collation.html) | ||||
| } | ||||
|  | ||||
| /// `feature = "vtab"` | ||||
| pub struct IndexConstraintIter<'a> { | ||||
|     iter: slice::Iter<'a, ffi::sqlite3_index_constraint>, | ||||
| } | ||||
| @@ -374,7 +376,7 @@ impl<'a> Iterator for IndexConstraintIter<'a> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// WHERE clause constraint | ||||
| /// `feature = "vtab"` WHERE clause constraint. | ||||
| pub struct IndexConstraint<'a>(&'a ffi::sqlite3_index_constraint); | ||||
|  | ||||
| impl IndexConstraint<'_> { | ||||
| @@ -394,7 +396,7 @@ impl IndexConstraint<'_> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Information about what parameters to pass to `VTabCursor.filter`. | ||||
| /// `feature = "vtab"` Information about what parameters to pass to `VTabCursor.filter`. | ||||
| pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage); | ||||
|  | ||||
| impl IndexConstraintUsage<'_> { | ||||
| @@ -409,6 +411,7 @@ impl IndexConstraintUsage<'_> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// `feature = "vtab"` | ||||
| pub struct OrderByIter<'a> { | ||||
|     iter: slice::Iter<'a, ffi::sqlite3_index_info_sqlite3_index_orderby>, | ||||
| } | ||||
| @@ -425,7 +428,7 @@ impl<'a> Iterator for OrderByIter<'a> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// A column of the ORDER BY clause. | ||||
| /// `feature = "vtab"` A column of the ORDER BY clause. | ||||
| pub struct OrderBy<'a>(&'a ffi::sqlite3_index_info_sqlite3_index_orderby); | ||||
|  | ||||
| impl OrderBy<'_> { | ||||
| @@ -440,7 +443,7 @@ impl OrderBy<'_> { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Virtual table cursor trait. | ||||
| /// `feature = "vtab"` Virtual table cursor trait. | ||||
| /// | ||||
| /// Implementations must be like: | ||||
| /// ```rust,ignore | ||||
| @@ -474,7 +477,7 @@ pub trait VTabCursor: Sized { | ||||
|     fn rowid(&self) -> Result<i64>; | ||||
| } | ||||
|  | ||||
| /// Context is used by `VTabCursor.column` to specify the cell value. | ||||
| /// `feature = "vtab"` Context is used by `VTabCursor.column` to specify the cell value. | ||||
| pub struct Context(*mut ffi::sqlite3_context); | ||||
|  | ||||
| impl Context { | ||||
| @@ -487,8 +490,8 @@ impl Context { | ||||
|     // TODO sqlite3_vtab_nochange (http://sqlite.org/c3ref/vtab_nochange.html) | ||||
| } | ||||
|  | ||||
| /// Wrapper to `VTabCursor.filter` arguments, the values requested by | ||||
| /// `VTab.best_index`. | ||||
| /// `feature = "vtab"` Wrapper to `VTabCursor.filter` arguments, the values | ||||
| /// requested by `VTab.best_index`. | ||||
| pub struct Values<'a> { | ||||
|     args: &'a [*mut ffi::sqlite3_value], | ||||
| } | ||||
| @@ -576,7 +579,7 @@ impl<'a> Iterator for ValueIter<'a> { | ||||
| } | ||||
|  | ||||
| impl Connection { | ||||
|     /// Register a virtual table implementation. | ||||
|     /// `feature = "vtab"` 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>( | ||||
| @@ -624,7 +627,8 @@ impl InnerConnection { | ||||
|     } | ||||
| } | ||||
|  | ||||
| /// Escape double-quote (`"`) character occurences by doubling them (`""`). | ||||
| /// `feature = "vtab"` Escape double-quote (`"`) character occurences by | ||||
| /// doubling them (`""`). | ||||
| pub fn escape_double_quote(identifier: &str) -> Cow<'_, str> { | ||||
|     if identifier.contains('"') { | ||||
|         // escape quote by doubling them | ||||
| @@ -633,7 +637,7 @@ pub fn escape_double_quote(identifier: &str) -> Cow<'_, str> { | ||||
|         Borrowed(identifier) | ||||
|     } | ||||
| } | ||||
| /// Dequote string | ||||
| /// `feature = "vtab"` Dequote string | ||||
| pub fn dequote(s: &str) -> &str { | ||||
|     if s.len() < 2 { | ||||
|         return s; | ||||
| @@ -646,7 +650,7 @@ pub fn dequote(s: &str) -> &str { | ||||
|         _ => s, | ||||
|     } | ||||
| } | ||||
| /// The boolean can be one of: | ||||
| /// `feature = "vtab"` The boolean can be one of: | ||||
| /// ```text | ||||
| /// 1 yes true on | ||||
| /// 0 no false off | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| //! generate series virtual table. | ||||
| //! `feature = "series"` Generate series virtual table: https://www.sqlite.org/series.html | ||||
| //! | ||||
| //! Port of C [generate series "function"](http://www.sqlite.org/cgi/src/finfo?name=ext/misc/series.c). | ||||
| use std::default::Default; | ||||
| @@ -12,7 +12,7 @@ use crate::vtab::{ | ||||
| }; | ||||
| use crate::{Connection, Result}; | ||||
|  | ||||
| /// Register the "generate_series" module. | ||||
| /// `feature = "series"` Register the "generate_series" module. | ||||
| pub fn load_module(conn: &Connection) -> Result<()> { | ||||
|     let aux: Option<()> = None; | ||||
|     conn.create_module("generate_series", &SERIES_MODULE, aux) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user