Skip to main content

good_ormning/pg/graph/
constraint.rs

1use std::collections::HashSet;
2use crate::{
3    graphmigrate::Comparison,
4    pg::schema::{
5        constraint::{
6            Constraint,
7            ConstraintType,
8        },
9    },
10    utils::Tokens,
11};
12use super::{
13    utils::{
14        NodeDataDispatch,
15        PgMigrateCtx,
16        NodeData,
17    },
18    GraphId,
19    Node,
20};
21
22#[derive(Clone)]
23pub(crate) struct NodeConstraint_ {
24    pub def: Constraint,
25}
26
27impl NodeConstraint_ {
28    pub fn compare(&self, old: &Self, created: &HashSet<GraphId>) -> Comparison {
29        if created.contains(&GraphId::Table(self.def.table.schema_id.clone())) || self.def.type_ != old.def.type_ {
30            Comparison::Recreate
31        } else if self.def.id != old.def.id {
32            Comparison::Update
33        } else {
34            Comparison::DoNothing
35        }
36    }
37}
38
39impl NodeDataDispatch for NodeConstraint_ {
40    fn create_coalesce(&mut self, other: Node) -> Option<Node> {
41        Some(other)
42    }
43
44    fn create(&self, ctx: &mut PgMigrateCtx) {
45        let mut stmt = Tokens::new();
46        stmt.s("alter table").id(&self.def.table.id).s("add constraint").id(&self.def.id);
47        match &self.def.type_ {
48            ConstraintType::PrimaryKey(x) => {
49                stmt.s("primary key (").f(|t| {
50                    for (i, field) in x.fields.iter().enumerate() {
51                        if i > 0 {
52                            t.s(",");
53                        }
54                        t.id(&field.id);
55                    }
56                }).s(")");
57            },
58            ConstraintType::ForeignKey(x) => {
59                stmt.s("foreign key (").f(|t| {
60                    for (i, pair) in x.fields.iter().enumerate() {
61                        if i > 0 {
62                            t.s(",");
63                        }
64                        t.id(&pair.0.id);
65                    }
66                }).s(") references ").f(|t| {
67                    for (i, pair) in x.fields.iter().enumerate() {
68                        if i == 0 {
69                            t.id(&pair.1.table.id).s("(");
70                        } else {
71                            t.s(",");
72                        }
73                        t.id(&pair.1.id);
74                    }
75                }).s(")");
76            },
77        }
78        ctx.statements.push(stmt.to_string());
79    }
80
81    fn delete_coalesce(&mut self, other: Node) -> Option<Node> {
82        Some(other)
83    }
84
85    fn delete(&self, ctx: &mut PgMigrateCtx) {
86        ctx
87            .statements
88            .push(
89                Tokens::new()
90                    .s("alter table")
91                    .id(&self.def.table.id)
92                    .s("drop constraint")
93                    .id(&self.def.id)
94                    .to_string(),
95            );
96    }
97}
98
99impl NodeData for NodeConstraint_ {
100    fn update(&self, ctx: &mut PgMigrateCtx, old: &Self) {
101        if self.def.id != old.def.id {
102            let mut stmt = Tokens::new();
103            stmt
104                .s("alter table")
105                .id(&self.def.table.0.id)
106                .s("rename constraint")
107                .id(&old.def.id)
108                .s("to")
109                .id(&self.def.id);
110            ctx.statements.push(stmt.to_string());
111        }
112    }
113}