mirror of
https://github.com/drawdb-io/drawdb.git
synced 2025-05-24 10:29:11 +00:00
Merge a8e178afb0
into 7faf7c3ef5
This commit is contained in:
commit
39aa78f4d1
@ -73,6 +73,7 @@ import { jsonToMermaid } from "../../utils/exportAs/mermaid";
|
|||||||
import { isRtl } from "../../i18n/utils/rtl";
|
import { isRtl } from "../../i18n/utils/rtl";
|
||||||
import { jsonToDocumentation } from "../../utils/exportAs/documentation";
|
import { jsonToDocumentation } from "../../utils/exportAs/documentation";
|
||||||
import { IdContext } from "../Workspace";
|
import { IdContext } from "../Workspace";
|
||||||
|
import { jsonToDBML } from "../../utils/exportAs/dbml";
|
||||||
|
|
||||||
export default function ControlPanel({
|
export default function ControlPanel({
|
||||||
diagramId,
|
diagramId,
|
||||||
@ -1086,6 +1087,26 @@ export default function ControlPanel({
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
DBML: () => {
|
||||||
|
setModal(MODAL.CODE);
|
||||||
|
const result = jsonToDBML({
|
||||||
|
tables: tables,
|
||||||
|
references: relationships,
|
||||||
|
notes: notes,
|
||||||
|
subjectAreas: areas,
|
||||||
|
database: database,
|
||||||
|
title: title,
|
||||||
|
...(databases[database].hasTypes && { types: types }),
|
||||||
|
...(databases[database].hasEnums && { enums: enums }),
|
||||||
|
});
|
||||||
|
setExportData((prev) => ({
|
||||||
|
...prev,
|
||||||
|
data: result,
|
||||||
|
extension: "dbml",
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
function: () => {},
|
function: () => {},
|
||||||
},
|
},
|
||||||
|
107
src/utils/exportAs/dbml.js
Normal file
107
src/utils/exportAs/dbml.js
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
import { toPostgres } from "../exportSQL/postgres";
|
||||||
|
import { DB } from '../../data/constants';
|
||||||
|
|
||||||
|
export function jsonToDBML(obj) {
|
||||||
|
let dbml = "Not supported yet.";
|
||||||
|
|
||||||
|
switch (obj.database) {
|
||||||
|
case DB.POSTGRES:
|
||||||
|
dbml = convertPostgresToDBML(toPostgres(obj));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbml;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertPostgresToDBML(postgresSchema) {
|
||||||
|
function mapDataType(type) {
|
||||||
|
const typeMap = {
|
||||||
|
'character varying': 'varchar',
|
||||||
|
'character': 'char',
|
||||||
|
'text': 'text',
|
||||||
|
'integer': 'int',
|
||||||
|
'bigint': 'bigint',
|
||||||
|
'smallint': 'smallint',
|
||||||
|
'decimal': 'decimal',
|
||||||
|
'numeric': 'decimal',
|
||||||
|
'real': 'float',
|
||||||
|
'double precision': 'double',
|
||||||
|
'boolean': 'boolean',
|
||||||
|
'date': 'date',
|
||||||
|
'timestamp without time zone': 'datetime',
|
||||||
|
'timestamp with time zone': 'datetime',
|
||||||
|
'smallserial': 'smallserial',
|
||||||
|
'serial': 'serial',
|
||||||
|
'bigserial': 'bigserial',
|
||||||
|
};
|
||||||
|
|
||||||
|
return typeMap[type] || type; // Fallback to the original type if not mapped
|
||||||
|
}
|
||||||
|
|
||||||
|
let dbmlOutput = '';
|
||||||
|
const tableDefinitions = postgresSchema.split(/;\s*CREATE TABLE/i).filter(Boolean);
|
||||||
|
|
||||||
|
if (!tableDefinitions) {
|
||||||
|
return dbmlOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
tableDefinitions.forEach(definition => {
|
||||||
|
const tableNameMatch = definition.match(/"([^"]+)"/);
|
||||||
|
const columnsMatch = definition.match(/\(([^)]+)\)/);
|
||||||
|
|
||||||
|
if (!tableNameMatch || !columnsMatch) return;
|
||||||
|
|
||||||
|
const tableName = tableNameMatch[1];
|
||||||
|
const columns = columnsMatch[1].trim();
|
||||||
|
|
||||||
|
dbmlOutput += `Table ${tableName} {\n`;
|
||||||
|
|
||||||
|
// Split column definitions by comma, allowing for potential whitespace
|
||||||
|
const columnDefinitions = columns.split(/\s*,\s*(?![^()]*\))/);
|
||||||
|
|
||||||
|
columnDefinitions.forEach(colDef => {
|
||||||
|
// Match the column name and type, and check for additional attributes
|
||||||
|
const colMatch = colDef.match(/"([^"]+)"\s+(\w+)/);
|
||||||
|
if (!colMatch) return;
|
||||||
|
|
||||||
|
const colName = colMatch[1];
|
||||||
|
const colType = mapDataType(colMatch[2]);
|
||||||
|
const colDefExtras = [];
|
||||||
|
let colExtras = '';
|
||||||
|
|
||||||
|
if (/DEFAULT\s+([^)]+)/i.test(colDef)) {
|
||||||
|
const defaultValue = colDef.match(/DEFAULT\s+([^)]+)/i)[1];
|
||||||
|
colDefExtras.push(`default: '${defaultValue}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/NOT NULL/i.test(colDef)) {
|
||||||
|
colDefExtras.push('not null');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/UNIQUE/i.test(colDef)) {
|
||||||
|
colDefExtras.push('unique');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colDefExtras.length > 0) {
|
||||||
|
colExtras = ` [${colDefExtras.join(', ')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbmlOutput += ` ${colName} ${colType}${colExtras}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
dbmlOutput += `}\n\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle foreign keys
|
||||||
|
const foreignKeyMatches = postgresSchema.match(/ALTER TABLE "([^"]+)"\s+ADD FOREIGN KEY\("([^"]+)"\)\s+REFERENCES "([^"]+)"\("([^"]+)"\)/g);
|
||||||
|
if (foreignKeyMatches) {
|
||||||
|
foreignKeyMatches.forEach(fk => {
|
||||||
|
const match = fk.match(/ALTER TABLE "([^"]+)"\s+ADD FOREIGN KEY\("([^"]+)"\)\s+REFERENCES "([^"]+)"\("([^"]+)"\)/);
|
||||||
|
if (match) {
|
||||||
|
dbmlOutput += `Ref: ${match[1]}.${match[2]} > ${match[3]}.${match[4]}\n`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbmlOutput;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user