good_ormning/pg/query/
update.rs1use 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 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 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}