sea_query/
raw_sql.rs

1pub mod seaql;
2
3use crate::QueryBuilder;
4use std::fmt::Write;
5
6#[derive(Debug)]
7pub struct RawSqlQueryBuilder {
8    sql: String,
9    parameter_index: usize,
10    placeholder: &'static str,
11    numbered: bool,
12}
13
14impl RawSqlQueryBuilder {
15    pub fn new<T: QueryBuilder>(backend: T) -> Self {
16        let (placeholder, numbered) = backend.placeholder();
17        Self {
18            sql: Default::default(),
19            parameter_index: 1,
20            placeholder,
21            numbered,
22        }
23    }
24
25    pub fn push_fragment(&mut self, sql: &str) -> &mut Self {
26        self.sql.push_str(sql);
27        self
28    }
29
30    pub fn push_parameters(&mut self, n: usize) -> &mut Self {
31        for i in 0..n {
32            if i > 0 {
33                self.sql.push_str(", ");
34            }
35            self.sql.push_str(self.placeholder);
36            if self.numbered {
37                write!(&mut self.sql, "{}", self.parameter_index).unwrap();
38                self.parameter_index += 1;
39            }
40        }
41        self
42    }
43
44    pub fn push_tuple_parameter_groups(&mut self, len: usize, tuple_arity: usize) -> &mut Self {
45        for i in 0..len {
46            if i > 0 {
47                self.sql.push_str(", ");
48            }
49            self.sql.push('(');
50            self.push_parameters(tuple_arity);
51            self.sql.push(')');
52        }
53        self
54    }
55
56    pub fn finish(self) -> String {
57        self.sql
58    }
59}
60
61#[cfg(test)]
62mod test {
63    use super::*;
64    use crate::PostgresQueryBuilder;
65
66    #[derive(Default)]
67    struct Values(Vec<String>);
68
69    impl Values {
70        fn bind<V: std::fmt::Debug>(&mut self, v: V) {
71            self.0.push(format!("{v:?}"));
72        }
73    }
74
75    #[test]
76    fn test_raw_sql_0() {
77        let mut builder = RawSqlQueryBuilder::new(PostgresQueryBuilder);
78        builder.push_fragment("SELECT");
79        assert_eq!(builder.finish(), "SELECT");
80    }
81
82    #[test]
83    fn test_raw_sql_1() {
84        let a = 1;
85        let b = vec![2i32, 3];
86        let c = [4i32, 5, 6];
87
88        let mut builder = RawSqlQueryBuilder::new(PostgresQueryBuilder);
89        builder
90            .push_fragment("SELECT")
91            .push_fragment(" ")
92            .push_parameters(1)
93            .push_fragment(", ")
94            .push_parameters((&b).len())
95            .push_fragment(", ")
96            .push_parameters((&c).len());
97
98        assert_eq!(builder.finish(), "SELECT $1, $2, $3, $4, $5, $6");
99
100        let mut values = Values::default();
101        values.bind(a);
102        for v in (&b).iter() {
103            values.bind(v);
104        }
105        for v in (&c).iter() {
106            values.bind(v);
107        }
108
109        assert_eq!(values.0, ["1", "2", "3", "4", "5", "6"]);
110    }
111}