1use crate::ast::{
4 Condition, Expr, Merge, MergeAction, MergeClause, MergeMatchKind, MergeSource, Operator, Qail,
5 Value,
6};
7
8impl Qail {
9 pub fn target_alias(mut self, alias: impl Into<String>) -> Self {
11 self.ensure_merge().target_alias = Some(alias.into());
12 self
13 }
14
15 pub fn using_table(mut self, table: impl Into<String>) -> Self {
17 self.ensure_merge().source = MergeSource::Table {
18 name: table.into(),
19 alias: None,
20 };
21 self
22 }
23
24 pub fn using_table_as(mut self, table: impl Into<String>, alias: impl Into<String>) -> Self {
26 self.ensure_merge().source = MergeSource::Table {
27 name: table.into(),
28 alias: Some(alias.into()),
29 };
30 self
31 }
32
33 pub fn using_query_as(mut self, query: Qail, alias: impl Into<String>) -> Self {
35 self.ensure_merge().source = MergeSource::Query {
36 query: Box::new(query),
37 alias: Some(alias.into()),
38 };
39 self
40 }
41
42 pub fn merge_on_column(
44 mut self,
45 left: impl Into<String>,
46 op: Operator,
47 right: impl Into<String>,
48 ) -> Self {
49 self.ensure_merge().on.push(Condition {
50 left: Expr::Named(left.into()),
51 op,
52 value: Value::Column(right.into()),
53 is_array_unnest: false,
54 });
55 self
56 }
57
58 pub fn merge_on_condition(mut self, condition: Condition) -> Self {
60 self.ensure_merge().on.push(condition);
61 self
62 }
63
64 pub fn when_matched_update<S>(mut self, assignments: &[(S, Expr)]) -> Self
66 where
67 S: AsRef<str>,
68 {
69 self.push_merge_clause(
70 MergeMatchKind::Matched,
71 Vec::new(),
72 MergeAction::Update {
73 assignments: assignments
74 .iter()
75 .map(|(col, expr)| (col.as_ref().to_string(), expr.clone()))
76 .collect(),
77 },
78 );
79 self
80 }
81
82 pub fn when_matched_update_if<S>(
84 mut self,
85 condition: Vec<Condition>,
86 assignments: &[(S, Expr)],
87 ) -> Self
88 where
89 S: AsRef<str>,
90 {
91 self.push_merge_clause(
92 MergeMatchKind::Matched,
93 condition,
94 MergeAction::Update {
95 assignments: assignments
96 .iter()
97 .map(|(col, expr)| (col.as_ref().to_string(), expr.clone()))
98 .collect(),
99 },
100 );
101 self
102 }
103
104 pub fn when_matched_delete(mut self) -> Self {
106 self.push_merge_clause(MergeMatchKind::Matched, Vec::new(), MergeAction::Delete);
107 self
108 }
109
110 pub fn when_matched_do_nothing(mut self) -> Self {
112 self.push_merge_clause(MergeMatchKind::Matched, Vec::new(), MergeAction::DoNothing);
113 self
114 }
115
116 pub fn when_not_matched_insert<S>(mut self, columns: &[S], values: &[Expr]) -> Self
118 where
119 S: AsRef<str>,
120 {
121 self.push_merge_clause(
122 MergeMatchKind::NotMatchedByTarget,
123 Vec::new(),
124 MergeAction::Insert {
125 columns: columns.iter().map(|col| col.as_ref().to_string()).collect(),
126 values: values.to_vec(),
127 },
128 );
129 self
130 }
131
132 pub fn when_not_matched_insert_if<S>(
134 mut self,
135 condition: Vec<Condition>,
136 columns: &[S],
137 values: &[Expr],
138 ) -> Self
139 where
140 S: AsRef<str>,
141 {
142 self.push_merge_clause(
143 MergeMatchKind::NotMatchedByTarget,
144 condition,
145 MergeAction::Insert {
146 columns: columns.iter().map(|col| col.as_ref().to_string()).collect(),
147 values: values.to_vec(),
148 },
149 );
150 self
151 }
152
153 pub fn when_not_matched_do_nothing(mut self) -> Self {
155 self.push_merge_clause(
156 MergeMatchKind::NotMatchedByTarget,
157 Vec::new(),
158 MergeAction::DoNothing,
159 );
160 self
161 }
162
163 pub fn when_not_matched_by_source_delete(mut self) -> Self {
165 self.push_merge_clause(
166 MergeMatchKind::NotMatchedBySource,
167 Vec::new(),
168 MergeAction::Delete,
169 );
170 self
171 }
172
173 pub fn when_not_matched_by_source_update<S>(mut self, assignments: &[(S, Expr)]) -> Self
175 where
176 S: AsRef<str>,
177 {
178 self.push_merge_clause(
179 MergeMatchKind::NotMatchedBySource,
180 Vec::new(),
181 MergeAction::Update {
182 assignments: assignments
183 .iter()
184 .map(|(col, expr)| (col.as_ref().to_string(), expr.clone()))
185 .collect(),
186 },
187 );
188 self
189 }
190
191 pub fn when_not_matched_by_source_do_nothing(mut self) -> Self {
193 self.push_merge_clause(
194 MergeMatchKind::NotMatchedBySource,
195 Vec::new(),
196 MergeAction::DoNothing,
197 );
198 self
199 }
200
201 fn push_merge_clause(
202 &mut self,
203 match_kind: MergeMatchKind,
204 condition: Vec<Condition>,
205 action: MergeAction,
206 ) {
207 self.ensure_merge().clauses.push(MergeClause {
208 match_kind,
209 condition,
210 action,
211 });
212 }
213
214 fn ensure_merge(&mut self) -> &mut Merge {
215 self.merge.get_or_insert_with(|| Merge {
216 target_alias: None,
217 source: MergeSource::Table {
218 name: String::new(),
219 alias: None,
220 },
221 on: Vec::new(),
222 clauses: Vec::new(),
223 })
224 }
225}