Janis Danisevskis | bf15d73 | 2020-12-08 10:35:26 -0800 | [diff] [blame^] | 1 | // Copyright 2020, The Android Open Source Project |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | use crate::error::Error as KsError; |
| 16 | use anyhow::{Context, Result}; |
| 17 | use rusqlite::{Row, Rows}; |
| 18 | |
| 19 | // Takes Rows as returned by a query call on prepared statement. |
| 20 | // Extracts exactly one row with the `row_extractor` and fails if more |
| 21 | // rows are available. |
| 22 | // If no row was found, `None` is passed to the `row_extractor`. |
| 23 | // This allows the row extractor to decide on an error condition or |
| 24 | // a different default behavior. |
| 25 | pub fn with_rows_extract_one<'a, T, F>(rows: &mut Rows<'a>, row_extractor: F) -> Result<T> |
| 26 | where |
| 27 | F: FnOnce(Option<&Row<'a>>) -> Result<T>, |
| 28 | { |
| 29 | let result = |
| 30 | row_extractor(rows.next().context("with_rows_extract_one: Failed to unpack row.")?); |
| 31 | |
| 32 | rows.next() |
| 33 | .context("In with_rows_extract_one: Failed to unpack unexpected row.")? |
| 34 | .map_or_else(|| Ok(()), |_| Err(KsError::sys())) |
| 35 | .context("In with_rows_extract_one: Unexpected row.")?; |
| 36 | |
| 37 | result |
| 38 | } |
| 39 | |
| 40 | pub fn with_rows_extract_all<'a, F>(rows: &mut Rows<'a>, mut row_extractor: F) -> Result<()> |
| 41 | where |
| 42 | F: FnMut(&Row<'a>) -> Result<()>, |
| 43 | { |
| 44 | loop { |
| 45 | match rows.next().context("In with_rows_extract_all: Failed to unpack row")? { |
| 46 | Some(row) => { |
| 47 | row_extractor(&row).context("In with_rows_extract_all.")?; |
| 48 | } |
| 49 | None => break Ok(()), |
| 50 | } |
| 51 | } |
| 52 | } |