1use std::borrow::Cow;
2
3use serde::{Deserialize, Serialize};
4
5use crate::states::types::{Dep, EntityKind};
6use crate::states::{
7 Column, Constraint, EnumDef, ExtensionDef, ForeignKey, FunctionDef, Index, Table,
8 TableOptionsMeta, TriggerDef, ViewDef,
9};
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14#[serde(tag = "type", rename_all = "snake_case")]
15pub enum Operation {
16 CreateTable {
17 table: Table,
18 },
19 DropTable {
20 table: Table,
21 },
22 RenameTable {
23 old_name: String,
24 new_name: String,
25 },
26 AcknowledgeTableOptions {
27 table_name: String,
28 old: TableOptionsMeta,
29 new: TableOptionsMeta,
30 },
31 AddColumn {
32 table_name: String,
33 column: Column,
34 },
35 DropColumn {
36 table_name: String,
37 column: Column,
38 #[serde(default)]
39 cascade: bool,
40 },
41 RenameColumn {
42 table_name: String,
43 old_name: String,
44 new_name: String,
45 },
46 AlterColumn {
47 table_name: String,
48 old: Column,
49 new: Column,
50 #[serde(default)]
51 cast_expr: Option<String>,
52 },
53 AddForeignKey {
54 table_name: String,
55 foreign_key: ForeignKey,
56 },
57 DropForeignKey {
58 table_name: String,
59 foreign_key: ForeignKey,
60 #[serde(default)]
61 cascade: bool,
62 },
63 AddIndex {
64 table_name: String,
65 index: Index,
66 #[serde(default)]
67 concurrent: bool,
68 },
69 DropIndex {
70 table_name: String,
71 index: Index,
72 #[serde(default)]
73 concurrent: bool,
74 },
75 AddConstraint {
76 table_name: String,
77 constraint: Constraint,
78 },
79 DropConstraint {
80 table_name: String,
81 constraint: Constraint,
82 },
83 Statement {
84 up: String,
85 down: Option<String>,
86 },
87 CreateFunction {
88 function: FunctionDef,
89 },
90 AlterFunction {
91 old: FunctionDef,
92 new: FunctionDef,
93 },
94 DropFunction {
95 function: FunctionDef,
96 },
97 CreateTrigger {
98 table_name: String,
99 trigger: TriggerDef,
100 },
101 AlterTrigger {
102 table_name: String,
103 old: TriggerDef,
104 new: TriggerDef,
105 },
106 DropTrigger {
107 table_name: String,
108 trigger: TriggerDef,
109 },
110 CreateView {
111 view: ViewDef,
112 },
113 DropView {
114 view: ViewDef,
115 },
116 ReplaceView {
117 old: ViewDef,
118 new: ViewDef,
119 },
120 CreateExtension {
121 extension: ExtensionDef,
122 },
123 DropExtension {
124 extension: ExtensionDef,
125 },
126 CreateEnum {
127 enum_def: EnumDef,
128 },
129 DropEnum {
130 enum_def: EnumDef,
131 },
132 RenameEnumValue {
133 enum_name: String,
134 #[serde(default)]
135 schema: Option<String>,
136 old_value: String,
137 new_value: String,
138 },
139 AlterEnum {
140 old: EnumDef,
141 new: EnumDef,
142 },
143}
144
145impl Operation {
146 pub fn inverse(&self) -> Option<Operation> {
147 match self {
148 Self::CreateTable { .. }
149 | Self::DropTable { .. }
150 | Self::RenameTable { .. }
151 | Self::AcknowledgeTableOptions { .. } => self.inverse_table_op(),
152 Self::AddColumn { .. }
153 | Self::DropColumn { .. }
154 | Self::RenameColumn { .. }
155 | Self::AlterColumn { .. }
156 | Self::AddForeignKey { .. }
157 | Self::DropForeignKey { .. }
158 | Self::AddIndex { .. }
159 | Self::DropIndex { .. }
160 | Self::AddConstraint { .. }
161 | Self::DropConstraint { .. } => self.inverse_table_item_op(),
162 Self::Statement { .. }
163 | Self::CreateFunction { .. }
164 | Self::AlterFunction { .. }
165 | Self::DropFunction { .. } => self.inverse_function_op(),
166 Self::CreateTrigger { .. } | Self::AlterTrigger { .. } | Self::DropTrigger { .. } => {
167 self.inverse_trigger_op()
168 }
169 Self::CreateView { .. } | Self::DropView { .. } | Self::ReplaceView { .. } => {
170 self.inverse_view_op()
171 }
172 Self::CreateExtension { .. } | Self::DropExtension { .. } => {
173 self.inverse_extension_op()
174 }
175 Self::CreateEnum { .. }
176 | Self::DropEnum { .. }
177 | Self::RenameEnumValue { .. }
178 | Self::AlterEnum { .. } => self.inverse_enum_op(),
179 }
180 }
181
182 fn inverse_table_op(&self) -> Option<Operation> {
183 match self {
184 Self::CreateTable { table } => Some(Self::DropTable {
185 table: table.clone(),
186 }),
187 Self::DropTable { table } => Some(Self::CreateTable {
188 table: table.clone(),
189 }),
190 Self::RenameTable { old_name, new_name } => Some(Self::RenameTable {
191 old_name: new_name.clone(),
192 new_name: old_name.clone(),
193 }),
194 Self::AcknowledgeTableOptions {
195 table_name,
196 old,
197 new,
198 } => Some(Self::AcknowledgeTableOptions {
199 table_name: table_name.clone(),
200 old: new.clone(),
201 new: old.clone(),
202 }),
203 _ => None,
204 }
205 }
206
207 fn inverse_table_item_op(&self) -> Option<Operation> {
208 match self {
209 Self::AddColumn { table_name, column } => Some(Self::DropColumn {
210 table_name: table_name.clone(),
211 column: column.clone(),
212 cascade: false,
213 }),
214 Self::DropColumn {
215 table_name, column, ..
216 } => Some(Self::AddColumn {
217 table_name: table_name.clone(),
218 column: column.clone(),
219 }),
220 Self::RenameColumn {
221 table_name,
222 old_name,
223 new_name,
224 } => Some(Self::RenameColumn {
225 table_name: table_name.clone(),
226 old_name: new_name.clone(),
227 new_name: old_name.clone(),
228 }),
229 Self::AlterColumn {
230 table_name,
231 old,
232 new,
233 ..
234 } => Some(Self::AlterColumn {
235 table_name: table_name.clone(),
236 old: new.clone(),
237 new: old.clone(),
238 cast_expr: None,
239 }),
240 Self::AddForeignKey {
241 table_name,
242 foreign_key,
243 } => Some(Self::DropForeignKey {
244 table_name: table_name.clone(),
245 foreign_key: foreign_key.clone(),
246 cascade: false,
247 }),
248 Self::DropForeignKey {
249 table_name,
250 foreign_key,
251 ..
252 } => Some(Self::AddForeignKey {
253 table_name: table_name.clone(),
254 foreign_key: foreign_key.clone(),
255 }),
256 Self::AddIndex {
257 table_name,
258 index,
259 concurrent,
260 } => Some(Self::DropIndex {
261 table_name: table_name.clone(),
262 index: index.clone(),
263 concurrent: *concurrent,
264 }),
265 Self::DropIndex {
266 table_name,
267 index,
268 concurrent,
269 } => Some(Self::AddIndex {
270 table_name: table_name.clone(),
271 index: index.clone(),
272 concurrent: *concurrent,
273 }),
274 Self::AddConstraint {
275 table_name,
276 constraint,
277 } => Some(Self::DropConstraint {
278 table_name: table_name.clone(),
279 constraint: constraint.clone(),
280 }),
281 Self::DropConstraint {
282 table_name,
283 constraint,
284 } => Some(Self::AddConstraint {
285 table_name: table_name.clone(),
286 constraint: constraint.clone(),
287 }),
288 _ => None,
289 }
290 }
291
292 fn inverse_function_op(&self) -> Option<Operation> {
293 match self {
294 Self::Statement {
295 up,
296 down: Some(down),
297 } => Some(Self::Statement {
298 up: down.clone(),
299 down: Some(up.clone()),
300 }),
301 Self::Statement { down: None, .. } => None,
302 Self::CreateFunction { function } => Some(Self::DropFunction {
303 function: function.clone(),
304 }),
305 Self::DropFunction { function } => Some(Self::CreateFunction {
306 function: function.clone(),
307 }),
308 Self::AlterFunction { old, new } => Some(Self::AlterFunction {
309 old: new.clone(),
310 new: old.clone(),
311 }),
312 _ => None,
313 }
314 }
315
316 fn inverse_trigger_op(&self) -> Option<Operation> {
317 match self {
318 Self::CreateTrigger {
319 table_name,
320 trigger,
321 } => Some(Self::DropTrigger {
322 table_name: table_name.clone(),
323 trigger: trigger.clone(),
324 }),
325 Self::DropTrigger {
326 table_name,
327 trigger,
328 } => Some(Self::CreateTrigger {
329 table_name: table_name.clone(),
330 trigger: trigger.clone(),
331 }),
332 Self::AlterTrigger {
333 table_name,
334 old,
335 new,
336 } => Some(Self::AlterTrigger {
337 table_name: table_name.clone(),
338 old: new.clone(),
339 new: old.clone(),
340 }),
341 _ => None,
342 }
343 }
344
345 fn inverse_view_op(&self) -> Option<Operation> {
346 match self {
347 Self::CreateView { view } => Some(Self::DropView { view: view.clone() }),
348 Self::DropView { view } => Some(Self::CreateView { view: view.clone() }),
349 Self::ReplaceView { old, new } => Some(Self::ReplaceView {
350 old: new.clone(),
351 new: old.clone(),
352 }),
353 _ => None,
354 }
355 }
356
357 fn inverse_extension_op(&self) -> Option<Operation> {
358 match self {
359 Self::CreateExtension { extension } => Some(Self::DropExtension {
360 extension: extension.clone(),
361 }),
362 Self::DropExtension { extension } => Some(Self::CreateExtension {
363 extension: extension.clone(),
364 }),
365 _ => None,
366 }
367 }
368
369 fn inverse_enum_op(&self) -> Option<Operation> {
370 match self {
371 Self::CreateEnum { enum_def } => Some(Self::DropEnum {
372 enum_def: enum_def.clone(),
373 }),
374 Self::DropEnum { enum_def } => Some(Self::CreateEnum {
375 enum_def: enum_def.clone(),
376 }),
377 Self::RenameEnumValue {
378 enum_name,
379 schema,
380 old_value,
381 new_value,
382 } => Some(Self::RenameEnumValue {
383 enum_name: enum_name.clone(),
384 schema: schema.clone(),
385 old_value: new_value.clone(),
386 new_value: old_value.clone(),
387 }),
388 Self::AlterEnum { .. } => None,
389 _ => None,
390 }
391 }
392
393 pub fn table_name(&self) -> Option<&str> {
394 match self {
395 Self::CreateTable { table } | Self::DropTable { table } => Some(&table.name),
396 Self::RenameTable { old_name, .. } => Some(old_name),
397 Self::AcknowledgeTableOptions { table_name, .. } => Some(table_name),
398 Self::AddColumn { table_name, .. }
399 | Self::DropColumn { table_name, .. }
400 | Self::RenameColumn { table_name, .. }
401 | Self::AlterColumn { table_name, .. }
402 | Self::AddForeignKey { table_name, .. }
403 | Self::DropForeignKey { table_name, .. }
404 | Self::AddIndex { table_name, .. }
405 | Self::DropIndex { table_name, .. }
406 | Self::AddConstraint { table_name, .. }
407 | Self::DropConstraint { table_name, .. }
408 | Self::CreateTrigger { table_name, .. }
409 | Self::AlterTrigger { table_name, .. }
410 | Self::DropTrigger { table_name, .. } => Some(table_name),
411 _ => None,
412 }
413 }
414
415 pub fn entity_name(&self) -> Cow<'_, str> {
416 match self {
417 Self::CreateTable { table } | Self::DropTable { table } => {
418 if table.schema.is_some() {
419 Cow::Owned(table.qualified_name())
420 } else {
421 Cow::Borrowed(&table.name)
422 }
423 }
424 Self::RenameTable { old_name, .. } => Cow::Borrowed(old_name),
425 Self::AcknowledgeTableOptions { table_name, .. } => Cow::Borrowed(table_name),
426 Self::AddColumn { column, .. } | Self::DropColumn { column, .. } => {
427 Cow::Borrowed(&column.name)
428 }
429 Self::RenameColumn { old_name, .. } => Cow::Borrowed(old_name),
430 Self::AlterColumn { old, .. } => Cow::Borrowed(&old.name),
431 Self::AddForeignKey { foreign_key, .. } | Self::DropForeignKey { foreign_key, .. } => {
432 Cow::Borrowed(&foreign_key.name)
433 }
434 Self::AddIndex { index, .. } | Self::DropIndex { index, .. } => {
435 Cow::Borrowed(&index.name)
436 }
437 Self::AddConstraint { constraint, .. } | Self::DropConstraint { constraint, .. } => {
438 Cow::Borrowed(constraint.name())
439 }
440 Self::CreateTrigger { trigger, .. } | Self::DropTrigger { trigger, .. } => {
441 Cow::Borrowed(trigger.name.as_deref().unwrap_or(""))
442 }
443 Self::AlterTrigger { old, .. } => Cow::Borrowed(old.name.as_deref().unwrap_or("")),
444 Self::CreateFunction { function } | Self::DropFunction { function } => {
445 if function.schema.is_some() {
446 Cow::Owned(function.qualified_name())
447 } else {
448 Cow::Borrowed(&function.name)
449 }
450 }
451 Self::AlterFunction { old, .. } => {
452 if old.schema.is_some() {
453 Cow::Owned(old.qualified_name())
454 } else {
455 Cow::Borrowed(&old.name)
456 }
457 }
458 Self::CreateView { view } | Self::DropView { view } => {
459 if view.schema.is_some() {
460 Cow::Owned(view.qualified_name())
461 } else {
462 Cow::Borrowed(&view.name)
463 }
464 }
465 Self::ReplaceView { old, .. } => {
466 if old.schema.is_some() {
467 Cow::Owned(old.qualified_name())
468 } else {
469 Cow::Borrowed(&old.name)
470 }
471 }
472 Self::CreateExtension { extension } | Self::DropExtension { extension } => {
473 if extension.schema.is_some() {
474 Cow::Owned(extension.qualified_name())
475 } else {
476 Cow::Borrowed(&extension.name)
477 }
478 }
479 Self::CreateEnum { enum_def } | Self::DropEnum { enum_def } => {
480 if enum_def.schema.is_some() {
481 Cow::Owned(enum_def.qualified_name())
482 } else {
483 Cow::Borrowed(&enum_def.name)
484 }
485 }
486 Self::RenameEnumValue {
487 enum_name, schema, ..
488 } => {
489 if let Some(schema) = schema {
490 Cow::Owned(format!("{schema}.{enum_name}"))
491 } else {
492 Cow::Borrowed(enum_name)
493 }
494 }
495 Self::AlterEnum { old, .. } => {
496 if old.schema.is_some() {
497 Cow::Owned(old.qualified_name())
498 } else {
499 Cow::Borrowed(&old.name)
500 }
501 }
502 Self::Statement { up, .. } => Cow::Borrowed(up),
503 }
504 }
505
506 pub fn type_name(&self) -> &'static str {
507 match self {
508 Self::CreateTable { .. } => "create_table",
509 Self::DropTable { .. } => "drop_table",
510 Self::RenameTable { .. } => "rename_table",
511 Self::AcknowledgeTableOptions { .. } => "acknowledge_table_options",
512 Self::AddColumn { .. } => "add_column",
513 Self::DropColumn { .. } => "drop_column",
514 Self::RenameColumn { .. } => "rename_column",
515 Self::AlterColumn { .. } => "alter_column",
516 Self::AddForeignKey { .. } => "add_foreign_key",
517 Self::DropForeignKey { .. } => "drop_foreign_key",
518 Self::AddIndex { .. } => "add_index",
519 Self::DropIndex { .. } => "drop_index",
520 Self::AddConstraint { .. } => "add_constraint",
521 Self::DropConstraint { .. } => "drop_constraint",
522 Self::Statement { .. } => "statement",
523 Self::CreateFunction { .. } => "create_function",
524 Self::AlterFunction { .. } => "alter_function",
525 Self::DropFunction { .. } => "drop_function",
526 Self::CreateTrigger { .. } => "create_trigger",
527 Self::AlterTrigger { .. } => "alter_trigger",
528 Self::DropTrigger { .. } => "drop_trigger",
529 Self::CreateView { .. } => "create_view",
530 Self::DropView { .. } => "drop_view",
531 Self::ReplaceView { .. } => "replace_view",
532 Self::CreateExtension { .. } => "create_extension",
533 Self::DropExtension { .. } => "drop_extension",
534 Self::CreateEnum { .. } => "create_enum",
535 Self::DropEnum { .. } => "drop_enum",
536 Self::RenameEnumValue { .. } => "rename_enum_value",
537 Self::AlterEnum { .. } => "alter_enum",
538 }
539 }
540
541 pub fn entity_kind(&self) -> Option<EntityKind> {
542 match self {
543 Self::CreateTable { .. }
544 | Self::DropTable { .. }
545 | Self::AcknowledgeTableOptions { .. } => Some(EntityKind::Table),
546 Self::CreateFunction { .. }
547 | Self::AlterFunction { .. }
548 | Self::DropFunction { .. } => Some(EntityKind::Function),
549 Self::CreateEnum { .. }
550 | Self::RenameEnumValue { .. }
551 | Self::AlterEnum { .. }
552 | Self::DropEnum { .. } => Some(EntityKind::Enum),
553 Self::CreateExtension { .. } | Self::DropExtension { .. } => {
554 Some(EntityKind::Extension)
555 }
556 Self::CreateView { .. } | Self::DropView { .. } | Self::ReplaceView { .. } => {
557 Some(EntityKind::View)
558 }
559 Self::AddColumn { .. }
560 | Self::DropColumn { .. }
561 | Self::AlterColumn { .. }
562 | Self::RenameColumn { .. } => Some(EntityKind::Column),
563 Self::AddForeignKey { .. } | Self::DropForeignKey { .. } => {
564 Some(EntityKind::ForeignKey)
565 }
566 Self::AddIndex { .. } | Self::DropIndex { .. } => Some(EntityKind::Index),
567 Self::AddConstraint { .. } | Self::DropConstraint { .. } => {
568 Some(EntityKind::Constraint)
569 }
570 Self::CreateTrigger { .. } | Self::AlterTrigger { .. } | Self::DropTrigger { .. } => {
571 Some(EntityKind::Trigger)
572 }
573 Self::RenameTable { .. } | Self::Statement { .. } => None,
574 }
575 }
576
577 pub fn is_create(&self) -> bool {
578 matches!(
579 self,
580 Self::CreateTable { .. }
581 | Self::CreateFunction { .. }
582 | Self::CreateEnum { .. }
583 | Self::CreateExtension { .. }
584 | Self::CreateView { .. }
585 | Self::CreateTrigger { .. }
586 | Self::RenameEnumValue { .. }
587 | Self::AlterEnum { .. }
588 | Self::AddColumn { .. }
589 | Self::AddForeignKey { .. }
590 | Self::AddIndex { .. }
591 | Self::AddConstraint { .. }
592 | Self::AcknowledgeTableOptions { .. }
593 )
594 }
595
596 pub fn is_drop(&self) -> bool {
597 matches!(
598 self,
599 Self::DropTable { .. }
600 | Self::DropFunction { .. }
601 | Self::DropEnum { .. }
602 | Self::DropExtension { .. }
603 | Self::DropView { .. }
604 | Self::DropTrigger { .. }
605 | Self::DropColumn { .. }
606 | Self::DropForeignKey { .. }
607 | Self::DropIndex { .. }
608 | Self::DropConstraint { .. }
609 )
610 }
611
612 pub fn forward_deps(&self) -> Vec<Dep> {
613 match self {
614 Self::CreateTable { table } | Self::DropTable { table } => {
615 let mut deps = vec![Dep::all_of(EntityKind::Extension)];
616 for col in &table.columns {
617 deps.push(Dep::new(EntityKind::Enum, &col.col_type));
618 }
619 deps
620 }
621 Self::AddColumn { table_name, column }
622 | Self::DropColumn {
623 table_name, column, ..
624 } => {
625 vec![
626 Dep::new(EntityKind::Table, table_name),
627 Dep::new(EntityKind::Enum, &column.col_type),
628 ]
629 }
630 Self::AlterColumn {
631 table_name, new, ..
632 } => {
633 vec![
634 Dep::new(EntityKind::Table, table_name),
635 Dep::new(EntityKind::Enum, &new.col_type),
636 ]
637 }
638 Self::AddForeignKey {
639 table_name,
640 foreign_key,
641 }
642 | Self::DropForeignKey {
643 table_name,
644 foreign_key,
645 ..
646 } => {
647 vec![
648 Dep::new(EntityKind::Table, table_name),
649 Dep::new(EntityKind::Table, &foreign_key.to_table),
650 ]
651 }
652 Self::AddIndex { table_name, .. } | Self::DropIndex { table_name, .. } => {
653 vec![Dep::new(EntityKind::Table, table_name)]
654 }
655 Self::AddConstraint { table_name, .. } | Self::DropConstraint { table_name, .. } => {
656 vec![Dep::new(EntityKind::Table, table_name)]
657 }
658 Self::CreateTrigger {
659 table_name,
660 trigger,
661 }
662 | Self::AlterTrigger {
663 table_name,
664 new: trigger,
665 ..
666 } => {
667 let mut deps = vec![Dep::new(EntityKind::Table, table_name)];
668 if let Some(fn_name) = trigger.function_name.as_deref() {
669 deps.push(Dep::new(EntityKind::Function, fn_name));
670 }
671 deps
672 }
673 Self::DropTrigger {
674 table_name,
675 trigger,
676 } => {
677 let mut deps = vec![Dep::new(EntityKind::Table, table_name)];
678 if let Some(fn_name) = trigger.function_name.as_deref() {
679 deps.push(Dep::new(EntityKind::Function, fn_name));
680 }
681 deps
682 }
683 Self::CreateFunction { .. }
684 | Self::AlterFunction { .. }
685 | Self::DropFunction { .. } => {
686 vec![Dep::all_of(EntityKind::Extension)]
687 }
688 Self::CreateView { .. } | Self::ReplaceView { .. } | Self::DropView { .. } => {
689 vec![
690 Dep::all_of(EntityKind::Table),
691 Dep::all_of(EntityKind::Function),
692 ]
693 }
694 Self::CreateExtension { .. } | Self::DropExtension { .. } => vec![],
695 Self::CreateEnum { .. }
696 | Self::RenameEnumValue { .. }
697 | Self::AlterEnum { .. }
698 | Self::DropEnum { .. } => vec![],
699 Self::AcknowledgeTableOptions { table_name, .. } => {
700 vec![Dep::new(EntityKind::Table, table_name)]
701 }
702 Self::RenameTable { .. } | Self::RenameColumn { .. } | Self::Statement { .. } => vec![],
703 }
704 }
705
706 pub fn backward_deps(&self) -> Vec<Dep> {
707 match self {
708 Self::AlterColumn {
709 table_name, old, ..
710 } => {
711 vec![
712 Dep::new(EntityKind::Table, table_name),
713 Dep::new(EntityKind::Enum, &old.col_type),
714 ]
715 }
716 _ => self.forward_deps(),
717 }
718 }
719
720 pub fn entity_label(&self) -> Option<&str> {
722 match self {
723 Self::CreateTable { table } | Self::DropTable { table } => Some(&table.name),
724 Self::RenameTable { new_name, .. } => Some(new_name),
725 Self::AcknowledgeTableOptions { table_name, .. }
726 | Self::AddColumn { table_name, .. }
727 | Self::DropColumn { table_name, .. }
728 | Self::RenameColumn { table_name, .. }
729 | Self::AlterColumn { table_name, .. }
730 | Self::AddForeignKey { table_name, .. }
731 | Self::DropForeignKey { table_name, .. }
732 | Self::AddIndex { table_name, .. }
733 | Self::DropIndex { table_name, .. }
734 | Self::AddConstraint { table_name, .. }
735 | Self::DropConstraint { table_name, .. }
736 | Self::CreateTrigger { table_name, .. }
737 | Self::AlterTrigger { table_name, .. }
738 | Self::DropTrigger { table_name, .. } => Some(table_name),
739 Self::CreateFunction { function } | Self::DropFunction { function } => {
740 Some(&function.name)
741 }
742 Self::AlterFunction { new, .. } => Some(&new.name),
743 Self::CreateView { view } | Self::DropView { view } => Some(&view.name),
744 Self::ReplaceView { new, .. } => Some(&new.name),
745 Self::CreateExtension { extension } | Self::DropExtension { extension } => {
746 Some(&extension.name)
747 }
748 Self::CreateEnum { enum_def } | Self::DropEnum { enum_def } => Some(&enum_def.name),
749 Self::RenameEnumValue { enum_name, .. } => Some(enum_name),
750 Self::AlterEnum { new, .. } => Some(&new.name),
751 Self::Statement { .. } => None,
752 }
753 }
754
755 pub fn touched_entities(&self) -> Vec<(EntityKind, String)> {
757 match self {
758 Self::CreateTable { table } | Self::DropTable { table } => {
759 let mut entities = vec![(EntityKind::Table, table.qualified_name())];
760 entities.extend(
761 table
762 .foreign_keys
763 .iter()
764 .map(|fk| (EntityKind::Table, fk.to_table.clone())),
765 );
766 entities
767 }
768 Self::AddForeignKey {
769 table_name,
770 foreign_key,
771 }
772 | Self::DropForeignKey {
773 table_name,
774 foreign_key,
775 ..
776 } => vec![
777 (EntityKind::Table, table_name.clone()),
778 (EntityKind::Table, foreign_key.to_table.clone()),
779 ],
780 Self::CreateEnum { enum_def }
781 | Self::DropEnum { enum_def }
782 | Self::AlterEnum { new: enum_def, .. } => {
783 vec![(EntityKind::Enum, enum_def.qualified_name())]
784 }
785 Self::RenameEnumValue {
786 enum_name, schema, ..
787 } => vec![(
788 EntityKind::Enum,
789 crate::states::schema_qualified_key(enum_name, schema.as_deref()),
790 )],
791 Self::CreateFunction { function }
792 | Self::DropFunction { function }
793 | Self::AlterFunction { new: function, .. } => {
794 vec![(EntityKind::Function, function.qualified_name())]
795 }
796 Self::CreateView { view }
797 | Self::DropView { view }
798 | Self::ReplaceView { new: view, .. } => {
799 vec![(EntityKind::View, view.qualified_name())]
800 }
801 Self::CreateExtension { extension } | Self::DropExtension { extension } => {
802 vec![(EntityKind::Extension, extension.qualified_name())]
803 }
804 _ => self.table_name().map_or_else(Vec::new, |table| {
805 vec![(EntityKind::Table, table.to_string())]
806 }),
807 }
808 }
809}