limbo_sqlite3_parser/to_sql_string/stmt/
insert.rs1use crate::{ast, to_sql_string::ToSqlString};
2
3impl ToSqlString for ast::Insert {
4 fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
5 format!(
6 "{}INSERT {}INTO {} {}{}{}",
7 self.with.as_ref().map_or("".to_string(), |with| format!(
8 "{} ",
9 with.to_sql_string(context)
10 )),
11 self.or_conflict
12 .map_or("".to_string(), |conflict| format!("OR {} ", conflict)),
13 self.tbl_name.to_sql_string(context),
14 self.columns
15 .as_ref()
16 .map_or("".to_string(), |col_names| format!(
17 "({}) ",
18 col_names
19 .iter()
20 .map(|name| name.0.clone())
21 .collect::<Vec<_>>()
22 .join(", ")
23 )),
24 self.body.to_sql_string(context),
25 self.returning
26 .as_ref()
27 .map_or("".to_string(), |returning| format!(
28 " RETURNING {}",
29 returning
30 .iter()
31 .map(|col| col.to_sql_string(context))
32 .collect::<Vec<_>>()
33 .join(", ")
34 ))
35 )
36 }
37}
38
39impl ToSqlString for ast::InsertBody {
40 fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
41 match self {
42 Self::DefaultValues => "DEFAULT VALUES".to_string(),
43 Self::Select(select, upsert) => format!(
44 "{}{}",
45 select.to_sql_string(context),
46 upsert.as_ref().map_or("".to_string(), |upsert| format!(
47 " {}",
48 upsert.to_sql_string(context)
49 )),
50 ),
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use crate::to_sql_string_test;
58
59 to_sql_string_test!(
61 test_insert_basic,
62 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000);"
63 );
64
65 to_sql_string_test!(
67 test_insert_multiple_rows,
68 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000), (2, 'Jane Smith', 60000);"
69 );
70
71 to_sql_string_test!(
73 test_insert_specific_columns,
74 "INSERT INTO employees (name, salary) VALUES ('Alice Brown', 55000);"
75 );
76
77 to_sql_string_test!(
79 test_insert_default_values,
80 "INSERT INTO employees DEFAULT VALUES;"
81 );
82
83 to_sql_string_test!(
85 test_insert_select_subquery,
86 "INSERT INTO employees (id, name, salary) SELECT id, name, salary FROM temp_employees WHERE salary > 40000;"
87 );
88
89 to_sql_string_test!(
91 test_insert_on_conflict_ignore,
92 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO NOTHING;"
93 );
94
95 to_sql_string_test!(
97 test_insert_on_conflict_replace,
98 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO UPDATE SET name = excluded.name, salary = excluded.salary;"
99 );
100
101 to_sql_string_test!(
103 test_insert_with_returning,
104 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) RETURNING id, name;"
105 );
106
107 to_sql_string_test!(
109 test_insert_with_null,
110 "INSERT INTO employees (id, name, salary, department_id) VALUES (1, 'John Doe', NULL, NULL);"
111 );
112
113 to_sql_string_test!(
115 test_insert_with_expression,
116 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000 * 1.1);"
117 );
118
119 to_sql_string_test!(
121 test_insert_schema_qualified,
122 "INSERT INTO main.employees (id, name, salary) VALUES (1, 'John Doe', 50000);"
123 );
124
125 to_sql_string_test!(
127 test_insert_subquery_join,
128 "INSERT INTO employees (id, name, department_id) SELECT e.id, e.name, d.id FROM temp_employees e JOIN departments d ON e.dept_name = d.name;"
129 );
130
131 to_sql_string_test!(
133 test_insert_all_columns_select,
134 "INSERT INTO employees SELECT * FROM temp_employees;"
135 );
136
137 to_sql_string_test!(
139 test_insert_on_conflict_where,
140 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO UPDATE SET salary = excluded.salary WHERE excluded.salary > employees.salary;"
141 );
142
143 to_sql_string_test!(
145 test_insert_quoted_columns,
146 "INSERT INTO employees (\"select\", \"from\") VALUES (1, 'data');"
147 );
148}