Skip to content

Commit

Permalink
handle strengthening after inheritance (fix #118)
Browse files Browse the repository at this point in the history
  • Loading branch information
laowantong committed Oct 17, 2024
1 parent f8c72ca commit c1a9c6c
Show file tree
Hide file tree
Showing 100 changed files with 3,557 additions and 2 deletions.
17 changes: 15 additions & 2 deletions mocodo/convert/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ def __init__(self, mcd, params):
self.freeze_strengthening_foreign_key_migration = set()
self.relations = {}
self.relations_from_entities()
self.strengthen_weak_identifiers()
self.inheritance_parent_or_children_to_delete = self.find_inheritance_parent_or_children_to_delete()
self.strengthen_children()
self.strengthen_parents()
self.strengthen_weak_identifiers()
self.process_associations()
self.process_inheritances()
self.delete_inheritance_parent_or_children_to_delete()
Expand Down Expand Up @@ -320,13 +320,26 @@ def strengthen_weak_identifiers(self):
break
else:
leg_note = None

# Patch for #118: if a child disappears but strengthens a weak entity, the outer source
# of this entity must be the outer source of this child. Otherwise, the relational diagram
# will contains the reference: #parent_id > CHILD > parent_id where CHILD no more exists.
# This doesn't fix #119: in the case of cascading inheritance, the outer source should be
# searched in the parent of the parent, etc.
outer_source = strengthening_entity.name_view
if strengthening_entity.bid in self.inheritance_parent_or_children_to_delete:
for attribute in self.relations[leg.entity_bid]["columns"]:
if attribute["is_primary"]:
outer_source = attribute["outer_source"]
break

# migrate the whole primary key of the strengthening entity into the weak one
self.relations[entity.bid]["columns"][0:0] = [{
"attribute": attribute["attribute"],
"optionality": "!",
"datatype": attribute["datatype"],
"adjacent_source": strengthening_entity.name_view,
"outer_source": strengthening_entity.name_view,
"outer_source": outer_source,
"association_name": association.name_view,
"leg_note": leg_note,
"is_primary": True,
Expand Down
11 changes: 11 additions & 0 deletions test/zoo/inheritance_weak/_strong_child_0.mcd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
% https://github.com/laowantong/mocodo/issues/118
% Class table inheritance: all entities are preserved

DF, _11 CONTRAT, 1N VACATAIRE
VACATAIRE: statut vacataire

CONTRAT: date contrat, salaire horaire contrat
/XT\ PROFESSEUR -> VACATAIRE, SALARIÉ
SALARIÉ: date embauche salarié, échelon salarié, salaire salarié

PROFESSEUR: num prof, nom prof, prénom prof, téléphone prof
11 changes: 11 additions & 0 deletions test/zoo/inheritance_weak/_strong_child_1.mcd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
% https://github.com/laowantong/mocodo/issues/118
% Single table inheritance: children are merged into the parent table

DF, _11 CONTRAT, 1N VACATAIRE
VACATAIRE: statut vacataire

CONTRAT: date contrat, salaire horaire contrat
/XT\ PROFESSEUR <- VACATAIRE, SALARIÉ
SALARIÉ: date embauche salarié, échelon salarié, salaire salarié

PROFESSEUR: num prof, nom prof, prénom prof, téléphone prof
11 changes: 11 additions & 0 deletions test/zoo/inheritance_weak/_strong_child_2.mcd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
% https://github.com/laowantong/mocodo/issues/118
% Concrete table inheritance: parent disappears

DF, _11 CONTRAT, 1N VACATAIRE
VACATAIRE: statut vacataire

CONTRAT: date contrat, salaire horaire contrat
/XT\ PROFESSEUR => VACATAIRE, SALARIÉ
SALARIÉ: date embauche salarié, échelon salarié, salaire salarié

PROFESSEUR: num prof, nom prof, prénom prof, téléphone prof
28 changes: 28 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_0_ddl.d2
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"CONTRAT": { shape: sql_table
"num prof": VARCHAR(42) {constraint: [PK; FK]}
"date contrat": VARCHAR(42) {constraint: PK}
"salaire horaire contrat": VARCHAR(42)
}

"PROFESSEUR": { shape: sql_table
"num prof": VARCHAR(42) {constraint: PK}
"nom prof": VARCHAR(42)
"prénom prof": VARCHAR(42)
"téléphone prof": VARCHAR(42)
}

"SALARIÉ": { shape: sql_table
"num prof": VARCHAR(42) {constraint: [PK; FK]}
"date embauche salarié": VARCHAR(42)
"échelon salarié": VARCHAR(42)
"salaire salarié": VARCHAR(42)
}

"VACATAIRE": { shape: sql_table
"num prof": VARCHAR(42) {constraint: [PK; FK]}
"statut vacataire": VARCHAR(42)
}

"CONTRAT"."num prof" -> "VACATAIRE"."num prof"
"SALARIÉ"."num prof" -> "PROFESSEUR"."num prof"
"VACATAIRE"."num prof" -> "PROFESSEUR"."num prof"
31 changes: 31 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_0_ddl.dbml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Table "CONTRAT" {
"num prof" VARCHAR(42) [NOT NULL]
"date contrat" VARCHAR(42) [NOT NULL]
"salaire horaire contrat" VARCHAR(42)
Indexes {
("num prof", "date contrat") [pk]
}
}

Table "PROFESSEUR" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"nom prof" VARCHAR(42)
"prénom prof" VARCHAR(42)
"téléphone prof" VARCHAR(42)
}

Table "SALARIÉ" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"date embauche salarié" VARCHAR(42)
"échelon salarié" VARCHAR(42)
"salaire salarié" VARCHAR(42)
}

Table "VACATAIRE" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"statut vacataire" VARCHAR(42)
}

Ref:"CONTRAT"."num prof" > "VACATAIRE"."num prof"
Ref:"SALARIÉ"."num prof" > "PROFESSEUR"."num prof"
Ref:"VACATAIRE"."num prof" > "PROFESSEUR"."num prof"
34 changes: 34 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_0_ddl.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CREATE TABLE CONTRAT (
PRIMARY KEY (num_prof, date_contrat),
num_prof VARCHAR(8) NOT NULL,
date_contrat DATE NOT NULL,
salaire_horaire_contrat VARCHAR(42)
);

CREATE TABLE PROFESSEUR (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
nom_prof VARCHAR(255),
prenom_prof VARCHAR(255),
telephone_prof VARCHAR(20)
);

CREATE TABLE SALARIE (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
date_embauche_salarie DATE,
echelon_salarie VARCHAR(42),
salaire_salarie VARCHAR(42)
);

CREATE TABLE VACATAIRE (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
statut_vacataire VARCHAR(20)
);

ALTER TABLE CONTRAT ADD FOREIGN KEY (num_prof) REFERENCES VACATAIRE (num_prof);

ALTER TABLE SALARIE ADD FOREIGN KEY (num_prof) REFERENCES PROFESSEUR (num_prof);

ALTER TABLE VACATAIRE ADD FOREIGN KEY (num_prof) REFERENCES PROFESSEUR (num_prof);
18 changes: 18 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_1_ddl.d2
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"CONTRAT": { shape: sql_table
"num prof": VARCHAR(42) {constraint: [PK; FK]}
"date contrat": VARCHAR(42) {constraint: PK}
"salaire horaire contrat": VARCHAR(42)
}

"PROFESSEUR": { shape: sql_table
"num prof": VARCHAR(42) {constraint: PK}
"nom prof": VARCHAR(42)
"prénom prof": VARCHAR(42)
"téléphone prof": VARCHAR(42)
"statut vacataire": VARCHAR(42) {constraint: "NULL"}
"date embauche salarié": VARCHAR(42) {constraint: "NULL"}
"échelon salarié": VARCHAR(42) {constraint: "NULL"}
"salaire salarié": VARCHAR(42) {constraint: "NULL"}
}

"CONTRAT"."num prof" -> "PROFESSEUR"."num prof"
21 changes: 21 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_1_ddl.dbml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Table "CONTRAT" {
"num prof" VARCHAR(42) [NOT NULL]
"date contrat" VARCHAR(42) [NOT NULL]
"salaire horaire contrat" VARCHAR(42)
Indexes {
("num prof", "date contrat") [pk]
}
}

Table "PROFESSEUR" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"nom prof" VARCHAR(42)
"prénom prof" VARCHAR(42)
"téléphone prof" VARCHAR(42)
"statut vacataire" VARCHAR(42) ["NULL"]
"date embauche salarié" VARCHAR(42) ["NULL"]
"échelon salarié" VARCHAR(42) ["NULL"]
"salaire salarié" VARCHAR(42) ["NULL"]
}

Ref:"CONTRAT"."num prof" > "PROFESSEUR"."num prof"
20 changes: 20 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_1_ddl.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
CREATE TABLE CONTRAT (
PRIMARY KEY (num_prof, date_contrat),
num_prof VARCHAR(8) NOT NULL,
date_contrat DATE NOT NULL,
salaire_horaire_contrat VARCHAR(42)
);

CREATE TABLE PROFESSEUR (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
nom_prof VARCHAR(255),
prenom_prof VARCHAR(255),
telephone_prof VARCHAR(20),
statut_vacataire VARCHAR(20) NULL,
date_embauche_salarie DATE NULL,
echelon_salarie VARCHAR(42) NULL,
salaire_salarie VARCHAR(42) NULL
);

ALTER TABLE CONTRAT ADD FOREIGN KEY (num_prof) REFERENCES PROFESSEUR (num_prof);
25 changes: 25 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_2_ddl.d2
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"CONTRAT": { shape: sql_table
"num prof": VARCHAR(42) {constraint: [PK; FK]}
"date contrat": VARCHAR(42) {constraint: PK}
"salaire horaire contrat": VARCHAR(42)
}

"SALARIÉ": { shape: sql_table
"num prof": VARCHAR(42) {constraint: PK}
"nom prof": VARCHAR(42)
"prénom prof": VARCHAR(42)
"téléphone prof": VARCHAR(42)
"date embauche salarié": VARCHAR(42)
"échelon salarié": VARCHAR(42)
"salaire salarié": VARCHAR(42)
}

"VACATAIRE": { shape: sql_table
"num prof": VARCHAR(42) {constraint: PK}
"nom prof": VARCHAR(42)
"prénom prof": VARCHAR(42)
"téléphone prof": VARCHAR(42)
"statut vacataire": VARCHAR(42)
}

"CONTRAT"."num prof" -> "VACATAIRE"."num prof"
28 changes: 28 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_2_ddl.dbml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Table "CONTRAT" {
"num prof" VARCHAR(42) [NOT NULL]
"date contrat" VARCHAR(42) [NOT NULL]
"salaire horaire contrat" VARCHAR(42)
Indexes {
("num prof", "date contrat") [pk]
}
}

Table "SALARIÉ" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"nom prof" VARCHAR(42)
"prénom prof" VARCHAR(42)
"téléphone prof" VARCHAR(42)
"date embauche salarié" VARCHAR(42)
"échelon salarié" VARCHAR(42)
"salaire salarié" VARCHAR(42)
}

Table "VACATAIRE" {
"num prof" VARCHAR(42) [pk, NOT NULL]
"nom prof" VARCHAR(42)
"prénom prof" VARCHAR(42)
"téléphone prof" VARCHAR(42)
"statut vacataire" VARCHAR(42)
}

Ref:"CONTRAT"."num prof" > "VACATAIRE"."num prof"
28 changes: 28 additions & 0 deletions test/zoo/inheritance_weak/ddl/strong_child_2_ddl.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
CREATE TABLE CONTRAT (
PRIMARY KEY (num_prof, date_contrat),
num_prof VARCHAR(8) NOT NULL,
date_contrat DATE NOT NULL,
salaire_horaire_contrat VARCHAR(42)
);

CREATE TABLE SALARIE (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
nom_prof VARCHAR(255),
prenom_prof VARCHAR(255),
telephone_prof VARCHAR(20),
date_embauche_salarie DATE,
echelon_salarie VARCHAR(42),
salaire_salarie VARCHAR(42)
);

CREATE TABLE VACATAIRE (
PRIMARY KEY (num_prof),
num_prof VARCHAR(8) NOT NULL,
nom_prof VARCHAR(255),
prenom_prof VARCHAR(255),
telephone_prof VARCHAR(20),
statut_vacataire VARCHAR(20)
);

ALTER TABLE CONTRAT ADD FOREIGN KEY (num_prof) REFERENCES VACATAIRE (num_prof);
71 changes: 71 additions & 0 deletions test/zoo/inheritance_weak/exported/strong_child_0_erd_chen.gv
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
graph{
start=42

// Entities
node [
shape=box
style=filled
penwidth=1.5
fillcolor="#FFFFFF"
]
3 [label="VACATAIRE"]
2 [label="CONTRAT",peripheries=2]

// Associative entities
7 [label="SALARIÉ",shape=Mdiamond]
11 [label="PROFESSEUR",shape=Mdiamond]

// Normal entity attributes
node [
shape=oval
penwidth=1.5
fillcolor="#FFFFFF"
]
6 [label="salaire\nhoraire\ncontrat"]
9 [label="échelon\nsalarié"]
10 [label="salaire\nsalarié"]
13 [label="nom prof"]
14 [label="prénom\nprof"]
15 [label="téléphone\nprof"]

// Weak and strong entity attributes
4 [label=<<u>statut<br/>vacataire</u>>]
5 [label=<<u>date<br/>contrat</u>> style="dashed,filled"]
8 [label=<<u>date<br/>embauche<br/>salarié</u>>]
12 [label=<<u>num prof</u>>]

// Relationships
node [
shape=diamond
height=0.7
penwidth=1.5
fillcolor="#FFFFFF"
]
1 [label="DF",peripheries=2]

// Edges between entities and attributes
edge [
penwidth=1.5
]
2 -- 5
2 -- 6
3 -- 4
7 -- 8
7 -- 9
7 -- 10
11 -- 12
11 -- 13
11 -- 14
11 -- 15

// Edges between entities and relationships
edge [
penwidth=1
color="#000000:#000000"
labeldistance=2
headlabel=1
]
3 -- 1
edge [headlabel=N]
2 -- 1
}
Loading

0 comments on commit c1a9c6c

Please sign in to comment.