diff --git a/benches/lib.rs b/benches/lib.rs index 849da2d..0063a11 100644 --- a/benches/lib.rs +++ b/benches/lib.rs @@ -13,9 +13,11 @@ macro_rules! ok(($result:expr) => ($result.unwrap())); fn read_cursor(bencher: &mut Bencher) { let connection = create(); populate(&connection, 100); - let mut cursor = ok!(connection.prepare(" + let mut cursor = ok!(connection.prepare( + " SELECT * FROM data WHERE a > ? AND b > ? - ")).cursor(); + ", + )).cursor(); bencher.iter(|| { ok!(cursor.bind(&[Integer(42), Float(42.0)])); @@ -30,9 +32,11 @@ fn read_cursor(bencher: &mut Bencher) { fn read_statement(bencher: &mut Bencher) { let connection = create(); populate(&connection, 100); - let mut statement = ok!(connection.prepare(" + let mut statement = ok!(connection.prepare( + " SELECT * FROM data WHERE a > ? AND b > ? - ")); + ", + )); bencher.iter(|| { ok!(statement.reset()); @@ -48,12 +52,16 @@ fn read_statement(bencher: &mut Bencher) { #[bench] fn write_cursor(bencher: &mut Bencher) { let connection = create(); - let mut cursor = ok!(connection.prepare(" + let mut cursor = ok!(connection.prepare( + " INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?) - ")).cursor(); + ", + )).cursor(); bencher.iter(|| { - ok!(cursor.bind(&[Integer(42), Float(42.0), Float(42.0), Float(42.0)])); + ok!(cursor.bind( + &[Integer(42), Float(42.0), Float(42.0), Float(42.0)], + )); ok!(cursor.next()); }) } @@ -61,9 +69,11 @@ fn write_cursor(bencher: &mut Bencher) { #[bench] fn write_statement(bencher: &mut Bencher) { let connection = create(); - let mut statement = ok!(connection.prepare(" + let mut statement = ok!(connection.prepare( + " INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?) - ")); + ", + )); bencher.iter(|| { ok!(statement.reset()); @@ -77,16 +87,20 @@ fn write_statement(bencher: &mut Bencher) { fn create() -> Connection { let connection = ok!(Connection::open(":memory:")); - ok!(connection.execute(" + ok!(connection.execute( + " CREATE TABLE data (a INTEGER, b REAL, c REAL, d REAL) - ")); + ", + )); connection } fn populate(connection: &Connection, count: usize) { - let mut statement = ok!(connection.prepare(" + let mut statement = ok!(connection.prepare( + " INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?) - ")); + ", + )); for i in 0..count { ok!(statement.reset()); ok!(statement.bind(1, i as i64)); diff --git a/src/connection.rs b/src/connection.rs index e5bf293..eaa55f4 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -19,19 +19,34 @@ impl Connection { pub fn open>(path: T) -> Result { let mut raw = 0 as *mut _; unsafe { - ok!(ffi::sqlite3_open_v2(path_to_cstr!(path.as_ref()).as_ptr(), &mut raw, - ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE, - 0 as *const _)); + ok!(ffi::sqlite3_open_v2( + path_to_cstr!(path.as_ref()).as_ptr(), + &mut raw, + ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE, + 0 as *const _, + )); } - Ok(Connection { raw: raw, busy_callback: None, phantom: PhantomData }) + Ok(Connection { + raw: raw, + busy_callback: None, + phantom: PhantomData, + }) } /// Execute a statement without processing the resulting rows if any. #[inline] pub fn execute>(&self, statement: T) -> Result<()> { unsafe { - ok!(self.raw, ffi::sqlite3_exec(self.raw, str_to_cstr!(statement.as_ref()).as_ptr(), - None, 0 as *mut _, 0 as *mut _)); + ok!( + self.raw, + ffi::sqlite3_exec( + self.raw, + str_to_cstr!(statement.as_ref()).as_ptr(), + None, + 0 as *mut _, + 0 as *mut _, + ) + ); } Ok(()) } @@ -43,14 +58,21 @@ impl Connection { /// types, prepared statement are highly preferable; see `prepare`. #[inline] pub fn iterate, F>(&self, statement: T, callback: F) -> Result<()> - where F: FnMut(&[(&str, Option<&str>)]) -> bool + where + F: FnMut(&[(&str, Option<&str>)]) -> bool, { unsafe { let callback = Box::new(callback); - ok!(self.raw, ffi::sqlite3_exec(self.raw, str_to_cstr!(statement.as_ref()).as_ptr(), - Some(process_callback::), - &*callback as *const F as *mut F as *mut _, - 0 as *mut _)); + ok!( + self.raw, + ffi::sqlite3_exec( + self.raw, + str_to_cstr!(statement.as_ref()).as_ptr(), + Some(process_callback::), + &*callback as *const F as *mut F as *mut _, + 0 as *mut _, + ) + ); } Ok(()) } @@ -67,13 +89,17 @@ impl Connection { /// due to processing of some other request. If the callback returns `true`, /// the operation will be repeated. pub fn set_busy_handler(&mut self, callback: F) -> Result<()> - where F: FnMut(usize) -> bool + Send + 'static + where + F: FnMut(usize) -> bool + Send + 'static, { try!(self.remove_busy_handler()); unsafe { let callback = Box::new(callback); - let result = ffi::sqlite3_busy_handler(self.raw, Some(busy_callback::), - &*callback as *const F as *mut F as *mut _); + let result = ffi::sqlite3_busy_handler( + self.raw, + Some(busy_callback::), + &*callback as *const F as *mut F as *mut _, + ); self.busy_callback = Some(callback); ok!(self.raw, result); } @@ -84,7 +110,12 @@ impl Connection { /// rejected operations until a timeout expires. #[inline] pub fn set_busy_timeout(&mut self, milliseconds: usize) -> Result<()> { - unsafe { ok!(self.raw, ffi::sqlite3_busy_timeout(self.raw, milliseconds as c_int)) }; + unsafe { + ok!( + self.raw, + ffi::sqlite3_busy_timeout(self.raw, milliseconds as c_int) + ) + }; Ok(()) } @@ -92,7 +123,12 @@ impl Connection { #[inline] pub fn remove_busy_handler(&mut self) -> Result<()> { self.busy_callback = None; - unsafe { ok!(self.raw, ffi::sqlite3_busy_handler(self.raw, None, 0 as *mut _)) }; + unsafe { + ok!( + self.raw, + ffi::sqlite3_busy_handler(self.raw, None, 0 as *mut _) + ) + }; Ok(()) } } @@ -106,15 +142,27 @@ impl Drop for Connection { } } -extern fn busy_callback(callback: *mut c_void, attempts: c_int) -> c_int - where F: FnMut(usize) -> bool +extern "C" fn busy_callback(callback: *mut c_void, attempts: c_int) -> c_int +where + F: FnMut(usize) -> bool, { - unsafe { if (*(callback as *mut F))(attempts as usize) { 1 } else { 0 } } + unsafe { + if (*(callback as *mut F))(attempts as usize) { + 1 + } else { + 0 + } + } } -extern fn process_callback(callback: *mut c_void, count: c_int, values: *mut *mut c_char, - columns: *mut *mut c_char) -> c_int - where F: FnMut(&[(&str, Option<&str>)]) -> bool +extern "C" fn process_callback( + callback: *mut c_void, + count: c_int, + values: *mut *mut c_char, + columns: *mut *mut c_char, +) -> c_int +where + F: FnMut(&[(&str, Option<&str>)]) -> bool, { unsafe { let mut pairs = Vec::with_capacity(count as usize); @@ -136,6 +184,10 @@ extern fn process_callback(callback: *mut c_void, count: c_int, values: *mut pairs.push((column, value)); } - if (*(callback as *mut F))(&pairs) { 0 } else { 1 } + if (*(callback as *mut F))(&pairs) { + 0 + } else { + 1 + } } } diff --git a/src/cursor.rs b/src/cursor.rs index 5890324..f07f0ef 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -22,12 +22,12 @@ impl<'l> Cursor<'l> { /// Advance to the next row and read all columns. pub fn next(&mut self) -> Result> { match self.state { - Some(State::Row) => {}, + Some(State::Row) => {} Some(State::Done) => return Ok(None), _ => { self.state = Some(try!(self.statement.next())); return self.next(); - }, + } } let values = match self.values.take() { Some(mut values) => { @@ -35,21 +35,21 @@ impl<'l> Cursor<'l> { match value { &mut Value::Binary(ref mut value) => { *value = try!(self.statement.read(i)); - }, + } &mut Value::Float(ref mut value) => { *value = try!(self.statement.read(i)); - }, + } &mut Value::Integer(ref mut value) => { *value = try!(self.statement.read(i)); - }, + } &mut Value::String(ref mut value) => { *value = try!(self.statement.read(i)); - }, - &mut Value::Null => {}, + } + &mut Value::Null => {} } } values - }, + } _ => { let count = self.statement.columns(); let mut values = Vec::with_capacity(count); @@ -57,7 +57,7 @@ impl<'l> Cursor<'l> { values.push(try!(self.statement.read(i))); } values - }, + } }; self.state = Some(try!(self.statement.next())); self.values = Some(values); @@ -73,5 +73,9 @@ impl<'l> Cursor<'l> { #[inline] pub fn new<'l>(statement: Statement<'l>) -> Cursor<'l> { - Cursor { state: None, values: None, statement: statement } + Cursor { + state: None, + values: None, + statement: statement, + } } diff --git a/src/lib.rs b/src/lib.rs index ed27553..78e77b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -279,6 +279,9 @@ fn last_error(raw: *mut ffi::sqlite3) -> Option { if message.is_null() { return None; } - Some(Error { code: Some(code as isize), message: Some(c_str_to_string!(message)) }) + Some(Error { + code: Some(code as isize), + message: Some(c_str_to_string!(message)), + }) } } diff --git a/src/statement.rs b/src/statement.rs index 7d3cd31..bf26881 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -125,10 +125,16 @@ impl<'l> Bindable for &'l [u8] { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { debug_assert!(i > 0, "the indexing starts from 1"); unsafe { - ok!(statement.raw.1, ffi::sqlite3_bind_blob(statement.raw.0, i as c_int, - self.as_ptr() as *const _, - self.len() as c_int, - transient!())); + ok!( + statement.raw.1, + ffi::sqlite3_bind_blob( + statement.raw.0, + i as c_int, + self.as_ptr() as *const _, + self.len() as c_int, + transient!(), + ) + ); } Ok(()) } @@ -139,8 +145,10 @@ impl Bindable for f64 { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { debug_assert!(i > 0, "the indexing starts from 1"); unsafe { - ok!(statement.raw.1, ffi::sqlite3_bind_double(statement.raw.0, i as c_int, - self as c_double)); + ok!( + statement.raw.1, + ffi::sqlite3_bind_double(statement.raw.0, i as c_int, self as c_double) + ); } Ok(()) } @@ -151,8 +159,10 @@ impl Bindable for i64 { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { debug_assert!(i > 0, "the indexing starts from 1"); unsafe { - ok!(statement.raw.1, ffi::sqlite3_bind_int64(statement.raw.0, i as c_int, - self as ffi::sqlite3_int64)); + ok!( + statement.raw.1, + ffi::sqlite3_bind_int64(statement.raw.0, i as c_int, self as ffi::sqlite3_int64) + ); } Ok(()) } @@ -163,10 +173,16 @@ impl<'l> Bindable for &'l str { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { debug_assert!(i > 0, "the indexing starts from 1"); unsafe { - ok!(statement.raw.1, ffi::sqlite3_bind_text(statement.raw.0, i as c_int, - self.as_ptr() as *const _, - self.len() as c_int, - transient!())); + ok!( + statement.raw.1, + ffi::sqlite3_bind_text( + statement.raw.0, + i as c_int, + self.as_ptr() as *const _, + self.len() as c_int, + transient!(), + ) + ); } Ok(()) } @@ -177,7 +193,10 @@ impl Bindable for () { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { debug_assert!(i > 0, "the indexing starts from 1"); unsafe { - ok!(statement.raw.1, ffi::sqlite3_bind_null(statement.raw.0, i as c_int)); + ok!( + statement.raw.1, + ffi::sqlite3_bind_null(statement.raw.0, i as c_int) + ); } Ok(()) } @@ -198,14 +217,18 @@ impl Readable for Value { impl Readable for f64 { #[inline] fn read(statement: &Statement, i: usize) -> Result { - Ok(unsafe { ffi::sqlite3_column_double(statement.raw.0, i as c_int) as f64 }) + Ok(unsafe { + ffi::sqlite3_column_double(statement.raw.0, i as c_int) as f64 + }) } } impl Readable for i64 { #[inline] fn read(statement: &Statement, i: usize) -> Result { - Ok(unsafe { ffi::sqlite3_column_int64(statement.raw.0, i as c_int) as i64 }) + Ok(unsafe { + ffi::sqlite3_column_int64(statement.raw.0, i as c_int) as i64 + }) } } @@ -244,8 +267,19 @@ impl Readable for Vec { pub fn new<'l, T: AsRef>(raw1: *mut ffi::sqlite3, statement: T) -> Result> { let mut raw0 = 0 as *mut _; unsafe { - ok!(raw1, ffi::sqlite3_prepare_v2(raw1, str_to_cstr!(statement.as_ref()).as_ptr(), -1, - &mut raw0, 0 as *mut _)); + ok!( + raw1, + ffi::sqlite3_prepare_v2( + raw1, + str_to_cstr!(statement.as_ref()).as_ptr(), + -1, + &mut raw0, + 0 as *mut _, + ) + ); } - Ok(Statement { raw: (raw0, raw1), phantom: PhantomData }) + Ok(Statement { + raw: (raw0, raw1), + phantom: PhantomData, + }) } diff --git a/tests/lib.rs b/tests/lib.rs index f766840..da34dd3 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -10,7 +10,12 @@ macro_rules! ok(($result:expr) => ($result.unwrap())); fn connection_error() { let connection = setup_users(":memory:"); match connection.execute(":)") { - Err(error) => assert_eq!(error.message, Some(String::from(r#"unrecognized token: ":""#))), + Err(error) => { + assert_eq!( + error.message, + Some(String::from(r#"unrecognized token: ":""#)) + ) + } _ => unreachable!(), } } @@ -46,21 +51,23 @@ fn connection_set_busy_handler() { let path = directory.path().join("database.sqlite3"); setup_users(&path); - let guards = (0..100).map(|_| { - let path = path.to_path_buf(); - thread::spawn(move || { - let mut connection = ok!(sqlite::open(&path)); - ok!(connection.set_busy_handler(|_| true)); - let statement = "INSERT INTO `users` (id, name, age, photo) VALUES (?, ?, ?, ?)"; - let mut statement = ok!(connection.prepare(statement)); - ok!(statement.bind(1, 2i64)); - ok!(statement.bind(2, "Bob")); - ok!(statement.bind(3, 69.42)); - ok!(statement.bind(4, &[0x69u8, 0x42u8][..])); - assert_eq!(ok!(statement.next()), State::Done); - true + let guards = (0..100) + .map(|_| { + let path = path.to_path_buf(); + thread::spawn(move || { + let mut connection = ok!(sqlite::open(&path)); + ok!(connection.set_busy_handler(|_| true)); + let statement = "INSERT INTO `users` (id, name, age, photo) VALUES (?, ?, ?, ?)"; + let mut statement = ok!(connection.prepare(statement)); + ok!(statement.bind(1, 2i64)); + ok!(statement.bind(2, "Bob")); + ok!(statement.bind(3, 69.42)); + ok!(statement.bind(4, &[0x69u8, 0x42u8][..])); + assert_eq!(ok!(statement.next()), State::Done); + true + }) }) - }).collect::>(); + .collect::>(); for guard in guards { assert!(ok!(guard.join())); @@ -108,19 +115,29 @@ fn cursor_workflow() { for _ in 0..10 { ok!(select.bind(&[Value::Integer(1)])); - assert_eq!(ok!(ok!(select.next())), &[Value::Integer(1), - Value::String("Alice".to_string())]); + assert_eq!( + ok!(ok!(select.next())), + &[Value::Integer(1), Value::String("Alice".to_string())] + ); assert_eq!(ok!(select.next()), None); } ok!(select.bind(&[Value::Integer(42)])); assert_eq!(ok!(select.next()), None); - ok!(insert.bind(&[Value::Integer(42), Value::String("Bob".to_string())])); + ok!(insert.bind( + &[ + Value::Integer(42), + Value::String("Bob".to_string()), + ], + )); assert_eq!(ok!(insert.next()), None); ok!(select.bind(&[Value::Integer(42)])); - assert_eq!(ok!(ok!(select.next())), &[Value::Integer(42), Value::String("Bob".to_string())]); + assert_eq!( + ok!(ok!(select.next())), + &[Value::Integer(42), Value::String("Bob".to_string())] + ); assert_eq!(ok!(select.next()), None); } @@ -212,7 +229,8 @@ fn statement_wildcard_without_binding() { fn setup_english>(path: T) -> Connection { let connection = ok!(sqlite::open(path)); - ok!(connection.execute(" + ok!(connection.execute( + " CREATE TABLE english (value TEXT); INSERT INTO english (value) VALUES ('cerotype'); INSERT INTO english (value) VALUES ('metatype'); @@ -221,15 +239,18 @@ fn setup_english>(path: T) -> Connection { INSERT INTO english (value) VALUES ('plastotype'); INSERT INTO english (value) VALUES ('undertype'); INSERT INTO english (value) VALUES ('nonsence'); - ")); + ", + )); connection } fn setup_users>(path: T) -> Connection { let connection = ok!(sqlite::open(path)); - ok!(connection.execute(" + ok!(connection.execute( + " CREATE TABLE users (id INTEGER, name TEXT, age REAL, photo BLOB); INSERT INTO users (id, name, age, photo) VALUES (1, 'Alice', 42.69, X'4269'); - ")); + ", + )); connection }