blob: 615005f5558391e6ad5e1ada34174ef53f2c5cbe [file] [log] [blame]
Janis Danisevskisbf15d732020-12-08 10:35:26 -08001// 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
15use crate::error::Error as KsError;
16use anyhow::{Context, Result};
17use 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.
25pub fn with_rows_extract_one<'a, T, F>(rows: &mut Rows<'a>, row_extractor: F) -> Result<T>
26where
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
40pub fn with_rows_extract_all<'a, F>(rows: &mut Rows<'a>, mut row_extractor: F) -> Result<()>
41where
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}