good_ormning/sqlite/query/
update.rs

1use {
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        // Prep
49        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        // Build query
64        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}