Skip to main content

rust_ef_sqlite/
sql_generator.rs

1use rust_ef::provider::ISqlGenerator;
2
3#[derive(Debug, Clone)]
4pub struct SqliteSqlGenerator;
5
6impl SqliteSqlGenerator {
7    pub fn new() -> Self {
8        Self
9    }
10}
11
12impl Default for SqliteSqlGenerator {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl ISqlGenerator for SqliteSqlGenerator {
19    fn select(&self, table: &str, columns: &[&str]) -> String {
20        let cols = if columns.is_empty() {
21            "*".to_string()
22        } else {
23            columns
24                .iter()
25                .map(|c| self.quote_identifier(c))
26                .collect::<Vec<_>>()
27                .join(", ")
28        };
29        format!("SELECT {} FROM {}", cols, self.quote_identifier(table))
30    }
31
32    fn insert(&self, table: &str, columns: &[&str], _returning: bool) -> String {
33        let cols = columns
34            .iter()
35            .map(|c| self.quote_identifier(c))
36            .collect::<Vec<_>>()
37            .join(", ");
38        let placeholders = vec!["?"; columns.len()].join(", ");
39        format!(
40            "INSERT INTO {} ({}) VALUES ({})",
41            self.quote_identifier(table),
42            cols,
43            placeholders
44        )
45    }
46
47    fn insert_batch(&self, table: &str, columns: &[&str], row_count: usize) -> String {
48        let cols = columns
49            .iter()
50            .map(|c| self.quote_identifier(c))
51            .collect::<Vec<_>>()
52            .join(", ");
53        let row = format!("({})", vec!["?"; columns.len()].join(", "));
54        let all_rows = vec![row; row_count].join(", ");
55        format!(
56            "INSERT INTO {} ({}) VALUES {}",
57            self.quote_identifier(table),
58            cols,
59            all_rows,
60        )
61    }
62
63    fn upsert_batch(
64        &self,
65        table: &str,
66        columns: &[&str],
67        conflict_cols: &[&str],
68        row_count: usize,
69    ) -> String {
70        let cols = columns
71            .iter()
72            .map(|c| self.quote_identifier(c))
73            .collect::<Vec<_>>()
74            .join(", ");
75        let row = format!("({})", vec!["?"; columns.len()].join(", "));
76        let all_rows = vec![row; row_count].join(", ");
77        let conflict = conflict_cols
78            .iter()
79            .map(|c| self.quote_identifier(c))
80            .collect::<Vec<_>>()
81            .join(", ");
82        let update_cols: Vec<&str> = columns
83            .iter()
84            .filter(|c| !conflict_cols.contains(c))
85            .copied()
86            .collect();
87        let sets = update_cols
88            .iter()
89            .map(|c| {
90                format!(
91                    "{} = EXCLUDED.{}",
92                    self.quote_identifier(c),
93                    self.quote_identifier(c)
94                )
95            })
96            .collect::<Vec<_>>()
97            .join(", ");
98        format!(
99            "INSERT INTO {} ({}) VALUES {} ON CONFLICT({}) DO UPDATE SET {}",
100            self.quote_identifier(table),
101            cols,
102            all_rows,
103            conflict,
104            sets,
105        )
106    }
107
108    fn update(&self, table: &str, set_columns: &[&str], where_clause: &str) -> String {
109        let sets: Vec<String> = set_columns
110            .iter()
111            .map(|c| format!("{} = ?", self.quote_identifier(c)))
112            .collect();
113        format!(
114            "UPDATE {} SET {} WHERE {}",
115            self.quote_identifier(table),
116            sets.join(", "),
117            where_clause
118        )
119    }
120
121    fn delete(&self, table: &str, where_clause: &str) -> String {
122        format!(
123            "DELETE FROM {} WHERE {}",
124            self.quote_identifier(table),
125            where_clause
126        )
127    }
128
129    fn create_table(&self, table: &str, columns: &[(String, String)]) -> String {
130        let col_defs: Vec<String> = columns
131            .iter()
132            .map(|(name, type_def)| format!("{} {}", self.quote_identifier(name), type_def))
133            .collect();
134        format!(
135            "CREATE TABLE {} (\n    {}\n)",
136            self.quote_identifier(table),
137            col_defs.join(",\n    ")
138        )
139    }
140
141    fn drop_table(&self, table: &str) -> String {
142        format!("DROP TABLE IF EXISTS {}", self.quote_identifier(table))
143    }
144
145    fn pagination(&self, skip: Option<usize>, take: Option<usize>) -> String {
146        match (skip, take) {
147            (Some(s), Some(t)) => format!("LIMIT {} OFFSET {}", t, s),
148            (None, Some(t)) => format!("LIMIT {}", t),
149            _ => String::new(),
150        }
151    }
152
153    fn parameter_placeholder(&self, _index: usize) -> String {
154        "?".to_string()
155    }
156
157    fn quote_identifier(&self, identifier: &str) -> String {
158        format!("\"{}\"", identifier)
159    }
160
161    fn auto_increment_syntax(&self) -> &'static str {
162        "AUTOINCREMENT"
163    }
164
165    fn supports_returning(&self) -> bool {
166        false
167    }
168
169    fn last_insert_id_sql(&self) -> Option<&'static str> {
170        Some("SELECT last_insert_rowid()")
171    }
172
173    fn last_insert_id_returns_first(&self) -> bool {
174        false
175    }
176}