good_ormning/sqlite/query/
update.rs1use {
2 std::collections::HashMap,
3 crate::{
4 sqlite::{
5 QueryResCount,
6 schema::{
7 table::Table,
8 field::Field,
9 },
10 },
11 utils::Tokens,
12 },
13 super::{
14 expr::{
15 check_bool,
16 Expr,
17 ExprType,
18 Binding,
19 },
20 select_body::Returning,
21 utils::{
22 build_returning,
23 build_set,
24 build_with,
25 QueryBody,
26 With,
27 },
28 },
29};
30
31pub struct Update {
32 pub with: Option<With>,
33 pub table: Table,
34 pub values: Vec<(Field, Expr)>,
35 pub where_: Option<Expr>,
36 pub returning: Vec<Returning>,
37}
38
39impl QueryBody for Update {
40 fn build(
41 &self,
42 ctx: &mut super::utils::SqliteQueryCtx,
43 path: &rpds::Vector<String>,
44 res_count: QueryResCount,
45 ) -> (super::expr::ExprType, crate::utils::Tokens) {
46 let mut out = Tokens::new();
47
48 if let Some(w) = &self.with {
50 out.s(&build_with(ctx, path, w).to_string());
51 }
52 let mut scope = HashMap::new();
53 for field in match ctx.tables.get(&self.table) {
54 Some(t) => t,
55 None => {
56 ctx.errs.err(path, format!("Unknown table {} for update", self.table));
57 return (ExprType(vec![]), Tokens::new());
58 },
59 } {
60 scope.insert(Binding::field(field), field.type_.type_.clone());
61 }
62
63 out.s("update").id(&self.table.id);
65 build_set(ctx, path, &scope, &mut out, &self.values);
66 if let Some(where_) = &self.where_ {
67 out.s("where");
68 let path = path.push_back("Where".into());
69 let (where_t, where_tokens) = where_.build(ctx, &path, &scope);
70 check_bool(ctx, &path, &where_t);
71 out.s(&where_tokens.to_string());
72 }
73 let out_type = build_returning(ctx, path, &scope, &mut out, &self.returning, res_count);
74 (out_type, out)
75 }
76}