Skip to main content

sql_middleware/sqlite/
query.rs

1use rusqlite::types::Value;
2use rusqlite::{Statement, ToSql};
3
4use crate::adapters::result_set::{column_count, init_result_set};
5use crate::middleware::{ResultSet, RowValues, SqlMiddlewareDbError};
6use crate::query_utils::extract_column_names;
7
8/// Extract a `RowValues` from a `SQLite` row.
9///
10/// # Errors
11///
12/// Returns `SqlMiddlewareDbError` if the value cannot be converted.
13pub fn sqlite_extract_value_sync(
14    row: &rusqlite::Row,
15    idx: usize,
16) -> Result<RowValues, SqlMiddlewareDbError> {
17    let value: Value = row.get(idx).map_err(SqlMiddlewareDbError::SqliteError)?;
18    match value {
19        Value::Null => Ok(RowValues::Null),
20        Value::Integer(i) => Ok(RowValues::Int(i)),
21        Value::Real(f) => Ok(RowValues::Float(f)),
22        Value::Text(s) => Ok(RowValues::Text(s)),
23        Value::Blob(b) => Ok(RowValues::Blob(b)),
24    }
25}
26
27/// Build a result set from a `SQLite` query
28/// Only SELECT queries return rows affected. If a DML is sent, it does run it.
29/// If there's more than one query in the statement, idk which statement will be run.
30///
31/// # Errors
32/// Returns `SqlMiddlewareDbError::ExecutionError` if query execution or result processing fails.
33pub fn build_result_set(
34    stmt: &mut Statement,
35    params: &[Value],
36) -> Result<ResultSet, SqlMiddlewareDbError> {
37    let param_refs: Vec<&dyn ToSql> = params.iter().map(|v| v as &dyn ToSql).collect();
38    let column_names = extract_column_names(stmt.column_names().iter(), |name| *name);
39
40    let mut rows_iter = stmt.query(&param_refs[..])?;
41    // Create result set with default capacity
42    let mut result_set = init_result_set(column_names, 10);
43
44    while let Some(row) = rows_iter.next()? {
45        let mut row_values = Vec::new();
46
47        let col_count = column_count(&result_set)?;
48
49        for i in 0..col_count {
50            let value = sqlite_extract_value_sync(row, i)?;
51            row_values.push(value);
52        }
53
54        result_set.add_row_values(row_values);
55    }
56
57    Ok(result_set)
58}