mirror of
https://github.com/fluencelabs/sqlite-wasm-connector
synced 2025-04-22 07:32:14 +00:00
Add a function to read the current state of a statement
This commit is contained in:
parent
dcff91a699
commit
42515bc5ec
@ -6,6 +6,7 @@ use {Result, Type, Value};
|
|||||||
|
|
||||||
/// A prepared statement.
|
/// A prepared statement.
|
||||||
pub struct Statement<'l> {
|
pub struct Statement<'l> {
|
||||||
|
state: Option<State>,
|
||||||
raw: (*mut ffi::sqlite3_stmt, *mut ffi::sqlite3),
|
raw: (*mut ffi::sqlite3_stmt, *mut ffi::sqlite3),
|
||||||
phantom: PhantomData<(ffi::sqlite3_stmt, &'l ffi::sqlite3)>,
|
phantom: PhantomData<(ffi::sqlite3_stmt, &'l ffi::sqlite3)>,
|
||||||
}
|
}
|
||||||
@ -15,37 +16,64 @@ pub struct Statement<'l> {
|
|||||||
pub enum State {
|
pub enum State {
|
||||||
/// There is a row available for reading.
|
/// There is a row available for reading.
|
||||||
Row,
|
Row,
|
||||||
/// There is nothing else to read.
|
/// The statement has been entirely evaluated.
|
||||||
Done,
|
Done,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type suitable for binding to a parameter of a prepared statement.
|
/// A type suitable for binding to a prepared statement.
|
||||||
pub trait Bindable {
|
pub trait Bindable {
|
||||||
/// Bind to a particular parameter.
|
/// Bind to a parameter.
|
||||||
///
|
///
|
||||||
/// The leftmost parameter has the index 1.
|
/// The leftmost parameter has the index 1.
|
||||||
fn bind(&self, &mut Statement, usize) -> Result<()>;
|
fn bind(&self, &mut Statement, usize) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type suitable for reading from a column of a prepared statement.
|
/// A type suitable for reading from a prepared statement.
|
||||||
pub trait Readable {
|
pub trait Readable {
|
||||||
/// Read from a particular column.
|
/// Read from a column.
|
||||||
///
|
///
|
||||||
/// The leftmost column has the index 0.
|
/// The leftmost column has the index 0.
|
||||||
fn read(&Statement, usize) -> Result<Self>;
|
fn read(&Statement, usize) -> Result<Self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l> Statement<'l> {
|
impl<'l> Statement<'l> {
|
||||||
|
/// Bind a value to a parameter.
|
||||||
|
///
|
||||||
|
/// The leftmost parameter has the index 1.
|
||||||
|
#[inline]
|
||||||
|
pub fn bind<T: Bindable>(&mut self, i: usize, parameter: T) -> Result<()> {
|
||||||
|
parameter.bind(self, i)
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the number of columns.
|
/// Return the number of columns.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn columns(&self) -> usize {
|
pub fn columns(&self) -> usize {
|
||||||
unsafe { ffi::sqlite3_column_count(self.raw.0) as usize }
|
unsafe { ffi::sqlite3_column_count(self.raw.0) as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Advance the statement to the next state.
|
||||||
|
///
|
||||||
|
/// The function should be called multiple times until `State::Done` is
|
||||||
|
/// reached in order to evaluate the statement entirely.
|
||||||
|
pub fn step(&mut self) -> Result<State> {
|
||||||
|
let state = match unsafe { ffi::sqlite3_step(self.raw.0) } {
|
||||||
|
ffi::SQLITE_ROW => State::Row,
|
||||||
|
ffi::SQLITE_DONE => State::Done,
|
||||||
|
code => error!(self.raw.1, code),
|
||||||
|
};
|
||||||
|
self.state = Some(state);
|
||||||
|
Ok(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the current state.
|
||||||
|
#[inline]
|
||||||
|
pub fn state(&self) -> Option<State> {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the type of a column.
|
/// Return the type of a column.
|
||||||
///
|
///
|
||||||
/// The type is revealed after the first step has been taken.
|
/// The type is revealed after the first step has been taken.
|
||||||
#[inline]
|
|
||||||
pub fn kind(&self, i: usize) -> Type {
|
pub fn kind(&self, i: usize) -> Type {
|
||||||
match unsafe { ffi::sqlite3_column_type(self.raw.0, i as c_int) } {
|
match unsafe { ffi::sqlite3_column_type(self.raw.0, i as c_int) } {
|
||||||
ffi::SQLITE_BLOB => Type::Binary,
|
ffi::SQLITE_BLOB => Type::Binary,
|
||||||
@ -57,15 +85,7 @@ impl<'l> Statement<'l> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind the parameter at a specific location.
|
/// Read a value from a column.
|
||||||
///
|
|
||||||
/// The leftmost location has the index 1.
|
|
||||||
#[inline]
|
|
||||||
pub fn bind<T: Bindable>(&mut self, i: usize, parameter: T) -> Result<()> {
|
|
||||||
parameter.bind(self, i)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read the value stored in a specific column.
|
|
||||||
///
|
///
|
||||||
/// The leftmost column has the index 0.
|
/// The leftmost column has the index 0.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -73,22 +93,11 @@ impl<'l> Statement<'l> {
|
|||||||
Readable::read(self, i)
|
Readable::read(self, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate the statement one step at a time.
|
|
||||||
///
|
|
||||||
/// The function should be called multiple times until `State::Done` is
|
|
||||||
/// reached in order to evaluate the statement entirely.
|
|
||||||
pub fn step(&mut self) -> Result<State> {
|
|
||||||
match unsafe { ffi::sqlite3_step(self.raw.0) } {
|
|
||||||
ffi::SQLITE_DONE => Ok(State::Done),
|
|
||||||
ffi::SQLITE_ROW => Ok(State::Row),
|
|
||||||
code => error!(self.raw.1, code),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the statement.
|
/// Reset the statement.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(&mut self) -> Result<()> {
|
pub fn reset(&mut self) -> Result<()> {
|
||||||
unsafe { ok!(self.raw.1, ffi::sqlite3_reset(self.raw.0)) };
|
unsafe { ok!(self.raw.1, ffi::sqlite3_reset(self.raw.0)) };
|
||||||
|
self.state = None;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,5 +251,5 @@ pub fn new<'l, T: AsRef<str>>(raw1: *mut ffi::sqlite3, statement: T) -> Result<S
|
|||||||
ok!(raw1, ffi::sqlite3_prepare_v2(raw1, str_to_cstr!(statement.as_ref()).as_ptr(), -1,
|
ok!(raw1, ffi::sqlite3_prepare_v2(raw1, str_to_cstr!(statement.as_ref()).as_ptr(), -1,
|
||||||
&mut raw0, 0 as *mut _));
|
&mut raw0, 0 as *mut _));
|
||||||
}
|
}
|
||||||
Ok(Statement { raw: (raw0, raw1), phantom: PhantomData })
|
Ok(Statement { state: None, raw: (raw0, raw1), phantom: PhantomData })
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user