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}