mirror of
https://github.com/fluencelabs/sqlite-wasm-connector
synced 2025-03-15 06:20:50 +00:00
Rename a couple of functions; add set_busy_timeout
This commit is contained in:
parent
2698514218
commit
bfa3a976c8
@ -11,7 +11,7 @@ pub struct Database {
|
||||
phantom: PhantomData<raw::sqlite3>,
|
||||
}
|
||||
|
||||
/// A callback triggered when an operation fails due to concurrent activity. If
|
||||
/// A callback triggered when the database is busy and rejects an operation. If
|
||||
/// the callback returns `true`, the operation will be repeated.
|
||||
pub type BusyCallback<'l> = FnMut(usize) -> bool + 'l;
|
||||
|
||||
@ -20,7 +20,7 @@ pub type BusyCallback<'l> = FnMut(usize) -> bool + 'l;
|
||||
pub type ExecuteCallback<'l> = FnMut(Vec<(String, String)>) -> bool + 'l;
|
||||
|
||||
impl Database {
|
||||
/// Open a database.
|
||||
/// Open a database connect.
|
||||
pub fn open(path: &Path) -> Result<Database> {
|
||||
let mut raw = 0 as *mut _;
|
||||
unsafe {
|
||||
@ -29,50 +29,53 @@ impl Database {
|
||||
Ok(Database { raw: raw, phantom: PhantomData })
|
||||
}
|
||||
|
||||
/// Execute an SQL statement.
|
||||
/// Execute an SQL query.
|
||||
pub fn execute<'l>(&self, sql: &str, callback: Option<&mut ExecuteCallback<'l>>)
|
||||
-> Result<()> {
|
||||
|
||||
unsafe {
|
||||
match callback {
|
||||
Some(callback) => {
|
||||
let mut callback = Box::new(callback);
|
||||
match callback {
|
||||
Some(callback) => unsafe {
|
||||
let mut callback = Box::new(callback);
|
||||
success!(self, raw::sqlite3_exec(self.raw, str_to_c_str!(sql),
|
||||
Some(execute_callback),
|
||||
&mut callback as *mut _ as *mut _,
|
||||
0 as *mut _));
|
||||
},
|
||||
None => {
|
||||
success!(self, raw::sqlite3_exec(self.raw, str_to_c_str!(sql), None,
|
||||
0 as *mut _, 0 as *mut _));
|
||||
},
|
||||
}
|
||||
},
|
||||
None => unsafe {
|
||||
success!(self, raw::sqlite3_exec(self.raw, str_to_c_str!(sql), None,
|
||||
0 as *mut _, 0 as *mut _));
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a prepared statement.
|
||||
/// Compile an SQL statement.
|
||||
#[inline]
|
||||
pub fn prepare_statement<'l>(&'l self, sql: &str) -> Result<Statement<'l>> {
|
||||
pub fn prepare<'l>(&'l self, sql: &str) -> Result<Statement<'l>> {
|
||||
::statement::new(self, sql)
|
||||
}
|
||||
|
||||
/// Set a callback for handling failures due to concurrent activity.
|
||||
/// Set a callback to handle rejected operations when the database is busy.
|
||||
pub fn set_busy_handler(&mut self, callback: Option<&mut BusyCallback>) -> Result<()> {
|
||||
unsafe {
|
||||
match callback {
|
||||
Some(callback) => {
|
||||
let mut callback = Box::new(callback);
|
||||
success!(self, raw::sqlite3_busy_handler(self.raw, Some(busy_callback),
|
||||
&mut callback as *mut _ as *mut _));
|
||||
},
|
||||
None => {
|
||||
success!(self, raw::sqlite3_busy_handler(self.raw, None, 0 as *mut _));
|
||||
},
|
||||
}
|
||||
match callback {
|
||||
Some(callback) => unsafe {
|
||||
let mut callback = Box::new(callback);
|
||||
success!(self, raw::sqlite3_busy_handler(self.raw, Some(busy_callback),
|
||||
&mut callback as *mut _ as *mut _));
|
||||
},
|
||||
None => unsafe {
|
||||
success!(self, raw::sqlite3_busy_handler(self.raw, None, 0 as *mut _));
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set a timeout before rejecting an operation when the database is busy.
|
||||
#[inline]
|
||||
pub fn set_busy_timeout(&mut self, milliseconds: usize) -> Result<()> {
|
||||
unsafe { success!(self, raw::sqlite3_busy_timeout(self.raw, milliseconds as c_int)) };
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Database {
|
||||
|
@ -10,58 +10,60 @@ pub struct Statement<'l> {
|
||||
phantom: PhantomData<(&'l raw::sqlite3, raw::sqlite3_stmt)>,
|
||||
}
|
||||
|
||||
/// A binding of a prepared statement.
|
||||
/// A binding of a parameter of a prepared statement.
|
||||
pub enum Binding<'l> {
|
||||
Float(usize, f64),
|
||||
Integer(usize, i64),
|
||||
Text(usize, &'l str),
|
||||
}
|
||||
|
||||
/// A value stored in a prepared statement.
|
||||
/// A value stored in a result row of a query.
|
||||
pub trait Value {
|
||||
/// Read the value at a specific column.
|
||||
/// Read the value stored in a specific column.
|
||||
fn read(statement: &Statement, i: usize) -> Result<Self>;
|
||||
}
|
||||
|
||||
impl<'l> Statement<'l> {
|
||||
/// Assign values to the placeholders.
|
||||
/// Bind values to the parameters.
|
||||
///
|
||||
/// The leftmost parameter has an index of 1.
|
||||
/// The leftmost parameter has the index 1.
|
||||
pub fn bind(&mut self, bindings: &[Binding]) -> Result<()> {
|
||||
for binding in bindings.iter() {
|
||||
match *binding {
|
||||
Binding::Float(i, value) => unsafe {
|
||||
debug_assert!(i > 0, "the indexation starts from 1");
|
||||
debug_assert!(i > 0, "the indexing starts from 1");
|
||||
success!(raw::sqlite3_bind_double(self.raw, i as c_int, value as c_double));
|
||||
},
|
||||
Binding::Integer(i, value) => unsafe {
|
||||
debug_assert!(i > 0, "the indexation starts from 1");
|
||||
debug_assert!(i > 0, "the indexing starts from 1");
|
||||
success!(raw::sqlite3_bind_int64(self.raw, i as c_int,
|
||||
value as raw::sqlite3_int64));
|
||||
},
|
||||
Binding::Text(i, value) => unsafe {
|
||||
debug_assert!(i > 0, "the indexation starts from 1");
|
||||
success!(raw::sqlite3_bind_text(self.raw, i as c_int, str_to_c_str!(value),
|
||||
-1, None));
|
||||
debug_assert!(i > 0, "the indexing starts from 1");
|
||||
success!(raw::sqlite3_bind_text(self.raw, i as c_int, str_to_c_str!(value), -1,
|
||||
None));
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Return the value of a column.
|
||||
/// Return the value stored in a specific column of the current result row.
|
||||
///
|
||||
/// The leftmost column has the index 0.
|
||||
#[inline]
|
||||
pub fn column<T: Value>(&self, i: usize) -> Result<T> {
|
||||
<T as Value>::read(self, i)
|
||||
}
|
||||
|
||||
/// Take a step.
|
||||
/// Evaluate the statement.
|
||||
#[inline]
|
||||
pub fn step(&mut self) -> ResultCode {
|
||||
unsafe { ::result::code_from_raw(raw::sqlite3_step(self.raw)) }
|
||||
}
|
||||
|
||||
/// Reset.
|
||||
/// Reset the statement.
|
||||
#[inline]
|
||||
pub fn reset(&mut self) -> Result<()> {
|
||||
unsafe { success!(raw::sqlite3_reset(self.raw)) };
|
||||
|
@ -25,7 +25,7 @@ fn workflow() {
|
||||
|
||||
{
|
||||
let sql = r#"INSERT INTO `users` (id, name, age) VALUES (?, ?, ?);"#;
|
||||
let mut statement = ok!(database.prepare_statement(sql));
|
||||
let mut statement = ok!(database.prepare(sql));
|
||||
ok!(statement.bind(&[Integer(1, 1), Text(2, "Alice"), Float(3, 20.99)]));
|
||||
assert!(statement.step() == ResultCode::Done);
|
||||
}
|
||||
@ -46,7 +46,7 @@ fn workflow() {
|
||||
|
||||
{
|
||||
let sql = r#"SELECT * FROM `users`;"#;
|
||||
let mut statement = ok!(database.prepare_statement(sql));
|
||||
let mut statement = ok!(database.prepare(sql));
|
||||
assert!(statement.step() == ResultCode::Row);
|
||||
assert!(ok!(statement.column::<i64>(0)) == 1);
|
||||
assert!(ok!(statement.column::<String>(1)) == String::from("Alice"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user