From c4b398f468aaf9736f38356e05ef3bad4927134c Mon Sep 17 00:00:00 2001 From: gwenn <45554+gwenn@users.noreply.github.com> Date: Sat, 3 Apr 2021 11:03:50 +0200 Subject: [PATCH] Doctest column name reference (#918) * Doctest column name reference * Document rusqlite assumption on column name reference And move doctest as a test. * Document when columns metadata should be extracted. * Rustfmt doc (wrap_comments) --- src/backup.rs | 38 +++++++++++++++------------ src/busy.rs | 19 +++++++------- src/cache.rs | 3 ++- src/collation.rs | 3 ++- src/column.rs | 59 ++++++++++++++++++++++++++++++++++++++++++ src/error.rs | 21 +++++++++------ src/functions.rs | 36 ++++++++++++++++---------- src/row.rs | 7 ++--- src/session.rs | 3 ++- src/statement.rs | 39 ++++++++++++++++------------ src/transaction.rs | 8 +++--- src/types/mod.rs | 12 +++++---- src/types/value.rs | 3 ++- src/types/value_ref.rs | 6 +++-- src/vtab/mod.rs | 11 ++++---- 15 files changed, 182 insertions(+), 86 deletions(-) diff --git a/src/backup.rs b/src/backup.rs index ba7a76b..b4b1807 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -3,9 +3,10 @@ //! To create a [`Backup`], you must have two distinct [`Connection`]s - one //! for the source (which can be used while the backup is running) and one for //! the destination (which cannot). A [`Backup`] handle exposes three methods: -//! [`step`](Backup::step) will attempt to back up a specified number of pages, [`progress`](Backup::progress) gets -//! the current progress of the backup as of the last call to [`step`](Backup::step), and -//! [`run_to_completion`](Backup::run_to_completion) will attempt to back up the entire source database, +//! [`step`](Backup::step) will attempt to back up a specified number of pages, +//! [`progress`](Backup::progress) gets the current progress of the backup as of +//! the last call to [`step`](Backup::step), and [`run_to_completion`](Backup::run_to_completion) +//! will attempt to back up the entire source database, //! allowing you to specify how many pages are backed up at a time and how long //! the thread should sleep between chunks of pages. //! @@ -130,7 +131,8 @@ impl Connection { } } -/// `feature = "backup"` Possible successful results of calling [`Backup::step`]. +/// `feature = "backup"` Possible successful results of calling +/// [`Backup::step`]. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[non_exhaustive] pub enum StepResult { @@ -152,9 +154,10 @@ pub enum StepResult { /// `feature = "backup"` Struct specifying the progress of a backup. The /// percentage completion can be calculated as `(pagecount - remaining) / -/// pagecount`. The progress of a backup is as of the last call to [`step`](Backup::step) - if -/// the source database is modified after a call to [`step`](Backup::step), the progress value -/// will become outdated and potentially incorrect. +/// pagecount`. The progress of a backup is as of the last call to +/// [`step`](Backup::step) - if the source database is modified after a call to +/// [`step`](Backup::step), the progress value will become outdated and +/// potentially incorrect. #[derive(Copy, Clone, Debug)] pub struct Progress { /// Number of pages in the source database that still need to be backed up. @@ -225,7 +228,8 @@ impl Backup<'_, '_> { }) } - /// Gets the progress of the backup as of the last call to [`step`](Backup::step). + /// Gets the progress of the backup as of the last call to + /// [`step`](Backup::step). #[inline] pub fn progress(&self) -> Progress { unsafe { @@ -240,7 +244,8 @@ impl Backup<'_, '_> { /// negative, will attempt to back up all remaining pages. This will hold a /// lock on the source database for the duration, so it is probably not /// what you want for databases that are currently active (see - /// [`run_to_completion`](Backup::run_to_completion) for a better alternative). + /// [`run_to_completion`](Backup::run_to_completion) for a better + /// alternative). /// /// # Failure /// @@ -262,12 +267,12 @@ impl Backup<'_, '_> { } } - /// Attempts to run the entire backup. Will call [`step(pages_per_step)`](Backup::step) as - /// many times as necessary, sleeping for `pause_between_pages` between - /// each call to give the source database time to process any pending - /// queries. This is a direct implementation of "Example 2: Online Backup - /// of a Running Database" from [SQLite's Online Backup API - /// documentation](https://www.sqlite.org/backup.html). + /// Attempts to run the entire backup. Will call + /// [`step(pages_per_step)`](Backup::step) as many times as necessary, + /// sleeping for `pause_between_pages` between each call to give the + /// source database time to process any pending queries. This is a + /// direct implementation of "Example 2: Online Backup of a Running + /// Database" from [SQLite's Online Backup API documentation](https://www.sqlite.org/backup.html). /// /// If `progress` is not `None`, it will be called after each step with the /// current progress of the backup. Note that is possible the progress may @@ -276,7 +281,8 @@ impl Backup<'_, '_> { /// /// # Failure /// - /// Will return `Err` if any of the calls to [`step`](Backup::step) return `Err`. + /// Will return `Err` if any of the calls to [`step`](Backup::step) return + /// `Err`. pub fn run_to_completion( &self, pages_per_step: c_int, diff --git a/src/busy.rs b/src/busy.rs index 591e12e..447610e 100644 --- a/src/busy.rs +++ b/src/busy.rs @@ -19,11 +19,11 @@ impl Connection { /// /// There can only be a single busy handler for a particular database /// connection at any given moment. If another busy handler was defined - /// (using [`busy_handler`](Connection::busy_handler)) prior to calling this routine, that other - /// busy handler is cleared. + /// (using [`busy_handler`](Connection::busy_handler)) prior to calling this + /// routine, that other busy handler is cleared. /// - /// Newly created connections currently have a default busy timeout of 5000ms, but this may be - /// subject to change. + /// Newly created connections currently have a default busy timeout of + /// 5000ms, but this may be subject to change. pub fn busy_timeout(&self, timeout: Duration) -> Result<()> { let ms: i32 = timeout .as_secs() @@ -48,12 +48,13 @@ impl Connection { /// /// There can only be a single busy handler defined for each database /// connection. Setting a new busy handler clears any previously set - /// handler. Note that calling [`busy_timeout()`](Connection::busy_timeout) or evaluating `PRAGMA - /// busy_timeout=N` will change the busy handler and thus - /// clear any previously set busy handler. + /// handler. Note that calling [`busy_timeout()`](Connection::busy_timeout) + /// or evaluating `PRAGMA busy_timeout=N` will change the busy handler + /// and thus clear any previously set busy handler. /// - /// Newly created connections default to a [`busy_timeout()`](Connection::busy_timeout) handler - /// with a timeout of 5000ms, although this is subject to change. + /// Newly created connections default to a + /// [`busy_timeout()`](Connection::busy_timeout) handler with a timeout + /// of 5000ms, although this is subject to change. pub fn busy_handler(&self, callback: Option bool>) -> Result<()> { unsafe extern "C" fn busy_handler_callback(p_arg: *mut c_void, count: c_int) -> c_int { let handler_fn: fn(i32) -> bool = mem::transmute(p_arg); diff --git a/src/cache.rs b/src/cache.rs index 0347174..89459ce 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -63,7 +63,8 @@ pub struct StatementCache(RefCell, RawStatement>>); /// Cacheable statement. /// /// Statement will return automatically to the cache by default. -/// If you want the statement to be discarded, call [`discard()`](CachedStatement::discard) on it. +/// If you want the statement to be discarded, call +/// [`discard()`](CachedStatement::discard) on it. pub struct CachedStatement<'conn> { stmt: Option>, cache: &'conn StatementCache, diff --git a/src/collation.rs b/src/collation.rs index eedefe8..100bb82 100644 --- a/src/collation.rs +++ b/src/collation.rs @@ -97,7 +97,8 @@ impl InnerConnection { ) }; let res = self.decode_result(r); - // The xDestroy callback is not called if the sqlite3_create_collation_v2() function fails. + // The xDestroy callback is not called if the sqlite3_create_collation_v2() + // function fails. if res.is_err() { drop(unsafe { Box::from_raw(boxed_f) }); } diff --git a/src/column.rs b/src/column.rs index cd96b99..b65a18b 100644 --- a/src/column.rs +++ b/src/column.rs @@ -25,6 +25,10 @@ impl Column<'_> { impl Statement<'_> { /// Get all the column names in the result set of the prepared statement. + /// + /// If associated DB schema can be altered concurrently, you should make + /// sure that current statement has already been stepped once before + /// calling this method. pub fn column_names(&self) -> Vec<&str> { let n = self.column_count(); let mut cols = Vec::with_capacity(n as usize); @@ -37,11 +41,34 @@ impl Statement<'_> { /// Return the number of columns in the result set returned by the prepared /// statement. + /// + /// If associated DB schema can be altered concurrently, you should make + /// sure that current statement has already been stepped once before + /// calling this method. #[inline] pub fn column_count(&self) -> usize { self.stmt.column_count() } + /// Check that column name reference lifetime is limited: + /// https://www.sqlite.org/c3ref/column_name.html + /// > The returned string pointer is valid... + /// + /// `column_name` reference can become invalid if `stmt` is reprepared + /// (because of schema change) when `query_row` is called. So we assert + /// that a compilation error happens if this reference is kept alive: + /// ```compile_fail + /// use rusqlite::{Connection, Result}; + /// fn main() -> Result<()> { + /// let db = Connection::open_in_memory()?; + /// let mut stmt = db.prepare("SELECT 1 as x")?; + /// let column_name = stmt.column_name(0)?; + /// let x = stmt.query_row([], |r| r.get::<_, i64>(0))?; // E0502 + /// assert_eq!(1, x); + /// assert_eq!("x", column_name); + /// Ok(()) + /// } + /// ``` #[inline] pub(super) fn column_name_unwrap(&self, col: usize) -> &str { // Just panic if the bounds are wrong for now, we never call this @@ -52,6 +79,10 @@ impl Statement<'_> { /// Returns the name assigned to a particular column in the result set /// returned by the prepared statement. /// + /// If associated DB schema can be altered concurrently, you should make + /// sure that current statement has already been stepped once before + /// calling this method. + /// /// ## Failure /// /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid @@ -73,6 +104,10 @@ impl Statement<'_> { /// If there is no AS clause then the name of the column is unspecified and /// may change from one release of SQLite to the next. /// + /// If associated DB schema can be altered concurrently, you should make + /// sure that current statement has already been stepped once before + /// calling this method. + /// /// # Failure /// /// Will return an `Error::InvalidColumnName` when there is no column with @@ -92,6 +127,10 @@ impl Statement<'_> { } /// Returns a slice describing the columns of the result of the query. + /// + /// If associated DB schema can be altered concurrently, you should make + /// sure that current statement has already been stepped once before + /// calling this method. #[cfg(feature = "column_decltype")] pub fn columns(&self) -> Vec { let n = self.column_count(); @@ -234,4 +273,24 @@ mod test { } Ok(()) } + + /// `column_name` reference should stay valid until `stmt` is reprepared (or + /// reset) even if DB schema is altered (SQLite documentation is + /// ambiguous here because it says reference "is valid until (...) the next + /// call to sqlite3_column_name() or sqlite3_column_name16() on the same + /// column.". We assume that reference is valid if only `sqlite3_column_name()` is used): + #[test] + #[cfg(feature = "modern_sqlite")] + fn test_column_name_reference() -> Result<()> { + let db = Connection::open_in_memory()?; + db.execute_batch("CREATE TABLE y (x);")?; + let stmt = db.prepare("SELECT x FROM y;")?; + let column_name = stmt.column_name(0)?; + assert_eq!("x", column_name); + db.execute_batch("ALTER TABLE y RENAME COLUMN x TO z;")?; + // column name is not refreshed until statement is re-prepared + let same_column_name = stmt.column_name(0)?; + assert_eq!(same_column_name, column_name); + Ok(()) + } } diff --git a/src/error.rs b/src/error.rs index 49778a8..a8d3f23 100644 --- a/src/error.rs +++ b/src/error.rs @@ -43,7 +43,8 @@ pub enum Error { /// Error converting a file path to a string. InvalidPath(PathBuf), - /// Error returned when an [`execute`](crate::Connection::execute) call returns rows. + /// Error returned when an [`execute`](crate::Connection::execute) call + /// returns rows. ExecuteReturnedResults, /// Error when a query that was expected to return at least one row (e.g., @@ -67,12 +68,13 @@ pub enum Error { /// any or insert many. StatementChangedRows(usize), - /// Error returned by [`functions::Context::get`](crate::functions::Context::get) when the function argument - /// cannot be converted to the requested type. + /// Error returned by + /// [`functions::Context::get`](crate::functions::Context::get) when the + /// function argument cannot be converted to the requested type. #[cfg(feature = "functions")] InvalidFunctionParameterType(usize, Type), - /// Error returned by [`vtab::Values::get`](crate::vtab::Values::get) when the filter argument cannot - /// be converted to the requested type. + /// Error returned by [`vtab::Values::get`](crate::vtab::Values::get) when + /// the filter argument cannot be converted to the requested type. #[cfg(feature = "vtab")] InvalidFilterParameterType(usize, Type), @@ -82,7 +84,8 @@ pub enum Error { #[allow(dead_code)] UserFunctionError(Box), - /// Error available for the implementors of the [`ToSql`](crate::types::ToSql) trait. + /// Error available for the implementors of the + /// [`ToSql`](crate::types::ToSql) trait. ToSqlConversionFailure(Box), /// Error when the SQL is not a `SELECT`, is not read-only. @@ -98,8 +101,10 @@ pub enum Error { #[cfg(feature = "functions")] UnwindingPanic, - /// An error returned when [`Context::get_aux`](crate::functions::Context::get_aux) attempts to retrieve data - /// of a different type than what had been stored using [`Context::set_aux`](crate::functions::Context::set_aux). + /// An error returned when + /// [`Context::get_aux`](crate::functions::Context::get_aux) attempts to + /// retrieve data of a different type than what had been stored using + /// [`Context::set_aux`](crate::functions::Context::set_aux). #[cfg(feature = "functions")] GetAuxWrongType, diff --git a/src/functions.rs b/src/functions.rs index 34245c5..efbc651 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -128,7 +128,8 @@ impl Context<'_> { /// /// # Failure /// - /// Will panic if `idx` is greater than or equal to [`self.len()`](Context::len). + /// Will panic if `idx` is greater than or equal to + /// [`self.len()`](Context::len). /// /// Will return Err if the underlying SQLite type cannot be converted to a /// `T`. @@ -158,7 +159,8 @@ impl Context<'_> { /// /// # Failure /// - /// Will panic if `idx` is greater than or equal to [`self.len()`](Context::len). + /// Will panic if `idx` is greater than or equal to + /// [`self.len()`](Context::len). #[inline] pub fn get_raw(&self, idx: usize) -> ValueRef<'_> { let arg = self.args[idx]; @@ -167,7 +169,8 @@ impl Context<'_> { /// Fetch or insert the auxilliary data associated with a particular /// parameter. This is intended to be an easier-to-use way of fetching it - /// compared to calling [`get_aux`](Context::get_aux) and [`set_aux`](Context::set_aux) separately. + /// compared to calling [`get_aux`](Context::get_aux) and + /// [`set_aux`](Context::set_aux) separately. /// /// See `https://www.sqlite.org/c3ref/get_auxdata.html` for a discussion of /// this feature, or the unit tests of this module for an example. @@ -208,9 +211,9 @@ impl Context<'_> { } /// Gets the auxilliary data that was associated with a given parameter via - /// [`set_aux`](Context::set_aux). Returns `Ok(None)` if no data has been associated, and - /// Ok(Some(v)) if it has. Returns an error if the requested type does not - /// match. + /// [`set_aux`](Context::set_aux). Returns `Ok(None)` if no data has been + /// associated, and Ok(Some(v)) if it has. Returns an error if the + /// requested type does not match. pub fn get_aux(&self, arg: c_int) -> Result>> { let p = unsafe { ffi::sqlite3_get_auxdata(self.ctx, arg) as *const AuxInner }; if p.is_null() { @@ -268,8 +271,9 @@ where T: ToSql, { /// Initializes the aggregation context. Will be called prior to the first - /// call to [`step()`](Aggregate::step) to set up the context for an invocation of the - /// function. (Note: `init()` will not be called if there are no rows.) + /// call to [`step()`](Aggregate::step) to set up the context for an + /// invocation of the function. (Note: `init()` will not be called if + /// there are no rows.) fn init(&self, _: &mut Context<'_>) -> Result; /// "step" function called once for each row in an aggregate group. May be @@ -277,10 +281,12 @@ where fn step(&self, _: &mut Context<'_>, _: &mut A) -> Result<()>; /// Computes and returns the final result. Will be called exactly once for - /// each invocation of the function. If [`step()`](Aggregate::step) was called at least - /// once, will be given `Some(A)` (the same `A` as was created by - /// [`init`](Aggregate::init) and given to [`step`](Aggregate::step)); if [`step()`](Aggregate::step) was not called (because - /// the function is running against 0 rows), will be given `None`. + /// each invocation of the function. If [`step()`](Aggregate::step) was + /// called at least once, will be given `Some(A)` (the same `A` as was + /// created by [`init`](Aggregate::init) and given to + /// [`step`](Aggregate::step)); if [`step()`](Aggregate::step) was not + /// called (because the function is running against 0 rows), will be + /// given `None`. /// /// The passed context will have no arguments. fn finalize(&self, _: &mut Context<'_>, _: Option) -> Result; @@ -344,7 +350,8 @@ impl Connection { /// given the same input, `deterministic` should be `true`. /// /// The function will remain available until the connection is closed or - /// until it is explicitly removed via [`remove_function`](Connection::remove_function). + /// until it is explicitly removed via + /// [`remove_function`](Connection::remove_function). /// /// # Example /// @@ -440,7 +447,8 @@ impl Connection { /// database connection. /// /// `fn_name` and `n_arg` should match the name and number of arguments - /// given to [`create_scalar_function`](Connection::create_scalar_function) or [`create_aggregate_function`](Connection::create_aggregate_function). + /// given to [`create_scalar_function`](Connection::create_scalar_function) + /// or [`create_aggregate_function`](Connection::create_aggregate_function). /// /// # Failure /// diff --git a/src/row.rs b/src/row.rs index e8e086a..ef51778 100644 --- a/src/row.rs +++ b/src/row.rs @@ -29,7 +29,8 @@ impl<'stmt> Rows<'stmt> { /// This interface is not compatible with Rust's `Iterator` trait, because /// the lifetime of the returned row is tied to the lifetime of `self`. /// This is a fallible "streaming iterator". For a more natural interface, - /// consider using [`query_map`](crate::Statement::query_map) or [`query_and_then`](crate::Statement::query_and_then) instead, which + /// consider using [`query_map`](crate::Statement::query_map) or + /// [`query_and_then`](crate::Statement::query_and_then) instead, which /// return types that implement `Iterator`. #[allow(clippy::should_implement_trait)] // cannot implement Iterator #[inline] @@ -331,8 +332,8 @@ impl<'stmt> Row<'stmt> { /// /// ## Failure /// - /// Panics if calling [`row.get_ref(idx)`](Row::get_ref) would return an error, - /// including: + /// Panics if calling [`row.get_ref(idx)`](Row::get_ref) would return an + /// error, including: /// /// * If `idx` is outside the range of columns in the returned query. /// * If `idx` is not a valid column name for this row. diff --git a/src/session.rs b/src/session.rs index 4f37a7a..4e4c354 100644 --- a/src/session.rs +++ b/src/session.rs @@ -411,7 +411,8 @@ impl Drop for ChangesetIter<'_> { } /// `feature = "session"` An item passed to a conflict-handler by -/// [`Connection::apply`](crate::Connection::apply), or an item generated by [`ChangesetIter::next`](ChangesetIter::next). +/// [`Connection::apply`](crate::Connection::apply), or an item generated by +/// [`ChangesetIter::next`](ChangesetIter::next). // TODO enum ? Delete, Insert, Update, ... pub struct ChangesetItem { it: *mut ffi::sqlite3_changeset_iter, diff --git a/src/statement.rs b/src/statement.rs index e7171e7..b8fc3ee 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -114,11 +114,11 @@ impl Statement<'_> { /// /// # Note /// - /// This function is a convenience wrapper around [`execute()`](Statement::execute) intended for - /// queries that insert a single item. It is possible to misuse this - /// function in a way that it cannot detect, such as by calling it on a - /// statement which _updates_ a single - /// item rather than inserting one. Please don't do that. + /// This function is a convenience wrapper around + /// [`execute()`](Statement::execute) intended for queries that insert a + /// single item. It is possible to misuse this function in a way that it + /// cannot detect, such as by calling it on a statement which _updates_ + /// a single item rather than inserting one. Please don't do that. /// /// # Failure /// @@ -136,8 +136,9 @@ impl Statement<'_> { /// rows. /// /// Due to lifetime restricts, the rows handle returned by `query` does not - /// implement the `Iterator` trait. Consider using [`query_map`](Statement::query_map) or - /// [`query_and_then`](Statement::query_and_then) instead, which do. + /// implement the `Iterator` trait. Consider using + /// [`query_map`](Statement::query_map) or [`query_and_then`](Statement::query_and_then) + /// instead, which do. /// /// ## Example /// @@ -396,8 +397,9 @@ impl Statement<'_> { /// iterator over the result of calling the mapping function over the /// query's rows. /// - /// Note: This function is deprecated in favor of [`Statement::query_and_then`], - /// which can now take named parameters directly. + /// Note: This function is deprecated in favor of + /// [`Statement::query_and_then`], which can now take named parameters + /// directly. /// /// If any parameters that were in the prepared statement are not included /// in `params`, they will continue to use the most-recently bound value @@ -436,9 +438,10 @@ impl Statement<'_> { /// ignored. /// /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the - /// query truly is optional, you can call [`.optional()`](crate::OptionalExtension::optional) on the result of - /// this to get a `Result>` (requires that the trait `rusqlite::OptionalExtension` - /// is imported). + /// query truly is optional, you can call + /// [`.optional()`](crate::OptionalExtension::optional) on the result of + /// this to get a `Result>` (requires that the trait + /// `rusqlite::OptionalExtension` is imported). /// /// # Failure /// @@ -456,16 +459,18 @@ impl Statement<'_> { /// Convenience method to execute a query with named parameter(s) that is /// expected to return a single row. /// - /// Note: This function is deprecated in favor of [`Statement::query_and_then`], - /// which can now take named parameters directly. + /// Note: This function is deprecated in favor of + /// [`Statement::query_and_then`], which can now take named parameters + /// directly. /// /// If the query returns more than one row, all rows except the first are /// ignored. /// /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the - /// query truly is optional, you can call [`.optional()`](crate::OptionalExtension::optional) on the result of - /// this to get a `Result>` (requires that the trait `rusqlite::OptionalExtension` - /// is imported). + /// query truly is optional, you can call + /// [`.optional()`](crate::OptionalExtension::optional) on the result of + /// this to get a `Result>` (requires that the trait + /// `rusqlite::OptionalExtension` is imported). /// /// # Failure /// diff --git a/src/transaction.rs b/src/transaction.rs index 2192ce7..a1b287d 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -377,8 +377,9 @@ impl Connection { /// Begin a new transaction with the default behavior (DEFERRED). /// /// The transaction defaults to rolling back when it is dropped. If you - /// want the transaction to commit, you must call [`commit`](Transaction::commit) or - /// [`set_drop_behavior(DropBehavior::Commit)`](Transaction::set_drop_behavior). + /// want the transaction to commit, you must call + /// [`commit`](Transaction::commit) or [`set_drop_behavior(DropBehavior: + /// :Commit)`](Transaction::set_drop_behavior). /// /// ## Example /// @@ -458,7 +459,8 @@ impl Connection { /// /// The savepoint defaults to rolling back when it is dropped. If you want /// the savepoint to commit, you must call [`commit`](Savepoint::commit) or - /// [`set_drop_behavior(DropBehavior::Commit)`](Savepoint::set_drop_behavior). + /// [`set_drop_behavior(DropBehavior::Commit)`](Savepoint:: + /// set_drop_behavior). /// /// ## Example /// diff --git a/src/types/mod.rs b/src/types/mod.rs index 48d93ba..706be0c 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -15,9 +15,11 @@ //! [`FromSql`] has different behaviour depending on the SQL and Rust types, and //! the value. //! -//! * `INTEGER` to integer: returns an [`Error::IntegralValueOutOfRange`](crate::Error::IntegralValueOutOfRange) error if -//! the value does not fit in the Rust type. -//! * `REAL` to integer: always returns an [`Error::InvalidColumnType`](crate::Error::InvalidColumnType) error. +//! * `INTEGER` to integer: returns an +//! [`Error::IntegralValueOutOfRange`](crate::Error::IntegralValueOutOfRange) +//! error if the value does not fit in the Rust type. +//! * `REAL` to integer: always returns an +//! [`Error::InvalidColumnType`](crate::Error::InvalidColumnType) error. //! * `INTEGER` to float: casts using `as` operator. Never fails. //! * `REAL` to float: casts using `as` operator. Never fails. //! @@ -62,8 +64,8 @@ impl ToSql for DateTimeSql { "## )] //! [`ToSql`] and [`FromSql`] are also implemented for `Option` where `T` -//! implements [`ToSql`] or [`FromSql`] for the cases where you want to know if a -//! value was NULL (which gets translated to `None`). +//! implements [`ToSql`] or [`FromSql`] for the cases where you want to know if +//! a value was NULL (which gets translated to `None`). pub use self::from_sql::{FromSql, FromSqlError, FromSqlResult}; pub use self::to_sql::{ToSql, ToSqlOutput}; diff --git a/src/types/value.rs b/src/types/value.rs index bccbef6..944655c 100644 --- a/src/types/value.rs +++ b/src/types/value.rs @@ -3,7 +3,8 @@ use super::{Null, Type}; /// Owning [dynamic type value](http://sqlite.org/datatype3.html). Value's type is typically /// dictated by SQLite (not by the caller). /// -/// See [`ValueRef`](crate::types::ValueRef) for a non-owning dynamic type value. +/// See [`ValueRef`](crate::types::ValueRef) for a non-owning dynamic type +/// value. #[derive(Clone, Debug, PartialEq)] pub enum Value { /// The value is a `NULL` value. diff --git a/src/types/value_ref.rs b/src/types/value_ref.rs index b95521b..446ad08 100644 --- a/src/types/value_ref.rs +++ b/src/types/value_ref.rs @@ -35,7 +35,8 @@ impl ValueRef<'_> { impl<'a> ValueRef<'a> { /// If `self` is case `Integer`, returns the integral value. Otherwise, - /// returns [`Err(Error::InvalidColumnType)`](crate::Error::InvalidColumnType). + /// returns [`Err(Error::InvalidColumnType)`](crate::Error:: + /// InvalidColumnType). #[inline] pub fn as_i64(&self) -> FromSqlResult { match *self { @@ -45,7 +46,8 @@ impl<'a> ValueRef<'a> { } /// If `self` is case `Real`, returns the floating point value. Otherwise, - /// returns [`Err(Error::InvalidColumnType)`](crate::Error::InvalidColumnType). + /// returns [`Err(Error::InvalidColumnType)`](crate::Error:: + /// InvalidColumnType). #[inline] pub fn as_f64(&self) -> FromSqlResult { match *self { diff --git a/src/vtab/mod.rs b/src/vtab/mod.rs index eaf4b0d..72decf6 100644 --- a/src/vtab/mod.rs +++ b/src/vtab/mod.rs @@ -2,8 +2,8 @@ //! //! 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. +//! 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. @@ -430,7 +430,8 @@ impl IndexConstraint<'_> { pub struct IndexConstraintUsage<'a>(&'a mut ffi::sqlite3_index_constraint_usage); impl IndexConstraintUsage<'_> { - /// if `argv_index` > 0, constraint is part of argv to [`VTabCursor::filter`] + /// if `argv_index` > 0, constraint is part of argv to + /// [`VTabCursor::filter`] #[inline] pub fn set_argv_index(&mut self, argv_index: c_int) { self.0.argvIndex = argv_index; @@ -496,8 +497,8 @@ pub unsafe trait VTabCursor: Sized { /// 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<()>; - /// Advance cursor to the next row of a result set initiated by [`filter`](VTabCursor::filter). - /// (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method)) + /// Advance cursor to the next row of a result set initiated by + /// [`filter`](VTabCursor::filter). (See [SQLite doc](https://sqlite.org/vtab.html#the_xnext_method)) fn next(&mut self) -> Result<()>; /// Must return `false` if the cursor currently points to a valid row of /// data, or `true` otherwise.