mirror of
				https://github.com/isar/rusqlite.git
				synced 2025-10-31 22:08:55 +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