mirror of
https://github.com/drawdb-io/drawdb.git
synced 2025-09-01 10:25:13 +00:00
128 lines
3.8 KiB
JavaScript
128 lines
3.8 KiB
JavaScript
import { Parser } from "@dbml/core";
|
|
import { arrangeTables } from "../arrangeTables";
|
|
import { Cardinality, Constraint } from "../../data/constants";
|
|
import { nanoid } from "nanoid";
|
|
|
|
const parser = new Parser();
|
|
|
|
export function fromDBML(src) {
|
|
const ast = parser.parse(src, "dbmlv2");
|
|
|
|
const tables = [];
|
|
const enums = [];
|
|
const relationships = [];
|
|
|
|
for (const schema of ast.schemas) {
|
|
for (const table of schema.tables) {
|
|
let parsedTable = {};
|
|
parsedTable.id = nanoid();
|
|
parsedTable.name = table.name;
|
|
parsedTable.comment = table.note ?? "";
|
|
parsedTable.color = "#175e7a";
|
|
parsedTable.fields = [];
|
|
parsedTable.indices = [];
|
|
|
|
for (const column of table.fields) {
|
|
const field = {};
|
|
|
|
field.id = nanoid();
|
|
field.name = column.name;
|
|
field.type = column.type.type_name.toUpperCase();
|
|
field.default = column.dbdefault?.value ?? "";
|
|
field.check = "";
|
|
field.primary = !!column.pk;
|
|
field.unique = !!column.pk;
|
|
field.notNull = !!column.not_null;
|
|
field.increment = !!column.increment;
|
|
field.comment = column.note ?? "";
|
|
|
|
parsedTable.fields.push(field);
|
|
}
|
|
|
|
for (const idx of table.indexes) {
|
|
const parsedIndex = {};
|
|
|
|
parsedIndex.id = idx.id - 1;
|
|
parsedIndex.fields = idx.columns.map((x) => x.value);
|
|
parsedIndex.name =
|
|
idx.name ?? `${parsedTable.name}_index_${parsedIndex.id}`;
|
|
parsedIndex.unique = !!idx.unique;
|
|
|
|
parsedTable.indices.push(parsedIndex);
|
|
}
|
|
|
|
tables.push(parsedTable);
|
|
}
|
|
|
|
for (const ref of schema.refs) {
|
|
const startTableName = ref.endpoints[0].tableName;
|
|
const endTableName = ref.endpoints[1].tableName;
|
|
const startFieldName = ref.endpoints[0].fieldNames[0];
|
|
const endFieldName = ref.endpoints[1].fieldNames[0];
|
|
|
|
const startTable = tables.find((t) => t.name === startTableName);
|
|
if (!startTable) continue;
|
|
|
|
const endTable = tables.find((t) => t.name === endTableName);
|
|
if (!endTable) continue;
|
|
|
|
const endField = endTable.fields.find((f) => f.name === endFieldName);
|
|
if (!endField) continue;
|
|
|
|
const startField = startTable.fields.find(
|
|
(f) => f.name === startFieldName,
|
|
);
|
|
if (!startField) continue;
|
|
|
|
const relationship = {};
|
|
|
|
relationship.name =
|
|
"fk_" + startTableName + "_" + startFieldName + "_" + endTableName;
|
|
relationship.startTableId = startTable.id;
|
|
relationship.endTableId = endTable.id;
|
|
relationship.endFieldId = endField.id;
|
|
relationship.startFieldId = startField.id;
|
|
relationship.id = relationships.length;
|
|
|
|
relationship.updateConstraint = ref.onDelete
|
|
? ref.onDelete[0].toUpperCase() + ref.onDelete.substring(1)
|
|
: Constraint.NONE;
|
|
relationship.deleteConstraint = ref.onUpdate
|
|
? ref.onUpdate[0].toUpperCase() + ref.onUpdate.substring(1)
|
|
: Constraint.NONE;
|
|
|
|
const startRelation = ref.endpoints[0].relation;
|
|
const endRelation = ref.endpoints[1].relation;
|
|
|
|
if (startRelation === "*" && endRelation === "1") {
|
|
relationship.cardinality = Cardinality.MANY_TO_ONE;
|
|
}
|
|
|
|
if (startRelation === "1" && endRelation === "*") {
|
|
relationship.cardinality = Cardinality.ONE_TO_MANY;
|
|
}
|
|
|
|
if (startRelation === "1" && endRelation === "1") {
|
|
relationship.cardinality = Cardinality.ONE_TO_ONE;
|
|
}
|
|
|
|
relationships.push(relationship);
|
|
}
|
|
|
|
for (const schemaEnum of schema.enums) {
|
|
const parsedEnum = {};
|
|
|
|
parsedEnum.name = schemaEnum.name;
|
|
parsedEnum.values = schemaEnum.values.map((x) => x.name);
|
|
|
|
enums.push(parsedEnum);
|
|
}
|
|
}
|
|
|
|
const diagram = { tables, enums, relationships };
|
|
|
|
arrangeTables(diagram);
|
|
|
|
return diagram;
|
|
}
|