toasty_core/stmt/
update.rs1use super::{Assignments, Node, Query, Returning, Statement, Visit, VisitMut};
2use crate::{
3 schema::{app::ModelId, db::TableId},
4 stmt::{self, Condition, Filter},
5};
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct Update {
9 pub target: UpdateTarget,
11
12 pub assignments: Assignments,
14
15 pub filter: Filter,
17
18 pub condition: Condition,
20
21 pub returning: Option<Returning>,
23}
24
25impl Statement {
26 pub fn is_update(&self) -> bool {
27 matches!(self, Self::Update(_))
28 }
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum UpdateTarget {
33 Query(Box<Query>),
35
36 Model(ModelId),
38
39 Table(TableId),
41}
42
43impl Update {
44 pub fn selection(&self) -> Query {
45 stmt::Query::new_select(self.target.model_id_unwrap(), self.filter.clone())
46 }
47}
48
49impl UpdateTarget {
50 pub fn model_id(&self) -> Option<ModelId> {
51 match self {
52 Self::Model(model_id) => Some(*model_id),
53 Self::Query(query) => query
54 .body
55 .as_select()
56 .and_then(|select| select.source.model_id()),
57 _ => None,
58 }
59 }
60
61 #[track_caller]
62 pub fn model_id_unwrap(&self) -> ModelId {
63 match self {
64 Self::Model(model_id) => *model_id,
65 Self::Query(query) => query.body.as_select_unwrap().source.model_id_unwrap(),
66 _ => todo!("not a model"),
67 }
68 }
69
70 pub fn is_table(&self) -> bool {
71 matches!(self, UpdateTarget::Table(..))
72 }
73
74 pub fn table(table: impl Into<TableId>) -> Self {
75 Self::Table(table.into())
76 }
77
78 #[track_caller]
79 pub fn as_table_unwrap(&self) -> TableId {
80 match self {
81 Self::Table(table) => *table,
82 _ => todo!(),
83 }
84 }
85}
86
87impl From<Update> for Statement {
88 fn from(src: Update) -> Self {
89 Self::Update(src)
90 }
91}
92
93impl Node for Update {
94 fn visit<V: Visit>(&self, mut visit: V) {
95 visit.visit_stmt_update(self);
96 }
97
98 fn visit_mut<V: VisitMut>(&mut self, mut visit: V) {
99 visit.visit_stmt_update_mut(self);
100 }
101}