mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 22:08:55 +08:00 
			
		
		
		
	Merge remote-tracking branch 'jgallagher/master' into vtab
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| [package] | ||||
| name = "rusqlite" | ||||
| version = "0.6.0" | ||||
| version = "0.7.2" | ||||
| authors = ["John Gallagher <jgallagher@bignerdranch.com>"] | ||||
| description = "Ergonomic wrapper for SQLite" | ||||
| repository = "https://github.com/jgallagher/rusqlite" | ||||
| @@ -37,7 +37,7 @@ regex = "~0.1.41" | ||||
|  | ||||
| [dependencies.libsqlite3-sys] | ||||
| path = "libsqlite3-sys" | ||||
| version = "0.4.0" | ||||
| version = "0.5.0" | ||||
|  | ||||
| [dependencies.csv] | ||||
| version = "~0.14.3" | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| # Version UPCOMING (...) | ||||
| # Version 0.7.2 (2016-05-19) | ||||
|  | ||||
| * BREAKING CHANGE: `Rows` no longer implements `Iterator`. It still has a `next()` method, but | ||||
|   the lifetime of the returned `Row` is now tied to the lifetime of the vending `Rows` object. | ||||
|   | ||||
| @@ -72,6 +72,12 @@ features](http://doc.crates.io/manifest.html#the-features-section). They are: | ||||
|   allows hooks into SQLite's tracing and profiling APIs. | ||||
| * [`blob`](http://jgallagher.github.io/rusqlite/rusqlite/blob/index.html) | ||||
|   gives `std::io::{Read, Write, Seek}` access to SQL BLOBs. | ||||
| * `chrono` implements [`FromSql`](http://jgallagher.github.io/rusqlite/rusqlite/types/trait.FromSql.html) | ||||
|   and [`ToSql`](http://jgallagher.github.io/rusqlite/rusqlite/types/trait.ToSql.html) for various | ||||
|   types from the [`chrono` crate](https://crates.io/crates/chrono). | ||||
| * `serde_json` implements [`FromSql`](http://jgallagher.github.io/rusqlite/rusqlite/types/trait.FromSql.html) | ||||
|   and [`ToSql`](http://jgallagher.github.io/rusqlite/rusqlite/types/trait.ToSql.html) for the | ||||
|   `Value` type from the [`serde_json` crate](https://crates.io/crates/serde_json). | ||||
|  | ||||
| ## Author | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								clippy.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								clippy.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| doc-valid-idents = ["SQLite", "lang_transaction"] | ||||
| @@ -1,6 +1,6 @@ | ||||
| [package] | ||||
| name = "libsqlite3-sys" | ||||
| version = "0.4.0" | ||||
| version = "0.5.0" | ||||
| authors = ["John Gallagher <jgallagher@bignerdranch.com>"] | ||||
| repository = "https://github.com/jgallagher/rusqlite" | ||||
| description = "Native bindings to the libsqlite3 library" | ||||
|   | ||||
| @@ -8,7 +8,7 @@ fi | ||||
|  | ||||
| cd $(git rev-parse --show-toplevel) | ||||
| rm -rf target/doc/ | ||||
| multirust run nightly cargo doc --no-deps --features "backup cache functions load_extension trace blob" | ||||
| rustup run nightly cargo doc --no-deps --features "backup blob chrono functions load_extension serde_json trace" | ||||
| echo '<meta http-equiv=refresh content=0;url=rusqlite/index.html>' > target/doc/index.html | ||||
| ghp-import target/doc | ||||
| git push origin gh-pages:gh-pages | ||||
|   | ||||
| @@ -235,7 +235,10 @@ 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)] | ||||
| pub struct ZeroBlob(pub i32); | ||||
|   | ||||
| @@ -34,7 +34,7 @@ impl Connection { | ||||
|     /// 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<CachedStatement<'a>> { | ||||
|         self.cache.get(&self, sql) | ||||
|         self.cache.get(self, sql) | ||||
|     } | ||||
|  | ||||
|     /// Set the maximum number of cached prepared statements this connection will hold. | ||||
| @@ -90,6 +90,8 @@ impl<'conn> CachedStatement<'conn> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Discard the statement, preventing it from being returned to its `Connection`'s collection | ||||
|     /// of cached statements. | ||||
|     pub fn discard(mut self) { | ||||
|         self.stmt = None; | ||||
|     } | ||||
|   | ||||
| @@ -170,8 +170,8 @@ impl error::Error for Error { | ||||
|             Error::InvalidColumnIndex(_) | | ||||
|             Error::InvalidColumnName(_) | | ||||
|             Error::InvalidColumnType(_, _) | | ||||
|             Error::InvalidPath(_) => None, | ||||
|             Error::StatementChangedRows(_) => None, | ||||
|             Error::InvalidPath(_) | | ||||
|             Error::StatementChangedRows(_) | | ||||
|             Error::StatementFailedToInsertRow => None, | ||||
|  | ||||
|             #[cfg(feature = "functions")] | ||||
|   | ||||
| @@ -111,7 +111,8 @@ impl<'a> ToResult for &'a str { | ||||
|                                          length as c_int, | ||||
|                                          ffi::SQLITE_TRANSIENT()) | ||||
|             } | ||||
|             Err(_) => ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_MISUSE), // TODO sqlite3_result_error | ||||
|             // TODO sqlite3_result_error | ||||
|             Err(_) => ffi::sqlite3_result_error_code(ctx, ffi::SQLITE_MISUSE), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -730,9 +731,10 @@ mod test { | ||||
|  | ||||
|         assert_eq!(true, result.unwrap()); | ||||
|  | ||||
|         let result: Result<i64> = db.query_row("SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1", | ||||
|                                   &[], | ||||
|                                   |r| r.get(0)); | ||||
|         let result: Result<i64> = | ||||
|             db.query_row("SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1", | ||||
|                          &[], | ||||
|                          |r| r.get(0)); | ||||
|  | ||||
|         assert_eq!(2, result.unwrap()); | ||||
|     } | ||||
| @@ -780,9 +782,10 @@ mod test { | ||||
|  | ||||
|         assert_eq!(true, result.unwrap()); | ||||
|  | ||||
|         let result: Result<i64> = db.query_row("SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1", | ||||
|                                   &[], | ||||
|                                   |r| r.get(0)); | ||||
|         let result: Result<i64> = | ||||
|             db.query_row("SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1", | ||||
|                          &[], | ||||
|                          |r| r.get(0)); | ||||
|  | ||||
|         assert_eq!(2, result.unwrap()); | ||||
|     } | ||||
|   | ||||
							
								
								
									
										29
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -80,7 +80,8 @@ use error::{error_from_sqlite_code, error_from_handle}; | ||||
| use raw_statement::RawStatement; | ||||
| use cache::StatementCache; | ||||
|  | ||||
| pub use transaction::{SqliteTransaction, Transaction, TransactionBehavior}; | ||||
| pub use transaction::{SqliteTransaction, SqliteTransactionBehavior, DropBehavior, Savepoint, | ||||
|                       Transaction, TransactionBehavior}; | ||||
| pub use error::{SqliteError, Error}; | ||||
| pub use cache::CachedStatement; | ||||
|  | ||||
| @@ -320,7 +321,9 @@ impl Connection { | ||||
|     /// ```rust,no_run | ||||
|     /// # use rusqlite::{Result,Connection}; | ||||
|     /// fn preferred_locale(conn: &Connection) -> Result<String> { | ||||
|     ///     conn.query_row_and_then("SELECT value FROM preferences WHERE name='locale'", &[], |row| { | ||||
|     ///     conn.query_row_and_then("SELECT value FROM preferences WHERE name='locale'", | ||||
|     ///                             &[], | ||||
|     ///                             |row| { | ||||
|     ///         row.get_checked(0) | ||||
|     ///     }) | ||||
|     /// } | ||||
| @@ -710,9 +713,12 @@ impl<'conn> Statement<'conn> { | ||||
|     } | ||||
|  | ||||
|     /// 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`. | ||||
|     pub fn column_index(&self, name: &str) -> Result<i32> { | ||||
|         let bytes = name.as_bytes(); | ||||
| @@ -966,9 +972,7 @@ pub struct Rows<'stmt> { | ||||
|  | ||||
| impl<'stmt> Rows<'stmt> { | ||||
|     fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> { | ||||
|         Rows { | ||||
|             stmt: Some(stmt), | ||||
|         } | ||||
|         Rows { stmt: Some(stmt) } | ||||
|     } | ||||
|  | ||||
|     fn get_expected_row<'a>(&'a mut self) -> Result<Row<'a, 'stmt>> { | ||||
| @@ -1372,19 +1376,6 @@ mod test { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     #[should_panic] | ||||
|     fn test_rows_dropped() { | ||||
|         let db = checked_memory_handle(); | ||||
|         db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap(); | ||||
|         db.execute_batch("INSERT INTO foo(x) VALUES(1)").unwrap(); | ||||
|  | ||||
|         let mut stmt = db.prepare("SELECT x FROM foo").unwrap(); | ||||
|         let row = stmt.query(&[]).unwrap().next().unwrap().unwrap(); | ||||
|  | ||||
|         assert_eq!(1i32, row.get(0)); | ||||
|     } | ||||
|  | ||||
|     mod query_and_then_tests { | ||||
|         extern crate libsqlite3_sys as ffi; | ||||
|         use super::*; | ||||
|   | ||||
| @@ -279,9 +279,10 @@ mod test { | ||||
|  | ||||
|         let mut stmt = db.prepare("SELECT id FROM test where name = :name").unwrap(); | ||||
|         let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| { | ||||
|             let id: i32 = row.get(0); | ||||
|             2 * id | ||||
|         }).unwrap(); | ||||
|                 let id: i32 = row.get(0); | ||||
|                 2 * id | ||||
|             }) | ||||
|             .unwrap(); | ||||
|  | ||||
|         let doubled_id: i32 = rows.next().unwrap().unwrap(); | ||||
|         assert_eq!(2, doubled_id); | ||||
| @@ -298,15 +299,17 @@ mod test { | ||||
|         "#; | ||||
|         db.execute_batch(sql).unwrap(); | ||||
|  | ||||
|         let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC").unwrap(); | ||||
|         let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC") | ||||
|             .unwrap(); | ||||
|         let mut rows = stmt.query_and_then_named(&[(":name", &"one")], |row| { | ||||
|             let id: i32 = row.get(0); | ||||
|             if id == 1 { | ||||
|                 Ok(id) | ||||
|             } else { | ||||
|                 Err(Error::SqliteSingleThreadedMode) | ||||
|             } | ||||
|         }).unwrap(); | ||||
|                 let id: i32 = row.get(0); | ||||
|                 if id == 1 { | ||||
|                     Ok(id) | ||||
|                 } else { | ||||
|                     Err(Error::SqliteSingleThreadedMode) | ||||
|                 } | ||||
|             }) | ||||
|             .unwrap(); | ||||
|  | ||||
|         // first row should be Ok | ||||
|         let doubled_id: i32 = rows.next().unwrap().unwrap(); | ||||
|   | ||||
| @@ -59,7 +59,8 @@ 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. | ||||
| @@ -83,7 +84,8 @@ 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. | ||||
|   | ||||
| @@ -209,7 +209,10 @@ impl<'conn> Drop for Transaction<'conn> { | ||||
| } | ||||
|  | ||||
| impl<'conn> Savepoint<'conn> { | ||||
|     fn with_depth_and_name<T: Into<String>>(conn: &Connection, depth: u32, name: T) -> Result<Savepoint> { | ||||
|     fn with_depth_and_name<T: Into<String>>(conn: &Connection, | ||||
|                                             depth: u32, | ||||
|                                             name: T) | ||||
|                                             -> Result<Savepoint> { | ||||
|         let name = name.into(); | ||||
|         conn.execute_batch(&format!("SAVEPOINT {}", name)).map(|_| { | ||||
|             Savepoint { | ||||
| @@ -349,7 +352,9 @@ impl Connection { | ||||
|     /// # Failure | ||||
|     /// | ||||
|     /// Will return `Err` if the underlying SQLite call fails. | ||||
|     pub fn transaction_with_behavior(&mut self, behavior: TransactionBehavior) -> Result<Transaction> { | ||||
|     pub fn transaction_with_behavior(&mut self, | ||||
|                                      behavior: TransactionBehavior) | ||||
|                                      -> Result<Transaction> { | ||||
|         Transaction::new(self, behavior) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -228,7 +228,7 @@ impl From<csv::Error> for Error { | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use Connection; | ||||
|     use {Connection,Result}; | ||||
|     use vtab::csvtab; | ||||
|  | ||||
|     #[test] | ||||
| @@ -244,13 +244,8 @@ mod test { | ||||
|                 assert_eq!(vec!["rowid", "colA", "colB", "colC"], headers); | ||||
|             } | ||||
|  | ||||
|             let rows = s.query(&[]).unwrap(); | ||||
|             let mut sum = 0; | ||||
|             for row in rows { | ||||
|                 let row = row.unwrap(); | ||||
|                 let id: i64 = row.get(0); | ||||
|                 sum = sum + id; | ||||
|             } | ||||
|             let ids: Result<Vec<i32>> = s.query_map(&[], |row| row.get::<i32, i32>(0)).unwrap().collect(); | ||||
|             let sum = ids.unwrap().iter().fold(0, |acc, &id| acc + id); | ||||
|             assert_eq!(sum, 15); | ||||
|         } | ||||
|         db.execute_batch("DROP TABLE vtab").unwrap(); | ||||
|   | ||||
| @@ -163,14 +163,12 @@ mod test { | ||||
|         p3.borrow_mut().append(&mut vec![-1, -5, -10]); | ||||
|  | ||||
|         { | ||||
|             let rows = s.query(&[]).unwrap(); | ||||
|             for row in rows { | ||||
|                 let row = row.unwrap(); | ||||
|             s.query_map(&[], |row| { | ||||
|                 let i1: i64 = row.get(0); | ||||
|                 assert!(i1 == 1 || i1 == 3); | ||||
|                 assert_eq!(11, row.get(1)); | ||||
|                 assert_eq!(-5, row.get(2)); | ||||
|             } | ||||
|             }).unwrap(); | ||||
|         } | ||||
|  | ||||
|         p1.borrow_mut().clear(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user