rust_ef_postgres/
sql_generator.rs1use rust_ef::provider::ISqlGenerator;
4
5#[derive(Debug, Clone)]
7pub struct PostgresSqlGenerator;
8
9impl PostgresSqlGenerator {
10 pub fn new() -> Self {
11 Self
12 }
13}
14
15impl Default for PostgresSqlGenerator {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl ISqlGenerator for PostgresSqlGenerator {
22 fn select(&self, table: &str, columns: &[&str]) -> String {
23 let cols = if columns.is_empty() {
24 "*".to_string()
25 } else {
26 columns
27 .iter()
28 .map(|c| self.quote_identifier(c))
29 .collect::<Vec<_>>()
30 .join(", ")
31 };
32 format!("SELECT {} FROM {}", cols, self.quote_identifier(table))
33 }
34
35 fn insert(&self, table: &str, columns: &[&str], returning: bool) -> String {
36 let cols = columns
37 .iter()
38 .map(|c| self.quote_identifier(c))
39 .collect::<Vec<_>>()
40 .join(", ");
41 let placeholders: Vec<String> = (1..=columns.len())
42 .map(|i| self.parameter_placeholder(i))
43 .collect();
44 let returning_clause = if returning {
45 " RETURNING *".to_string()
46 } else {
47 String::new()
48 };
49 format!(
50 "INSERT INTO {} ({}) VALUES ({}){}",
51 self.quote_identifier(table),
52 cols,
53 placeholders.join(", "),
54 returning_clause
55 )
56 }
57
58 fn insert_batch(&self, table: &str, columns: &[&str], row_count: usize) -> String {
59 let cols = columns
60 .iter()
61 .map(|c| self.quote_identifier(c))
62 .collect::<Vec<_>>()
63 .join(", ");
64 let cols_per_row = columns.len();
65 let mut idx = 1usize;
66 let rows: Vec<String> = (0..row_count)
67 .map(|_| {
68 let ph: Vec<String> = (0..cols_per_row)
69 .map(|_| {
70 let p = self.parameter_placeholder(idx);
71 idx += 1;
72 p
73 })
74 .collect();
75 format!("({})", ph.join(", "))
76 })
77 .collect();
78 format!(
79 "INSERT INTO {} ({}) VALUES {} RETURNING *",
80 self.quote_identifier(table),
81 cols,
82 rows.join(", "),
83 )
84 }
85
86 fn update(&self, table: &str, set_columns: &[&str], where_clause: &str) -> String {
87 let sets: Vec<String> = set_columns
88 .iter()
89 .enumerate()
90 .map(|(i, c)| {
91 format!(
92 "{} = {}",
93 self.quote_identifier(c),
94 self.parameter_placeholder(i + 1)
95 )
96 })
97 .collect();
98 format!(
99 "UPDATE {} SET {} WHERE {}",
100 self.quote_identifier(table),
101 sets.join(", "),
102 where_clause
103 )
104 }
105
106 fn delete(&self, table: &str, where_clause: &str) -> String {
107 format!(
108 "DELETE FROM {} WHERE {}",
109 self.quote_identifier(table),
110 where_clause
111 )
112 }
113
114 fn create_table(&self, table: &str, columns: &[(String, String)]) -> String {
115 let col_defs: Vec<String> = columns
116 .iter()
117 .map(|(name, type_def)| format!("{} {}", self.quote_identifier(name), type_def))
118 .collect();
119 format!(
120 "CREATE TABLE {} (\n {}\n)",
121 self.quote_identifier(table),
122 col_defs.join(",\n ")
123 )
124 }
125
126 fn drop_table(&self, table: &str) -> String {
127 format!("DROP TABLE IF EXISTS {}", self.quote_identifier(table))
128 }
129
130 fn pagination(&self, skip: Option<usize>, take: Option<usize>) -> String {
131 match (skip, take) {
132 (Some(s), Some(t)) => format!("OFFSET {} LIMIT {}", s, t),
133 (Some(s), None) => format!("OFFSET {}", s),
134 (None, Some(t)) => format!("LIMIT {}", t),
135 (None, None) => String::new(),
136 }
137 }
138
139 fn parameter_placeholder(&self, index: usize) -> String {
140 format!("${}", index)
141 }
142
143 fn quote_identifier(&self, identifier: &str) -> String {
144 format!("\"{}\"", identifier)
145 }
146
147 fn auto_increment_syntax(&self) -> &'static str {
148 "SERIAL"
149 }
150}