dbrest_core/plan/
mutate_plan.rs1use crate::api_request::types::{FieldName, Payload};
7use crate::types::identifiers::QualifiedIdentifier;
8
9use super::types::*;
10
11#[derive(Debug, Clone)]
19pub enum MutatePlan {
20 Insert(InsertPlan),
22 Update(UpdatePlan),
24 Delete(DeletePlan),
26}
27
28impl MutatePlan {
29 pub fn qi(&self) -> &QualifiedIdentifier {
31 match self {
32 MutatePlan::Insert(p) => &p.into,
33 MutatePlan::Update(p) => &p.into,
34 MutatePlan::Delete(p) => &p.from,
35 }
36 }
37
38 pub fn returning(&self) -> &[CoercibleSelectField] {
40 match self {
41 MutatePlan::Insert(p) => &p.returning,
42 MutatePlan::Update(p) => &p.returning,
43 MutatePlan::Delete(p) => &p.returning,
44 }
45 }
46}
47
48#[derive(Debug, Clone)]
54pub struct InsertPlan {
55 pub into: QualifiedIdentifier,
57 pub columns: Vec<CoercibleField>,
59 pub body: Payload,
61 pub on_conflict: Option<OnConflict>,
63 pub where_: Vec<CoercibleLogicTree>,
65 pub returning: Vec<CoercibleSelectField>,
67 pub pk_cols: Vec<FieldName>,
69 pub apply_defaults: bool,
71}
72
73#[derive(Debug, Clone)]
75pub struct UpdatePlan {
76 pub into: QualifiedIdentifier,
78 pub columns: Vec<CoercibleField>,
80 pub body: Payload,
82 pub where_: Vec<CoercibleLogicTree>,
84 pub returning: Vec<CoercibleSelectField>,
86 pub apply_defaults: bool,
88}
89
90#[derive(Debug, Clone)]
92pub struct DeletePlan {
93 pub from: QualifiedIdentifier,
95 pub where_: Vec<CoercibleLogicTree>,
97 pub returning: Vec<CoercibleSelectField>,
99}
100
101#[derive(Debug, Clone)]
103pub struct OnConflict {
104 pub columns: Vec<FieldName>,
106 pub merge_duplicates: bool,
108}
109
110#[cfg(test)]
115mod tests {
116 use super::*;
117
118 fn test_qi(name: &str) -> QualifiedIdentifier {
119 QualifiedIdentifier::new("public", name)
120 }
121
122 #[test]
123 fn test_mutate_plan_qi() {
124 let insert = MutatePlan::Insert(InsertPlan {
125 into: test_qi("users"),
126 columns: vec![],
127 body: Payload::RawJSON(bytes::Bytes::new()),
128 on_conflict: None,
129 where_: vec![],
130 returning: vec![],
131 pk_cols: vec![],
132 apply_defaults: false,
133 });
134 assert_eq!(insert.qi().name.as_str(), "users");
135
136 let update = MutatePlan::Update(UpdatePlan {
137 into: test_qi("posts"),
138 columns: vec![],
139 body: Payload::RawJSON(bytes::Bytes::new()),
140 where_: vec![],
141 returning: vec![],
142 apply_defaults: false,
143 });
144 assert_eq!(update.qi().name.as_str(), "posts");
145
146 let delete = MutatePlan::Delete(DeletePlan {
147 from: test_qi("comments"),
148 where_: vec![],
149 returning: vec![],
150 });
151 assert_eq!(delete.qi().name.as_str(), "comments");
152 }
153
154 #[test]
155 fn test_on_conflict() {
156 let oc = OnConflict {
157 columns: vec!["id".into()],
158 merge_duplicates: true,
159 };
160 assert!(oc.merge_duplicates);
161 assert_eq!(oc.columns.len(), 1);
162 }
163
164 #[test]
165 fn test_insert_plan_with_on_conflict() {
166 let plan = InsertPlan {
167 into: test_qi("users"),
168 columns: vec![],
169 body: Payload::RawJSON(bytes::Bytes::from("{}")),
170 on_conflict: Some(OnConflict {
171 columns: vec!["id".into()],
172 merge_duplicates: true,
173 }),
174 where_: vec![],
175 returning: vec![],
176 pk_cols: vec!["id".into()],
177 apply_defaults: true,
178 };
179 assert!(plan.on_conflict.is_some());
180 assert!(plan.apply_defaults);
181 assert_eq!(plan.pk_cols.len(), 1);
182 }
183}