1#[derive(Debug, Clone, PartialEq, Eq)]
2pub enum OracleIndexCompression {
3 Enabled,
4 Prefix(u32),
5}
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct UniqueConstraintDef {
9 name: String,
10 columns: Vec<String>,
11 timing: ConstraintTiming,
12 nulls_not_distinct: bool,
13 sqlite_on_conflict: Option<String>,
14 mssql_filegroup: Option<String>,
15 mssql_clustered: Option<bool>,
16 oracle_tablespace: Option<String>,
17 oracle_compress: Option<OracleIndexCompression>,
18}
19
20impl UniqueConstraintDef {
21 pub fn new(name: impl Into<String>, columns: Vec<String>) -> Self {
22 Self {
23 name: name.into(),
24 columns,
25 timing: ConstraintTiming::default(),
26 nulls_not_distinct: false,
27 sqlite_on_conflict: None,
28 mssql_filegroup: None,
29 mssql_clustered: None,
30 oracle_tablespace: None,
31 oracle_compress: None,
32 }
33 }
34
35 pub fn with_timing(mut self, timing: ConstraintTiming) -> Self {
36 self.timing = timing;
37 self
38 }
39
40 pub fn nulls_not_distinct(mut self) -> Self {
41 self.nulls_not_distinct = true;
42 self
43 }
44
45 pub fn with_nulls_not_distinct(mut self, nulls_not_distinct: bool) -> Self {
46 self.nulls_not_distinct = nulls_not_distinct;
47 self
48 }
49
50 pub fn with_sqlite_on_conflict(mut self, policy: impl Into<String>) -> Self {
51 self.sqlite_on_conflict = Some(policy.into());
52 self
53 }
54
55 pub fn with_sqlite_on_conflict_option(mut self, policy: Option<String>) -> Self {
56 self.sqlite_on_conflict = policy;
57 self
58 }
59
60 pub fn with_mssql_filegroup(mut self, filegroup: impl Into<String>) -> Self {
61 self.mssql_filegroup = Some(filegroup.into());
62 self
63 }
64
65 pub fn with_mssql_filegroup_option(mut self, filegroup: Option<String>) -> Self {
66 self.mssql_filegroup = filegroup;
67 self
68 }
69
70 pub fn with_mssql_clustered(mut self, clustered: bool) -> Self {
71 self.mssql_clustered = Some(clustered);
72 self
73 }
74
75 pub fn with_mssql_clustered_option(mut self, clustered: Option<bool>) -> Self {
76 self.mssql_clustered = clustered;
77 self
78 }
79
80 pub fn with_oracle_tablespace(mut self, tablespace: impl Into<String>) -> Self {
81 self.oracle_tablespace = Some(tablespace.into());
82 self
83 }
84
85 pub fn with_oracle_tablespace_option(mut self, tablespace: Option<String>) -> Self {
86 self.oracle_tablespace = tablespace;
87 self
88 }
89
90 pub fn with_oracle_compress(mut self) -> Self {
91 self.oracle_compress = Some(OracleIndexCompression::Enabled);
92 self
93 }
94
95 pub fn with_oracle_compress_prefix(mut self, prefix_length: u32) -> Self {
96 self.oracle_compress = Some(OracleIndexCompression::Prefix(prefix_length));
97 self
98 }
99
100 pub fn with_oracle_compress_option(mut self, compress: Option<OracleIndexCompression>) -> Self {
101 self.oracle_compress = compress;
102 self
103 }
104
105 pub fn name(&self) -> &str {
106 &self.name
107 }
108
109 pub fn columns(&self) -> &[String] {
110 &self.columns
111 }
112
113 pub fn timing(&self) -> &ConstraintTiming {
114 &self.timing
115 }
116
117 pub fn is_nulls_not_distinct(&self) -> bool {
118 self.nulls_not_distinct
119 }
120
121 pub fn sqlite_on_conflict(&self) -> Option<&str> {
122 self.sqlite_on_conflict.as_deref()
123 }
124
125 pub fn mssql_filegroup(&self) -> Option<&str> {
126 self.mssql_filegroup.as_deref()
127 }
128
129 pub fn mssql_clustered(&self) -> Option<bool> {
130 self.mssql_clustered
131 }
132
133 pub fn oracle_tablespace(&self) -> Option<&str> {
134 self.oracle_tablespace.as_deref()
135 }
136
137 pub fn oracle_compress(&self) -> Option<&OracleIndexCompression> {
138 self.oracle_compress.as_ref()
139 }
140}
141
142#[derive(Debug, Clone, PartialEq, Eq)]
143pub enum ConstraintDef {
144 Unique(UniqueConstraintDef),
145 Check(CheckConstraintDef),
146 ForeignKey(ForeignKeyDef),
147 Exclusion(ExclusionConstraintDef),
148}
149
150#[derive(Debug, Clone, PartialEq, Eq, Default)]
151pub struct ConstraintTiming {
152 deferrable: Option<bool>,
153 initially_deferred: bool,
154}
155
156impl ConstraintTiming {
157 pub fn new(deferrable: Option<bool>, initially_deferred: bool) -> Self {
158 Self {
159 deferrable: if initially_deferred && deferrable.is_none() {
160 Some(true)
161 } else {
162 deferrable
163 },
164 initially_deferred,
165 }
166 }
167
168 pub fn deferrable(&self) -> Option<bool> {
169 self.deferrable
170 }
171
172 pub fn initially_deferred(&self) -> bool {
173 self.initially_deferred
174 }
175}
176
177#[derive(Debug, Clone, PartialEq, Eq)]
178pub struct CheckConstraintDef {
179 name: Option<String>,
180 expression: String,
181 validated: bool,
182 no_inherit: bool,
183}
184
185impl CheckConstraintDef {
186 pub fn new(expression: impl Into<String>) -> Self {
187 Self {
188 name: None,
189 expression: expression.into(),
190 validated: true,
191 no_inherit: false,
192 }
193 }
194
195 pub fn named(mut self, name: impl Into<String>) -> Self {
196 self.name = Some(name.into());
197 self
198 }
199
200 pub fn validated(mut self, validated: bool) -> Self {
201 self.validated = validated;
202 self
203 }
204
205 pub fn not_validated(self) -> Self {
206 self.validated(false)
207 }
208
209 pub fn no_inherit(mut self) -> Self {
210 self.no_inherit = true;
211 self
212 }
213
214 pub fn name(&self) -> Option<&str> {
215 self.name.as_deref()
216 }
217
218 pub fn expression(&self) -> &str {
219 &self.expression
220 }
221
222 pub fn is_validated(&self) -> bool {
223 self.validated
224 }
225
226 pub fn is_no_inherit(&self) -> bool {
227 self.no_inherit
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq)]
232pub struct ExclusionElementDef {
233 expression: String,
234 operator: String,
235 quoted: bool,
236 opclass: Option<String>,
237}
238
239impl ExclusionElementDef {
240 pub fn column(column: impl Into<String>, operator: impl Into<String>) -> Self {
241 Self {
242 expression: column.into(),
243 operator: operator.into(),
244 quoted: true,
245 opclass: None,
246 }
247 }
248
249 pub fn expression(expression: impl Into<String>, operator: impl Into<String>) -> Self {
250 Self {
251 expression: expression.into(),
252 operator: operator.into(),
253 quoted: false,
254 opclass: None,
255 }
256 }
257
258 pub fn opclass(mut self, opclass: impl Into<String>) -> Self {
259 self.opclass = Some(opclass.into());
260 self
261 }
262
263 pub fn value(&self) -> &str {
264 &self.expression
265 }
266
267 pub fn operator(&self) -> &str {
268 &self.operator
269 }
270
271 pub fn operator_class(&self) -> Option<&str> {
272 self.opclass.as_deref()
273 }
274
275 pub fn is_quoted(&self) -> bool {
276 self.quoted
277 }
278}
279
280#[derive(Debug, Clone, PartialEq, Eq)]
281pub struct ExclusionConstraintDef {
282 name: String,
283 elements: Vec<ExclusionElementDef>,
284 method: String,
285 predicate: Option<String>,
286 timing: ConstraintTiming,
287}
288
289impl ExclusionConstraintDef {
290 pub fn new(name: impl Into<String>, elements: Vec<ExclusionElementDef>) -> Self {
291 Self {
292 name: name.into(),
293 elements,
294 method: "gist".to_string(),
295 predicate: None,
296 timing: ConstraintTiming::default(),
297 }
298 }
299
300 pub fn method(mut self, method: impl Into<String>) -> Self {
301 self.method = method.into();
302 self
303 }
304
305 pub fn where_expr(mut self, predicate: impl Into<String>) -> Self {
306 self.predicate = Some(predicate.into());
307 self
308 }
309
310 pub fn with_timing(mut self, timing: ConstraintTiming) -> Self {
311 self.timing = timing;
312 self
313 }
314
315 pub fn name(&self) -> &str {
316 &self.name
317 }
318
319 pub fn elements(&self) -> &[ExclusionElementDef] {
320 &self.elements
321 }
322
323 pub fn method_name(&self) -> &str {
324 &self.method
325 }
326
327 pub fn predicate(&self) -> Option<&str> {
328 self.predicate.as_deref()
329 }
330
331 pub fn timing(&self) -> &ConstraintTiming {
332 &self.timing
333 }
334}
335
336#[derive(Debug, Clone, PartialEq, Eq)]
337pub enum ForeignKeyAction {
338 Cascade,
339 Restrict,
340 SetNull,
341 SetDefault,
342 NoAction,
343}
344
345#[derive(Debug, Clone, PartialEq, Eq)]
346pub enum ForeignKeyMatch {
347 Simple,
348 Full,
349}
350
351#[derive(Debug, Clone, PartialEq, Eq)]
352pub struct ForeignKeyDef {
353 name: Option<String>,
354 local_columns: Vec<String>,
355 remote_table: String,
356 remote_columns: Vec<String>,
357 on_delete: Option<ForeignKeyAction>,
358 on_update: Option<ForeignKeyAction>,
359 timing: ConstraintTiming,
360 validated: bool,
361 match_type: Option<ForeignKeyMatch>,
362}
363
364impl ForeignKeyDef {
365 pub fn new(
366 local_columns: Vec<String>,
367 remote_table: impl Into<String>,
368 remote_columns: Vec<String>,
369 ) -> Self {
370 Self {
371 name: None,
372 local_columns,
373 remote_table: remote_table.into(),
374 remote_columns,
375 on_delete: None,
376 on_update: None,
377 timing: ConstraintTiming::default(),
378 validated: true,
379 match_type: None,
380 }
381 }
382
383 pub fn named(mut self, name: impl Into<String>) -> Self {
384 self.name = Some(name.into());
385 self
386 }
387
388 pub fn on_delete(mut self, action: ForeignKeyAction) -> Self {
389 self.on_delete = Some(action);
390 self
391 }
392
393 pub fn on_update(mut self, action: ForeignKeyAction) -> Self {
394 self.on_update = Some(action);
395 self
396 }
397
398 pub fn with_timing(mut self, timing: ConstraintTiming) -> Self {
399 self.timing = timing;
400 self
401 }
402
403 pub fn with_match(mut self, match_type: ForeignKeyMatch) -> Self {
404 self.match_type = Some(match_type);
405 self
406 }
407
408 pub fn validated(mut self, validated: bool) -> Self {
409 self.validated = validated;
410 self
411 }
412
413 pub fn not_validated(self) -> Self {
414 self.validated(false)
415 }
416
417 pub fn name(&self) -> Option<&str> {
418 self.name.as_deref()
419 }
420
421 pub fn local_columns(&self) -> &[String] {
422 &self.local_columns
423 }
424
425 pub fn remote_table(&self) -> &str {
426 &self.remote_table
427 }
428
429 pub fn remote_columns(&self) -> &[String] {
430 &self.remote_columns
431 }
432
433 pub fn on_delete_action(&self) -> Option<&ForeignKeyAction> {
434 self.on_delete.as_ref()
435 }
436
437 pub fn on_update_action(&self) -> Option<&ForeignKeyAction> {
438 self.on_update.as_ref()
439 }
440
441 pub fn timing(&self) -> &ConstraintTiming {
442 &self.timing
443 }
444
445 pub fn match_type(&self) -> Option<&ForeignKeyMatch> {
446 self.match_type.as_ref()
447 }
448
449 pub fn is_validated(&self) -> bool {
450 self.validated
451 }
452}