1use ormdantic_core::{QualifiedName, TableId};
2
3use crate::{
4 CheckConstraintDef, ColumnDef, ExclusionConstraintDef, FieldKind, ForeignKeyDef, IndexDef,
5 RelationshipDef, UniqueConstraintDef,
6};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub enum OracleTableCompression {
10 Enabled,
11 Level(u32),
12}
13
14#[derive(Debug, Clone, PartialEq, Eq, Default)]
15pub struct MysqlTableOptions {
16 pub engine: Option<String>,
17 pub charset: Option<String>,
18 pub collation: Option<String>,
19 pub row_format: Option<String>,
20 pub key_block_size: Option<u32>,
21 pub pack_keys: Option<bool>,
22 pub checksum: Option<bool>,
23 pub delay_key_write: Option<bool>,
24 pub stats_persistent: Option<bool>,
25 pub stats_auto_recalc: Option<bool>,
26 pub stats_sample_pages: Option<u32>,
27 pub avg_row_length: Option<u32>,
28 pub max_rows: Option<u32>,
29 pub min_rows: Option<u32>,
30 pub insert_method: Option<String>,
31 pub data_directory: Option<String>,
32 pub index_directory: Option<String>,
33 pub connection: Option<String>,
34 pub union: Vec<String>,
35 pub partition_by: Option<String>,
36 pub partitions: Option<u32>,
37 pub subpartition_by: Option<String>,
38 pub subpartitions: Option<u32>,
39 pub auto_increment: Option<u32>,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct TableDef {
44 id: Option<TableId>,
45 model_key: String,
46 name: String,
47 primary_key: String,
48 columns: Vec<ColumnDef>,
49 indexes: Vec<IndexDef>,
50 unique_constraints: Vec<UniqueConstraintDef>,
51 relationships: Vec<RelationshipDef>,
52 check_constraints: Vec<CheckConstraintDef>,
53 foreign_keys: Vec<ForeignKeyDef>,
54 exclusion_constraints: Vec<ExclusionConstraintDef>,
55 schema: Option<String>,
56 comment: Option<String>,
57 tablespace: Option<String>,
58 mysql_engine: Option<String>,
59 mysql_charset: Option<String>,
60 mysql_collation: Option<String>,
61 mysql_row_format: Option<String>,
62 mysql_key_block_size: Option<u32>,
63 mysql_pack_keys: Option<bool>,
64 mysql_checksum: Option<bool>,
65 mysql_delay_key_write: Option<bool>,
66 mysql_stats_persistent: Option<bool>,
67 mysql_stats_auto_recalc: Option<bool>,
68 mysql_stats_sample_pages: Option<u32>,
69 mysql_avg_row_length: Option<u32>,
70 mysql_max_rows: Option<u32>,
71 mysql_min_rows: Option<u32>,
72 mysql_insert_method: Option<String>,
73 mysql_data_directory: Option<String>,
74 mysql_index_directory: Option<String>,
75 mysql_connection: Option<String>,
76 mysql_union: Vec<String>,
77 mysql_partition_by: Option<String>,
78 mysql_partitions: Option<u32>,
79 mysql_subpartition_by: Option<String>,
80 mysql_subpartitions: Option<u32>,
81 mysql_auto_increment: Option<u32>,
82 postgres_inherits: Vec<String>,
83 postgres_with: Vec<(String, String)>,
84 postgres_using: Option<String>,
85 postgres_unlogged: bool,
86 postgres_partition_by: Option<String>,
87 postgres_partition_of: Option<String>,
88 postgres_partition_for: Option<String>,
89 sqlite_strict: bool,
90 sqlite_without_rowid: bool,
91 oracle_compress: Option<OracleTableCompression>,
92 mssql_primary_key_nonclustered: bool,
93}
94
95impl TableDef {
96 pub fn new(
97 name: impl Into<String>,
98 primary_key: impl Into<String>,
99 columns: Vec<String>,
100 ) -> Self {
101 let name = name.into();
102 Self {
103 id: None,
104 model_key: name.clone(),
105 name,
106 primary_key: primary_key.into(),
107 columns: columns
108 .into_iter()
109 .map(|column| ColumnDef::new(column, FieldKind::Unknown))
110 .collect(),
111 indexes: Vec::new(),
112 unique_constraints: Vec::new(),
113 relationships: Vec::new(),
114 check_constraints: Vec::new(),
115 foreign_keys: Vec::new(),
116 exclusion_constraints: Vec::new(),
117 schema: None,
118 comment: None,
119 tablespace: None,
120 mysql_engine: None,
121 mysql_charset: None,
122 mysql_collation: None,
123 mysql_row_format: None,
124 mysql_key_block_size: None,
125 mysql_pack_keys: None,
126 mysql_checksum: None,
127 mysql_delay_key_write: None,
128 mysql_stats_persistent: None,
129 mysql_stats_auto_recalc: None,
130 mysql_stats_sample_pages: None,
131 mysql_avg_row_length: None,
132 mysql_max_rows: None,
133 mysql_min_rows: None,
134 mysql_insert_method: None,
135 mysql_data_directory: None,
136 mysql_index_directory: None,
137 mysql_connection: None,
138 mysql_union: Vec::new(),
139 mysql_partition_by: None,
140 mysql_partitions: None,
141 mysql_subpartition_by: None,
142 mysql_subpartitions: None,
143 mysql_auto_increment: None,
144 postgres_inherits: Vec::new(),
145 postgres_with: Vec::new(),
146 postgres_using: None,
147 postgres_unlogged: false,
148 postgres_partition_by: None,
149 postgres_partition_of: None,
150 postgres_partition_for: None,
151 sqlite_strict: false,
152 sqlite_without_rowid: false,
153 oracle_compress: None,
154 mssql_primary_key_nonclustered: false,
155 }
156 }
157
158 pub fn from_parts(
159 name: impl Into<String>,
160 model_key: impl Into<String>,
161 primary_key: impl Into<String>,
162 columns: Vec<ColumnDef>,
163 indexes: Vec<IndexDef>,
164 unique_constraints: Vec<UniqueConstraintDef>,
165 relationships: Vec<RelationshipDef>,
166 ) -> Self {
167 Self {
168 id: None,
169 model_key: model_key.into(),
170 name: name.into(),
171 primary_key: primary_key.into(),
172 columns,
173 indexes,
174 unique_constraints,
175 relationships,
176 check_constraints: Vec::new(),
177 foreign_keys: Vec::new(),
178 exclusion_constraints: Vec::new(),
179 schema: None,
180 comment: None,
181 tablespace: None,
182 mysql_engine: None,
183 mysql_charset: None,
184 mysql_collation: None,
185 mysql_row_format: None,
186 mysql_key_block_size: None,
187 mysql_pack_keys: None,
188 mysql_checksum: None,
189 mysql_delay_key_write: None,
190 mysql_stats_persistent: None,
191 mysql_stats_auto_recalc: None,
192 mysql_stats_sample_pages: None,
193 mysql_avg_row_length: None,
194 mysql_max_rows: None,
195 mysql_min_rows: None,
196 mysql_insert_method: None,
197 mysql_data_directory: None,
198 mysql_index_directory: None,
199 mysql_connection: None,
200 mysql_union: Vec::new(),
201 mysql_partition_by: None,
202 mysql_partitions: None,
203 mysql_subpartition_by: None,
204 mysql_subpartitions: None,
205 mysql_auto_increment: None,
206 postgres_inherits: Vec::new(),
207 postgres_with: Vec::new(),
208 postgres_using: None,
209 postgres_unlogged: false,
210 postgres_partition_by: None,
211 postgres_partition_of: None,
212 postgres_partition_for: None,
213 sqlite_strict: false,
214 sqlite_without_rowid: false,
215 oracle_compress: None,
216 mssql_primary_key_nonclustered: false,
217 }
218 }
219
220 pub fn with_relationships(mut self, relationships: Vec<RelationshipDef>) -> Self {
221 self.relationships = relationships;
222 self
223 }
224
225 pub fn with_schema(mut self, schema: impl Into<String>) -> Self {
226 self.schema = Some(schema.into());
227 self
228 }
229
230 pub fn with_comment(mut self, comment: impl Into<String>) -> Self {
231 self.comment = Some(comment.into());
232 self
233 }
234
235 pub fn with_tablespace(mut self, tablespace: impl Into<String>) -> Self {
236 self.tablespace = Some(tablespace.into());
237 self
238 }
239
240 pub fn with_mysql_engine(mut self, engine: impl Into<String>) -> Self {
241 self.mysql_engine = Some(engine.into());
242 self
243 }
244
245 pub fn with_mysql_charset(mut self, charset: impl Into<String>) -> Self {
246 self.mysql_charset = Some(charset.into());
247 self
248 }
249
250 pub fn with_mysql_collation(mut self, collation: impl Into<String>) -> Self {
251 self.mysql_collation = Some(collation.into());
252 self
253 }
254
255 pub fn with_mysql_row_format(mut self, row_format: impl Into<String>) -> Self {
256 self.mysql_row_format = Some(row_format.into());
257 self
258 }
259
260 pub fn with_mysql_key_block_size(mut self, key_block_size: u32) -> Self {
261 self.mysql_key_block_size = Some(key_block_size);
262 self
263 }
264
265 pub fn with_mysql_pack_keys(mut self, pack_keys: bool) -> Self {
266 self.mysql_pack_keys = Some(pack_keys);
267 self
268 }
269
270 pub fn with_mysql_checksum(mut self, checksum: bool) -> Self {
271 self.mysql_checksum = Some(checksum);
272 self
273 }
274
275 pub fn with_mysql_delay_key_write(mut self, delay_key_write: bool) -> Self {
276 self.mysql_delay_key_write = Some(delay_key_write);
277 self
278 }
279
280 pub fn with_mysql_stats_persistent(mut self, stats_persistent: bool) -> Self {
281 self.mysql_stats_persistent = Some(stats_persistent);
282 self
283 }
284
285 pub fn with_mysql_stats_auto_recalc(mut self, stats_auto_recalc: bool) -> Self {
286 self.mysql_stats_auto_recalc = Some(stats_auto_recalc);
287 self
288 }
289
290 pub fn with_mysql_stats_sample_pages(mut self, stats_sample_pages: u32) -> Self {
291 self.mysql_stats_sample_pages = Some(stats_sample_pages);
292 self
293 }
294
295 pub fn with_mysql_avg_row_length(mut self, avg_row_length: u32) -> Self {
296 self.mysql_avg_row_length = Some(avg_row_length);
297 self
298 }
299
300 pub fn with_mysql_max_rows(mut self, max_rows: u32) -> Self {
301 self.mysql_max_rows = Some(max_rows);
302 self
303 }
304
305 pub fn with_mysql_min_rows(mut self, min_rows: u32) -> Self {
306 self.mysql_min_rows = Some(min_rows);
307 self
308 }
309
310 pub fn with_mysql_insert_method(mut self, insert_method: impl Into<String>) -> Self {
311 self.mysql_insert_method = Some(insert_method.into());
312 self
313 }
314
315 pub fn with_mysql_data_directory(mut self, data_directory: impl Into<String>) -> Self {
316 self.mysql_data_directory = Some(data_directory.into());
317 self
318 }
319
320 pub fn with_mysql_index_directory(mut self, index_directory: impl Into<String>) -> Self {
321 self.mysql_index_directory = Some(index_directory.into());
322 self
323 }
324
325 pub fn with_mysql_connection(mut self, connection: impl Into<String>) -> Self {
326 self.mysql_connection = Some(connection.into());
327 self
328 }
329
330 pub fn with_mysql_union(mut self, tables: Vec<String>) -> Self {
331 self.mysql_union = tables;
332 self
333 }
334
335 pub fn with_mysql_partition_by(mut self, partition_by: impl Into<String>) -> Self {
336 self.mysql_partition_by = Some(partition_by.into());
337 self
338 }
339
340 pub fn with_mysql_partitions(mut self, partitions: u32) -> Self {
341 self.mysql_partitions = Some(partitions);
342 self
343 }
344
345 pub fn with_mysql_subpartition_by(mut self, subpartition_by: impl Into<String>) -> Self {
346 self.mysql_subpartition_by = Some(subpartition_by.into());
347 self
348 }
349
350 pub fn with_mysql_subpartitions(mut self, subpartitions: u32) -> Self {
351 self.mysql_subpartitions = Some(subpartitions);
352 self
353 }
354
355 pub fn with_mysql_auto_increment(mut self, auto_increment: u32) -> Self {
356 self.mysql_auto_increment = Some(auto_increment);
357 self
358 }
359
360 pub fn with_mysql_options(mut self, options: MysqlTableOptions) -> Self {
361 self.mysql_engine = options.engine;
362 self.mysql_charset = options.charset;
363 self.mysql_collation = options.collation;
364 self.mysql_row_format = options.row_format;
365 self.mysql_key_block_size = options.key_block_size;
366 self.mysql_pack_keys = options.pack_keys;
367 self.mysql_checksum = options.checksum;
368 self.mysql_delay_key_write = options.delay_key_write;
369 self.mysql_stats_persistent = options.stats_persistent;
370 self.mysql_stats_auto_recalc = options.stats_auto_recalc;
371 self.mysql_stats_sample_pages = options.stats_sample_pages;
372 self.mysql_avg_row_length = options.avg_row_length;
373 self.mysql_max_rows = options.max_rows;
374 self.mysql_min_rows = options.min_rows;
375 self.mysql_insert_method = options.insert_method;
376 self.mysql_data_directory = options.data_directory;
377 self.mysql_index_directory = options.index_directory;
378 self.mysql_connection = options.connection;
379 self.mysql_union = options.union;
380 self.mysql_partition_by = options.partition_by;
381 self.mysql_partitions = options.partitions;
382 self.mysql_subpartition_by = options.subpartition_by;
383 self.mysql_subpartitions = options.subpartitions;
384 self.mysql_auto_increment = options.auto_increment;
385 self
386 }
387
388 pub fn with_postgres_inherits(mut self, parents: Vec<String>) -> Self {
389 self.postgres_inherits = parents;
390 self
391 }
392
393 pub fn with_postgres_with(mut self, parameters: Vec<(String, String)>) -> Self {
394 self.postgres_with = parameters;
395 self
396 }
397
398 pub fn with_postgres_using(mut self, access_method: impl Into<String>) -> Self {
399 self.postgres_using = Some(access_method.into());
400 self
401 }
402
403 pub fn with_postgres_using_option(mut self, access_method: Option<String>) -> Self {
404 self.postgres_using = access_method;
405 self
406 }
407
408 pub fn postgres_unlogged(mut self) -> Self {
409 self.postgres_unlogged = true;
410 self
411 }
412
413 pub fn with_postgres_unlogged(mut self, unlogged: bool) -> Self {
414 self.postgres_unlogged = unlogged;
415 self
416 }
417
418 pub fn sqlite_strict(mut self) -> Self {
419 self.sqlite_strict = true;
420 self
421 }
422
423 pub fn with_sqlite_strict(mut self, strict: bool) -> Self {
424 self.sqlite_strict = strict;
425 self
426 }
427
428 pub fn sqlite_without_rowid(mut self) -> Self {
429 self.sqlite_without_rowid = true;
430 self
431 }
432
433 pub fn with_sqlite_without_rowid(mut self, without_rowid: bool) -> Self {
434 self.sqlite_without_rowid = without_rowid;
435 self
436 }
437
438 pub fn with_oracle_compress(mut self) -> Self {
439 self.oracle_compress = Some(OracleTableCompression::Enabled);
440 self
441 }
442
443 pub fn with_oracle_compress_level(mut self, level: u32) -> Self {
444 self.oracle_compress = Some(OracleTableCompression::Level(level));
445 self
446 }
447
448 pub fn with_oracle_compress_option(mut self, compress: Option<OracleTableCompression>) -> Self {
449 self.oracle_compress = compress;
450 self
451 }
452
453 pub fn with_mssql_primary_key_nonclustered(mut self, nonclustered: bool) -> Self {
454 self.mssql_primary_key_nonclustered = nonclustered;
455 self
456 }
457
458 pub fn with_postgres_partition_by(mut self, partition_by: impl Into<String>) -> Self {
459 self.postgres_partition_by = Some(partition_by.into());
460 self
461 }
462
463 pub fn with_postgres_partition_by_option(mut self, partition_by: Option<String>) -> Self {
464 self.postgres_partition_by = partition_by;
465 self
466 }
467
468 pub fn with_postgres_partition_of(mut self, parent: impl Into<String>) -> Self {
469 self.postgres_partition_of = Some(parent.into());
470 self
471 }
472
473 pub fn with_postgres_partition_of_option(mut self, parent: Option<String>) -> Self {
474 self.postgres_partition_of = parent;
475 self
476 }
477
478 pub fn with_postgres_partition_for(mut self, bound: impl Into<String>) -> Self {
479 self.postgres_partition_for = Some(bound.into());
480 self
481 }
482
483 pub fn with_postgres_partition_for_option(mut self, bound: Option<String>) -> Self {
484 self.postgres_partition_for = bound;
485 self
486 }
487
488 pub fn with_check_constraints(mut self, check_constraints: Vec<CheckConstraintDef>) -> Self {
489 self.check_constraints = check_constraints;
490 self
491 }
492
493 pub fn with_foreign_keys(mut self, foreign_keys: Vec<ForeignKeyDef>) -> Self {
494 self.foreign_keys = foreign_keys;
495 self
496 }
497
498 pub fn with_exclusion_constraints(
499 mut self,
500 exclusion_constraints: Vec<ExclusionConstraintDef>,
501 ) -> Self {
502 self.exclusion_constraints = exclusion_constraints;
503 self
504 }
505
506 pub fn set_id(&mut self, id: TableId) {
507 self.id = Some(id);
508 }
509
510 pub fn id(&self) -> Option<TableId> {
511 self.id
512 }
513
514 pub fn model_key(&self) -> &str {
515 &self.model_key
516 }
517
518 pub fn name(&self) -> &str {
519 &self.name
520 }
521
522 pub fn primary_key(&self) -> &str {
523 &self.primary_key
524 }
525
526 pub fn columns(&self) -> &[ColumnDef] {
527 &self.columns
528 }
529
530 pub fn column_names(&self) -> impl Iterator<Item = &str> {
531 self.columns.iter().map(|column| column.name())
532 }
533
534 pub fn relationships(&self) -> &[RelationshipDef] {
535 &self.relationships
536 }
537
538 pub fn indexes(&self) -> &[IndexDef] {
539 &self.indexes
540 }
541
542 pub fn unique_constraints(&self) -> &[UniqueConstraintDef] {
543 &self.unique_constraints
544 }
545
546 pub fn check_constraints(&self) -> &[CheckConstraintDef] {
547 &self.check_constraints
548 }
549
550 pub fn foreign_keys(&self) -> &[ForeignKeyDef] {
551 &self.foreign_keys
552 }
553
554 pub fn exclusion_constraints(&self) -> &[ExclusionConstraintDef] {
555 &self.exclusion_constraints
556 }
557
558 pub fn schema(&self) -> Option<&str> {
559 self.schema.as_deref()
560 }
561
562 pub fn comment(&self) -> Option<&str> {
563 self.comment.as_deref()
564 }
565
566 pub fn tablespace(&self) -> Option<&str> {
567 self.tablespace.as_deref()
568 }
569
570 pub fn mysql_engine(&self) -> Option<&str> {
571 self.mysql_engine.as_deref()
572 }
573
574 pub fn mysql_charset(&self) -> Option<&str> {
575 self.mysql_charset.as_deref()
576 }
577
578 pub fn mysql_collation(&self) -> Option<&str> {
579 self.mysql_collation.as_deref()
580 }
581
582 pub fn mysql_row_format(&self) -> Option<&str> {
583 self.mysql_row_format.as_deref()
584 }
585
586 pub fn mysql_key_block_size(&self) -> Option<u32> {
587 self.mysql_key_block_size
588 }
589
590 pub fn mysql_pack_keys(&self) -> Option<bool> {
591 self.mysql_pack_keys
592 }
593
594 pub fn mysql_checksum(&self) -> Option<bool> {
595 self.mysql_checksum
596 }
597
598 pub fn mysql_delay_key_write(&self) -> Option<bool> {
599 self.mysql_delay_key_write
600 }
601
602 pub fn mysql_stats_persistent(&self) -> Option<bool> {
603 self.mysql_stats_persistent
604 }
605
606 pub fn mysql_stats_auto_recalc(&self) -> Option<bool> {
607 self.mysql_stats_auto_recalc
608 }
609
610 pub fn mysql_stats_sample_pages(&self) -> Option<u32> {
611 self.mysql_stats_sample_pages
612 }
613
614 pub fn mysql_avg_row_length(&self) -> Option<u32> {
615 self.mysql_avg_row_length
616 }
617
618 pub fn mysql_max_rows(&self) -> Option<u32> {
619 self.mysql_max_rows
620 }
621
622 pub fn mysql_min_rows(&self) -> Option<u32> {
623 self.mysql_min_rows
624 }
625
626 pub fn mysql_insert_method(&self) -> Option<&str> {
627 self.mysql_insert_method.as_deref()
628 }
629
630 pub fn mysql_data_directory(&self) -> Option<&str> {
631 self.mysql_data_directory.as_deref()
632 }
633
634 pub fn mysql_index_directory(&self) -> Option<&str> {
635 self.mysql_index_directory.as_deref()
636 }
637
638 pub fn mysql_connection(&self) -> Option<&str> {
639 self.mysql_connection.as_deref()
640 }
641
642 pub fn mysql_union(&self) -> &[String] {
643 &self.mysql_union
644 }
645
646 pub fn mysql_partition_by(&self) -> Option<&str> {
647 self.mysql_partition_by.as_deref()
648 }
649
650 pub fn mysql_partitions(&self) -> Option<u32> {
651 self.mysql_partitions
652 }
653
654 pub fn mysql_subpartition_by(&self) -> Option<&str> {
655 self.mysql_subpartition_by.as_deref()
656 }
657
658 pub fn mysql_subpartitions(&self) -> Option<u32> {
659 self.mysql_subpartitions
660 }
661
662 pub fn mysql_auto_increment(&self) -> Option<u32> {
663 self.mysql_auto_increment
664 }
665
666 pub fn postgres_inherits(&self) -> &[String] {
667 &self.postgres_inherits
668 }
669
670 pub fn postgres_with(&self) -> &[(String, String)] {
671 &self.postgres_with
672 }
673
674 pub fn postgres_using(&self) -> Option<&str> {
675 self.postgres_using.as_deref()
676 }
677
678 pub fn is_postgres_unlogged(&self) -> bool {
679 self.postgres_unlogged
680 }
681
682 pub fn postgres_partition_by(&self) -> Option<&str> {
683 self.postgres_partition_by.as_deref()
684 }
685
686 pub fn postgres_partition_of(&self) -> Option<&str> {
687 self.postgres_partition_of.as_deref()
688 }
689
690 pub fn postgres_partition_for(&self) -> Option<&str> {
691 self.postgres_partition_for.as_deref()
692 }
693
694 pub fn is_sqlite_strict(&self) -> bool {
695 self.sqlite_strict
696 }
697
698 pub fn is_sqlite_without_rowid(&self) -> bool {
699 self.sqlite_without_rowid
700 }
701
702 pub fn oracle_compress(&self) -> Option<&OracleTableCompression> {
703 self.oracle_compress.as_ref()
704 }
705
706 pub fn is_mssql_primary_key_nonclustered(&self) -> bool {
707 self.mssql_primary_key_nonclustered
708 }
709
710 pub fn qualified_name(&self) -> QualifiedName {
711 QualifiedName::unchecked(self.schema.clone(), self.name.clone())
712 }
713}