sea_query/
raw_sql.rs

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