limbo_sqlite3_parser/to_sql_string/stmt/
update.rs1use crate::{ast, to_sql_string::ToSqlString};
2
3impl ToSqlString for ast::Update {
4 fn to_sql_string<C: crate::to_sql_string::ToSqlContext>(&self, context: &C) -> String {
5 format!(
6 "{}UPDATE {}{}{} SET {}{}{}{}",
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.indexed
15 .as_ref()
16 .map_or("".to_string(), |indexed| format!(" {}", indexed)),
17 self.sets
18 .iter()
19 .map(|set| set.to_sql_string(context))
20 .collect::<Vec<_>>()
21 .join(", "),
22 self.from.as_ref().map_or("".to_string(), |from| format!(
23 " {}",
24 from.to_sql_string(context)
25 )),
26 self.where_clause
27 .as_ref()
28 .map_or("".to_string(), |expr| format!(
29 " WHERE {}",
30 expr.to_sql_string(context)
31 )),
32 self.returning
33 .as_ref()
34 .map_or("".to_string(), |returning| format!(
35 " RETURNING {}",
36 returning
37 .iter()
38 .map(|col| col.to_sql_string(context))
39 .collect::<Vec<_>>()
40 .join(", ")
41 ))
42 )
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use crate::to_sql_string_test;
49
50 to_sql_string_test!(
52 test_update_single_column,
53 "UPDATE employees SET salary = 55000;"
54 );
55
56 to_sql_string_test!(
58 test_update_multiple_columns,
59 "UPDATE employees SET salary = 60000, name = 'John Smith';"
60 );
61
62 to_sql_string_test!(
64 test_update_with_where,
65 "UPDATE employees SET salary = 60000 WHERE id = 1;"
66 );
67
68 to_sql_string_test!(
70 test_update_with_multi_where,
71 "UPDATE employees SET salary = 65000 WHERE department_id = 3 AND salary < 50000;"
72 );
73
74 to_sql_string_test!(
76 test_update_with_subquery_set,
77 "UPDATE employees SET department_id = (SELECT id FROM departments WHERE name = 'Sales') WHERE id = 1;"
78 );
79
80 to_sql_string_test!(
82 test_update_with_subquery_where,
83 "UPDATE employees SET salary = 70000 WHERE department_id IN (SELECT id FROM departments WHERE name = 'Marketing');"
84 );
85
86 to_sql_string_test!(
88 test_update_with_exists,
89 "UPDATE employees SET salary = 75000 WHERE EXISTS (SELECT 1 FROM orders WHERE orders.employee_id = employees.id AND orders.status = 'pending');"
90 );
91
92 to_sql_string_test!(
94 test_update_with_from,
95 "UPDATE employees SET salary = 80000 FROM departments WHERE employees.department_id = departments.id AND departments.name = 'Engineering';"
96 );
97
98 to_sql_string_test!(
100 test_update_with_returning,
101 "UPDATE employees SET salary = 60000 WHERE id = 1 RETURNING id, name, salary;"
102 );
103
104 to_sql_string_test!(
106 test_update_with_expression,
107 "UPDATE employees SET salary = salary * 1.1 WHERE department_id = 2;"
108 );
109
110 to_sql_string_test!(
112 test_update_with_null,
113 "UPDATE employees SET department_id = NULL WHERE id = 1;"
114 );
115
116 to_sql_string_test!(
118 test_update_schema_qualified,
119 "UPDATE main.employees SET salary = 65000 WHERE id = 1;"
120 );
121
122 to_sql_string_test!(
124 test_update_with_case,
125 "UPDATE employees SET salary = CASE WHEN salary < 50000 THEN 55000 ELSE salary * 1.05 END WHERE department_id = 3;"
126 );
127
128 to_sql_string_test!(
130 test_update_with_like,
131 "UPDATE employees SET name = 'Updated' WHERE name LIKE 'J%';"
132 );
133
134 to_sql_string_test!(
136 test_update_with_on_conflict,
137 "INSERT INTO employees (id, name, salary) VALUES (1, 'John Doe', 50000) ON CONFLICT(id) DO UPDATE SET name = excluded.name, salary = excluded.salary;"
138 );
139}