mirror of
https://github.com/isar/rusqlite.git
synced 2025-09-16 12:42:18 +08:00
Merge pull request #149 from jgallagher/gwenn-reset
Reset statements ASAP.
This commit is contained in:
89
src/lib.rs
89
src/lib.rs
@@ -521,8 +521,8 @@ impl Connection {
|
||||
impl fmt::Debug for Connection {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("Connection")
|
||||
.field("path", &self.path)
|
||||
.finish()
|
||||
.field("path", &self.path)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,7 +708,6 @@ pub type SqliteStatement<'conn> = Statement<'conn>;
|
||||
pub struct Statement<'conn> {
|
||||
conn: &'conn Connection,
|
||||
stmt: *mut ffi::sqlite3_stmt,
|
||||
needs_reset: bool,
|
||||
column_count: c_int,
|
||||
}
|
||||
|
||||
@@ -717,7 +716,6 @@ impl<'conn> Statement<'conn> {
|
||||
Statement {
|
||||
conn: conn,
|
||||
stmt: stmt,
|
||||
needs_reset: false,
|
||||
column_count: unsafe { ffi::sqlite3_column_count(stmt) },
|
||||
}
|
||||
}
|
||||
@@ -826,13 +824,10 @@ impl<'conn> Statement<'conn> {
|
||||
///
|
||||
/// Will return `Err` if binding parameters fails.
|
||||
pub fn query<'a>(&'a mut self, params: &[&ToSql]) -> Result<Rows<'a>> {
|
||||
self.reset_if_needed();
|
||||
|
||||
unsafe {
|
||||
try!(self.bind_parameters(params));
|
||||
}
|
||||
|
||||
self.needs_reset = true;
|
||||
Ok(Rows::new(self))
|
||||
}
|
||||
|
||||
@@ -906,15 +901,6 @@ impl<'conn> Statement<'conn> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reset_if_needed(&mut self) {
|
||||
if self.needs_reset {
|
||||
unsafe {
|
||||
ffi::sqlite3_reset(self.stmt);
|
||||
};
|
||||
self.needs_reset = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn finalize_(&mut self) -> Result<()> {
|
||||
let r = unsafe { ffi::sqlite3_finalize(self.stmt) };
|
||||
self.stmt = ptr::null_mut();
|
||||
@@ -929,10 +915,10 @@ impl<'conn> fmt::Debug for Statement<'conn> {
|
||||
str::from_utf8(c_slice)
|
||||
};
|
||||
f.debug_struct("Statement")
|
||||
.field("conn", self.conn)
|
||||
.field("stmt", &self.stmt)
|
||||
.field("sql", &sql)
|
||||
.finish()
|
||||
.field("conn", self.conn)
|
||||
.field("stmt", &self.stmt)
|
||||
.field("sql", &sql)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -949,7 +935,8 @@ pub struct MappedRows<'stmt, F> {
|
||||
map: F,
|
||||
}
|
||||
|
||||
impl<'stmt, T, F> Iterator for MappedRows<'stmt, F> where F: FnMut(&Row) -> T
|
||||
impl<'stmt, T, F> Iterator for MappedRows<'stmt, F>
|
||||
where F: FnMut(&Row) -> T
|
||||
{
|
||||
type Item = Result<T>;
|
||||
|
||||
@@ -974,7 +961,7 @@ impl<'stmt, T, E, F> Iterator for AndThenRows<'stmt, F>
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.rows.next().map(|row_result| {
|
||||
row_result.map_err(E::from)
|
||||
.and_then(|row| (self.map)(&row))
|
||||
.and_then(|row| (self.map)(&row))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1015,17 +1002,15 @@ pub type SqliteRows<'stmt> = Rows<'stmt>;
|
||||
/// `min`/`max` (which could return a stale row unless the last row happened to be the min or max,
|
||||
/// respectively).
|
||||
pub struct Rows<'stmt> {
|
||||
stmt: &'stmt Statement<'stmt>,
|
||||
stmt: Option<&'stmt Statement<'stmt>>,
|
||||
current_row: Rc<Cell<c_int>>,
|
||||
failed: bool,
|
||||
}
|
||||
|
||||
impl<'stmt> Rows<'stmt> {
|
||||
fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> {
|
||||
Rows {
|
||||
stmt: stmt,
|
||||
stmt: Some(stmt),
|
||||
current_row: Rc::new(Cell::new(0)),
|
||||
failed: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,31 +1020,47 @@ impl<'stmt> Rows<'stmt> {
|
||||
None => Err(Error::QueryReturnedNoRows),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
if let Some(stmt) = self.stmt.take() {
|
||||
unsafe {
|
||||
ffi::sqlite3_reset(stmt.stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> Iterator for Rows<'stmt> {
|
||||
type Item = Result<Row<'stmt>>;
|
||||
|
||||
fn next(&mut self) -> Option<Result<Row<'stmt>>> {
|
||||
if self.failed {
|
||||
return None;
|
||||
}
|
||||
match unsafe { ffi::sqlite3_step(self.stmt.stmt) } {
|
||||
ffi::SQLITE_ROW => {
|
||||
let current_row = self.current_row.get() + 1;
|
||||
self.current_row.set(current_row);
|
||||
Some(Ok(Row {
|
||||
stmt: self.stmt,
|
||||
current_row: self.current_row.clone(),
|
||||
row_idx: current_row,
|
||||
}))
|
||||
self.stmt.and_then(|stmt| {
|
||||
match unsafe { ffi::sqlite3_step(stmt.stmt) } {
|
||||
ffi::SQLITE_ROW => {
|
||||
let current_row = self.current_row.get() + 1;
|
||||
self.current_row.set(current_row);
|
||||
Some(Ok(Row {
|
||||
stmt: stmt,
|
||||
current_row: self.current_row.clone(),
|
||||
row_idx: current_row,
|
||||
}))
|
||||
}
|
||||
ffi::SQLITE_DONE => {
|
||||
self.reset();
|
||||
None
|
||||
}
|
||||
code => {
|
||||
self.reset();
|
||||
Some(Err(stmt.conn.decode_result(code).unwrap_err()))
|
||||
}
|
||||
}
|
||||
ffi::SQLITE_DONE => None,
|
||||
code => {
|
||||
self.failed = true;
|
||||
Some(Err(self.stmt.conn.decode_result(code).unwrap_err()))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'stmt> Drop for Rows<'stmt> {
|
||||
fn drop(&mut self) {
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user