mirror of
https://github.com/isar/rusqlite.git
synced 2025-08-20 21:09:31 +08:00
Merge remote-tracking branch 'jgallagher/master' into vtab
This commit is contained in:
@@ -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