good_ormning/pg/query/
update.rs

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