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: 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 343 impl<'stmt> AsRef<Statement<'stmt>> for Row<'stmt> { as_ref(&self) -> &Statement<'stmt>344 fn as_ref(&self) -> &Statement<'stmt> { 345 self.stmt 346 } 347 } 348 349 /// Debug `Row` like an ordered `Map<Result<&str>, Result<(Type, ValueRef)>>` 350 /// with column name as key except that for `Type::Blob` only its size is 351 /// printed (not its content). 352 impl<'stmt> std::fmt::Debug for Row<'stmt> { fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result353 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 354 let mut dm = f.debug_map(); 355 for c in 0..self.stmt.column_count() { 356 let name = self.stmt.column_name(c); 357 dm.key(&name); 358 let value = self.get_ref(c); 359 match value { 360 Ok(value) => { 361 let dt = value.data_type(); 362 match value { 363 ValueRef::Null => { 364 dm.value(&(dt, ())); 365 } 366 ValueRef::Integer(i) => { 367 dm.value(&(dt, i)); 368 } 369 ValueRef::Real(f) => { 370 dm.value(&(dt, f)); 371 } 372 ValueRef::Text(s) => { 373 dm.value(&(dt, String::from_utf8_lossy(s))); 374 } 375 ValueRef::Blob(b) => { 376 dm.value(&(dt, b.len())); 377 } 378 } 379 } 380 Err(ref _err) => { 381 dm.value(&value); 382 } 383 } 384 } 385 dm.finish() 386 } 387 } 388 389 mod sealed { 390 /// This trait exists just to ensure that the only impls of `trait Params` 391 /// that are allowed are ones in this crate. 392 pub trait Sealed {} 393 impl Sealed for usize {} 394 impl Sealed for &str {} 395 } 396 397 /// A trait implemented by types that can index into columns of a row. 398 /// 399 /// It is only implemented for `usize` and `&str`. 400 pub trait RowIndex: sealed::Sealed { 401 /// Returns the index of the appropriate column, or `None` if no such 402 /// column exists. idx(&self, stmt: &Statement<'_>) -> Result<usize>403 fn idx(&self, stmt: &Statement<'_>) -> Result<usize>; 404 } 405 406 impl RowIndex for usize { 407 #[inline] idx(&self, stmt: &Statement<'_>) -> Result<usize>408 fn idx(&self, stmt: &Statement<'_>) -> Result<usize> { 409 if *self >= stmt.column_count() { 410 Err(Error::InvalidColumnIndex(*self)) 411 } else { 412 Ok(*self) 413 } 414 } 415 } 416 417 impl RowIndex for &'_ str { 418 #[inline] idx(&self, stmt: &Statement<'_>) -> Result<usize>419 fn idx(&self, stmt: &Statement<'_>) -> Result<usize> { 420 stmt.column_index(self) 421 } 422 } 423 424 macro_rules! tuple_try_from_row { 425 ($($field:ident),*) => { 426 impl<'a, $($field,)*> convert::TryFrom<&'a Row<'a>> for ($($field,)*) where $($field: FromSql,)* { 427 type Error = crate::Error; 428 429 // we end with index += 1, which rustc warns about 430 // unused_variables and unused_mut are allowed for () 431 #[allow(unused_assignments, unused_variables, unused_mut)] 432 fn try_from(row: &'a Row<'a>) -> Result<Self> { 433 let mut index = 0; 434 $( 435 #[allow(non_snake_case)] 436 let $field = row.get::<_, $field>(index)?; 437 index += 1; 438 )* 439 Ok(($($field,)*)) 440 } 441 } 442 } 443 } 444 445 macro_rules! tuples_try_from_row { 446 () => { 447 // not very useful, but maybe some other macro users will find this helpful 448 tuple_try_from_row!(); 449 }; 450 ($first:ident $(, $remaining:ident)*) => { 451 tuple_try_from_row!($first $(, $remaining)*); 452 tuples_try_from_row!($($remaining),*); 453 }; 454 } 455 456 tuples_try_from_row!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); 457 458 #[cfg(test)] 459 mod tests { 460 #![allow(clippy::redundant_closure)] // false positives due to lifetime issues; clippy issue #5594 461 use crate::{Connection, Result}; 462 463 #[test] test_try_from_row_for_tuple_1() -> Result<()>464 fn test_try_from_row_for_tuple_1() -> Result<()> { 465 use crate::ToSql; 466 use std::convert::TryFrom; 467 468 let conn = Connection::open_in_memory()?; 469 conn.execute( 470 "CREATE TABLE test (a INTEGER)", 471 crate::params_from_iter(std::iter::empty::<&dyn ToSql>()), 472 )?; 473 conn.execute("INSERT INTO test VALUES (42)", [])?; 474 let val = conn.query_row("SELECT a FROM test", [], |row| <(u32,)>::try_from(row))?; 475 assert_eq!(val, (42,)); 476 let fail = conn.query_row("SELECT a FROM test", [], |row| <(u32, u32)>::try_from(row)); 477 fail.unwrap_err(); 478 Ok(()) 479 } 480 481 #[test] test_try_from_row_for_tuple_2() -> Result<()>482 fn test_try_from_row_for_tuple_2() -> Result<()> { 483 use std::convert::TryFrom; 484 485 let conn = Connection::open_in_memory()?; 486 conn.execute("CREATE TABLE test (a INTEGER, b INTEGER)", [])?; 487 conn.execute("INSERT INTO test VALUES (42, 47)", [])?; 488 let val = conn.query_row("SELECT a, b FROM test", [], |row| { 489 <(u32, u32)>::try_from(row) 490 })?; 491 assert_eq!(val, (42, 47)); 492 let fail = conn.query_row("SELECT a, b FROM test", [], |row| { 493 <(u32, u32, u32)>::try_from(row) 494 }); 495 fail.unwrap_err(); 496 Ok(()) 497 } 498 499 #[test] test_try_from_row_for_tuple_16() -> Result<()>500 fn test_try_from_row_for_tuple_16() -> Result<()> { 501 use std::convert::TryFrom; 502 503 let create_table = "CREATE TABLE test ( 504 a INTEGER, 505 b INTEGER, 506 c INTEGER, 507 d INTEGER, 508 e INTEGER, 509 f INTEGER, 510 g INTEGER, 511 h INTEGER, 512 i INTEGER, 513 j INTEGER, 514 k INTEGER, 515 l INTEGER, 516 m INTEGER, 517 n INTEGER, 518 o INTEGER, 519 p INTEGER 520 )"; 521 522 let insert_values = "INSERT INTO test VALUES ( 523 0, 524 1, 525 2, 526 3, 527 4, 528 5, 529 6, 530 7, 531 8, 532 9, 533 10, 534 11, 535 12, 536 13, 537 14, 538 15 539 )"; 540 541 type BigTuple = ( 542 u32, 543 u32, 544 u32, 545 u32, 546 u32, 547 u32, 548 u32, 549 u32, 550 u32, 551 u32, 552 u32, 553 u32, 554 u32, 555 u32, 556 u32, 557 u32, 558 ); 559 560 let conn = Connection::open_in_memory()?; 561 conn.execute(create_table, [])?; 562 conn.execute(insert_values, [])?; 563 let val = conn.query_row("SELECT * FROM test", [], |row| BigTuple::try_from(row))?; 564 // Debug is not implemented for tuples of 16 565 assert_eq!(val.0, 0); 566 assert_eq!(val.1, 1); 567 assert_eq!(val.2, 2); 568 assert_eq!(val.3, 3); 569 assert_eq!(val.4, 4); 570 assert_eq!(val.5, 5); 571 assert_eq!(val.6, 6); 572 assert_eq!(val.7, 7); 573 assert_eq!(val.8, 8); 574 assert_eq!(val.9, 9); 575 assert_eq!(val.10, 10); 576 assert_eq!(val.11, 11); 577 assert_eq!(val.12, 12); 578 assert_eq!(val.13, 13); 579 assert_eq!(val.14, 14); 580 assert_eq!(val.15, 15); 581 582 // We don't test one bigger because it's unimplemented 583 Ok(()) 584 } 585 } 586