Run rustfmt on all crate files

This commit is contained in:
John Gallagher 2015-12-10 16:48:09 -05:00
parent 26a7930d73
commit a1f1480b18
5 changed files with 488 additions and 317 deletions

View File

@ -52,8 +52,11 @@
//! ```
extern crate libc;
extern crate libsqlite3_sys as ffi;
#[macro_use] extern crate bitflags;
#[cfg(test)] #[macro_use] extern crate lazy_static;
#[macro_use]
extern crate bitflags;
#[cfg(test)]
#[macro_use]
extern crate lazy_static;
use std::default::Default;
use std::convert;
@ -62,7 +65,7 @@ use std::ptr;
use std::fmt;
use std::path::{Path, PathBuf};
use std::error;
use std::rc::{Rc};
use std::rc::Rc;
use std::cell::{RefCell, Cell};
use std::ffi::{CStr, CString};
use std::str;
@ -70,13 +73,12 @@ use libc::{c_int, c_void, c_char};
use types::{ToSql, FromSql};
pub use transaction::{SqliteTransaction};
pub use transaction::{SqliteTransactionBehavior,
SqliteTransactionDeferred,
SqliteTransactionImmediate,
SqliteTransactionExclusive};
pub use transaction::SqliteTransaction;
pub use transaction::{SqliteTransactionBehavior, SqliteTransactionDeferred,
SqliteTransactionImmediate, SqliteTransactionExclusive};
#[cfg(feature = "load_extension")] pub use load_extension_guard::{SqliteLoadExtensionGuard};
#[cfg(feature = "load_extension")]
pub use load_extension_guard::SqliteLoadExtensionGuard;
pub mod types;
mod transaction;
@ -124,21 +126,27 @@ impl SqliteError {
} else {
unsafe { errmsg_to_string(ffi::sqlite3_errmsg(db)) }
};
SqliteError{ code: code, message: message }
SqliteError {
code: code,
message: message,
}
}
}
fn str_to_cstring(s: &str) -> SqliteResult<CString> {
CString::new(s).map_err(|_| SqliteError{
CString::new(s).map_err(|_| {
SqliteError {
code: ffi::SQLITE_MISUSE,
message: format!("Could not convert string {} to C-combatible string", s),
}
})
}
fn path_to_cstring(p: &Path) -> SqliteResult<CString> {
let s = try!(p.to_str().ok_or(SqliteError {
code: ffi::SQLITE_MISUSE,
message: format!("Could not convert path {} to UTF-8 string", p.to_string_lossy()),
message: format!("Could not convert path {} to UTF-8 string",
p.to_string_lossy()),
}));
str_to_cstring(s)
}
@ -211,11 +219,15 @@ impl SqliteConnection {
///
/// 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<P: AsRef<Path>>(path: P, flags: SqliteOpenFlags)
pub fn open_with_flags<P: AsRef<Path>>(path: P,
flags: SqliteOpenFlags)
-> SqliteResult<SqliteConnection> {
let c_path = try!(path_to_cstring(path.as_ref()));
InnerSqliteConnection::open_with_flags(&c_path, flags).map(|db| {
SqliteConnection{ db: RefCell::new(db), path: Some(path.as_ref().to_path_buf()) }
SqliteConnection {
db: RefCell::new(db),
path: Some(path.as_ref().to_path_buf()),
}
})
}
@ -230,7 +242,10 @@ impl SqliteConnection {
pub fn open_in_memory_with_flags(flags: SqliteOpenFlags) -> SqliteResult<SqliteConnection> {
let c_memory = try!(str_to_cstring(":memory:"));
InnerSqliteConnection::open_with_flags(&c_memory, flags).map(|db| {
SqliteConnection{ db: RefCell::new(db), path: None }
SqliteConnection {
db: RefCell::new(db),
path: None,
}
})
}
@ -269,7 +284,8 @@ impl SqliteConnection {
/// # Failure
///
/// Will return `Err` if the underlying SQLite call fails.
pub fn transaction_with_behavior<'a>(&'a self, behavior: SqliteTransactionBehavior)
pub fn transaction_with_behavior<'a>(&'a self,
behavior: SqliteTransactionBehavior)
-> SqliteResult<SqliteTransaction<'a>> {
SqliteTransaction::new(self, behavior)
}
@ -351,18 +367,21 @@ impl SqliteConnection {
/// Will return `Err` if `sql` cannot be converted to a C-compatible string or if the
/// underlying SQLite call fails.
pub fn query_row<T, F>(&self, sql: &str, params: &[&ToSql], f: F) -> SqliteResult<T>
where F: FnOnce(SqliteRow) -> T {
where F: FnOnce(SqliteRow) -> T
{
let mut stmt = try!(self.prepare(sql));
let mut rows = try!(stmt.query(params));
match rows.next() {
Some(row) => row.map(f),
None => Err(SqliteError{
None => {
Err(SqliteError {
code: ffi::SQLITE_NOTICE,
message: "Query did not return a row".to_string(),
})
}
}
}
/// 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.
@ -387,18 +406,21 @@ impl SqliteConnection {
/// underlying SQLite call fails.
pub fn query_row_and_then<T, E, F>(&self, sql: &str, params: &[&ToSql], f: F) -> Result<T, E>
where F: FnOnce(SqliteRow) -> Result<T, E>,
E: convert::From<SqliteError> {
E: convert::From<SqliteError>
{
let mut stmt = try!(self.prepare(sql));
let mut rows = try!(stmt.query(params));
match rows.next() {
Some(row) => row.map_err(E::from).and_then(f),
None => Err(E::from(SqliteError{
None => {
Err(E::from(SqliteError {
code: ffi::SQLITE_NOTICE,
message: "Query did not return a row".to_string(),
}))
}
}
}
/// Convenience method to execute a query that is expected to return a single row.
///
@ -420,7 +442,8 @@ impl SqliteConnection {
/// This method should be considered deprecated. Use `query_row` instead, which now
/// does exactly the same thing.
pub fn query_row_safe<T, F>(&self, sql: &str, params: &[&ToSql], f: F) -> SqliteResult<T>
where F: FnOnce(SqliteRow) -> T {
where F: FnOnce(SqliteRow) -> T
{
self.query_row(sql, params, f)
}
@ -517,7 +540,10 @@ impl SqliteConnection {
///
/// Will return `Err` if the underlying SQLite call fails.
#[cfg(feature = "load_extension")]
pub fn load_extension<P: AsRef<Path>>(&self, dylib_path: P, entry_point: Option<&str>) -> SqliteResult<()> {
pub fn load_extension<P: AsRef<Path>>(&self,
dylib_path: P,
entry_point: Option<&str>)
-> SqliteResult<()> {
self.db.borrow_mut().load_extension(dylib_path.as_ref(), entry_point)
}
@ -561,23 +587,23 @@ bitflags! {
impl Default for SqliteOpenFlags {
fn default() -> SqliteOpenFlags {
SQLITE_OPEN_READ_WRITE
| SQLITE_OPEN_CREATE
| SQLITE_OPEN_NO_MUTEX
| SQLITE_OPEN_URI
SQLITE_OPEN_READ_WRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NO_MUTEX | SQLITE_OPEN_URI
}
}
impl InnerSqliteConnection {
fn open_with_flags(c_path: &CString, flags: SqliteOpenFlags)
fn open_with_flags(c_path: &CString,
flags: SqliteOpenFlags)
-> SqliteResult<InnerSqliteConnection> {
unsafe {
let mut db: *mut ffi::sqlite3 = mem::uninitialized();
let r = ffi::sqlite3_open_v2(c_path.as_ptr(), &mut db, flags.bits(), ptr::null());
if r != ffi::SQLITE_OK {
let e = if db.is_null() {
SqliteError{ code: r,
message: ffi::code_to_str(r).to_string() }
SqliteError {
code: r,
message: ffi::code_to_str(r).to_string(),
}
} else {
let e = SqliteError::from_handle(db, r);
ffi::sqlite3_close(db);
@ -608,13 +634,19 @@ impl InnerSqliteConnection {
}
}
unsafe fn decode_result_with_errmsg(&self, code: c_int, errmsg: *mut c_char) -> SqliteResult<()> {
unsafe fn decode_result_with_errmsg(&self,
code: c_int,
errmsg: *mut c_char)
-> SqliteResult<()> {
if code == ffi::SQLITE_OK {
Ok(())
} else {
let message = errmsg_to_string(&*errmsg);
ffi::sqlite3_free(errmsg as *mut c_void);
Err(SqliteError{ code: code, message: message })
Err(SqliteError {
code: code,
message: message,
})
}
}
@ -630,7 +662,11 @@ impl InnerSqliteConnection {
let c_sql = try!(str_to_cstring(sql));
unsafe {
let mut errmsg: *mut c_char = mem::uninitialized();
let r = ffi::sqlite3_exec(self.db(), c_sql.as_ptr(), None, ptr::null_mut(), &mut errmsg);
let r = ffi::sqlite3_exec(self.db(),
c_sql.as_ptr(),
None,
ptr::null_mut(),
&mut errmsg);
self.decode_result_with_errmsg(r, errmsg)
}
}
@ -648,7 +684,10 @@ impl InnerSqliteConnection {
let mut errmsg: *mut c_char = mem::uninitialized();
let r = if let Some(entry_point) = entry_point {
let c_entry = try!(str_to_cstring(entry_point));
ffi::sqlite3_load_extension(self.db, dylib_str.as_ptr(), c_entry.as_ptr(), &mut errmsg)
ffi::sqlite3_load_extension(self.db,
dylib_str.as_ptr(),
c_entry.as_ptr(),
&mut errmsg)
} else {
ffi::sqlite3_load_extension(self.db, dylib_str.as_ptr(), ptr::null(), &mut errmsg)
};
@ -657,30 +696,30 @@ impl InnerSqliteConnection {
}
fn last_insert_rowid(&self) -> i64 {
unsafe {
ffi::sqlite3_last_insert_rowid(self.db())
}
unsafe { ffi::sqlite3_last_insert_rowid(self.db()) }
}
fn prepare<'a>(&mut self,
conn: &'a SqliteConnection,
sql: &str) -> SqliteResult<SqliteStatement<'a>> {
sql: &str)
-> SqliteResult<SqliteStatement<'a>> {
if sql.len() >= ::std::i32::MAX as usize {
return Err(SqliteError {
code: ffi::SQLITE_TOOBIG,
message: "statement too long".to_string()
message: "statement too long".to_string(),
});
}
let mut c_stmt: *mut ffi::sqlite3_stmt = unsafe { mem::uninitialized() };
let c_sql = try!(str_to_cstring(sql));
let r = unsafe {
let len_with_nul = (sql.len() + 1) as c_int;
ffi::sqlite3_prepare_v2(self.db(), c_sql.as_ptr(), len_with_nul, &mut c_stmt,
ffi::sqlite3_prepare_v2(self.db(),
c_sql.as_ptr(),
len_with_nul,
&mut c_stmt,
ptr::null_mut())
};
self.decode_result(r).map(|_| {
SqliteStatement::new(conn, c_stmt)
})
self.decode_result(r).map(|_| SqliteStatement::new(conn, c_stmt))
}
fn changes(&mut self) -> c_int {
@ -705,8 +744,12 @@ pub struct SqliteStatement<'conn> {
impl<'conn> SqliteStatement<'conn> {
fn new(conn: &SqliteConnection, stmt: *mut ffi::sqlite3_stmt) -> SqliteStatement {
SqliteStatement{ conn: conn, stmt: stmt, needs_reset: false,
column_count: unsafe { ffi::sqlite3_column_count(stmt) }}
SqliteStatement {
conn: conn,
stmt: stmt,
needs_reset: false,
column_count: unsafe { ffi::sqlite3_column_count(stmt) },
}
}
/// Get all the column names in the result set of the prepared statement.
@ -714,9 +757,7 @@ impl<'conn> SqliteStatement<'conn> {
let n = self.column_count;
let mut cols = Vec::with_capacity(n as usize);
for i in 0..n {
let slice = unsafe {
CStr::from_ptr(ffi::sqlite3_column_name(self.stmt, i))
};
let slice = unsafe { CStr::from_ptr(ffi::sqlite3_column_name(self.stmt, i)) };
let s = str::from_utf8(slice.to_bytes()).unwrap();
cols.push(s);
}
@ -755,14 +796,21 @@ impl<'conn> SqliteStatement<'conn> {
match r {
ffi::SQLITE_DONE => {
if self.column_count != 0 {
Err(SqliteError{ code: ffi::SQLITE_MISUSE,
message: "Unexpected column count - did you mean to call query?".to_string() })
Err(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Unexpected column count - did you mean to call query?"
.to_string(),
})
} else {
Ok(self.conn.changes())
}
},
ffi::SQLITE_ROW => Err(SqliteError{ code: r,
message: "Unexpected row result - did you mean to call query?".to_string() }),
}
ffi::SQLITE_ROW => {
Err(SqliteError {
code: r,
message: "Unexpected row result - did you mean to call query?".to_string(),
})
}
_ => Err(self.conn.decode_result(r).unwrap_err()),
}
}
@ -811,9 +859,12 @@ impl<'conn> SqliteStatement<'conn> {
/// # Failure
///
/// Will return `Err` if binding parameters fails.
pub fn query_map<'a, T, F>(&'a mut self, params: &[&ToSql], f: F)
pub fn query_map<'a, T, F>(&'a mut self,
params: &[&ToSql],
f: F)
-> SqliteResult<MappedRows<'a, F>>
where F: FnMut(&SqliteRow) -> T {
where F: FnMut(&SqliteRow) -> T
{
let row_iter = try!(self.query(params));
Ok(MappedRows {
@ -832,10 +883,13 @@ impl<'conn> SqliteStatement<'conn> {
/// # Failure
///
/// Will return `Err` if binding parameters fails.
pub fn query_and_then<'a, T, E, F>(&'a mut self, params: &[&ToSql], f: F)
pub fn query_and_then<'a, T, E, F>(&'a mut self,
params: &[&ToSql],
f: F)
-> SqliteResult<AndThenRows<'a, F>>
where E: convert::From<SqliteError>,
F: FnMut(&SqliteRow) -> Result<T, E> {
F: FnMut(&SqliteRow) -> Result<T, E>
{
let row_iter = try!(self.query(params));
Ok(AndThenRows {
@ -871,7 +925,9 @@ impl<'conn> SqliteStatement<'conn> {
fn reset_if_needed(&mut self) {
if self.needs_reset {
unsafe { ffi::sqlite3_reset(self.stmt); };
unsafe {
ffi::sqlite3_reset(self.stmt);
};
self.needs_reset = false;
}
}
@ -910,8 +966,8 @@ pub struct MappedRows<'stmt, F> {
map: F,
}
impl<'stmt, T, F> Iterator for MappedRows<'stmt, F>
where F: FnMut(&SqliteRow) -> T {
impl<'stmt, T, F> Iterator for MappedRows<'stmt, F> where F: FnMut(&SqliteRow) -> T
{
type Item = SqliteResult<T>;
fn next(&mut self) -> Option<SqliteResult<T>> {
@ -928,13 +984,15 @@ pub struct AndThenRows<'stmt, F> {
impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
where E: convert::From<SqliteError>,
F: FnMut(&SqliteRow) -> Result<T, E> {
F: FnMut(&SqliteRow) -> Result<T, E>
{
type Item = Result<T, E>;
fn next(&mut self) -> Option<Self::Item> {
self.rows.next().map(|row_result| row_result
.map_err(E::from)
.and_then(|row| (self.map)(&row)))
self.rows.next().map(|row_result| {
row_result.map_err(E::from)
.and_then(|row| (self.map)(&row))
})
}
}
@ -981,7 +1039,11 @@ pub struct SqliteRows<'stmt> {
impl<'stmt> SqliteRows<'stmt> {
fn new(stmt: &'stmt SqliteStatement<'stmt>) -> SqliteRows<'stmt> {
SqliteRows{ stmt: stmt, current_row: Rc::new(Cell::new(0)), failed: false }
SqliteRows {
stmt: stmt,
current_row: Rc::new(Cell::new(0)),
failed: false,
}
}
}
@ -1001,7 +1063,7 @@ impl<'stmt> Iterator for SqliteRows<'stmt> {
current_row: self.current_row.clone(),
row_idx: current_row,
}))
},
}
ffi::SQLITE_DONE => None,
code => {
self.failed = true;
@ -1062,13 +1124,17 @@ impl<'stmt> SqliteRow<'stmt> {
/// for this row or if this row is stale.
pub fn get_checked<T: FromSql>(&self, idx: c_int) -> SqliteResult<T> {
if self.row_idx != self.current_row.get() {
return Err(SqliteError{ code: ffi::SQLITE_MISUSE,
message: "Cannot get values from a row after advancing to next row".to_string() });
return Err(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Cannot get values from a row after advancing to next row".to_string(),
});
}
unsafe {
if idx < 0 || idx >= self.stmt.column_count {
return Err(SqliteError{ code: ffi::SQLITE_MISUSE,
message: "Invalid column index".to_string() });
return Err(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Invalid column index".to_string(),
});
}
if T::column_has_valid_sqlite_type(self.stmt.stmt, idx) {
@ -1105,6 +1171,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_persistence() {
let temp_dir = TempDir::new("test_open_file").unwrap();
let path = temp_dir.path().join("test.db3");
@ -1120,9 +1187,7 @@ mod test {
let path_string = path.to_str().unwrap();
let db = SqliteConnection::open(&path_string).unwrap();
let the_answer = db.query_row("SELECT x FROM foo",
&[],
|r| r.get::<i64>(0));
let the_answer = db.query_row("SELECT x FROM foo", &[], |r| r.get::<i64>(0));
assert_eq!(42i64, the_answer.unwrap());
}
@ -1137,16 +1202,16 @@ mod test {
#[test]
fn test_open_with_flags() {
for bad_flags in [
SqliteOpenFlags::empty(),
for bad_flags in [SqliteOpenFlags::empty(),
SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_READ_WRITE,
SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_CREATE,
].iter() {
SQLITE_OPEN_READ_ONLY | SQLITE_OPEN_CREATE]
.iter() {
assert!(SqliteConnection::open_in_memory_with_flags(*bad_flags).is_err());
}
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_execute_batch() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1168,10 +1233,13 @@ mod test {
let db = checked_memory_handle();
db.execute_batch("CREATE TABLE foo(x INTEGER)").unwrap();
assert_eq!(db.execute("INSERT INTO foo(x) VALUES (?)", &[&1i32]).unwrap(), 1);
assert_eq!(db.execute("INSERT INTO foo(x) VALUES (?)", &[&2i32]).unwrap(), 1);
assert_eq!(db.execute("INSERT INTO foo(x) VALUES (?)", &[&1i32]).unwrap(),
1);
assert_eq!(db.execute("INSERT INTO foo(x) VALUES (?)", &[&2i32]).unwrap(),
1);
assert_eq!(3i32, db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
assert_eq!(3i32,
db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
}
#[test]
@ -1240,6 +1308,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_map() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1252,8 +1321,7 @@ mod test {
db.execute_batch(sql).unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let results: SqliteResult<Vec<String>> = query
.query_map(&[], |row| row.get(1))
let results: SqliteResult<Vec<String>> = query.query_map(&[], |row| row.get(1))
.unwrap()
.collect();
@ -1261,6 +1329,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_row() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1272,9 +1341,9 @@ mod test {
END;";
db.execute_batch(sql).unwrap();
assert_eq!(10i64, db.query_row("SELECT SUM(x) FROM foo", &[], |r| {
r.get::<i64>(0)
}).unwrap());
assert_eq!(10i64,
db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get::<i64>(0))
.unwrap());
let result = db.query_row("SELECT x FROM foo WHERE x > 5", &[], |r| r.get::<i64>(0));
let error = result.unwrap_err();
@ -1358,7 +1427,9 @@ mod test {
}
impl StdError for CustomError {
fn description(&self) -> &str { "my custom error" }
fn description(&self) -> &str {
"my custom error"
}
fn cause(&self) -> Option<&StdError> {
match *self {
CustomError::SomeError => None,
@ -1376,6 +1447,7 @@ mod test {
type CustomResult<T> = Result<T, CustomError>;
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_and_then() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1388,8 +1460,8 @@ mod test {
db.execute_batch(sql).unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let results: SqliteResult<Vec<String>> = query
.query_and_then(&[], |row| row.get_checked(1))
let results: SqliteResult<Vec<String>> = query.query_and_then(&[],
|row| row.get_checked(1))
.unwrap()
.collect();
@ -1397,6 +1469,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_and_then_fails() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1409,28 +1482,31 @@ mod test {
db.execute_batch(sql).unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let bad_type: SqliteResult<Vec<f64>> = query
.query_and_then(&[], |row| row.get_checked(1))
let bad_type: SqliteResult<Vec<f64>> = query.query_and_then(&[],
|row| row.get_checked(1))
.unwrap()
.collect();
assert_eq!(bad_type, Err(SqliteError{
assert_eq!(bad_type,
Err(SqliteError {
code: ffi::SQLITE_MISMATCH,
message: "Invalid column type".to_owned(),
}));
let bad_idx: SqliteResult<Vec<String>> = query
.query_and_then(&[], |row| row.get_checked(3))
let bad_idx: SqliteResult<Vec<String>> = query.query_and_then(&[],
|row| row.get_checked(3))
.unwrap()
.collect();
assert_eq!(bad_idx, Err(SqliteError{
assert_eq!(bad_idx,
Err(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Invalid column index".to_owned(),
}));
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_and_then_custom_error() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1443,8 +1519,10 @@ mod test {
db.execute_batch(sql).unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let results: CustomResult<Vec<String>> = query
.query_and_then(&[], |row| row.get_checked(1).map_err(CustomError::Sqlite))
let results: CustomResult<Vec<String>> = query.query_and_then(&[], |row| {
row.get_checked(1)
.map_err(CustomError::Sqlite)
})
.unwrap()
.collect();
@ -1452,6 +1530,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_and_then_custom_error_fails() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1464,28 +1543,35 @@ mod test {
db.execute_batch(sql).unwrap();
let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC").unwrap();
let bad_type: CustomResult<Vec<f64>> = query
.query_and_then(&[], |row| row.get_checked(1).map_err(CustomError::Sqlite))
let bad_type: CustomResult<Vec<f64>> = query.query_and_then(&[], |row| {
row.get_checked(1)
.map_err(CustomError::Sqlite)
})
.unwrap()
.collect();
assert_eq!(bad_type, Err(CustomError::Sqlite(SqliteError{
assert_eq!(bad_type,
Err(CustomError::Sqlite(SqliteError {
code: ffi::SQLITE_MISMATCH,
message: "Invalid column type".to_owned(),
})));
let bad_idx: CustomResult<Vec<String>> = query
.query_and_then(&[], |row| row.get_checked(3).map_err(CustomError::Sqlite))
let bad_idx: CustomResult<Vec<String>> = query.query_and_then(&[], |row| {
row.get_checked(3)
.map_err(CustomError::Sqlite)
})
.unwrap()
.collect();
assert_eq!(bad_idx, Err(CustomError::Sqlite(SqliteError{
assert_eq!(bad_idx,
Err(CustomError::Sqlite(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Invalid column index".to_owned(),
})));
let non_sqlite_err: CustomResult<Vec<String>> = query
.query_and_then(&[], |_| Err(CustomError::SomeError))
let non_sqlite_err: CustomResult<Vec<String>> = query.query_and_then(&[], |_| {
Err(CustomError::SomeError)
})
.unwrap()
.collect();
@ -1493,6 +1579,7 @@ mod test {
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_row_and_then_custom_error() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1502,13 +1589,15 @@ mod test {
db.execute_batch(sql).unwrap();
let query = "SELECT x, y FROM foo ORDER BY x DESC";
let results: CustomResult<String> = db
.query_row_and_then(query, &[], |row| row.get_checked(1).map_err(CustomError::Sqlite));
let results: CustomResult<String> = db.query_row_and_then(query, &[], |row| {
row.get_checked(1).map_err(CustomError::Sqlite)
});
assert_eq!(results.unwrap(), "hello");
}
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_query_row_and_then_custom_error_fails() {
let db = checked_memory_handle();
let sql = "BEGIN;
@ -1518,24 +1607,29 @@ mod test {
db.execute_batch(sql).unwrap();
let query = "SELECT x, y FROM foo ORDER BY x DESC";
let bad_type: CustomResult<f64> = db
.query_row_and_then(query, &[], |row| row.get_checked(1).map_err(CustomError::Sqlite));
let bad_type: CustomResult<f64> = db.query_row_and_then(query, &[], |row| {
row.get_checked(1).map_err(CustomError::Sqlite)
});
assert_eq!(bad_type, Err(CustomError::Sqlite(SqliteError{
assert_eq!(bad_type,
Err(CustomError::Sqlite(SqliteError {
code: ffi::SQLITE_MISMATCH,
message: "Invalid column type".to_owned(),
})));
let bad_idx: CustomResult<String> = db
.query_row_and_then(query, &[], |row| row.get_checked(3).map_err(CustomError::Sqlite));
let bad_idx: CustomResult<String> = db.query_row_and_then(query, &[], |row| {
row.get_checked(3).map_err(CustomError::Sqlite)
});
assert_eq!(bad_idx, Err(CustomError::Sqlite(SqliteError{
assert_eq!(bad_idx,
Err(CustomError::Sqlite(SqliteError {
code: ffi::SQLITE_MISUSE,
message: "Invalid column index".to_owned(),
})));
let non_sqlite_err: CustomResult<String> = db
.query_row_and_then(query, &[], |_| Err(CustomError::SomeError));
let non_sqlite_err: CustomResult<String> = db.query_row_and_then(query, &[], |_| {
Err(CustomError::SomeError)
});
assert_eq!(non_sqlite_err, Err(CustomError::SomeError));
}

View File

@ -35,7 +35,7 @@ pub unsafe fn config_log(callback: Option<fn(c_int, &str)>) -> SqliteResult<()>
Some(f) => {
let p_arg: *mut c_void = mem::transmute(f);
ffi::sqlite3_config(ffi::SQLITE_CONFIG_LOG, Some(log_callback), p_arg)
},
}
None => {
let nullptr: *mut c_void = ptr::null_mut();
ffi::sqlite3_config(ffi::SQLITE_CONFIG_LOG, nullptr, nullptr)
@ -43,7 +43,10 @@ pub unsafe fn config_log(callback: Option<fn(c_int, &str)>) -> SqliteResult<()>
};
if rc != ffi::SQLITE_OK {
return Err(SqliteError{ code: rc, message: "sqlite3_config(SQLITE_CONFIG_LOG, ...)".to_string() });
return Err(SqliteError {
code: rc,
message: "sqlite3_config(SQLITE_CONFIG_LOG, ...)".to_string(),
});
}
Ok(())
@ -74,8 +77,12 @@ impl SqliteConnection {
let c = self.db.borrow_mut();
match trace_fn {
Some(f) => unsafe { ffi::sqlite3_trace(c.db(), Some(trace_callback), mem::transmute(f)); },
None => unsafe { ffi::sqlite3_trace(c.db(), None, ptr::null_mut()); },
Some(f) => unsafe {
ffi::sqlite3_trace(c.db(), Some(trace_callback), mem::transmute(f));
},
None => unsafe {
ffi::sqlite3_trace(c.db(), None, ptr::null_mut());
},
}
}
@ -84,7 +91,9 @@ impl SqliteConnection {
/// 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<fn(&str, Duration)>) {
extern "C" fn profile_callback(p_arg: *mut c_void, z_sql: *const c_char, nanoseconds: u64) {
extern "C" fn profile_callback(p_arg: *mut c_void,
z_sql: *const c_char,
nanoseconds: u64) {
let profile_fn: fn(&str, Duration) = unsafe { mem::transmute(p_arg) };
let c_slice = unsafe { CStr::from_ptr(z_sql).to_bytes() };
if let Ok(s) = str::from_utf8(c_slice) {
@ -98,7 +107,9 @@ impl SqliteConnection {
let c = self.db.borrow_mut();
match profile_fn {
Some(f) => unsafe { ffi::sqlite3_profile(c.db(), Some(profile_callback), mem::transmute(f)) },
Some(f) => unsafe {
ffi::sqlite3_profile(c.db(), Some(profile_callback), mem::transmute(f))
},
None => unsafe { ffi::sqlite3_profile(c.db(), None, ptr::null_mut()) },
};
}

View File

@ -1,8 +1,6 @@
use {SqliteResult, SqliteConnection};
pub use SqliteTransactionBehavior::{
SqliteTransactionDeferred,
SqliteTransactionImmediate,
pub use SqliteTransactionBehavior::{SqliteTransactionDeferred, SqliteTransactionImmediate,
SqliteTransactionExclusive};
/// Options for transaction behavior. See [BEGIN
@ -46,14 +44,20 @@ pub struct SqliteTransaction<'conn> {
impl<'conn> SqliteTransaction<'conn> {
/// Begin a new transaction. Cannot be nested; see `savepoint` for nested transactions.
pub fn new(conn: &SqliteConnection,
behavior: SqliteTransactionBehavior) -> SqliteResult<SqliteTransaction> {
behavior: SqliteTransactionBehavior)
-> SqliteResult<SqliteTransaction> {
let query = match behavior {
SqliteTransactionDeferred => "BEGIN DEFERRED",
SqliteTransactionImmediate => "BEGIN IMMEDIATE",
SqliteTransactionExclusive => "BEGIN EXCLUSIVE",
};
conn.execute_batch(query).map(|_| {
SqliteTransaction{ conn: conn, depth: 0, commit: false, finished: false }
SqliteTransaction {
conn: conn,
depth: 0,
commit: false,
finished: false,
}
})
}
@ -86,7 +90,10 @@ impl<'conn> SqliteTransaction<'conn> {
pub fn savepoint<'a>(&'a self) -> SqliteResult<SqliteTransaction<'a>> {
self.conn.execute_batch("SAVEPOINT sp").map(|_| {
SqliteTransaction {
conn: self.conn, depth: self.depth + 1, commit: false, finished: false
conn: self.conn,
depth: self.depth + 1,
commit: false,
finished: false,
}
})
}
@ -118,7 +125,11 @@ impl<'conn> SqliteTransaction<'conn> {
fn commit_(&mut self) -> SqliteResult<()> {
self.finished = true;
self.conn.execute_batch(if self.depth == 0 { "COMMIT" } else { "RELEASE sp" })
self.conn.execute_batch(if self.depth == 0 {
"COMMIT"
} else {
"RELEASE sp"
})
}
/// A convenience method which consumes and rolls back a transaction.
@ -128,7 +139,11 @@ impl<'conn> SqliteTransaction<'conn> {
fn rollback_(&mut self) -> SqliteResult<()> {
self.finished = true;
self.conn.execute_batch(if self.depth == 0 { "ROLLBACK" } else { "ROLLBACK TO sp" })
self.conn.execute_batch(if self.depth == 0 {
"ROLLBACK"
} else {
"ROLLBACK TO sp"
})
}
/// Consumes the transaction, committing or rolling back according to the current setting
@ -181,7 +196,8 @@ mod test {
}
{
let _tx = db.transaction().unwrap();
assert_eq!(2i32, db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
assert_eq!(2i32,
db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
}
}
@ -200,7 +216,8 @@ mod test {
}
{
let _tx = db.transaction().unwrap();
assert_eq!(2i32, db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
assert_eq!(2i32,
db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
}
}
@ -228,6 +245,7 @@ mod test {
}
}
}
assert_eq!(3i32, db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
assert_eq!(3i32,
db.query_row("SELECT SUM(x) FROM foo", &[], |r| r.get(0)).unwrap());
}
}

View File

@ -55,14 +55,14 @@
extern crate time;
use libc::{c_int, c_double, c_char};
use std::ffi::{CStr};
use std::ffi::CStr;
use std::mem;
use std::str;
use super::ffi;
use super::{SqliteResult, SqliteError, str_to_cstring};
pub use ffi::sqlite3_stmt as sqlite3_stmt;
pub use ffi::sqlite3_column_type as sqlite3_column_type;
pub use ffi::sqlite3_stmt;
pub use ffi::sqlite3_column_type;
pub use ffi::{SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, SQLITE_NULL};
@ -107,8 +107,13 @@ impl<'a> ToSql for &'a str {
return ffi::SQLITE_TOOBIG;
}
match str_to_cstring(self) {
Ok(c_str) => ffi::sqlite3_bind_text(stmt, col, c_str.as_ptr(), length as c_int,
ffi::SQLITE_TRANSIENT()),
Ok(c_str) => {
ffi::sqlite3_bind_text(stmt,
col,
c_str.as_ptr(),
length as c_int,
ffi::SQLITE_TRANSIENT())
}
Err(_) => ffi::SQLITE_MISUSE,
}
}
@ -125,8 +130,11 @@ impl<'a> ToSql for &'a [u8] {
if self.len() > ::std::i32::MAX as usize {
return ffi::SQLITE_TOOBIG;
}
ffi::sqlite3_bind_blob(
stmt, col, mem::transmute(self.as_ptr()), self.len() as c_int, ffi::SQLITE_TRANSIENT())
ffi::sqlite3_bind_blob(stmt,
col,
mem::transmute(self.as_ptr()),
self.len() as c_int,
ffi::SQLITE_TRANSIENT())
}
}
@ -203,9 +211,13 @@ impl FromSql for String {
} else {
let c_slice = CStr::from_ptr(c_text as *const c_char).to_bytes();
let utf8_str = str::from_utf8(c_slice);
utf8_str
.map(|s| { s.to_string() })
.map_err(|e| { SqliteError{code: 0, message: e.to_string()} })
utf8_str.map(|s| s.to_string())
.map_err(|e| {
SqliteError {
code: 0,
message: e.to_string(),
}
})
}
}
@ -222,7 +234,8 @@ impl FromSql for Vec<u8> {
// The documentation for sqlite3_column_bytes indicates it is always non-negative,
// but we should assert here just to be sure.
assert!(len >= 0, "unexpected negative return from sqlite3_column_bytes");
assert!(len >= 0,
"unexpected negative return from sqlite3_column_bytes");
let len = len as usize;
Ok(from_raw_parts(mem::transmute(c_blob), len).to_vec())
@ -234,14 +247,16 @@ impl FromSql for Vec<u8> {
}
impl FromSql for time::Timespec {
unsafe fn column_result(stmt: *mut sqlite3_stmt,
col: c_int) -> SqliteResult<time::Timespec> {
unsafe fn column_result(stmt: *mut sqlite3_stmt, col: c_int) -> SqliteResult<time::Timespec> {
let col_str = FromSql::column_result(stmt, col);
col_str.and_then(|txt: String| {
time::strptime(&txt, SQLITE_DATETIME_FMT).map(|tm| {
tm.to_timespec()
}).map_err(|parse_error| {
SqliteError{ code: ffi::SQLITE_MISMATCH, message: format!("{}", parse_error) }
time::strptime(&txt, SQLITE_DATETIME_FMT)
.map(|tm| tm.to_timespec())
.map_err(|parse_error| {
SqliteError {
code: ffi::SQLITE_MISMATCH,
message: format!("{}", parse_error),
}
})
})
}
@ -305,7 +320,10 @@ mod test {
fn test_timespec() {
let db = checked_memory_handle();
let ts = time::Timespec{sec: 10_000, nsec: 0 };
let ts = time::Timespec {
sec: 10_000,
nsec: 0,
};
db.execute("INSERT INTO foo(t) VALUES (?)", &[&ts]).unwrap();
let from: time::Timespec = db.query_row("SELECT t FROM foo", &[], |r| r.get(0)).unwrap();
@ -342,7 +360,9 @@ mod test {
fn test_mismatched_types() {
let db = checked_memory_handle();
db.execute("INSERT INTO foo(b, t, i, f) VALUES (X'0102', 'text', 1, 1.5)", &[]).unwrap();
db.execute("INSERT INTO foo(b, t, i, f) VALUES (X'0102', 'text', 1, 1.5)",
&[])
.unwrap();
let mut stmt = db.prepare("SELECT b, t, i, f, n FROM foo").unwrap();
let mut rows = stmt.query(&[]).unwrap();
@ -361,41 +381,69 @@ mod test {
// check some invalid types
// 0 is actually a blob (Vec<u8>)
assert_eq!(row.get_checked::<c_int>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(0).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_int>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(0).err().unwrap().code,
ffi::SQLITE_MISMATCH);
// 1 is actually a text (String)
assert_eq!(row.get_checked::<c_int>(1).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(1).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(1).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(1).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(1).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_int>(1).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(1).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(1).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(1).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(1).err().unwrap().code,
ffi::SQLITE_MISMATCH);
// 2 is actually an integer
assert_eq!(row.get_checked::<c_double>(2).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(2).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(2).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(2).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_double>>(2).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(2).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(2).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(2).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(2).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_double>>(2).err().unwrap().code,
ffi::SQLITE_MISMATCH);
// 3 is actually a float (c_double)
assert_eq!(row.get_checked::<c_int>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(3).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_int>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Option<c_int>>(3).err().unwrap().code,
ffi::SQLITE_MISMATCH);
// 4 is actually NULL
assert_eq!(row.get_checked::<c_int>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(4).err().unwrap().code, ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_int>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<i64>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<c_double>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<String>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<Vec<u8>>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
assert_eq!(row.get_checked::<time::Timespec>(4).err().unwrap().code,
ffi::SQLITE_MISMATCH);
}
}