Skip to main content

uqa_client/
sql_statement.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7use std::fmt;
8
9use serde::Serialize;
10use uqa_sql::SQLParam;
11
12use crate::{sql_parameter::SQLParameter, HttpEngineError};
13
14/// Owned SQL text and typed bind parameters for one HTTP operation.
15#[derive(Serialize)]
16pub struct SQLStatement {
17    sql: String,
18    params: Vec<SQLParameter>,
19}
20
21impl SQLStatement {
22    pub fn new(sql: impl Into<String>, params: &[SQLParam]) -> Result<Self, HttpEngineError> {
23        let sql = sql.into();
24        if sql.trim().is_empty() {
25            return Err(HttpEngineError::EmptySQL);
26        }
27        let params = params
28            .iter()
29            .map(SQLParameter::try_from)
30            .collect::<Result<_, _>>()?;
31        Ok(Self { sql, params })
32    }
33}
34
35impl fmt::Debug for SQLStatement {
36    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37        formatter
38            .debug_struct("SQLStatement")
39            .field("sql", &"[REDACTED]")
40            .field("parameter_count", &self.params.len())
41            .finish()
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn debug_output_omits_sql() {
51        let statement = SQLStatement::new("SELECT customer_secret", &[]).unwrap();
52        assert!(!format!("{statement:?}").contains("customer_secret"));
53    }
54}