mirror of
https://github.com/fluencelabs/sqlite-wasm-connector
synced 2025-04-25 00:32:14 +00:00
Run rustfmt
This commit is contained in:
parent
4759cb346d
commit
006027159b
@ -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));
|
||||||
|
@ -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(
|
||||||
ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE,
|
path_to_cstr!(path.as_ref()).as_ptr(),
|
||||||
0 as *const _));
|
&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.
|
/// 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!(
|
||||||
Some(process_callback::<F>),
|
self.raw,
|
||||||
&*callback as *const F as *mut F as *mut _,
|
ffi::sqlite3_exec(
|
||||||
0 as *mut _));
|
self.raw,
|
||||||
|
str_to_cstr!(statement.as_ref()).as_ptr(),
|
||||||
|
Some(process_callback::<F>),
|
||||||
|
&*callback as *const F as *mut F 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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!(
|
||||||
self.as_ptr() as *const _,
|
statement.raw.1,
|
||||||
self.len() as c_int,
|
ffi::sqlite3_bind_blob(
|
||||||
transient!()));
|
statement.raw.0,
|
||||||
|
i as c_int,
|
||||||
|
self.as_ptr() as *const _,
|
||||||
|
self.len() as c_int,
|
||||||
|
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!(
|
||||||
self.as_ptr() as *const _,
|
statement.raw.1,
|
||||||
self.len() as c_int,
|
ffi::sqlite3_bind_text(
|
||||||
transient!()));
|
statement.raw.0,
|
||||||
|
i as c_int,
|
||||||
|
self.as_ptr() as *const _,
|
||||||
|
self.len() as c_int,
|
||||||
|
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,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
67
tests/lib.rs
67
tests/lib.rs
@ -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,21 +51,23 @@ 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)
|
||||||
let path = path.to_path_buf();
|
.map(|_| {
|
||||||
thread::spawn(move || {
|
let path = path.to_path_buf();
|
||||||
let mut connection = ok!(sqlite::open(&path));
|
thread::spawn(move || {
|
||||||
ok!(connection.set_busy_handler(|_| true));
|
let mut connection = ok!(sqlite::open(&path));
|
||||||
let statement = "INSERT INTO `users` (id, name, age, photo) VALUES (?, ?, ?, ?)";
|
ok!(connection.set_busy_handler(|_| true));
|
||||||
let mut statement = ok!(connection.prepare(statement));
|
let statement = "INSERT INTO `users` (id, name, age, photo) VALUES (?, ?, ?, ?)";
|
||||||
ok!(statement.bind(1, 2i64));
|
let mut statement = ok!(connection.prepare(statement));
|
||||||
ok!(statement.bind(2, "Bob"));
|
ok!(statement.bind(1, 2i64));
|
||||||
ok!(statement.bind(3, 69.42));
|
ok!(statement.bind(2, "Bob"));
|
||||||
ok!(statement.bind(4, &[0x69u8, 0x42u8][..]));
|
ok!(statement.bind(3, 69.42));
|
||||||
assert_eq!(ok!(statement.next()), State::Done);
|
ok!(statement.bind(4, &[0x69u8, 0x42u8][..]));
|
||||||
true
|
assert_eq!(ok!(statement.next()), State::Done);
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user