Run rustfmt

This commit is contained in:
Ivan Ukhov 2017-08-22 17:34:03 +02:00
parent 4759cb346d
commit 006027159b
6 changed files with 216 additions and 88 deletions

View File

@ -13,9 +13,11 @@ macro_rules! ok(($result:expr) => ($result.unwrap()));
fn read_cursor(bencher: &mut Bencher) { fn read_cursor(bencher: &mut Bencher) {
let connection = create(); let connection = create();
populate(&connection, 100); populate(&connection, 100);
let mut cursor = ok!(connection.prepare(" let mut cursor = ok!(connection.prepare(
"
SELECT * FROM data WHERE a > ? AND b > ? SELECT * FROM data WHERE a > ? AND b > ?
")).cursor(); ",
)).cursor();
bencher.iter(|| { bencher.iter(|| {
ok!(cursor.bind(&[Integer(42), Float(42.0)])); ok!(cursor.bind(&[Integer(42), Float(42.0)]));
@ -30,9 +32,11 @@ fn read_cursor(bencher: &mut Bencher) {
fn read_statement(bencher: &mut Bencher) { fn read_statement(bencher: &mut Bencher) {
let connection = create(); let connection = create();
populate(&connection, 100); populate(&connection, 100);
let mut statement = ok!(connection.prepare(" let mut statement = ok!(connection.prepare(
"
SELECT * FROM data WHERE a > ? AND b > ? SELECT * FROM data WHERE a > ? AND b > ?
")); ",
));
bencher.iter(|| { bencher.iter(|| {
ok!(statement.reset()); ok!(statement.reset());
@ -48,12 +52,16 @@ fn read_statement(bencher: &mut Bencher) {
#[bench] #[bench]
fn write_cursor(bencher: &mut Bencher) { fn write_cursor(bencher: &mut Bencher) {
let connection = create(); let connection = create();
let mut cursor = ok!(connection.prepare(" let mut cursor = ok!(connection.prepare(
"
INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?) INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?)
")).cursor(); ",
)).cursor();
bencher.iter(|| { 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()); ok!(cursor.next());
}) })
} }
@ -61,9 +69,11 @@ fn write_cursor(bencher: &mut Bencher) {
#[bench] #[bench]
fn write_statement(bencher: &mut Bencher) { fn write_statement(bencher: &mut Bencher) {
let connection = create(); let connection = create();
let mut statement = ok!(connection.prepare(" let mut statement = ok!(connection.prepare(
"
INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?) INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?)
")); ",
));
bencher.iter(|| { bencher.iter(|| {
ok!(statement.reset()); ok!(statement.reset());
@ -77,16 +87,20 @@ fn write_statement(bencher: &mut Bencher) {
fn create() -> Connection { fn create() -> Connection {
let connection = ok!(Connection::open(":memory:")); let connection = ok!(Connection::open(":memory:"));
ok!(connection.execute(" ok!(connection.execute(
"
CREATE TABLE data (a INTEGER, b REAL, c REAL, d REAL) CREATE TABLE data (a INTEGER, b REAL, c REAL, d REAL)
")); ",
));
connection connection
} }
fn populate(connection: &Connection, count: usize) { 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 (?, ?, ?, ?) INSERT INTO data (a, b, c, d) VALUES (?, ?, ?, ?)
")); ",
));
for i in 0..count { for i in 0..count {
ok!(statement.reset()); ok!(statement.reset());
ok!(statement.bind(1, i as i64)); ok!(statement.bind(1, i as i64));

View File

@ -19,19 +19,34 @@ impl Connection {
pub fn open<T: AsRef<Path>>(path: T) -> Result<Connection> { pub fn open<T: AsRef<Path>>(path: T) -> Result<Connection> {
let mut raw = 0 as *mut _; let mut raw = 0 as *mut _;
unsafe { unsafe {
ok!(ffi::sqlite3_open_v2(path_to_cstr!(path.as_ref()).as_ptr(), &mut raw, ok!(ffi::sqlite3_open_v2(
path_to_cstr!(path.as_ref()).as_ptr(),
&mut raw,
ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE, ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE,
0 as *const _)); 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. /// Execute a statement without processing the resulting rows if any.
#[inline] #[inline]
pub fn execute<T: AsRef<str>>(&self, statement: T) -> Result<()> { pub fn execute<T: AsRef<str>>(&self, statement: T) -> Result<()> {
unsafe { unsafe {
ok!(self.raw, ffi::sqlite3_exec(self.raw, str_to_cstr!(statement.as_ref()).as_ptr(), ok!(
None, 0 as *mut _, 0 as *mut _)); self.raw,
ffi::sqlite3_exec(
self.raw,
str_to_cstr!(statement.as_ref()).as_ptr(),
None,
0 as *mut _,
0 as *mut _,
)
);
} }
Ok(()) Ok(())
} }
@ -43,14 +58,21 @@ impl Connection {
/// types, prepared statement are highly preferable; see `prepare`. /// types, prepared statement are highly preferable; see `prepare`.
#[inline] #[inline]
pub fn iterate<T: AsRef<str>, F>(&self, statement: T, callback: F) -> Result<()> pub fn iterate<T: AsRef<str>, F>(&self, statement: T, callback: F) -> Result<()>
where F: FnMut(&[(&str, Option<&str>)]) -> bool where
F: FnMut(&[(&str, Option<&str>)]) -> bool,
{ {
unsafe { unsafe {
let callback = Box::new(callback); let callback = Box::new(callback);
ok!(self.raw, ffi::sqlite3_exec(self.raw, str_to_cstr!(statement.as_ref()).as_ptr(), ok!(
self.raw,
ffi::sqlite3_exec(
self.raw,
str_to_cstr!(statement.as_ref()).as_ptr(),
Some(process_callback::<F>), Some(process_callback::<F>),
&*callback as *const F as *mut F as *mut _, &*callback as *const F as *mut F as *mut _,
0 as *mut _)); 0 as *mut _,
)
);
} }
Ok(()) Ok(())
} }
@ -67,13 +89,17 @@ impl Connection {
/// due to processing of some other request. If the callback returns `true`, /// due to processing of some other request. If the callback returns `true`,
/// the operation will be repeated. /// the operation will be repeated.
pub fn set_busy_handler<F>(&mut self, callback: F) -> Result<()> pub fn set_busy_handler<F>(&mut self, callback: F) -> Result<()>
where F: FnMut(usize) -> bool + Send + 'static where
F: FnMut(usize) -> bool + Send + 'static,
{ {
try!(self.remove_busy_handler()); try!(self.remove_busy_handler());
unsafe { unsafe {
let callback = Box::new(callback); let callback = Box::new(callback);
let result = ffi::sqlite3_busy_handler(self.raw, Some(busy_callback::<F>), let result = ffi::sqlite3_busy_handler(
&*callback as *const F as *mut F as *mut _); self.raw,
Some(busy_callback::<F>),
&*callback as *const F as *mut F as *mut _,
);
self.busy_callback = Some(callback); self.busy_callback = Some(callback);
ok!(self.raw, result); ok!(self.raw, result);
} }
@ -84,7 +110,12 @@ impl Connection {
/// rejected operations until a timeout expires. /// rejected operations until a timeout expires.
#[inline] #[inline]
pub fn set_busy_timeout(&mut self, milliseconds: usize) -> Result<()> { 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(()) Ok(())
} }
@ -92,7 +123,12 @@ impl Connection {
#[inline] #[inline]
pub fn remove_busy_handler(&mut self) -> Result<()> { pub fn remove_busy_handler(&mut self) -> Result<()> {
self.busy_callback = None; 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(()) Ok(())
} }
} }
@ -106,15 +142,27 @@ impl Drop for Connection {
} }
} }
extern fn busy_callback<F>(callback: *mut c_void, attempts: c_int) -> c_int extern "C" fn busy_callback<F>(callback: *mut c_void, attempts: c_int) -> c_int
where F: FnMut(usize) -> bool 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<F>(callback: *mut c_void, count: c_int, values: *mut *mut c_char, extern "C" fn process_callback<F>(
columns: *mut *mut c_char) -> c_int callback: *mut c_void,
where F: FnMut(&[(&str, Option<&str>)]) -> bool count: c_int,
values: *mut *mut c_char,
columns: *mut *mut c_char,
) -> c_int
where
F: FnMut(&[(&str, Option<&str>)]) -> bool,
{ {
unsafe { unsafe {
let mut pairs = Vec::with_capacity(count as usize); let mut pairs = Vec::with_capacity(count as usize);
@ -136,6 +184,10 @@ extern fn process_callback<F>(callback: *mut c_void, count: c_int, values: *mut
pairs.push((column, value)); pairs.push((column, value));
} }
if (*(callback as *mut F))(&pairs) { 0 } else { 1 } if (*(callback as *mut F))(&pairs) {
0
} else {
1
}
} }
} }

View File

@ -22,12 +22,12 @@ impl<'l> Cursor<'l> {
/// Advance to the next row and read all columns. /// Advance to the next row and read all columns.
pub fn next(&mut self) -> Result<Option<&[Value]>> { pub fn next(&mut self) -> Result<Option<&[Value]>> {
match self.state { match self.state {
Some(State::Row) => {}, Some(State::Row) => {}
Some(State::Done) => return Ok(None), Some(State::Done) => return Ok(None),
_ => { _ => {
self.state = Some(try!(self.statement.next())); self.state = Some(try!(self.statement.next()));
return self.next(); return self.next();
}, }
} }
let values = match self.values.take() { let values = match self.values.take() {
Some(mut values) => { Some(mut values) => {
@ -35,21 +35,21 @@ impl<'l> Cursor<'l> {
match value { match value {
&mut Value::Binary(ref mut value) => { &mut Value::Binary(ref mut value) => {
*value = try!(self.statement.read(i)); *value = try!(self.statement.read(i));
}, }
&mut Value::Float(ref mut value) => { &mut Value::Float(ref mut value) => {
*value = try!(self.statement.read(i)); *value = try!(self.statement.read(i));
}, }
&mut Value::Integer(ref mut value) => { &mut Value::Integer(ref mut value) => {
*value = try!(self.statement.read(i)); *value = try!(self.statement.read(i));
}, }
&mut Value::String(ref mut value) => { &mut Value::String(ref mut value) => {
*value = try!(self.statement.read(i)); *value = try!(self.statement.read(i));
}, }
&mut Value::Null => {}, &mut Value::Null => {}
} }
} }
values values
}, }
_ => { _ => {
let count = self.statement.columns(); let count = self.statement.columns();
let mut values = Vec::with_capacity(count); let mut values = Vec::with_capacity(count);
@ -57,7 +57,7 @@ impl<'l> Cursor<'l> {
values.push(try!(self.statement.read(i))); values.push(try!(self.statement.read(i)));
} }
values values
}, }
}; };
self.state = Some(try!(self.statement.next())); self.state = Some(try!(self.statement.next()));
self.values = Some(values); self.values = Some(values);
@ -73,5 +73,9 @@ impl<'l> Cursor<'l> {
#[inline] #[inline]
pub fn new<'l>(statement: Statement<'l>) -> Cursor<'l> { pub fn new<'l>(statement: Statement<'l>) -> Cursor<'l> {
Cursor { state: None, values: None, statement: statement } Cursor {
state: None,
values: None,
statement: statement,
}
} }

View File

@ -279,6 +279,9 @@ fn last_error(raw: *mut ffi::sqlite3) -> Option<Error> {
if message.is_null() { if message.is_null() {
return None; 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)),
})
} }
} }

View File

@ -125,10 +125,16 @@ impl<'l> Bindable for &'l [u8] {
fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> {
debug_assert!(i > 0, "the indexing starts from 1"); debug_assert!(i > 0, "the indexing starts from 1");
unsafe { unsafe {
ok!(statement.raw.1, ffi::sqlite3_bind_blob(statement.raw.0, i as c_int, ok!(
statement.raw.1,
ffi::sqlite3_bind_blob(
statement.raw.0,
i as c_int,
self.as_ptr() as *const _, self.as_ptr() as *const _,
self.len() as c_int, self.len() as c_int,
transient!())); transient!(),
)
);
} }
Ok(()) Ok(())
} }
@ -139,8 +145,10 @@ impl Bindable for f64 {
fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> {
debug_assert!(i > 0, "the indexing starts from 1"); debug_assert!(i > 0, "the indexing starts from 1");
unsafe { unsafe {
ok!(statement.raw.1, ffi::sqlite3_bind_double(statement.raw.0, i as c_int, ok!(
self as c_double)); statement.raw.1,
ffi::sqlite3_bind_double(statement.raw.0, i as c_int, self as c_double)
);
} }
Ok(()) Ok(())
} }
@ -151,8 +159,10 @@ impl Bindable for i64 {
fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> {
debug_assert!(i > 0, "the indexing starts from 1"); debug_assert!(i > 0, "the indexing starts from 1");
unsafe { unsafe {
ok!(statement.raw.1, ffi::sqlite3_bind_int64(statement.raw.0, i as c_int, ok!(
self as ffi::sqlite3_int64)); statement.raw.1,
ffi::sqlite3_bind_int64(statement.raw.0, i as c_int, self as ffi::sqlite3_int64)
);
} }
Ok(()) Ok(())
} }
@ -163,10 +173,16 @@ impl<'l> Bindable for &'l str {
fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> {
debug_assert!(i > 0, "the indexing starts from 1"); debug_assert!(i > 0, "the indexing starts from 1");
unsafe { unsafe {
ok!(statement.raw.1, ffi::sqlite3_bind_text(statement.raw.0, i as c_int, ok!(
statement.raw.1,
ffi::sqlite3_bind_text(
statement.raw.0,
i as c_int,
self.as_ptr() as *const _, self.as_ptr() as *const _,
self.len() as c_int, self.len() as c_int,
transient!())); transient!(),
)
);
} }
Ok(()) Ok(())
} }
@ -177,7 +193,10 @@ impl Bindable for () {
fn bind(self, statement: &mut Statement, i: usize) -> Result<()> { fn bind(self, statement: &mut Statement, i: usize) -> Result<()> {
debug_assert!(i > 0, "the indexing starts from 1"); debug_assert!(i > 0, "the indexing starts from 1");
unsafe { 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(()) Ok(())
} }
@ -198,14 +217,18 @@ impl Readable for Value {
impl Readable for f64 { impl Readable for f64 {
#[inline] #[inline]
fn read(statement: &Statement, i: usize) -> Result<Self> { fn read(statement: &Statement, i: usize) -> Result<Self> {
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 { impl Readable for i64 {
#[inline] #[inline]
fn read(statement: &Statement, i: usize) -> Result<Self> { fn read(statement: &Statement, i: usize) -> Result<Self> {
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<u8> {
pub fn new<'l, T: AsRef<str>>(raw1: *mut ffi::sqlite3, statement: T) -> Result<Statement<'l>> { pub fn new<'l, T: AsRef<str>>(raw1: *mut ffi::sqlite3, statement: T) -> Result<Statement<'l>> {
let mut raw0 = 0 as *mut _; let mut raw0 = 0 as *mut _;
unsafe { unsafe {
ok!(raw1, ffi::sqlite3_prepare_v2(raw1, str_to_cstr!(statement.as_ref()).as_ptr(), -1, ok!(
&mut raw0, 0 as *mut _)); 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,
})
} }

View File

@ -10,7 +10,12 @@ macro_rules! ok(($result:expr) => ($result.unwrap()));
fn connection_error() { fn connection_error() {
let connection = setup_users(":memory:"); let connection = setup_users(":memory:");
match connection.execute(":)") { 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!(), _ => unreachable!(),
} }
} }
@ -46,7 +51,8 @@ fn connection_set_busy_handler() {
let path = directory.path().join("database.sqlite3"); let path = directory.path().join("database.sqlite3");
setup_users(&path); setup_users(&path);
let guards = (0..100).map(|_| { let guards = (0..100)
.map(|_| {
let path = path.to_path_buf(); let path = path.to_path_buf();
thread::spawn(move || { thread::spawn(move || {
let mut connection = ok!(sqlite::open(&path)); let mut connection = ok!(sqlite::open(&path));
@ -60,7 +66,8 @@ fn connection_set_busy_handler() {
assert_eq!(ok!(statement.next()), State::Done); assert_eq!(ok!(statement.next()), State::Done);
true true
}) })
}).collect::<Vec<_>>(); })
.collect::<Vec<_>>();
for guard in guards { for guard in guards {
assert!(ok!(guard.join())); assert!(ok!(guard.join()));
@ -108,19 +115,29 @@ fn cursor_workflow() {
for _ in 0..10 { for _ in 0..10 {
ok!(select.bind(&[Value::Integer(1)])); ok!(select.bind(&[Value::Integer(1)]));
assert_eq!(ok!(ok!(select.next())), &[Value::Integer(1), assert_eq!(
Value::String("Alice".to_string())]); ok!(ok!(select.next())),
&[Value::Integer(1), Value::String("Alice".to_string())]
);
assert_eq!(ok!(select.next()), None); assert_eq!(ok!(select.next()), None);
} }
ok!(select.bind(&[Value::Integer(42)])); ok!(select.bind(&[Value::Integer(42)]));
assert_eq!(ok!(select.next()), None); 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); assert_eq!(ok!(insert.next()), None);
ok!(select.bind(&[Value::Integer(42)])); 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); assert_eq!(ok!(select.next()), None);
} }
@ -212,7 +229,8 @@ fn statement_wildcard_without_binding() {
fn setup_english<T: AsRef<Path>>(path: T) -> Connection { fn setup_english<T: AsRef<Path>>(path: T) -> Connection {
let connection = ok!(sqlite::open(path)); let connection = ok!(sqlite::open(path));
ok!(connection.execute(" ok!(connection.execute(
"
CREATE TABLE english (value TEXT); CREATE TABLE english (value TEXT);
INSERT INTO english (value) VALUES ('cerotype'); INSERT INTO english (value) VALUES ('cerotype');
INSERT INTO english (value) VALUES ('metatype'); INSERT INTO english (value) VALUES ('metatype');
@ -221,15 +239,18 @@ fn setup_english<T: AsRef<Path>>(path: T) -> Connection {
INSERT INTO english (value) VALUES ('plastotype'); INSERT INTO english (value) VALUES ('plastotype');
INSERT INTO english (value) VALUES ('undertype'); INSERT INTO english (value) VALUES ('undertype');
INSERT INTO english (value) VALUES ('nonsence'); INSERT INTO english (value) VALUES ('nonsence');
")); ",
));
connection connection
} }
fn setup_users<T: AsRef<Path>>(path: T) -> Connection { fn setup_users<T: AsRef<Path>>(path: T) -> Connection {
let connection = ok!(sqlite::open(path)); let connection = ok!(sqlite::open(path));
ok!(connection.execute(" ok!(connection.execute(
"
CREATE TABLE users (id INTEGER, name TEXT, age REAL, photo BLOB); 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'); INSERT INTO users (id, name, age, photo) VALUES (1, 'Alice', 42.69, X'4269');
")); ",
));
connection connection
} }