veloq_query/sql/
fragment.rs1use duckdb::types::Value;
2
3#[derive(Debug, Clone, Default, PartialEq)]
5pub struct SqlFragment {
6 pub sql: String,
7 pub params: Vec<Value>,
8}
9
10impl SqlFragment {
11 pub fn new(sql: impl Into<String>, params: Vec<Value>) -> Self {
12 Self {
13 sql: sql.into(),
14 params,
15 }
16 }
17}
18
19#[derive(Debug, Clone, Default, PartialEq)]
22pub struct SqlFilter {
23 parts: Vec<String>,
24 params: Vec<Value>,
25}
26
27impl SqlFilter {
28 pub fn push_predicate(&mut self, sql: impl Into<String>) {
29 self.parts.push(sql.into());
30 }
31
32 pub fn push_param(&mut self, value: Value) {
33 self.params.push(value);
34 }
35
36 pub fn push_fragment(&mut self, fragment: SqlFragment) {
37 if !fragment.sql.is_empty() {
38 self.parts.push(fragment.sql);
39 }
40 self.params.extend(fragment.params);
41 }
42
43 pub fn where_clause(&self) -> String {
44 where_clause(&self.parts)
45 }
46
47 pub fn into_params(self) -> Vec<Value> {
48 self.params
49 }
50}
51
52pub fn where_clause(predicates: &[String]) -> String {
53 if predicates.is_empty() {
54 String::new()
55 } else {
56 format!("WHERE {}", predicates.join(" AND "))
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn filter_keeps_predicate_and_param_order() {
66 let mut filter = SqlFilter::default();
67 filter.push_fragment(SqlFragment::new("start < ?", vec![Value::BigInt(20)]));
68 filter.push_predicate("device_id = ?");
69 filter.push_param(Value::Int(3));
70
71 assert_eq!(filter.where_clause(), "WHERE start < ? AND device_id = ?");
72 assert_eq!(
73 filter.clone().into_params(),
74 vec![Value::BigInt(20), Value::Int(3)]
75 );
76 }
77
78 #[test]
79 fn empty_filter_has_empty_where_clause() {
80 let filter = SqlFilter::default();
81 assert_eq!(filter.where_clause(), "");
82 assert!(filter.into_params().is_empty());
83 }
84
85 #[test]
86 fn where_clause_joins_predicates_or_empty() {
87 assert_eq!(where_clause(&[]), "");
88 assert_eq!(
89 where_clause(&["a = ?".to_string(), "b > ?".to_string()]),
90 "WHERE a = ? AND b > ?"
91 );
92 }
93}