1 use fallible_iterator::FallibleIterator; 2 use fallible_streaming_iterator::FallibleStreamingIterator; 3 use std::convert; 4 5 use super::{Error, Result, Statement}; 6 use crate::types::{FromSql, FromSqlError, ValueRef}; 7 8 /// An handle for the resulting rows of a query. 9 #[must_use = "Rows is lazy and will do nothing unless consumed"] 10 pub struct Rows<'stmt> { 11 pub(crate) stmt: Option<&'stmt Statement<'stmt>>, 12 row: Option<Row<'stmt>>, 13 } 14 15 impl<'stmt> Rows<'stmt> { 16 #[inline] reset(&mut self)17 fn reset(&mut self) { 18 if let Some(stmt) = self.stmt.take() { 19 stmt.reset(); 20 } 21 } 22 23 /// Attempt to get the next row from the query. Returns `Ok(Some(Row))` if 24 /// there is another row, `Err(...)` if there was an error 25 /// getting the next row, and `Ok(None)` if all rows have been retrieved. 26 /// 27 /// ## Note 28 /// 29 /// This interface is not compatible with Rust's `Iterator` trait, because 30 /// the lifetime of the returned row is tied to the lifetime of `self`. 31 /// This is a fallible "streaming iterator". For a more natural interface, 32 /// consider using [`query_map`](crate::Statement::query_map) or 33 /// [`query_and_then`](crate::Statement::query_and_then) instead, which 34 /// return types that implement `Iterator`. 35 #[allow(clippy::should_implement_trait)] // cannot implement Iterator 36 #[inline] next(&mut self) -> Result<Option<&Row<'stmt>>>37 pub fn next(&mut self) -> Result<Option<&Row<'stmt>>> { 38 self.advance()?; 39 Ok((*self).get()) 40 } 41 42 /// Map over this `Rows`, converting it to a [`Map`], which 43 /// implements `FallibleIterator`. 44 /// ```rust,no_run 45 /// use fallible_iterator::FallibleIterator; 46 /// # use rusqlite::{Result, Statement}; 47 /// fn query(stmt: &mut Statement) -> Result<Vec<i64>> { 48 /// let rows = stmt.query([])?; 49 /// rows.map(|r| r.get(0)).collect() 50 /// } 51 /// ``` 52 // FIXME Hide FallibleStreamingIterator::map 53 #[inline] map<F, B>(self, f: F) -> Map<'stmt, F> where F: FnMut(&Row<'_>) -> Result<B>,54 pub fn map<F, B>(self, f: F) -> Map<'stmt, F> 55 where 56 F: FnMut(&Row<'_>) -> Result<B>, 57 { 58 Map { rows: self, f } 59 } 60 61 /// Map over this `Rows`, converting it to a [`MappedRows`], which 62 /// implements `Iterator`. 63 #[inline] mapped<F, B>(self, f: F) -> MappedRows<'stmt, F> where F: FnMut(&Row<'_>) -> Result<B>,64 pub fn mapped<F, B>(self, f: F) -> MappedRows<'stmt, F> 65 where 66 F: FnMut(&Row<'_>) -> Result<B>, 67 { 68 MappedRows { rows: self, map: f } 69 } 70 71 /// Map over this `Rows` with a fallible function, converting it to a 72 /// [`AndThenRows`], which implements `Iterator` (instead of 73 /// `FallibleStreamingIterator`). 74 #[inline] and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F> where F: FnMut(&Row<'_>) -> Result<T, E>,75 pub fn and_then<F, T, E>(self, f: F) -> AndThenRows<'stmt, F> 76 where 77 F: FnMut(&Row<'_>) -> Result<T, E>, 78 { 79 AndThenRows { rows: self, map: f } 80 } 81 82 /// Give access to the underlying statement 83 #[must_use] as_ref(&self) -> Option<&Statement<'stmt>>84 pub fn as_ref(&self) -> Option<&Statement<'stmt>> { 85 self.stmt 86 } 87 } 88 89 impl<'stmt> Rows<'stmt> { 90 #[inline] new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt>91 pub(crate) fn new(stmt: &'stmt Statement<'stmt>) -> Rows<'stmt> { 92 Rows { 93 stmt: Some(stmt), 94 row: None, 95 } 96 } 97 98 #[inline] get_expected_row(&mut self) -> Result<&Row<'stmt>>99 pub(crate) fn get_expected_row(&mut self) -> Result<&Row<'stmt>> { 100 match self.next()? { 101 Some(row) => Ok(row), 102 None => Err(Error::QueryReturnedNoRows), 103 } 104 } 105 } 106 107 impl Drop for Rows<'_> { 108 #[inline] drop(&mut self)109 fn drop(&mut self) { 110 self.reset(); 111 } 112 } 113 114 /// `F` is used to transform the _streaming_ iterator into a _fallible_ 115 /// iterator. 116 #[must_use = "iterators are lazy and do nothing unless consumed"] 117 pub struct Map<'stmt, F> { 118 rows: Rows<'stmt>, 119 f: F, 120 } 121 122 impl<F, B> FallibleIterator for Map<'_, F> 123 where 124 F: FnMut(&Row<'_>) -> Result<B>, 125 { 126 type Error = Error; 127 type Item = B; 128 129 #[inline] next(&mut self) -> Result<Option<B>>130 fn next(&mut self) -> Result<Option<B>> { 131 match self.rows.next()? { 132 Some(v) => Ok(Some((self.f)(v)?)), 133 None => Ok(None), 134 } 135 } 136 } 137 138 /// An iterator over the mapped resulting rows of a query. 139 /// 140 /// `F` is used to transform the _streaming_ iterator into a _standard_ 141 /// iterator. 142 #[must_use = "iterators are lazy and do nothing unless consumed"] 143 pub struct MappedRows<'stmt, F> { 144 rows: Rows<'stmt>, 145 map: F, 146 } 147 148 impl<T, F> Iterator for MappedRows<'_, F> 149 where 150 F: FnMut(&Row<'_>) -> Result<T>, 151 { 152 type Item = Result<T>; 153 154 #[inline] next(&mut self) -> Option<Result<T>>155 fn next(&mut self) -> Option<Result<T>> { 156 let map = &mut self.map; 157 self.rows 158 .next() 159 .transpose() 160 .map(|row_result| row_result.and_then(map)) 161 } 162 } 163 164 /// An iterator over the mapped resulting rows of a query, with an Error type 165 /// unifying with Error. 166 #[must_use = "iterators are lazy and do nothing unless consumed"] 167 pub struct AndThenRows<'stmt, F> { 168 rows: Rows<'stmt>, 169 map: F, 170 } 171 172 impl<T, E, F> Iterator for AndThenRows<'_, F> 173 where 174 E: convert::From<Error>, 175 F: FnMut(&Row<'_>) -> Result<T, E>, 176 { 177 type Item = Result<T, E>; 178 179 #[inline] next(&mut self) -> Option<Self::Item>180 fn next(&mut self) -> Option<Self::Item> { 181 let map = &mut self.map; 182 self.rows 183 .next() 184 .transpose() 185 .map(|row_result| row_result.map_err(E::from).and_then(map)) 186 } 187 } 188 189 /// `FallibleStreamingIterator` differs from the standard library's `Iterator` 190 /// in two ways: 191 /// * each call to `next` (`sqlite3_step`) can fail. 192 /// * returned `Row` is valid until `next` is called again or `Statement` is 193 /// reset or finalized. 194 /// 195 /// While these iterators cannot be used with Rust `for` loops, `while let` 196 /// loops offer a similar level of ergonomics: 197 /// ```rust,no_run 198 /// # use rusqlite::{Result, Statement}; 199 /// fn query(stmt: &mut Statement) -> Result<()> { 200 /// let mut rows = stmt.query([])?; 201 /// while let Some(row) = rows.next()? { 202 /// // scan columns value 203 /// } 204 /// Ok(()) 205 /// } 206 /// ``` 207 impl<'stmt> FallibleStreamingIterator for Rows<'stmt> { 208 type Error = Error; 209 type Item = Row<'stmt>; 210 211 #[inline] advance(&mut self) -> Result<()>212 fn advance(&mut self) -> Result<()> { 213 if let Some(stmt) = self.stmt { 214 match stmt.step() { 215 Ok(true) => { 216 self.row = Some(Row { stmt }); 217 Ok(()) 218 } 219 Ok(false) => { 220 self.reset(); 221 self.row = None; 222 Ok(()) 223 } 224 Err(e) => { 225 self.reset(); 226 self.row = None; 227 Err(e) 228 } 229 } 230 } else { 231 self.row = None; 232 Ok(()) 233 } 234 } 235 236 #[inline] get(&self) -> Option<&Row<'stmt>>237 fn get(&self) -> Option<&Row<'stmt>> { 238 self.row.as_ref() 239 } 240 } 241 242 /// A single result row of a query. 243 pub struct Row<'stmt> { 244 pub(crate) stmt: &'stmt Statement<'stmt>, 245 } 246 247 impl<'stmt> Row<'stmt> { 248 /// Get the value of a particular column of the result row. 249 /// 250 /// ## Failure 251 /// 252 /// Panics if calling [`row.get(idx)`](Row::get) would return an error, 253 /// including: 254 /// 255 /// * If the underlying SQLite column type is not a valid type as a source 256 /// for `T` 257 /// * If the underlying SQLite integral value is outside the range 258 /// representable by `T` 259 /// * If `idx` is outside the range of columns in the returned query get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T260 pub fn get_unwrap<I: RowIndex, T: FromSql>(&self, idx: I) -> T { 261 self.get(idx).unwrap() 262 } 263 264 /// Get the value of a particular column of the result row. 265 /// 266 /// ## Failure 267 /// 268 /// Returns an `Error::InvalidColumnType` if the underlying SQLite column 269 /// type is not a valid type as a source for `T`. 270 /// 271 /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid 272 /// column range for this row. 273 /// 274 /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column 275 /// name for this row. 276 /// 277 /// If the result type is i128 (which requires the `i128_blob` feature to be 278 /// enabled), and the underlying SQLite column is a blob whose size is not 279 /// 16 bytes, `Error::InvalidColumnType` will also be returned. get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T>280 pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> Result<T> { 281 let idx = idx.idx(self.stmt)?; 282 let value = self.stmt.value_ref(idx); 283 FromSql::column_result(value).map_err(|err| match err { 284 FromSqlError::InvalidType => Error::InvalidColumnType( 285 idx, 286 self.stmt.column_name_unwrap(idx).into(), 287 value.data_type(), 288 ), 289 FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i), 290 FromSqlError::Other(err) => { 291 Error::FromSqlConversionFailure(idx, value.data_type(), err) 292 } 293 FromSqlError::InvalidBlobSize { .. } => { 294 Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err)) 295 } 296 }) 297 } 298 299 /// Get the value of a particular column of the result row as a `ValueRef`, 300 /// allowing data to be read out of a row without copying. 301 /// 302 /// This `ValueRef` is valid only as long as this Row, which is enforced by 303 /// it's lifetime. This means that while this method is completely safe, 304 /// it can be somewhat difficult to use, and most callers will be better 305 /// served by [`get`](Row::get) or [`get_unwrap`](Row::get_unwrap). 306 /// 307 /// ## Failure 308 /// 309 /// Returns an `Error::InvalidColumnIndex` if `idx` is outside the valid 310 /// column range for this row. 311 /// 312 /// Returns an `Error::InvalidColumnName` if `idx` is not a valid column 313 /// name for this row. get_ref<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>>314 pub fn get_ref<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>> { 315 let idx = idx.idx(self.stmt)?; 316 // Narrowing from `ValueRef<'stmt>` (which `self.stmt.value_ref(idx)` 317 // returns) to `ValueRef<'a>` is needed because it's only valid until 318 // the next call to sqlite3_step. 319 let val_ref = self.stmt.value_ref(idx); 320 Ok(val_ref) 321 } 322 323 /// Get the value of a particular column of the result row as a `ValueRef`, 324 /// allowing data to be read out of a row without copying. 325 /// 326 /// This `ValueRef` is valid only as long as this Row, which is enforced by 327 /// it's lifetime. This means that while this method is completely safe, 328 /// it can be difficult to use, and most callers will be better served by 329 /// [`get`](Row::get) or [`get_unwrap`](Row::get_unwrap). 330 /// 331 /// ## Failure 332 /// 333 /// Panics if calling [`row.get_ref(idx)`](Row::get_ref) would return an 334 /// error, including: 335 /// 336 /// * If `idx` is outside the range of columns in the returned query. 337 /// * If `idx` is not a valid column name for this row. get_ref_unwrap<I: RowIndex>(&self, idx: I) -> ValueRef<'_>338 pub fn get_ref_unwrap<I: RowIndex>(&self, idx: I) -> ValueRef<'_> { 339 self.get_ref(idx).unwrap() 340 } 341 342 /// Renamed to [`get_ref`](Row::get_ref). 343 #[deprecated = "Use [`get_ref`](Row::get_ref) instead."] 344 #[inline] get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>>345 pub fn get_raw_checked<I: RowIndex>(&self, idx: I) -> Result<ValueRef<'_>> { 346 self.get_ref(idx) 347 } 348 349 /// Renamed to [`get_ref_unwrap`](Row::get_ref_unwrap). 350 #[deprecated = "Use [`get_ref_unwrap`](Row::get_ref_unwrap) instead."] 351 #[inline] get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_>352 pub fn get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'_> { 353 self.get_ref_unwrap(idx) 354 } 355 } 356 357 impl<'stmt> AsRef<Statement<'stmt>> for Row<'stmt> { as_ref(&self) -> &Statement<'stmt>358 fn as_ref(&self) -> &Statement<'stmt> { 359 self.stmt 360 } 361 } 362 363 mod sealed { 364 /// This trait exists just to ensure that the only impls of `trait Params` 365 /// that are allowed are ones in this crate. 366 pub trait Sealed {} 367 impl Sealed for usize {} 368 impl Sealed for &str {} 369 } 370 371 /// A trait implemented by types that can index into columns of a row. 372 /// 373 /// It is only implemented for `usize` and `&str`. 374 pub trait RowIndex: sealed::Sealed { 375 /// Returns the index of the appropriate column, or `None` if no such 376 /// column exists. idx(&self, stmt: &Statement<'_>) -> Result<usize>377 fn idx(&self, stmt: &Statement<'_>) -> Result<usize>; 378 } 379 380 impl RowIndex for usize { 381 #[inline] idx(&self, stmt: &Statement<'_>) -> Result<usize>382 fn idx(&self, stmt: &Statement<'_>) -> Result<usize> { 383 if *self >= stmt.column_count() { 384 Err(Error::InvalidColumnIndex(*self)) 385 } else { 386 Ok(*self) 387 } 388 } 389 } 390 391 impl RowIndex for &'_ str { 392 #[inline] idx(&self, stmt: &Statement<'_>) -> Result<usize>393 fn idx(&self, stmt: &Statement<'_>) -> Result<usize> { 394 stmt.column_index(*self) 395 } 396 } 397 398 macro_rules! tuple_try_from_row { 399 ($($field:ident),*) => { 400 impl<'a, $($field,)*> convert::TryFrom<&'a Row<'a>> for ($($field,)*) where $($field: FromSql,)* { 401 type Error = crate::Error; 402 403 // we end with index += 1, which rustc warns about 404 // unused_variables and unused_mut are allowed for () 405 #[allow(unused_assignments, unused_variables, unused_mut)] 406 fn try_from(row: &'a Row<'a>) -> Result<Self> { 407 let mut index = 0; 408 $( 409 #[allow(non_snake_case)] 410 let $field = row.get::<_, $field>(index)?; 411 index += 1; 412 )* 413 Ok(($($field,)*)) 414 } 415 } 416 } 417 } 418 419 macro_rules! tuples_try_from_row { 420 () => { 421 // not very useful, but maybe some other macro users will find this helpful 422 tuple_try_from_row!(); 423 }; 424 ($first:ident $(, $remaining:ident)*) => { 425 tuple_try_from_row!($first $(, $remaining)*); 426 tuples_try_from_row!($($remaining),*); 427 }; 428 } 429 430 tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); 431 432 #[cfg(test)] 433 mod tests { 434 #![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594 435 use crate::{Connection, Result}; 436 437 #[test] test_try_from_row_for_tuple_1() -> Result<()>438 fn test_try_from_row_for_tuple_1() -> Result<()> { 439 use crate::ToSql; 440 use std::convert::TryFrom; 441 442 let conn = Connection::open_in_memory()?; 443 conn.execute( 444 "CREATE TABLE test (a INTEGER)", 445 crate::params_from_iter(std::iter::empty::<&dyn ToSql>()), 446 )?; 447 conn.execute("INSERT INTO test VALUES (42)", [])?; 448 let val = conn.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))?; 449 assert_eq!(val, (42,)); 450 let fail = conn.query_row("SELECT a FROM test", [], |row| <(u32, u32)>::try_from(row)); 451 assert!(fail.is_err()); 452 Ok(()) 453 } 454 455 #[test] test_try_from_row_for_tuple_2() -> Result<()>456 fn test_try_from_row_for_tuple_2() -> Result<()> { 457 use std::convert::TryFrom; 458 459 let conn = Connection::open_in_memory()?; 460 conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])?; 461 conn.execute("INSERT INTO test VALUES (42, 47)", [])?; 462 let val = conn.query_row("SELECT a, b FROM test", [], |row| { 463 <(u32, u32)>::try_from(row) 464 })?; 465 assert_eq!(val, (42, 47)); 466 let fail = conn.query_row("SELECT a, b FROM test", [], |row| { 467 <(u32, u32, u32)>::try_from(row) 468 }); 469 assert!(fail.is_err()); 470 Ok(()) 471 } 472 473 #[test] test_try_from_row_for_tuple_16() -> Result<()>474 fn test_try_from_row_for_tuple_16() -> Result<()> { 475 use std::convert::TryFrom; 476 477 let create_table = "CREATE TABLE test ( 478 a INTEGER, 479 b INTEGER, 480 c INTEGER, 481 d INTEGER, 482 e INTEGER, 483 f INTEGER, 484 g INTEGER, 485 h INTEGER, 486 i INTEGER, 487 j INTEGER, 488 k INTEGER, 489 l INTEGER, 490 m INTEGER, 491 n INTEGER, 492 o INTEGER, 493 p INTEGER 494 )"; 495 496 let insert_values = "INSERT INTO test VALUES ( 497 0, 498 1, 499 2, 500 3, 501 4, 502 5, 503 6, 504 7, 505 8, 506 9, 507 10, 508 11, 509 12, 510 13, 511 14, 512 15 513 )"; 514 515 type BigTuple = ( 516 u32, 517 u32, 518 u32, 519 u32, 520 u32, 521 u32, 522 u32, 523 u32, 524 u32, 525 u32, 526 u32, 527 u32, 528 u32, 529 u32, 530 u32, 531 u32, 532 ); 533 534 let conn = Connection::open_in_memory()?; 535 conn.execute(create_table, [])?; 536 conn.execute(insert_values, [])?; 537 let val = conn.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))?; 538 // Debug is not implemented for tuples of 16 539 assert_eq!(val.0, 0); 540 assert_eq!(val.1, 1); 541 assert_eq!(val.2, 2); 542 assert_eq!(val.3, 3); 543 assert_eq!(val.4, 4); 544 assert_eq!(val.5, 5); 545 assert_eq!(val.6, 6); 546 assert_eq!(val.7, 7); 547 assert_eq!(val.8, 8); 548 assert_eq!(val.9, 9); 549 assert_eq!(val.10, 10); 550 assert_eq!(val.11, 11); 551 assert_eq!(val.12, 12); 552 assert_eq!(val.13, 13); 553 assert_eq!(val.14, 14); 554 assert_eq!(val.15, 15); 555 556 // We don't test one bigger because it's unimplemented 557 Ok(()) 558 } 559 } 560