diff --git a/src/backup.rs b/src/backup.rs index 2a4a8b0..16f6561 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -18,8 +18,11 @@ //! # use std::path::Path; //! # use std::time; //! -//! fn backup_db>(src: &Connection, dst: P, progress: fn(backup::Progress)) -//! -> Result<()> { +//! fn backup_db>( +//! src: &Connection, +//! dst: P, +//! progress: fn(backup::Progress), +//! ) -> Result<()> { //! let mut dst = try!(Connection::open(dst)); //! let backup = try!(backup::Backup::new(src, &mut dst)); //! backup.run_to_completion(5, time::Duration::from_millis(250), Some(progress)) @@ -136,7 +139,8 @@ pub enum StepResult { /// The backup is complete. Done, - /// The step was successful but there are still more pages that need to be backed up. + /// The step was successful but there are still more pages that need to be + /// backed up. More, /// The step failed because appropriate locks could not be aquired. This is diff --git a/src/blob.rs b/src/blob.rs index 76b10ee..c44211a 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -1,14 +1,15 @@ //! Incremental BLOB I/O. //! -//! Note that SQLite does not provide API-level access to change the size of a BLOB; that must -//! be performed through SQL statements. +//! Note that SQLite does not provide API-level access to change the size of a +//! BLOB; that must be performed through SQL statements. //! -//! `Blob` conforms to `std::io::Read`, `std::io::Write`, and `std::io::Seek`, so it plays -//! nicely with other types that build on these (such as `std::io::BufReader` and -//! `std::io::BufWriter`). However, you must be careful with the size of the blob. For example, -//! when using a `BufWriter`, the `BufWriter` will accept more data than the `Blob` will allow, -//! so make sure to call `flush` and check for errors. (See the unit tests in this module for -//! an example.) +//! `Blob` conforms to `std::io::Read`, `std::io::Write`, and `std::io::Seek`, +//! so it plays nicely with other types that build on these (such as +//! `std::io::BufReader` and `std::io::BufWriter`). However, you must be +//! careful with the size of the blob. For example, when using a `BufWriter`, +//! the `BufWriter` will accept more data than the `Blob` +//! will allow, so make sure to call `flush` and check for errors. (See the +//! unit tests in this module for an example.) //! //! ## Example //! @@ -16,17 +17,21 @@ //! extern crate libsqlite3_sys; //! extern crate rusqlite; //! -//! use rusqlite::{Connection, DatabaseName}; //! use rusqlite::blob::ZeroBlob; -//! use std::io::{Read, Write, Seek, SeekFrom}; +//! use rusqlite::{Connection, DatabaseName}; +//! use std::io::{Read, Seek, SeekFrom, Write}; //! //! fn main() { //! let db = Connection::open_in_memory().unwrap(); -//! db.execute_batch("CREATE TABLE test (content BLOB);").unwrap(); -//! db.execute("INSERT INTO test (content) VALUES (ZEROBLOB(10))", &[]).unwrap(); +//! db.execute_batch("CREATE TABLE test (content BLOB);") +//! .unwrap(); +//! db.execute("INSERT INTO test (content) VALUES (ZEROBLOB(10))", &[]) +//! .unwrap(); //! //! let rowid = db.last_insert_rowid(); -//! let mut blob = db.blob_open(DatabaseName::Main, "test", "content", rowid, false).unwrap(); +//! let mut blob = db +//! .blob_open(DatabaseName::Main, "test", "content", rowid, false) +//! .unwrap(); //! //! // Make sure to test that the number of bytes written matches what you expect; //! // if you try to write too much, the data will be truncated to the size of the BLOB. @@ -39,7 +44,8 @@ //! let bytes_read = blob.read(&mut buf[..]).unwrap(); //! assert_eq!(bytes_read, 10); // note we read 10 bytes because the blob has size 10 //! -//! db.execute("INSERT INTO test (content) VALUES (?)", &[&ZeroBlob(64)]).unwrap(); +//! db.execute("INSERT INTO test (content) VALUES (?)", &[&ZeroBlob(64)]) +//! .unwrap(); //! //! // given a new row ID, we can reopen the blob on that row //! let rowid = db.last_insert_rowid(); @@ -64,12 +70,14 @@ pub struct Blob<'conn> { } impl Connection { - /// Open a handle to the BLOB located in `row_id`, `column`, `table` in database `db`. + /// Open a handle to the BLOB located in `row_id`, `column`, `table` in + /// database `db`. /// /// # Failure /// - /// Will return `Err` if `db`/`table`/`column` cannot be converted to a C-compatible string - /// or if the underlying SQLite BLOB open call fails. + /// Will return `Err` if `db`/`table`/`column` cannot be converted to a + /// C-compatible string or if the underlying SQLite BLOB open call + /// fails. pub fn blob_open<'a>( &'a self, db: DatabaseName, @@ -124,8 +132,9 @@ impl<'conn> Blob<'conn> { /// Close a BLOB handle. /// - /// Calling `close` explicitly is not required (the BLOB will be closed when the - /// `Blob` is dropped), but it is available so you can get any errors that occur. + /// Calling `close` explicitly is not required (the BLOB will be closed + /// when the `Blob` is dropped), but it is available so you can get any + /// errors that occur. /// /// # Failure /// @@ -142,8 +151,8 @@ impl<'conn> Blob<'conn> { } impl<'conn> io::Read for Blob<'conn> { - /// Read data from a BLOB incrementally. Will return Ok(0) if the end of the blob - /// has been reached. + /// Read data from a BLOB incrementally. Will return Ok(0) if the end of + /// the blob has been reached. /// /// # Failure /// @@ -165,12 +174,13 @@ impl<'conn> io::Read for Blob<'conn> { } impl<'conn> io::Write for Blob<'conn> { - /// Write data into a BLOB incrementally. Will return `Ok(0)` if the end of the blob - /// has been reached; consider using `Write::write_all(buf)` if you want to get an - /// error if the entirety of the buffer cannot be written. + /// Write data into a BLOB incrementally. Will return `Ok(0)` if the end of + /// the blob has been reached; consider using `Write::write_all(buf)` + /// if you want to get an error if the entirety of the buffer cannot be + /// written. /// - /// This function may only modify the contents of the BLOB; it is not possible to increase - /// the size of a BLOB using this API. + /// This function may only modify the contents of the BLOB; it is not + /// possible to increase the size of a BLOB using this API. /// /// # Failure /// @@ -230,8 +240,8 @@ impl<'conn> Drop for Blob<'conn> { /// BLOB of length N that is filled with zeroes. /// -/// Zeroblobs are intended to serve as placeholders for BLOBs whose content is later written using -/// incremental BLOB I/O routines. +/// Zeroblobs are intended to serve as placeholders for BLOBs whose content is +/// later written using incremental BLOB I/O routines. /// /// A negative value for the zeroblob results in a zero-length BLOB. #[derive(Copy, Clone)] diff --git a/src/busy.rs b/src/busy.rs index f9bf6f3..6156caf 100644 --- a/src/busy.rs +++ b/src/busy.rs @@ -8,13 +8,17 @@ use ffi; use {Connection, InnerConnection, Result}; impl Connection { - /// Set a busy handler that sleeps for a specified amount of time when a table is locked. - /// The handler will sleep multiple times until at least "ms" milliseconds of sleeping have accumulated. + /// Set a busy handler that sleeps for a specified amount of time when a + /// table is locked. The handler will sleep multiple times until at + /// least "ms" milliseconds of sleeping have accumulated. /// - /// Calling this routine with an argument equal to zero turns off all busy handlers. + /// Calling this routine with an argument equal to zero turns off all busy + /// handlers. // - /// 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`) prior to calling this routine, that other busy handler is cleared. + /// 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`) prior to calling this routine, that other + /// busy handler is cleared. pub fn busy_timeout(&self, timeout: Duration) -> Result<()> { let ms = timeout .as_secs() @@ -26,14 +30,21 @@ impl Connection { /// Register a callback to handle `SQLITE_BUSY` errors. /// - /// If the busy callback is `None`, then `SQLITE_BUSY is returned immediately upon encountering the lock.` - /// The argument to the busy handler callback is the number of times that the busy handler has been invoked previously for the same locking event. - /// If the busy callback returns `false`, then no additional attempts are made to access the database and `SQLITE_BUSY` is returned to the application. - /// If the callback returns `true`, then another attempt is made to access the database and the cycle repeats. + /// If the busy callback is `None`, then `SQLITE_BUSY is returned + /// immediately upon encountering the lock.` The argument to the busy + /// handler callback is the number of times that the + /// busy handler has been invoked previously for the + /// same locking event. If the busy callback returns `false`, then no + /// additional attempts are made to access the + /// database and `SQLITE_BUSY` is returned to the + /// application. If the callback returns `true`, then another attempt + /// is made to access the database and the cycle repeats. /// - /// 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()` or evaluating `PRAGMA busy_timeout=N` will change the busy handler and thus clear any previously set busy handler. + /// 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()` or evaluating `PRAGMA + /// busy_timeout=N` will change the busy handler and thus + /// clear any previously set busy handler. 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 69bd0c7..bd31b39 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -7,10 +7,10 @@ use std::ops::{Deref, DerefMut}; use {Connection, Result, Statement}; impl Connection { - /// Prepare a SQL statement for execution, returning a previously prepared (but - /// not currently in-use) statement if one is available. The returned statement - /// will be cached for reuse by future calls to `prepare_cached` once it is - /// dropped. + /// Prepare a SQL statement for execution, returning a previously prepared + /// (but not currently in-use) statement if one is available. The + /// returned statement will be cached for reuse by future calls to + /// `prepare_cached` once it is dropped. /// /// ```rust,no_run /// # use rusqlite::{Connection, Result}; @@ -31,16 +31,17 @@ impl Connection { /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn prepare_cached<'a>(&'a self, sql: &str) -> Result> { self.cache.get(self, sql) } - /// Set the maximum number of cached prepared statements this connection will hold. - /// By default, a connection will hold a relatively small number of cached statements. - /// If you need more, or know that you will not use cached statements, you can set - /// the capacity manually using this method. + /// Set the maximum number of cached prepared statements this connection + /// will hold. By default, a connection will hold a relatively small + /// number of cached statements. If you need more, or know that you + /// will not use cached statements, you + /// can set the capacity manually using this method. pub fn set_prepared_statement_cache_capacity(&self, capacity: usize) { self.cache.set_capacity(capacity) } @@ -95,8 +96,8 @@ impl<'conn> CachedStatement<'conn> { } } - /// Discard the statement, preventing it from being returned to its `Connection`'s collection - /// of cached statements. + /// Discard the statement, preventing it from being returned to its + /// `Connection`'s collection of cached statements. pub fn discard(mut self) { self.stmt = None; } @@ -117,8 +118,8 @@ impl StatementCache { // // # Failure // - // Will return `Err` if no cached statement can be found and the underlying SQLite prepare - // call fails. + // Will return `Err` if no cached statement can be found and the underlying + // SQLite prepare call fails. fn get<'conn>( &'conn self, conn: &'conn Connection, diff --git a/src/error.rs b/src/error.rs index 0d6504f..27674f8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -17,26 +17,29 @@ pub enum Error { /// An error from an underlying SQLite call. SqliteFailure(ffi::Error, Option), - /// Error reported when attempting to open a connection when SQLite was configured to - /// allow single-threaded use only. + /// Error reported when attempting to open a connection when SQLite was + /// configured to allow single-threaded use only. SqliteSingleThreadedMode, - /// Error when the value of a particular column is requested, but it cannot be converted to - /// the requested Rust type. + /// Error when the value of a particular column is requested, but it cannot + /// be converted to the requested Rust type. FromSqlConversionFailure(usize, Type, Box), - /// Error when SQLite gives us an integral value outside the range of the requested type (e.g., - /// trying to get the value 1000 into a `u8`). The associated `usize` is the column index, and - /// the associated `i64` is the value returned by SQLite. + /// Error when SQLite gives us an integral value outside the range of the + /// requested type (e.g., trying to get the value 1000 into a `u8`). + /// The associated `usize` is the column index, + /// and the associated `i64` is the value returned by SQLite. IntegralValueOutOfRange(usize, i64), /// Error converting a string to UTF-8. Utf8Error(str::Utf8Error), - /// Error converting a string to a C-compatible string because it contained an embedded nul. + /// Error converting a string to a C-compatible string because it contained + /// an embedded nul. NulError(::std::ffi::NulError), - /// Error when using SQL named parameters and passing a parameter name not present in the SQL. + /// Error when using SQL named parameters and passing a parameter name not + /// present in the SQL. InvalidParameterName(String), /// Error converting a file path to a string. @@ -45,31 +48,33 @@ pub enum Error { /// Error returned when an `execute` call returns rows. ExecuteReturnedResults, - /// Error when a query that was expected to return at least one row (e.g., for `query_row`) - /// did not return any. + /// Error when a query that was expected to return at least one row (e.g., + /// for `query_row`) did not return any. QueryReturnedNoRows, - /// Error when the value of a particular column is requested, but the index is out of range - /// for the statement. + /// Error when the value of a particular column is requested, but the index + /// is out of range for the statement. InvalidColumnIndex(usize), - /// Error when the value of a named column is requested, but no column matches the name - /// for the statement. + /// Error when the value of a named column is requested, but no column + /// matches the name for the statement. InvalidColumnName(String), - /// Error when the value of a particular column is requested, but the type of the result in - /// that column cannot be converted to the requested Rust type. + /// Error when the value of a particular column is requested, but the type + /// of the result in that column cannot be converted to the requested + /// Rust type. InvalidColumnType(usize, Type), - /// Error when a query that was expected to insert one row did not insert any or insert many. + /// Error when a query that was expected to insert one row did not insert + /// any or insert many. StatementChangedRows(usize), - /// Error returned by `functions::Context::get` when the function argument cannot be converted - /// to the requested type. + /// Error returned by `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` when the filter argument cannot be converted - /// to the requested type. + /// Error returned by `vtab::Values::get` when the filter argument cannot + /// be converted to the requested type. #[cfg(feature = "vtab")] InvalidFilterParameterType(usize, Type), diff --git a/src/functions.rs b/src/functions.rs index c0064c3..7137c0d 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -2,19 +2,20 @@ //! //! # Example //! -//! Adding a `regexp` function to a connection in which compiled regular expressions -//! are cached in a `HashMap`. For an alternative implementation that uses SQLite's -//! [Function Auxilliary Data](https://www.sqlite.org/c3ref/get_auxdata.html) interface -//! to avoid recompiling regular expressions, see the unit tests for this module. +//! Adding a `regexp` function to a connection in which compiled regular +//! expressions are cached in a `HashMap`. For an alternative implementation +//! that uses SQLite's [Function Auxilliary Data](https://www.sqlite.org/c3ref/get_auxdata.html) interface +//! to avoid recompiling regular expressions, see the unit tests for this +//! module. //! //! ```rust //! extern crate libsqlite3_sys; //! extern crate rusqlite; //! extern crate regex; //! +//! use regex::Regex; //! use rusqlite::{Connection, Error, Result}; //! use std::collections::HashMap; -//! use regex::Regex; //! //! fn add_regexp_function(db: &Connection) -> Result<()> { //! let mut cached_regexes = HashMap::new(); @@ -25,12 +26,10 @@ //! use std::collections::hash_map::Entry::{Occupied, Vacant}; //! match entry { //! Occupied(occ) => occ.into_mut(), -//! Vacant(vac) => { -//! match Regex::new(®ex_s) { -//! Ok(r) => vac.insert(r), -//! Err(err) => return Err(Error::UserFunctionError(Box::new(err))), -//! } -//! } +//! Vacant(vac) => match Regex::new(®ex_s) { +//! Ok(r) => vac.insert(r), +//! Err(err) => return Err(Error::UserFunctionError(Box::new(err))), +//! }, //! } //! }; //! @@ -43,8 +42,10 @@ //! let db = Connection::open_in_memory().unwrap(); //! add_regexp_function(&db).unwrap(); //! -//! let is_match: bool = db.query_row("SELECT regexp('[aeiou]*', 'aaaaeeeiii')", &[], -//! |row| row.get(0)).unwrap(); +//! let is_match: bool = db +//! .query_row("SELECT regexp('[aeiou]*', 'aaaaeeeiii')", &[], |row| { +//! row.get(0) +//! }).unwrap(); //! //! assert!(is_match); //! } @@ -64,10 +65,10 @@ use types::{FromSql, FromSqlError, ToSql, ValueRef}; use {str_to_cstring, Connection, Error, InnerConnection, Result}; unsafe fn report_error(ctx: *mut sqlite3_context, err: &Error) { - // Extended constraint error codes were added in SQLite 3.7.16. We don't have an explicit - // feature check for that, and this doesn't really warrant one. We'll use the extended code - // if we're on the bundled version (since it's at least 3.17.0) and the normal constraint - // error code if not. + // Extended constraint error codes were added in SQLite 3.7.16. We don't have + // an explicit feature check for that, and this doesn't really warrant one. + // We'll use the extended code if we're on the bundled version (since it's + // at least 3.17.0) and the normal constraint error code if not. #[cfg(feature = "bundled")] fn constraint_error_code() -> i32 { ffi::SQLITE_CONSTRAINT_FUNCTION @@ -108,6 +109,7 @@ impl<'a> Context<'a> { pub fn len(&self) -> usize { self.args.len() } + /// Returns `true` when there is no argument. pub fn is_empty(&self) -> bool { self.args.is_empty() @@ -119,7 +121,8 @@ impl<'a> Context<'a> { /// /// Will panic if `idx` is greater than or equal to `self.len()`. /// - /// Will return Err if the underlying SQLite type cannot be converted to a `T`. + /// Will return Err if the underlying SQLite type cannot be converted to a + /// `T`. pub fn get(&self, idx: usize) -> Result { let arg = self.args[idx]; let value = unsafe { ValueRef::from_value(arg) }; @@ -169,26 +172,26 @@ impl<'a> Context<'a> { /// Aggregate is the callback interface for user-defined aggregate function. /// -/// `A` is the type of the aggregation context and `T` is the type of the final result. -/// Implementations should be stateless. +/// `A` is the type of the aggregation context and `T` is the type of the final +/// result. Implementations should be stateless. pub trait Aggregate where T: ToSql, { - /// Initializes the aggregation context. Will be called prior to the first call - /// to `step()` to set up the context for an invocation of the function. (Note: - /// `init()` will not be called if there are no rows.) + /// Initializes the aggregation context. Will be called prior to the first + /// call to `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) -> A; - /// "step" function called once for each row in an aggregate group. May be called - /// 0 times if there are no rows. + /// "step" function called once for each row in an aggregate group. May be + /// called 0 times if there are no rows. 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()` was called at least once, will be given - /// `Some(A)` (the same `A` as was created by `init` and given to `step`); if `step()` - /// was not called (because the function is running against 0 rows), will be given - /// `None`. + /// Computes and returns the final result. Will be called exactly once for + /// each invocation of the function. If `step()` was called at least + /// once, will be given `Some(A)` (the same `A` as was created by + /// `init` and given to `step`); if `step()` was not called (because + /// the function is running against 0 rows), will be given `None`. fn finalize(&self, Option) -> Result; } @@ -196,9 +199,9 @@ impl Connection { /// Attach a user-defined scalar function to this database connection. /// /// `fn_name` is the name the function will be accessible from SQL. - /// `n_arg` is the number of arguments to the function. Use `-1` for a variable - /// number. If the function always returns the same value given the same - /// input, `deterministic` should be `true`. + /// `n_arg` is the number of arguments to the function. Use `-1` for a + /// variable number. If the function always returns the same value + /// 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`. diff --git a/src/hooks.rs b/src/hooks.rs index afc7ba0..c36b313 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -91,7 +91,8 @@ impl From for Action { } impl Connection { - /// Register a callback function to be invoked whenever a transaction is committed. + /// Register a callback function to be invoked whenever a transaction is + /// committed. /// /// The callback returns `true` to rollback. pub fn commit_hook(&self, hook: Option) @@ -101,7 +102,8 @@ impl Connection { self.db.borrow_mut().commit_hook(hook); } - /// Register a callback function to be invoked whenever a transaction is committed. + /// Register a callback function to be invoked whenever a transaction is + /// committed. /// /// The callback returns `true` to rollback. pub fn rollback_hook(&self, hook: Option) @@ -116,10 +118,11 @@ impl Connection { /// /// The callback parameters are: /// - /// - the type of database update (SQLITE_INSERT, SQLITE_UPDATE or SQLITE_DELETE), - /// - the name of the database ("main", "temp", ...), - /// - the name of the table that is updated, - /// - the ROWID of the row that is updated. + /// - the type of database update (SQLITE_INSERT, SQLITE_UPDATE or + /// SQLITE_DELETE), + /// - the name of the database ("main", "temp", ...), + /// - the name of the table that is updated, + /// - the ROWID of the row that is updated. pub fn update_hook(&self, hook: Option) where F: FnMut(Action, &str, &str, i64) + Send + 'static, @@ -151,8 +154,9 @@ impl InnerConnection { } } - // unlike `sqlite3_create_function_v2`, we cannot specify a `xDestroy` with `sqlite3_commit_hook`. - // so we keep the `xDestroy` function in `InnerConnection.free_boxed_hook`. + // unlike `sqlite3_create_function_v2`, we cannot specify a `xDestroy` with + // `sqlite3_commit_hook`. so we keep the `xDestroy` function in + // `InnerConnection.free_boxed_hook`. let free_commit_hook = if hook.is_some() { Some(free_boxed_hook:: as fn(*mut c_void)) } else { diff --git a/src/lib.rs b/src/lib.rs index 5a41849..b6023dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,49 +1,55 @@ -//! Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to expose -//! an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres). +//! Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to +//! expose an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres). //! //! ```rust //! extern crate rusqlite; //! extern crate time; //! -//! use time::Timespec; //! use rusqlite::Connection; +//! use time::Timespec; //! //! #[derive(Debug)] //! struct Person { //! id: i32, //! name: String, //! time_created: Timespec, -//! data: Option> +//! data: Option>, //! } //! //! fn main() { //! let conn = Connection::open_in_memory().unwrap(); //! -//! conn.execute("CREATE TABLE person ( +//! conn.execute( +//! "CREATE TABLE person ( //! id INTEGER PRIMARY KEY, //! name TEXT NOT NULL, //! time_created TEXT NOT NULL, //! data BLOB -//! )", &[]).unwrap(); +//! )", +//! &[], +//! ).unwrap(); //! let me = Person { //! id: 0, //! name: "Steven".to_string(), //! time_created: time::get_time(), -//! data: None +//! data: None, //! }; -//! conn.execute("INSERT INTO person (name, time_created, data) +//! conn.execute( +//! "INSERT INTO person (name, time_created, data) //! VALUES (?1, ?2, ?3)", -//! &[&me.name, &me.time_created, &me.data]).unwrap(); +//! &[&me.name, &me.time_created, &me.data], +//! ).unwrap(); //! -//! let mut stmt = conn.prepare("SELECT id, name, time_created, data FROM person").unwrap(); -//! let person_iter = stmt.query_map(&[], |row| { -//! Person { +//! let mut stmt = conn +//! .prepare("SELECT id, name, time_created, data FROM person") +//! .unwrap(); +//! let person_iter = stmt +//! .query_map(&[], |row| Person { //! id: row.get(0), //! name: row.get(1), //! time_created: row.get(2), -//! data: row.get(3) -//! } -//! }).unwrap(); +//! data: row.get(3), +//! }).unwrap(); //! //! for person in person_iter { //! println!("Found person {:?}", person.unwrap()); @@ -168,8 +174,8 @@ pub enum DatabaseName<'a> { Attached(&'a str), } -// Currently DatabaseName is only used by the backup and blob mods, so hide this (private) -// impl to avoid dead code warnings. +// Currently DatabaseName is only used by the backup and blob mods, so hide +// this (private) impl to avoid dead code warnings. #[cfg(any(feature = "backup", feature = "blob"))] impl<'a> DatabaseName<'a> { fn to_cstring(&self) -> Result { @@ -204,13 +210,15 @@ impl Drop for Connection { impl Connection { /// Open a new connection to a SQLite database. /// - /// `Connection::open(path)` is equivalent to `Connection::open_with_flags(path, - /// OpenFlags::SQLITE_OPEN_READ_WRITE | OpenFlags::SQLITE_OPEN_CREATE)`. + /// `Connection::open(path)` is equivalent to + /// `Connection::open_with_flags(path, + /// OpenFlags::SQLITE_OPEN_READ_WRITE | + /// OpenFlags::SQLITE_OPEN_CREATE)`. /// /// # Failure /// - /// Will return `Err` if `path` cannot be converted to a C-compatible string or if the - /// underlying SQLite open call fails. + /// Will return `Err` if `path` cannot be converted to a C-compatible + /// string or if the underlying SQLite open call fails. pub fn open>(path: P) -> Result { let flags = OpenFlags::default(); Connection::open_with_flags(path, flags) @@ -233,8 +241,8 @@ impl Connection { /// /// # Failure /// - /// Will return `Err` if `path` cannot be converted to a C-compatible string or if the - /// underlying SQLite open call fails. + /// Will return `Err` if `path` cannot be converted to a C-compatible + /// string or if the underlying SQLite open call fails. pub fn open_with_flags>(path: P, flags: OpenFlags) -> Result { let c_path = try!(path_to_cstring(path.as_ref())); InnerConnection::open_with_flags(&c_path, flags).map(|db| Connection { @@ -261,7 +269,8 @@ impl Connection { }) } - /// Convenience method to run multiple SQL statements (that cannot take any parameters). + /// Convenience method to run multiple SQL statements (that cannot take any + /// parameters). /// /// Uses [sqlite3_exec](http://www.sqlite.org/c3ref/exec.html) under the hood. /// @@ -270,25 +279,27 @@ impl Connection { /// ```rust,no_run /// # use rusqlite::{Connection, Result}; /// fn create_tables(conn: &Connection) -> Result<()> { - /// conn.execute_batch("BEGIN; + /// conn.execute_batch( + /// "BEGIN; /// CREATE TABLE foo(x INTEGER); /// CREATE TABLE bar(y TEXT); - /// COMMIT;") + /// COMMIT;", + /// ) /// } /// ``` /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn execute_batch(&self, sql: &str) -> Result<()> { self.db.borrow_mut().execute_batch(sql) } /// Convenience method to prepare and execute a single SQL statement. /// - /// On success, returns the number of rows that were changed or inserted or deleted (via - /// `sqlite3_changes`). + /// On success, returns the number of rows that were changed or inserted or + /// deleted (via `sqlite3_changes`). /// /// ## Example /// @@ -304,30 +315,34 @@ impl Connection { /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn execute(&self, sql: &str, params: &[&ToSql]) -> Result { self.prepare(sql).and_then(|mut stmt| stmt.execute(params)) } - /// Convenience method to prepare and execute a single SQL statement with named parameter(s). + /// Convenience method to prepare and execute a single SQL statement with + /// named parameter(s). /// - /// On success, returns the number of rows that were changed or inserted or deleted (via - /// `sqlite3_changes`). + /// On success, returns the number of rows that were changed or inserted or + /// deleted (via `sqlite3_changes`). /// /// ## Example /// /// ```rust,no_run /// # use rusqlite::{Connection, Result}; /// fn insert(conn: &Connection) -> Result { - /// conn.execute_named("INSERT INTO test (name) VALUES (:name)", &[(":name", &"one")]) + /// conn.execute_named( + /// "INSERT INTO test (name) VALUES (:name)", + /// &[(":name", &"one")], + /// ) /// } /// ``` /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn execute_named(&self, sql: &str, params: &[(&str, &ToSql)]) -> Result { self.prepare(sql) .and_then(|mut stmt| stmt.execute_named(params)) @@ -341,25 +356,29 @@ impl Connection { self.db.borrow_mut().last_insert_rowid() } - /// Convenience method to execute a query that is expected to return a single row. + /// Convenience method to execute a query that is expected to return a + /// single row. /// /// ## Example /// /// ```rust,no_run /// # use rusqlite::{Result,Connection}; /// fn preferred_locale(conn: &Connection) -> Result { - /// conn.query_row("SELECT value FROM preferences WHERE name='locale'", &[], |row| { - /// row.get(0) - /// }) + /// conn.query_row( + /// "SELECT value FROM preferences WHERE name='locale'", + /// &[], + /// |row| row.get(0), + /// ) /// } /// ``` /// - /// If the query returns more than one row, all rows except the first are ignored. + /// If the query returns more than one row, all rows except the first are + /// ignored. /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn query_row(&self, sql: &str, params: &[&ToSql], f: F) -> Result where F: FnOnce(&Row) -> T, @@ -368,15 +387,16 @@ impl Connection { stmt.query_row(params, f) } - /// Convenience method to execute a query with named parameter(s) that is expected to return - /// a single row. + /// Convenience method to execute a query with named parameter(s) that is + /// expected to return a single row. /// - /// If the query returns more than one row, all rows except the first are ignored. + /// If the query returns more than one row, all rows except the first are + /// ignored. /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn query_row_named(&self, sql: &str, params: &[(&str, &ToSql)], f: F) -> Result where F: FnOnce(&Row) -> T, @@ -387,29 +407,31 @@ impl Connection { rows.get_expected_row().map(|r| f(&r)) } - /// Convenience method to execute a query that is expected to return a single row, - /// and execute a mapping via `f` on that returned row with the possibility of failure. - /// The `Result` type of `f` must implement `std::convert::From`. + /// Convenience method to execute a query that is expected to return a + /// single row, and execute a mapping via `f` on that returned row with + /// the possibility of failure. The `Result` type of `f` must implement + /// `std::convert::From`. /// /// ## Example /// /// ```rust,no_run /// # use rusqlite::{Result,Connection}; /// fn preferred_locale(conn: &Connection) -> Result { - /// conn.query_row_and_then("SELECT value FROM preferences WHERE name='locale'", - /// &[], - /// |row| { - /// row.get_checked(0) - /// }) + /// conn.query_row_and_then( + /// "SELECT value FROM preferences WHERE name='locale'", + /// &[], + /// |row| row.get_checked(0), + /// ) /// } /// ``` /// - /// If the query returns more than one row, all rows except the first are ignored. + /// If the query returns more than one row, all rows except the first are + /// ignored. /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn query_row_and_then( &self, sql: &str, @@ -426,25 +448,29 @@ impl Connection { rows.get_expected_row().map_err(E::from).and_then(|r| f(&r)) } - /// Convenience method to execute a query that is expected to return a single row. + /// Convenience method to execute a query that is expected to return a + /// single row. /// /// ## Example /// /// ```rust,no_run /// # use rusqlite::{Result,Connection}; /// fn preferred_locale(conn: &Connection) -> Result { - /// conn.query_row_safe("SELECT value FROM preferences WHERE name='locale'", &[], |row| { - /// row.get(0) - /// }) + /// conn.query_row_safe( + /// "SELECT value FROM preferences WHERE name='locale'", + /// &[], + /// |row| row.get(0), + /// ) /// } /// ``` /// - /// If the query returns more than one row, all rows except the first are ignored. + /// If the query returns more than one row, all rows except the first are + /// ignored. /// /// ## Deprecated /// - /// This method should be considered deprecated. Use `query_row` instead, which now - /// does exactly the same thing. + /// This method should be considered deprecated. Use `query_row` instead, + /// which now does exactly the same thing. #[deprecated(since = "0.1.0", note = "Use query_row instead")] pub fn query_row_safe(&self, sql: &str, params: &[&ToSql], f: F) -> Result where @@ -469,17 +495,17 @@ impl Connection { /// /// # Failure /// - /// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the - /// underlying SQLite call fails. + /// Will return `Err` if `sql` cannot be converted to a C-compatible string + /// or if the underlying SQLite call fails. pub fn prepare<'a>(&'a self, sql: &str) -> Result> { self.db.borrow_mut().prepare(self, sql) } /// Close the SQLite connection. /// - /// This is functionally equivalent to the `Drop` implementation for `Connection` except - /// that on failure, it returns an error and the connection itself (presumably so closing - /// can be attempted again). + /// This is functionally equivalent to the `Drop` implementation for + /// `Connection` except that on failure, it returns an error and the + /// connection itself (presumably so closing can be attempted again). /// /// # Failure /// @@ -490,8 +516,8 @@ impl Connection { r.map_err(move |err| (self, err)) } - /// Enable loading of SQLite extensions. Strongly consider using `LoadExtensionGuard` - /// instead of this function. + /// Enable loading of SQLite extensions. Strongly consider using + /// `LoadExtensionGuard` instead of this function. /// /// ## Example /// @@ -525,12 +551,13 @@ impl Connection { self.db.borrow_mut().enable_load_extension(0) } - /// Load the SQLite extension at `dylib_path`. `dylib_path` is passed through to - /// `sqlite3_load_extension`, which may attempt OS-specific modifications if the file - /// cannot be loaded directly. + /// Load the SQLite extension at `dylib_path`. `dylib_path` is passed + /// through to `sqlite3_load_extension`, which may attempt OS-specific + /// modifications if the file cannot be loaded directly. /// - /// If `entry_point` is `None`, SQLite will attempt to find the entry point. If it is not - /// `None`, the entry point will be passed through to `sqlite3_load_extension`. + /// If `entry_point` is `None`, SQLite will attempt to find the entry + /// point. If it is not `None`, the entry point will be passed through + /// to `sqlite3_load_extension`. /// /// ## Example /// @@ -562,10 +589,11 @@ impl Connection { /// /// # Warning /// - /// You should not need to use this function. If you do need to, please [open an issue - /// on the rusqlite repository](https://github.com/jgallagher/rusqlite/issues) and describe - /// your use case. This function is unsafe because it gives you raw access to the SQLite - /// connection, and what you do with it could impact the safety of this `Connection`. + /// You should not need to use this function. If you do need to, please + /// [open an issue on the rusqlite repository](https://github.com/jgallagher/rusqlite/issues) and describe + /// your use case. This function is unsafe because it gives you raw access + /// to the SQLite connection, and what you do with it could impact the + /// safety of this `Connection`. pub unsafe fn handle(&self) -> *mut ffi::sqlite3 { self.db.borrow().db() } @@ -644,27 +672,34 @@ static SQLITE_VERSION_CHECK: Once = ONCE_INIT; static BYPASS_SQLITE_INIT: AtomicBool = ATOMIC_BOOL_INIT; static BYPASS_VERSION_CHECK: AtomicBool = ATOMIC_BOOL_INIT; -/// rusqlite's check for a safe SQLite threading mode requires SQLite 3.7.0 or later. If you are -/// running against a SQLite older than that, rusqlite attempts to ensure safety by performing -/// configuration and initialization of SQLite itself the first time you attempt to open a -/// connection. By default, rusqlite panics if that initialization fails, since that could mean -/// SQLite has been initialized in single-thread mode. +/// rusqlite's check for a safe SQLite threading mode requires SQLite 3.7.0 or +/// later. If you are running against a SQLite older than that, rusqlite +/// attempts to ensure safety by performing configuration and initialization of +/// SQLite itself the first time you +/// attempt to open a connection. By default, rusqlite panics if that +/// initialization fails, since that could mean SQLite has been initialized in +/// single-thread mode. /// -/// If you are encountering that panic _and_ can ensure that SQLite has been initialized in either -/// multi-thread or serialized mode, call this function prior to attempting to open a connection -/// and rusqlite's initialization process will by skipped. This function is unsafe because if you -/// call it and SQLite has actually been configured to run in single-thread mode, you may enounter -/// memory errors or data corruption or any number of terrible things that should not be possible -/// when you're using Rust. +/// If you are encountering that panic _and_ can ensure that SQLite has been +/// initialized in either multi-thread or serialized mode, call this function +/// prior to attempting to open a connection and rusqlite's initialization +/// process will by skipped. This +/// function is unsafe because if you call it and SQLite has actually been +/// configured to run in single-thread mode, +/// you may enounter memory errors or data corruption or any number of terrible +/// things that should not be possible when you're using Rust. pub unsafe fn bypass_sqlite_initialization() { BYPASS_SQLITE_INIT.store(true, Ordering::Relaxed); } -/// rusqlite performs a one-time check that the runtime SQLite version is at least as new as -/// the version of SQLite found when rusqlite was built. Bypassing this check may be dangerous; -/// e.g., if you use features of SQLite that are not present in the runtime version. If you are -/// sure the runtime version is compatible with the build-time version for your usage, you can -/// bypass the version check by calling this function before your first connection attempt. +/// rusqlite performs a one-time check that the runtime SQLite version is at +/// least as new as the version of SQLite found when rusqlite was built. +/// Bypassing this check may be dangerous; e.g., if you use features of SQLite +/// that are not present in the runtime +/// version. If you are sure the runtime version is compatible with the +/// build-time version for your usage, you can bypass the version check by +/// calling this function before +/// your first connection attempt. pub unsafe fn bypass_sqlite_version_check() { BYPASS_VERSION_CHECK.store(true, Ordering::Relaxed); } @@ -693,8 +728,8 @@ fn ensure_valid_sqlite_version() { return; } - // Check that the runtime version number is compatible with the version number we found at - // build-time. + // Check that the runtime version number is compatible with the version number + // we found at build-time. if version_number < ffi::SQLITE_VERSION_NUMBER { panic!( "\ @@ -716,21 +751,23 @@ fn ensure_safe_sqlite_threading_mode() -> Result<()> { return Err(Error::SqliteSingleThreadedMode); } - // Now we know SQLite is _capable_ of being in Multi-thread of Serialized mode, but it's - // possible someone configured it to be in Single-thread mode before calling into us. That - // would mean we're exposing an unsafe API via a safe one (in Rust terminology), which is - // no good. We have two options to protect against this, depending on the version of SQLite - // we're linked with: + // Now we know SQLite is _capable_ of being in Multi-thread of Serialized mode, + // but it's possible someone configured it to be in Single-thread mode + // before calling into us. That would mean we're exposing an unsafe API via + // a safe one (in Rust terminology), which is no good. We have two options + // to protect against this, depending on the version of SQLite we're linked + // with: // - // 1. If we're on 3.7.0 or later, we can ask SQLite for a mutex and check for the magic value - // 8. This isn't documented, but it's what SQLite returns for its mutex allocation function - // in Single-thread mode. - // 2. If we're prior to SQLite 3.7.0, AFAIK there's no way to check the threading mode. The - // check we perform for >= 3.7.0 will segfault. Instead, we insist on being able to call - // sqlite3_config and sqlite3_initialize ourself, ensuring we know the threading mode. This - // will fail if someone else has already initialized SQLite even if they initialized it - // safely. That's not ideal either, which is why we expose bypass_sqlite_initialization - // above. + // 1. If we're on 3.7.0 or later, we can ask SQLite for a mutex and check for + // the magic value 8. This isn't documented, but it's what SQLite + // returns for its mutex allocation function in Single-thread mode. + // 2. If we're prior to SQLite 3.7.0, AFAIK there's no way to check the + // threading mode. The check we perform for >= 3.7.0 will segfault. + // Instead, we insist on being able to call sqlite3_config and + // sqlite3_initialize ourself, ensuring we know the threading + // mode. This will fail if someone else has already initialized SQLite + // even if they initialized it safely. That's not ideal either, which is + // why we expose bypass_sqlite_initialization above. if version_number() >= 3_007_000 { const SQLITE_SINGLETHREADED_MUTEX_MAGIC: usize = 8; let is_singlethreaded = unsafe { @@ -775,6 +812,7 @@ impl InnerConnection { fn new(db: *mut ffi::sqlite3) -> InnerConnection { InnerConnection { db } } + #[cfg(feature = "hooks")] fn new(db: *mut ffi::sqlite3) -> InnerConnection { InnerConnection { @@ -789,8 +827,8 @@ impl InnerConnection { ensure_valid_sqlite_version(); ensure_safe_sqlite_threading_mode()?; - // Replicate the check for sane open flags from SQLite, because the check in SQLite itself - // wasn't added until version 3.7.3. + // Replicate the check for sane open flags from SQLite, because the check in + // SQLite itself wasn't added until version 3.7.3. debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_ONLY.bits, 0x02); debug_assert_eq!(1 << OpenFlags::SQLITE_OPEN_READ_WRITE.bits, 0x04); debug_assert_eq!( @@ -1105,8 +1143,9 @@ mod test { fn test_close_retry() { let db = checked_memory_handle(); - // force the DB to be busy by preparing a statement; this must be done at the FFI - // level to allow us to call .close() without dropping the prepared statement first. + // force the DB to be busy by preparing a statement; this must be done at the + // FFI level to allow us to call .close() without dropping the prepared + // statement first. let raw_stmt = { use super::str_to_cstring; use std::mem; @@ -1129,7 +1168,8 @@ mod test { raw_stmt }; - // now that we have an open statement, trying (and retrying) to close should fail. + // now that we have an open statement, trying (and retrying) to close should + // fail. let (db, _) = db.close().unwrap_err(); let (db, _) = db.close().unwrap_err(); let (db, _) = db.close().unwrap_err(); @@ -1439,6 +1479,7 @@ mod test { fn description(&self) -> &str { "my custom error" } + fn cause(&self) -> Option<&StdError> { match *self { CustomError::SomeError => None, diff --git a/src/load_extension_guard.rs b/src/load_extension_guard.rs index 37a4d6e..9843fcd 100644 --- a/src/load_extension_guard.rs +++ b/src/load_extension_guard.rs @@ -22,8 +22,9 @@ pub struct LoadExtensionGuard<'conn> { } impl<'conn> LoadExtensionGuard<'conn> { - /// Attempt to enable loading extensions. Loading extensions will be disabled when this - /// guard goes out of scope. Cannot be meaningfully nested. + /// Attempt to enable loading extensions. Loading extensions will be + /// disabled when this guard goes out of scope. Cannot be meaningfully + /// nested. pub fn new(conn: &Connection) -> Result { conn.load_extension_enable() .map(|_| LoadExtensionGuard { conn }) diff --git a/src/row.rs b/src/row.rs index c81a25c..60ebe58 100644 --- a/src/row.rs +++ b/src/row.rs @@ -16,16 +16,17 @@ impl<'stmt> Rows<'stmt> { } } - /// Attempt to get the next row from the query. Returns `Some(Ok(Row))` if there - /// is another row, `Some(Err(...))` if there was an error getting the next - /// row, and `None` if all rows have been retrieved. + /// Attempt to get the next row from the query. Returns `Some(Ok(Row))` if + /// there is another row, `Some(Err(...))` if there was an error + /// getting the next row, and `None` if all rows have been retrieved. /// /// ## Note /// - /// 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 - /// "streaming iterator". For a more natural interface, consider using `query_map` - /// or `query_and_then` instead, which return types that implement `Iterator`. + /// 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 "streaming iterator". For a more natural interface, + /// consider using `query_map` or `query_and_then` instead, which + /// return types that implement `Iterator`. #[cfg_attr(feature = "cargo-clippy", allow(should_implement_trait))] // cannot implement Iterator pub fn next<'a>(&'a mut self) -> Option>> { self.stmt.and_then(|stmt| match stmt.step() { @@ -135,11 +136,15 @@ impl<'a, 'stmt> Row<'a, 'stmt> { /// /// ## Failure /// - /// Panics if calling `row.get_checked(idx)` would return an error, including: + /// Panics if calling `row.get_checked(idx)` would return an error, + /// including: /// - /// * If the underlying SQLite column type is not a valid type as a source for `T` - /// * If the underlying SQLite integral value is outside the range representable by `T` - /// * If `idx` is outside the range of columns in the returned query + /// * If the underlying SQLite column type is not a valid type as a + /// source for `T` + /// * If the underlying SQLite integral value is + /// outside the range representable by `T` + /// * If `idx` is outside the range of columns in the + /// returned query pub fn get(&self, idx: I) -> T { self.get_checked(idx).unwrap() } @@ -151,11 +156,11 @@ impl<'a, 'stmt> Row<'a, 'stmt> { /// Returns an `Error::InvalidColumnType` if the underlying SQLite column /// type is not a valid type as a source for `T`. /// - /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid column range - /// for this row. + /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid + /// column range for this row. /// - /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column name - /// for this row. + /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column + /// name for this row. pub fn get_checked(&self, idx: I) -> Result { let idx = try!(idx.idx(self.stmt)); let value = self.stmt.value_ref(idx); diff --git a/src/statement.rs b/src/statement.rs index 8edc8bb..f2b239a 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -33,19 +33,21 @@ impl<'conn> Statement<'conn> { cols } - /// Return the number of columns in the result set returned by the prepared statement. + /// Return the number of columns in the result set returned by the prepared + /// statement. pub fn column_count(&self) -> usize { self.stmt.column_count() } /// Returns the column index in the result set for a given column name. /// - /// 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 there is no AS clause then the name of the column is unspecified and + /// may change from one release of SQLite to the next. /// /// # Failure /// - /// Will return an `Error::InvalidColumnName` when there is no column with the specified `name`. + /// Will return an `Error::InvalidColumnName` when there is no column with + /// the specified `name`. pub fn column_index(&self, name: &str) -> Result { let bytes = name.as_bytes(); let n = self.column_count(); @@ -59,8 +61,8 @@ impl<'conn> Statement<'conn> { /// Execute the prepared statement. /// - /// On success, returns the number of rows that were changed or inserted or deleted (via - /// `sqlite3_changes`). + /// On success, returns the number of rows that were changed or inserted or + /// deleted (via `sqlite3_changes`). /// /// ## Example /// @@ -78,20 +80,22 @@ impl<'conn> Statement<'conn> { /// /// # Failure /// - /// Will return `Err` if binding parameters fails, the executed statement returns rows (in - /// which case `query` should be used instead), or the underling SQLite call fails. + /// Will return `Err` if binding parameters fails, the executed statement + /// returns rows (in which case `query` should be used instead), or the + /// underling SQLite call fails. pub fn execute(&mut self, params: &[&ToSql]) -> Result { try!(self.bind_parameters(params)); self.execute_with_bound_parameters() } - /// Execute the prepared statement with named parameter(s). If any parameters - /// that were in the prepared statement are not included in `params`, they - /// will continue to use the most-recently bound value from a previous call - /// to `execute_named`, or `NULL` if they have never been bound. + /// Execute the prepared statement with named parameter(s). If any + /// parameters that were in the prepared statement are not included in + /// `params`, they will continue to use the most-recently bound value + /// from a previous call to `execute_named`, or `NULL` if they have + /// never been bound. /// - /// On success, returns the number of rows that were changed or inserted or deleted (via - /// `sqlite3_changes`). + /// On success, returns the number of rows that were changed or inserted or + /// deleted (via `sqlite3_changes`). /// /// ## Example /// @@ -105,8 +109,9 @@ impl<'conn> Statement<'conn> { /// /// # Failure /// - /// Will return `Err` if binding parameters fails, the executed statement returns rows (in - /// which case `query` should be used instead), or the underling SQLite call fails. + /// Will return `Err` if binding parameters fails, the executed statement + /// returns rows (in which case `query` should be used instead), or the + /// underling SQLite call fails. pub fn execute_named(&mut self, params: &[(&str, &ToSql)]) -> Result { try!(self.bind_parameters_named(params)); self.execute_with_bound_parameters() @@ -116,10 +121,11 @@ impl<'conn> Statement<'conn> { /// /// # Note /// - /// This function is a convenience wrapper around `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()` 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 /// @@ -132,11 +138,12 @@ impl<'conn> Statement<'conn> { } } - /// Execute the prepared statement, returning a handle to the resulting rows. + /// Execute the prepared statement, returning a handle to the resulting + /// rows. /// /// Due to lifetime restricts, the rows handle returned by `query` does not - /// implement the `Iterator` trait. Consider using `query_map` or `query_and_then` - /// instead, which do. + /// implement the `Iterator` trait. Consider using `query_map` or + /// `query_and_then` instead, which do. /// /// ## Example /// @@ -165,10 +172,11 @@ impl<'conn> Statement<'conn> { Ok(Rows::new(self)) } - /// Execute the prepared statement with named parameter(s), returning a handle for the - /// resulting rows. If any parameters that were in the prepared statement are not included in - /// `params`, they will continue to use the most-recently bound value from a previous call to - /// `query_named`, or `NULL` if they have never been bound. + /// Execute the prepared statement with named parameter(s), returning a + /// handle for the resulting rows. If any parameters that were in the + /// prepared statement are not included in `params`, they will continue + /// to use the most-recently bound value from a previous + /// call to `query_named`, or `NULL` if they have never been bound. /// /// ## Example /// @@ -193,8 +201,8 @@ impl<'conn> Statement<'conn> { Ok(Rows::new(self)) } - /// Executes the prepared statement and maps a function over the resulting rows, returning - /// an iterator over the mapped function results. + /// Executes the prepared statement and maps a function over the resulting + /// rows, returning an iterator over the mapped function results. /// /// ## Example /// @@ -224,11 +232,12 @@ impl<'conn> Statement<'conn> { Ok(MappedRows::new(rows, f)) } - /// Execute the prepared statement with named parameter(s), returning an iterator over the - /// result of calling the mapping function over the query's rows. If any parameters that were - /// in the prepared statement are not included in `params`, they will continue to use the - /// most-recently bound value from a previous call to `query_named`, or `NULL` if they have - /// never been bound. + /// Execute the prepared statement with named parameter(s), returning an + /// iterator over the result of calling the mapping function over the + /// query's rows. If any parameters that were in the prepared statement + /// are not included in `params`, they will continue to use the + /// most-recently bound value from a previous call to `query_named`, + /// or `NULL` if they have never been bound. /// /// ## Example /// @@ -263,8 +272,8 @@ impl<'conn> Statement<'conn> { } /// Executes the prepared statement and maps a function over the resulting - /// rows, where the function returns a `Result` with `Error` type implementing - /// `std::convert::From` (so errors can be unified). + /// rows, where the function returns a `Result` with `Error` type + /// implementing `std::convert::From` (so errors can be unified). /// /// # Failure /// @@ -282,28 +291,31 @@ impl<'conn> Statement<'conn> { Ok(AndThenRows::new(rows, f)) } - /// Execute the prepared statement with named parameter(s), returning an iterator over the - /// result of calling the mapping function over the query's rows. If any parameters that were - /// in the prepared statement are not included in `params`, they will continue to use the - /// most-recently bound value from a previous call to `query_named`, or `NULL` if they have - /// never been bound. + /// Execute the prepared statement with named parameter(s), returning an + /// iterator over the result of calling the mapping function over the + /// query's rows. If any parameters that were in the prepared statement + /// are not included in + /// `params`, they will + /// continue to use the most-recently bound value from a previous call + /// to `query_named`, or `NULL` if they have never been bound. /// /// ## Example /// /// ```rust,no_run /// # use rusqlite::{Connection, Result}; - /// struct Person { name: String }; + /// struct Person { + /// name: String, + /// }; /// /// fn name_to_person(name: String) -> Result { /// // ... check for valid name - /// Ok(Person{ name: name }) + /// Ok(Person { name: name }) /// } /// /// fn get_names(conn: &Connection) -> Result> { /// let mut stmt = try!(conn.prepare("SELECT name FROM people WHERE id = :id")); - /// let rows = try!(stmt.query_and_then_named(&[(":id", &"one")], |row| { - /// name_to_person(row.get(0)) - /// })); + /// let rows = + /// try!(stmt.query_and_then_named(&[(":id", &"one")], |row| name_to_person(row.get(0)))); /// /// let mut persons = Vec::new(); /// for person_result in rows { @@ -330,8 +342,8 @@ impl<'conn> Statement<'conn> { Ok(AndThenRows::new(rows, f)) } - /// Return `true` if a query in the SQL statement it executes returns one or more rows - /// and `false` if the SQL returns an empty set. + /// Return `true` if a query in the SQL statement it executes returns one + /// or more rows and `false` if the SQL returns an empty set. pub fn exists(&mut self, params: &[&ToSql]) -> Result { let mut rows = try!(self.query(params)); let exists = { @@ -343,9 +355,11 @@ impl<'conn> Statement<'conn> { Ok(exists) } - /// Convenience method to execute a query that is expected to return a single row. + /// Convenience method to execute a query that is expected to return a + /// single row. /// - /// If the query returns more than one row, all rows except the first are ignored. + /// If the query returns more than one row, all rows except the first are + /// ignored. /// /// # Failure /// @@ -361,8 +375,8 @@ impl<'conn> Statement<'conn> { /// Consumes the statement. /// - /// Functionally equivalent to the `Drop` implementation, but allows callers to see any errors - /// that occur. + /// Functionally equivalent to the `Drop` implementation, but allows + /// callers to see any errors that occur. /// /// # Failure /// @@ -514,7 +528,8 @@ impl<'conn> Statement<'conn> { Ok(()) } - /// Returns a string containing the SQL text of prepared statement with bound parameters expanded. + /// Returns a string containing the SQL text of prepared statement with + /// bound parameters expanded. #[cfg(feature = "bundled")] pub fn expanded_sql(&self) -> Option<&str> { unsafe { diff --git a/src/trace.rs b/src/trace.rs index 69dc731..423569b 100644 --- a/src/trace.rs +++ b/src/trace.rs @@ -61,12 +61,12 @@ pub fn log(err_code: c_int, msg: &str) { } impl Connection { - /// Register or clear a callback function that can be used for tracing the execution of SQL - /// statements. + /// Register or clear a callback function that can be used for tracing the + /// execution of SQL statements. /// - /// Prepared statement placeholders are replaced/logged with their assigned values. - /// There can only be a single tracer defined for each database connection. - /// Setting a new tracer clears the old one. + /// Prepared statement placeholders are replaced/logged with their assigned + /// values. There can only be a single tracer defined for each database + /// connection. Setting a new tracer clears the old one. pub fn trace(&mut self, trace_fn: Option) { unsafe extern "C" fn trace_callback(p_arg: *mut c_void, z_sql: *const c_char) { let trace_fn: fn(&str) = mem::transmute(p_arg); @@ -86,11 +86,11 @@ impl Connection { } } - /// Register or clear a callback function that can be used for profiling the execution of SQL - /// statements. + /// Register or clear a callback function that can be used for profiling + /// the execution of SQL statements. /// - /// There can only be a single profiler defined for each database connection. - /// Setting a new profiler clears the old one. + /// There can only be a single profiler defined for each database + /// connection. Setting a new profiler clears the old one. pub fn profile(&mut self, profile_fn: Option) { unsafe extern "C" fn profile_callback( p_arg: *mut c_void, diff --git a/src/transaction.rs b/src/transaction.rs index 57199cf..a44ca7b 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,7 +1,8 @@ use std::ops::Deref; use {Connection, Result}; -/// Old name for `TransactionBehavior`. `SqliteTransactionBehavior` is deprecated. +/// Old name for `TransactionBehavior`. `SqliteTransactionBehavior` is +/// deprecated. #[deprecated(since = "0.6.0", note = "Use TransactionBehavior instead")] pub type SqliteTransactionBehavior = TransactionBehavior; @@ -23,8 +24,8 @@ pub enum DropBehavior { /// Commit the changes. Commit, - /// Do not commit or roll back changes - this will leave the transaction or savepoint - /// open, so should be used with care. + /// Do not commit or roll back changes - this will leave the transaction or + /// savepoint open, so should be used with care. Ignore, /// Panic. Used to enforce intentional behavior during development. @@ -39,9 +40,9 @@ pub type SqliteTransaction<'conn> = Transaction<'conn>; /// /// ## Note /// -/// Transactions will roll back by default. Use `commit` method to explicitly commit the -/// transaction, or use `set_drop_behavior` to change what happens when the transaction -/// is dropped. +/// Transactions will roll back by default. Use `commit` method to explicitly +/// commit the transaction, or use `set_drop_behavior` to change what happens +/// when the transaction is dropped. /// /// ## Example /// @@ -67,9 +68,9 @@ pub struct Transaction<'conn> { /// /// ## Note /// -/// Savepoints will roll back by default. Use `commit` method to explicitly commit the -/// savepoint, or use `set_drop_behavior` to change what happens when the savepoint -/// is dropped. +/// Savepoints will roll back by default. Use `commit` method to explicitly +/// commit the savepoint, or use `set_drop_behavior` to change what happens +/// when the savepoint is dropped. /// /// ## Example /// @@ -95,7 +96,8 @@ pub struct Savepoint<'conn> { } impl<'conn> Transaction<'conn> { - /// Begin a new transaction. Cannot be nested; see `savepoint` for nested transactions. + /// Begin a new transaction. Cannot be nested; see `savepoint` for nested + /// transactions. // Even though we don't mutate the connection, we take a `&mut Connection` // so as to prevent nested or concurrent transactions on the same // connection. @@ -116,7 +118,8 @@ impl<'conn> Transaction<'conn> { /// /// ## Note /// - /// Just like outer level transactions, savepoint transactions rollback by default. + /// Just like outer level transactions, savepoint transactions rollback by + /// default. /// /// ## Example /// @@ -146,12 +149,14 @@ impl<'conn> Transaction<'conn> { Savepoint::with_depth_and_name(self.conn, 1, name) } - /// Get the current setting for what happens to the transaction when it is dropped. + /// Get the current setting for what happens to the transaction when it is + /// dropped. pub fn drop_behavior(&self) -> DropBehavior { self.drop_behavior } - /// Configure the transaction to perform the specified action when it is dropped. + /// Configure the transaction to perform the specified action when it is + /// dropped. pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) { self.drop_behavior = drop_behavior } @@ -176,11 +181,11 @@ impl<'conn> Transaction<'conn> { Ok(()) } - /// Consumes the transaction, committing or rolling back according to the current setting - /// (see `drop_behavior`). + /// Consumes the transaction, committing or rolling back according to the + /// current setting (see `drop_behavior`). /// - /// Functionally equivalent to the `Drop` implementation, but allows callers to see any - /// errors that occur. + /// Functionally equivalent to the `Drop` implementation, but allows + /// callers to see any errors that occur. pub fn finish(mut self) -> Result<()> { self.finish_() } @@ -255,12 +260,14 @@ impl<'conn> Savepoint<'conn> { Savepoint::with_depth_and_name(self.conn, self.depth + 1, name) } - /// Get the current setting for what happens to the savepoint when it is dropped. + /// Get the current setting for what happens to the savepoint when it is + /// dropped. pub fn drop_behavior(&self) -> DropBehavior { self.drop_behavior } - /// Configure the savepoint to perform the specified action when it is dropped. + /// Configure the savepoint to perform the specified action when it is + /// dropped. pub fn set_drop_behavior(&mut self, drop_behavior: DropBehavior) { self.drop_behavior = drop_behavior } @@ -280,18 +287,18 @@ impl<'conn> Savepoint<'conn> { /// /// ## Note /// - /// Unlike `Transaction`s, savepoints remain active after they have been rolled back, - /// and can be rolled back again or committed. + /// Unlike `Transaction`s, savepoints remain active after they have been + /// rolled back, and can be rolled back again or committed. pub fn rollback(&mut self) -> Result<()> { self.conn .execute_batch(&format!("ROLLBACK TO {}", self.name)) } - /// Consumes the savepoint, committing or rolling back according to the current setting - /// (see `drop_behavior`). + /// Consumes the savepoint, committing or rolling back according to the + /// current setting (see `drop_behavior`). /// - /// Functionally equivalent to the `Drop` implementation, but allows callers to see any - /// errors that occur. + /// Functionally equivalent to the `Drop` implementation, but allows + /// callers to see any errors that occur. pub fn finish(mut self) -> Result<()> { self.finish_() } @@ -327,8 +334,9 @@ impl<'conn> Drop for Savepoint<'conn> { 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` or `set_drop_behavior(DropBehavior::Commit)`. + /// The transaction defaults to rolling back when it is dropped. If you + /// want the transaction to commit, you must call `commit` or + /// `set_drop_behavior(DropBehavior::Commit)`. /// /// ## Example /// @@ -369,8 +377,9 @@ impl Connection { /// Begin a new savepoint with the default behavior (DEFERRED). /// - /// The savepoint defaults to rolling back when it is dropped. If you want the savepoint to - /// commit, you must call `commit` or `set_drop_behavior(DropBehavior::Commit)`. + /// The savepoint defaults to rolling back when it is dropped. If you want + /// the savepoint to commit, you must call `commit` or + /// `set_drop_behavior(DropBehavior::Commit)`. /// /// ## Example /// diff --git a/src/types/chrono.rs b/src/types/chrono.rs index 74317a0..075a552 100644 --- a/src/types/chrono.rs +++ b/src/types/chrono.rs @@ -53,7 +53,8 @@ impl FromSql for NaiveTime { } } -/// ISO 8601 combined date and time without timezone => "YYYY-MM-DD HH:MM:SS.SSS" +/// ISO 8601 combined date and time without timezone => +/// "YYYY-MM-DD HH:MM:SS.SSS" impl ToSql for NaiveDateTime { fn to_sql(&self) -> Result { let date_str = self.format("%Y-%m-%dT%H:%M:%S%.f").to_string(); @@ -61,8 +62,9 @@ impl ToSql for NaiveDateTime { } } -/// "YYYY-MM-DD HH:MM:SS"/"YYYY-MM-DD HH:MM:SS.SSS" => ISO 8601 combined date and time -/// without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS" also supported) +/// "YYYY-MM-DD HH:MM:SS"/"YYYY-MM-DD HH:MM:SS.SSS" => ISO 8601 combined date +/// and time without timezone. ("YYYY-MM-DDTHH:MM:SS"/"YYYY-MM-DDTHH:MM:SS.SSS" +/// also supported) impl FromSql for NaiveDateTime { fn column_result(value: ValueRef) -> FromSqlResult { value.as_str().and_then(|s| { @@ -80,7 +82,8 @@ impl FromSql for NaiveDateTime { } } -/// Date and time with time zone => UTC RFC3339 timestamp ("YYYY-MM-DDTHH:MM:SS.SSS+00:00"). +/// Date and time with time zone => UTC RFC3339 timestamp +/// ("YYYY-MM-DDTHH:MM:SS.SSS+00:00"). impl ToSql for DateTime { fn to_sql(&self) -> Result { Ok(ToSqlOutput::from(self.with_timezone(&Utc).to_rfc3339())) diff --git a/src/types/from_sql.rs b/src/types/from_sql.rs index 33a2a6b..5ec139b 100644 --- a/src/types/from_sql.rs +++ b/src/types/from_sql.rs @@ -5,11 +5,12 @@ use std::fmt; /// Enum listing possible errors from `FromSql` trait. #[derive(Debug)] pub enum FromSqlError { - /// Error when an SQLite value is requested, but the type of the result cannot be converted to - /// the requested Rust type. + /// Error when an SQLite value is requested, but the type of the result + /// cannot be converted to the requested Rust type. InvalidType, - /// Error when the i64 value returned by SQLite cannot be stored into the requested type. + /// Error when the i64 value returned by SQLite cannot be stored into the + /// requested type. OutOfRange(i64), /// An error case available for implementors of the `FromSql` trait. @@ -49,13 +50,15 @@ pub type FromSqlResult = Result; /// A trait for types that can be created from a SQLite value. /// -/// Note that `FromSql` and `ToSql` are defined for most integral types, but not `u64` or `usize`. -/// This is intentional; SQLite returns integers as signed 64-bit values, which cannot fully -/// represent the range of these types. Rusqlite would have to decide how to handle negative -/// values: return an error or reinterpret as a very large postive numbers, neither of which is -/// guaranteed to be correct for everyone. Callers can work around this by fetching values as i64 -/// and then doing the interpretation themselves or by defining a newtype and implementing -/// `FromSql`/`ToSql` for it. +/// Note that `FromSql` and `ToSql` are defined for most integral types, but +/// not `u64` or `usize`. This is intentional; SQLite returns integers as +/// signed 64-bit values, which cannot fully represent the range of these +/// types. Rusqlite would have to +/// decide how to handle negative values: return an error or reinterpret as a +/// very large postive numbers, neither of which +/// is guaranteed to be correct for everyone. Callers can work around this by +/// fetching values as i64 and then doing the interpretation themselves or by +/// defining a newtype and implementing `FromSql`/`ToSql` for it. pub trait FromSql: Sized { fn column_result(value: ValueRef) -> FromSqlResult; } diff --git a/src/types/mod.rs b/src/types/mod.rs index f4dce33..4c3da3f 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,11 +1,11 @@ //! Traits dealing with SQLite data types. //! //! SQLite uses a [dynamic type system](https://www.sqlite.org/datatype3.html). Implementations of -//! the `ToSql` and `FromSql` traits are provided for the basic types that SQLite provides methods -//! for: +//! the `ToSql` and `FromSql` traits are provided for the basic types that +//! SQLite provides methods for: //! -//! * Integers (`i32` and `i64`; SQLite uses `i64` internally, so getting an `i32` will truncate -//! if the value is too large or too small). +//! * Integers (`i32` and `i64`; SQLite uses `i64` internally, so getting an +//! `i32` will truncate if the value is too large or too small). //! * Reals (`f64`) //! * Strings (`String` and `&str`) //! * Blobs (`Vec` and `&[u8]`) @@ -22,16 +22,18 @@ //! extern crate rusqlite; //! extern crate time; //! -//! use rusqlite::types::{FromSql, FromSqlResult, ValueRef, ToSql, ToSqlOutput}; -//! use rusqlite::{Result}; +//! use rusqlite::types::{FromSql, FromSqlResult, ToSql, ToSqlOutput, ValueRef}; +//! use rusqlite::Result; //! //! pub struct TimespecSql(pub time::Timespec); //! //! impl FromSql for TimespecSql { //! fn column_result(value: ValueRef) -> FromSqlResult { //! f64::column_result(value).map(|as_f64| { -//! TimespecSql(time::Timespec{ sec: as_f64.trunc() as i64, -//! nsec: (as_f64.fract() * 1.0e9) as i32 }) +//! TimespecSql(time::Timespec { +//! sec: as_f64.trunc() as i64, +//! nsec: (as_f64.fract() * 1.0e9) as i32, +//! }) //! }) //! } //! } @@ -48,9 +50,9 @@ //! # fn main() {} //! ``` //! -//! `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`). +//! `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`). pub use self::from_sql::{FromSql, FromSqlError, FromSqlResult}; pub use self::to_sql::{ToSql, ToSqlOutput}; @@ -77,8 +79,7 @@ mod value_ref; /// # extern crate rusqlite; /// # use rusqlite::{Connection, Result}; /// # use rusqlite::types::{Null}; -/// fn main() { -/// } +/// fn main() {} /// fn insert_null(conn: &Connection) -> Result { /// conn.execute("INSERT INTO people (name) VALUES (?)", &[&Null]) /// } diff --git a/src/types/to_sql.rs b/src/types/to_sql.rs index 56f3d60..a533013 100644 --- a/src/types/to_sql.rs +++ b/src/types/to_sql.rs @@ -4,7 +4,8 @@ use std::borrow::Cow; use vtab::array::Array; use Result; -/// `ToSqlOutput` represents the possible output types for implementors of the `ToSql` trait. +/// `ToSqlOutput` represents the possible output types for implementors of the +/// `ToSql` trait. #[derive(Clone, Debug, PartialEq)] pub enum ToSqlOutput<'a> { /// A borrowed SQLite-representable value. diff --git a/src/types/value_ref.rs b/src/types/value_ref.rs index 65ea5ad..531bf1c 100644 --- a/src/types/value_ref.rs +++ b/src/types/value_ref.rs @@ -32,8 +32,8 @@ impl<'a> ValueRef<'a> { } impl<'a> ValueRef<'a> { - /// If `self` is case `Integer`, returns the integral value. Otherwise, returns - /// `Err(Error::InvalidColumnType)`. + /// If `self` is case `Integer`, returns the integral value. Otherwise, + /// returns `Err(Error::InvalidColumnType)`. pub fn as_i64(&self) -> FromSqlResult { match *self { ValueRef::Integer(i) => Ok(i), @@ -41,8 +41,8 @@ impl<'a> ValueRef<'a> { } } - /// If `self` is case `Real`, returns the floating point value. Otherwise, returns - /// `Err(Error::InvalidColumnType)`. + /// If `self` is case `Real`, returns the floating point value. Otherwise, + /// returns `Err(Error::InvalidColumnType)`. pub fn as_f64(&self) -> FromSqlResult { match *self { ValueRef::Real(f) => Ok(f), diff --git a/src/version.rs b/src/version.rs index 910feb7..39c7d6b 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,7 +1,8 @@ use ffi; use std::ffi::CStr; -/// Returns the SQLite version as an integer; e.g., `3016002` for version 3.16.2. +/// Returns the SQLite version as an integer; e.g., `3016002` for version +/// 3.16.2. /// /// See [`sqlite3_libversion_number()`](https://www.sqlite.org/c3ref/libversion.html). pub fn version_number() -> i32 { diff --git a/src/vtab/array.rs b/src/vtab/array.rs index 09501be..23d3aa1 100644 --- a/src/vtab/array.rs +++ b/src/vtab/array.rs @@ -120,6 +120,7 @@ impl ArrayTabCursor { ptr: None, } } + fn len(&self) -> i64 { match self.ptr { Some(ref a) => a.len() as i64, @@ -137,13 +138,16 @@ impl VTabCursor for ArrayTabCursor { self.row_id = 1; Ok(()) } + fn next(&mut self) -> Result<()> { self.row_id += 1; Ok(()) } + fn eof(&self) -> bool { self.row_id > self.len() } + fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> { match i { CARRAY_COLUMN_POINTER => Ok(()), @@ -157,6 +161,7 @@ impl VTabCursor for ArrayTabCursor { } } } + fn rowid(&self) -> Result { Ok(self.row_id) } diff --git a/src/vtab/csvtab.rs b/src/vtab/csvtab.rs index 5bbdeac..0b80dc0 100644 --- a/src/vtab/csvtab.rs +++ b/src/vtab/csvtab.rs @@ -293,6 +293,7 @@ impl VTabCursor for CSVTabCursor { self.row_number = 0; self.next() } + fn next(&mut self) -> Result<()> { { self.eof = self.reader.is_done(); @@ -306,9 +307,11 @@ impl VTabCursor for CSVTabCursor { self.row_number += 1; Ok(()) } + fn eof(&self) -> bool { self.eof } + fn column(&self, ctx: &mut Context, col: c_int) -> Result<()> { if col < 0 || col as usize >= self.cols.len() { return Err(Error::ModuleError(format!( @@ -322,6 +325,7 @@ impl VTabCursor for CSVTabCursor { // TODO Affinity ctx.set_result(&self.cols[col as usize].to_owned()) } + fn rowid(&self) -> Result { Ok(self.row_number as i64) } diff --git a/src/vtab/mod.rs b/src/vtab/mod.rs index 529115e..63e2f44 100644 --- a/src/vtab/mod.rs +++ b/src/vtab/mod.rs @@ -278,12 +278,14 @@ impl IndexInfo { (*self.0).idxNum = idx_num; } } + /// True if output is already ordered pub fn set_order_by_consumed(&mut self, order_by_consumed: bool) { unsafe { (*self.0).orderByConsumed = if order_by_consumed { 1 } else { 0 }; } } + /// Estimated cost of using this index pub fn set_estimated_cost(&mut self, estimated_ost: f64) { unsafe { @@ -329,10 +331,12 @@ impl<'a> IndexConstraint<'a> { pub fn column(&self) -> c_int { self.0.iColumn } + /// Constraint operator pub fn operator(&self) -> IndexConstraintOp { IndexConstraintOp::from_bits_truncate(self.0.op) } + /// True if this constraint is usable pub fn is_usable(&self) -> bool { self.0.usable != 0 @@ -347,6 +351,7 @@ impl<'a> IndexConstraintUsage<'a> { pub fn set_argv_index(&mut self, argv_index: c_int) { self.0.argvIndex = argv_index; } + /// if `omit`, do not code a test for this constraint pub fn set_omit(&mut self, omit: bool) { self.0.omit = if omit { 1 } else { 0 }; @@ -377,6 +382,7 @@ impl<'a> OrderBy<'a> { pub fn column(&self) -> c_int { self.0.iColumn } + /// True for DESC. False for ASC. pub fn is_order_by_desc(&self) -> bool { self.0.desc != 0 @@ -483,8 +489,8 @@ impl<'a> Values<'a> { } impl<'a> IntoIterator for &'a Values<'a> { - type Item = ValueRef<'a>; type IntoIter = ValueIter<'a>; + type Item = ValueRef<'a>; fn into_iter(self) -> ValueIter<'a> { self.iter() diff --git a/src/vtab/series.rs b/src/vtab/series.rs index 0105dd5..25d6865 100644 --- a/src/vtab/series.rs +++ b/src/vtab/series.rs @@ -227,6 +227,7 @@ impl VTabCursor for SeriesTabCursor { self.row_id = 1; Ok(()) } + fn next(&mut self) -> Result<()> { if self.is_desc { self.value -= self.step; @@ -236,6 +237,7 @@ impl VTabCursor for SeriesTabCursor { self.row_id += 1; Ok(()) } + fn eof(&self) -> bool { if self.is_desc { self.value < self.min_value @@ -243,6 +245,7 @@ impl VTabCursor for SeriesTabCursor { self.value > self.max_value } } + fn column(&self, ctx: &mut Context, i: c_int) -> Result<()> { let x = match i { SERIES_COLUMN_START => self.min_value, @@ -252,6 +255,7 @@ impl VTabCursor for SeriesTabCursor { }; ctx.set_result(&x) } + fn rowid(&self) -> Result { Ok(self.row_id) } diff --git a/tests/config_log.rs b/tests/config_log.rs index cd9a25c..f4bdd5d 100644 --- a/tests/config_log.rs +++ b/tests/config_log.rs @@ -1,5 +1,6 @@ -//! This file contains unit tests for `rusqlite::trace::config_log`. This function affects -//! SQLite process-wide and so is not safe to run as a normal #[test] in the library. +//! This file contains unit tests for `rusqlite::trace::config_log`. This +//! function affects SQLite process-wide and so is not safe to run as a normal +//! #[test] in the library. #[cfg(feature = "trace")] #[macro_use] diff --git a/tests/vtab.rs b/tests/vtab.rs index 36463c8..99a16a6 100644 --- a/tests/vtab.rs +++ b/tests/vtab.rs @@ -65,16 +65,20 @@ fn test_dummy_module() { self.row_id = 1; Ok(()) } + fn next(&mut self) -> Result<()> { self.row_id += 1; Ok(()) } + fn eof(&self) -> bool { self.row_id > 1 } + fn column(&self, ctx: &mut Context, _: c_int) -> Result<()> { ctx.set_result(&self.row_id) } + fn rowid(&self) -> Result { Ok(self.row_id) }