mirror of
https://github.com/chartdb/chartdb.git
synced 2025-11-02 13:03:17 +00:00
fix: handle bidirectional relationships in DBML export (#924)
This commit is contained in:
129
src/lib/dbml/dbml-export/__tests__/cases/5.inline.dbml
Normal file
129
src/lib/dbml/dbml-export/__tests__/cases/5.inline.dbml
Normal file
@@ -0,0 +1,129 @@
|
||||
Enum "cbhpm_entradas_tipo" {
|
||||
"grupo"
|
||||
"subgrupo"
|
||||
"procedimento"
|
||||
}
|
||||
|
||||
Enum "cid_entradas_tipo" {
|
||||
"capitulo"
|
||||
"agrupamento"
|
||||
"categoria"
|
||||
"subcategoria"
|
||||
}
|
||||
|
||||
Enum "digital_signature_provider" {
|
||||
"soluti"
|
||||
"valid"
|
||||
}
|
||||
|
||||
Enum "impresso_posicao" {
|
||||
"start"
|
||||
"center"
|
||||
"end"
|
||||
}
|
||||
|
||||
Enum "otp_provider" {
|
||||
"clinic"
|
||||
"soluti_bird_id"
|
||||
}
|
||||
|
||||
Enum "tipo_cobranca" {
|
||||
"valor"
|
||||
"porte"
|
||||
}
|
||||
|
||||
Enum "tipo_contato_movel" {
|
||||
"celular"
|
||||
"telefone_residencial"
|
||||
"telefone_comercial"
|
||||
}
|
||||
|
||||
Enum "tipo_contrato" {
|
||||
"trial"
|
||||
"common"
|
||||
}
|
||||
|
||||
Enum "tipo_endereco" {
|
||||
"residencial"
|
||||
"comercial"
|
||||
"cobranca"
|
||||
}
|
||||
|
||||
Enum "tipo_espectro_autista" {
|
||||
"leve"
|
||||
"moderado"
|
||||
"severo"
|
||||
}
|
||||
|
||||
Enum "tipo_estado_civil" {
|
||||
"nao_infomado"
|
||||
"solteiro"
|
||||
"casado"
|
||||
"divorciado"
|
||||
"viuvo"
|
||||
}
|
||||
|
||||
Enum "tipo_etnia" {
|
||||
"nao_infomado"
|
||||
"branca"
|
||||
"preta"
|
||||
"parda"
|
||||
"amarela"
|
||||
"indigena"
|
||||
}
|
||||
|
||||
Enum "tipo_excecao" {
|
||||
"bloqueio"
|
||||
"compromisso"
|
||||
}
|
||||
|
||||
Enum "tipo_metodo_reajuste" {
|
||||
"percentual"
|
||||
"valor"
|
||||
}
|
||||
|
||||
Enum "tipo_pessoa" {
|
||||
"fisica"
|
||||
"juridica"
|
||||
}
|
||||
|
||||
Enum "tipo_procedimento" {
|
||||
"consulta"
|
||||
"exame_laboratorial"
|
||||
"exame_imagem"
|
||||
"procedimento_clinico"
|
||||
"procedimento_cirurgico"
|
||||
"terapia"
|
||||
"outros"
|
||||
}
|
||||
|
||||
Enum "tipo_relacionamento" {
|
||||
"pai"
|
||||
"mae"
|
||||
"conjuge"
|
||||
"filho_a"
|
||||
"tutor_legal"
|
||||
"contato_emergencia"
|
||||
"outro"
|
||||
}
|
||||
|
||||
Enum "tipo_sexo" {
|
||||
"nao_infomado"
|
||||
"masculino"
|
||||
"feminino"
|
||||
"intersexo"
|
||||
}
|
||||
|
||||
Enum "tipo_status_agendamento" {
|
||||
"em espera"
|
||||
"faltou"
|
||||
"ok"
|
||||
}
|
||||
|
||||
Table "public"."organizacao_cfg_impressos" {
|
||||
"id_organizacao" integer [pk, not null, ref: < "public"."organizacao"."id"]
|
||||
}
|
||||
|
||||
Table "public"."organizacao" {
|
||||
"id" integer [pk, not null]
|
||||
}
|
||||
1
src/lib/dbml/dbml-export/__tests__/cases/5.json
Normal file
1
src/lib/dbml/dbml-export/__tests__/cases/5.json
Normal file
File diff suppressed because one or more lines are too long
@@ -14,14 +14,36 @@ const testCase = (caseNumber: string) => {
|
||||
|
||||
// Generate DBML from the diagram
|
||||
const result = generateDBMLFromDiagram(diagram);
|
||||
const generatedDBML = result.standardDbml;
|
||||
|
||||
// Read the expected DBML file
|
||||
const dbmlPath = path.join(__dirname, 'cases', `${caseNumber}.dbml`);
|
||||
const expectedDBML = fs.readFileSync(dbmlPath, 'utf-8');
|
||||
// Check for both regular and inline DBML files
|
||||
const regularDbmlPath = path.join(__dirname, 'cases', `${caseNumber}.dbml`);
|
||||
const inlineDbmlPath = path.join(
|
||||
__dirname,
|
||||
'cases',
|
||||
`${caseNumber}.inline.dbml`
|
||||
);
|
||||
|
||||
// Compare the generated DBML with the expected DBML
|
||||
expect(generatedDBML).toBe(expectedDBML);
|
||||
const hasRegularDbml = fs.existsSync(regularDbmlPath);
|
||||
const hasInlineDbml = fs.existsSync(inlineDbmlPath);
|
||||
|
||||
// Test regular DBML if file exists
|
||||
if (hasRegularDbml) {
|
||||
const expectedRegularDBML = fs.readFileSync(regularDbmlPath, 'utf-8');
|
||||
expect(result.standardDbml).toBe(expectedRegularDBML);
|
||||
}
|
||||
|
||||
// Test inline DBML if file exists
|
||||
if (hasInlineDbml) {
|
||||
const expectedInlineDBML = fs.readFileSync(inlineDbmlPath, 'utf-8');
|
||||
expect(result.inlineDbml).toBe(expectedInlineDBML);
|
||||
}
|
||||
|
||||
// Ensure at least one DBML file exists
|
||||
if (!hasRegularDbml && !hasInlineDbml) {
|
||||
throw new Error(
|
||||
`No DBML file found for test case ${caseNumber}. Expected either ${caseNumber}.dbml or ${caseNumber}.inline.dbml`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
describe('DBML Export cases', () => {
|
||||
@@ -40,4 +62,8 @@ describe('DBML Export cases', () => {
|
||||
it('should handle case 4 diagram', { timeout: 30000 }, async () => {
|
||||
testCase('4');
|
||||
});
|
||||
|
||||
it('should handle case 5 diagram', { timeout: 30000 }, async () => {
|
||||
testCase('5');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -506,15 +506,30 @@ const deduplicateRelationships = (diagram: Diagram): Diagram => {
|
||||
if (!diagram.relationships) return diagram;
|
||||
|
||||
const seenRelationships = new Set<string>();
|
||||
const seenBidirectional = new Set<string>();
|
||||
const uniqueRelationships = diagram.relationships.filter((rel) => {
|
||||
// Create a unique key based on the relationship endpoints
|
||||
const relationshipKey = `${rel.sourceTableId}-${rel.sourceFieldId}->${rel.targetTableId}-${rel.targetFieldId}`;
|
||||
|
||||
// Create a normalized key that's the same for both directions
|
||||
const normalizedKey = [
|
||||
`${rel.sourceTableId}-${rel.sourceFieldId}`,
|
||||
`${rel.targetTableId}-${rel.targetFieldId}`,
|
||||
]
|
||||
.sort()
|
||||
.join('<->');
|
||||
|
||||
if (seenRelationships.has(relationshipKey)) {
|
||||
return false; // Skip duplicate
|
||||
return false; // Skip exact duplicate
|
||||
}
|
||||
|
||||
if (seenBidirectional.has(normalizedKey)) {
|
||||
// This is a bidirectional relationship, skip the second one
|
||||
return false;
|
||||
}
|
||||
|
||||
seenRelationships.add(relationshipKey);
|
||||
seenBidirectional.add(normalizedKey);
|
||||
return true; // Keep unique relationship
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user