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