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