mirror of
https://github.com/drawdb-io/drawdb.git
synced 2025-05-24 02:09:17 +00:00
Import tables from dbml
This commit is contained in:
parent
5bd6f936a1
commit
d76a9e9ff8
@ -1444,7 +1444,7 @@ export default function ControlPanel({
|
||||
function toolbar() {
|
||||
return (
|
||||
<div
|
||||
className="py-1.5 px-5 flex justify-between items-center rounded-xl my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme"
|
||||
className="py-1.5 px-5 flex justify-between items-center rounded-lg my-1 sm:mx-1 xl:mx-6 select-none overflow-hidden toolbar-theme"
|
||||
style={isRtl(i18n.language) ? { direction: "rtl" } : {}}
|
||||
>
|
||||
<div className="flex justify-start items-center">
|
||||
|
@ -2,28 +2,28 @@ import { useEffect, useState } from "react";
|
||||
import CodeMirror from "@uiw/react-codemirror";
|
||||
import { vscodeDark, vscodeLight } from "@uiw/codemirror-theme-vscode";
|
||||
import { languageExtension } from "../../../data/editorExtensions";
|
||||
import { useSettings } from "../../../hooks";
|
||||
import { useDiagram, useSettings } from "../../../hooks";
|
||||
import { useDebounceValue } from "usehooks-ts";
|
||||
import { Parser } from "@dbml/core";
|
||||
import "./styles.css";
|
||||
|
||||
const parser = new Parser();
|
||||
import { fromDBML } from "../../../utils/dbml/fromDBML";
|
||||
|
||||
export default function DBMLEditor() {
|
||||
const { settings } = useSettings();
|
||||
const { setTables } = useDiagram();
|
||||
const [value, setValue] = useState("");
|
||||
const [debouncedValue] = useDebounceValue(value, 1000);
|
||||
|
||||
useEffect(() => {
|
||||
if (debouncedValue) {
|
||||
try {
|
||||
const database = parser.parse(debouncedValue, "dbml");
|
||||
console.log(database);
|
||||
const { tables } = fromDBML(debouncedValue);
|
||||
console.log(tables);
|
||||
setTables(tables);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("error: ", e);
|
||||
}
|
||||
}
|
||||
}, [debouncedValue]);
|
||||
}, [debouncedValue, setTables]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -9,3 +9,15 @@
|
||||
.ͼ1o .cm-gutters {
|
||||
background-color: var(--semi-color-bg-0);
|
||||
}
|
||||
|
||||
.ͼ1.cm-focused {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.ͼ16 {
|
||||
background-color: #1e1e1e00;
|
||||
}
|
||||
|
||||
.ͼ16 .cm-gutters {
|
||||
background-color: rgba(var(--semi-grey-1), 0.3);
|
||||
}
|
@ -92,31 +92,12 @@ export default function SidePanel({ width, resize, setResize }) {
|
||||
style={{ width: `${width}px` }}
|
||||
>
|
||||
<div className="h-full flex-1 overflow-y-auto">
|
||||
<<<<<<< HEAD
|
||||
<Tabs
|
||||
type="card"
|
||||
activeKey={selectedElement.currentTab}
|
||||
lazyRender
|
||||
keepDOM={false}
|
||||
onChange={(key) =>
|
||||
setSelectedElement((prev) => ({ ...prev, currentTab: key }))
|
||||
}
|
||||
collapsible
|
||||
tabBarStyle={{ direction: "ltr" }}
|
||||
>
|
||||
{tabList.length &&
|
||||
tabList.map((tab) => (
|
||||
<TabPane tab={tab.tab} itemKey={tab.itemKey} key={tab.itemKey}>
|
||||
<div className="p-2">{tab.component}</div>
|
||||
</TabPane>
|
||||
))}
|
||||
</Tabs>
|
||||
=======
|
||||
{layout.dbmlEditor ? (
|
||||
<Tabs
|
||||
type="card"
|
||||
activeKey={selectedElement.currentTab}
|
||||
lazyRender
|
||||
keepDOM={false}
|
||||
onChange={(key) =>
|
||||
setSelectedElement((prev) => ({ ...prev, currentTab: key }))
|
||||
}
|
||||
@ -137,7 +118,6 @@ export default function SidePanel({ width, resize, setResize }) {
|
||||
) : (
|
||||
<DBMLEditor />
|
||||
)}
|
||||
>>>>>>> feb41e8 (Add dbml editor to sidepanel)
|
||||
</div>
|
||||
{layout.issues && (
|
||||
<div className="mt-auto border-t-2 border-color shadow-inner">
|
||||
|
@ -243,11 +243,8 @@ const en = {
|
||||
failed_to_load: "Failed to load. Make sure the link is correct.",
|
||||
share_info:
|
||||
"* Sharing this link will not create a live real-time collaboration session.",
|
||||
<<<<<<< HEAD
|
||||
show_relationship_labels: "Show relationship labels",
|
||||
=======
|
||||
dbml_editor: "DBML editor",
|
||||
>>>>>>> feb41e8 (Add dbml editor to sidepanel)
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -105,7 +105,7 @@
|
||||
}
|
||||
|
||||
.toolbar-theme {
|
||||
background-color: rgba(var(--semi-grey-1), 1);
|
||||
background-color: rgba(var(--semi-grey-1), 0.7);
|
||||
}
|
||||
|
||||
.hover-1:hover {
|
||||
|
27
src/utils/arrangeTables.js
Normal file
27
src/utils/arrangeTables.js
Normal file
@ -0,0 +1,27 @@
|
||||
import {
|
||||
tableColorStripHeight,
|
||||
tableFieldHeight,
|
||||
tableHeaderHeight,
|
||||
} from "../data/constants";
|
||||
|
||||
export function arrangeTables(diagram) {
|
||||
let maxHeight = -1;
|
||||
const tableWidth = 200;
|
||||
const gapX = 54;
|
||||
const gapY = 40;
|
||||
diagram.tables.forEach((table, i) => {
|
||||
if (i < diagram.tables.length / 2) {
|
||||
table.x = i * tableWidth + (i + 1) * gapX;
|
||||
table.y = gapY;
|
||||
const height =
|
||||
table.fields.length * tableFieldHeight +
|
||||
tableHeaderHeight +
|
||||
tableColorStripHeight;
|
||||
maxHeight = Math.max(height, maxHeight);
|
||||
} else {
|
||||
const index = diagram.tables.length - i - 1;
|
||||
table.x = index * tableWidth + (index + 1) * gapX;
|
||||
table.y = maxHeight + 2 * gapY;
|
||||
}
|
||||
});
|
||||
}
|
78
src/utils/dbml/fromDBML.js
Normal file
78
src/utils/dbml/fromDBML.js
Normal file
@ -0,0 +1,78 @@
|
||||
import { Parser } from "@dbml/core";
|
||||
import { arrangeTables } from "../arrangeTables";
|
||||
|
||||
const parser = new Parser();
|
||||
|
||||
/**
|
||||
|
||||
{
|
||||
"id": 0,
|
||||
"name": "some_table",
|
||||
"x": 812.9083754222163,
|
||||
"y": 400.3451698134321,
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"type": "INT",
|
||||
"default": "",
|
||||
"check": "",
|
||||
"primary": true,
|
||||
"unique": true,
|
||||
"notNull": true,
|
||||
"increment": true,
|
||||
"comment": "",
|
||||
"id": 0
|
||||
}
|
||||
],
|
||||
"comment": "",
|
||||
"indices": [],
|
||||
"color": "#175e7a",
|
||||
"key": 1737222753837
|
||||
}
|
||||
*/
|
||||
|
||||
export function fromDBML(src) {
|
||||
const ast = parser.parse(src, "dbml");
|
||||
|
||||
const tables = [];
|
||||
|
||||
for (const schema of ast.schemas) {
|
||||
for (const table of schema.tables) {
|
||||
let parsedTable = {};
|
||||
parsedTable.id = tables.length;
|
||||
parsedTable.name = table.name;
|
||||
parsedTable.comment = "";
|
||||
parsedTable.color = "#175e7a";
|
||||
parsedTable.fields = [];
|
||||
parsedTable.indices = [];
|
||||
|
||||
for (const column of table.fields) {
|
||||
const field = {};
|
||||
field.id = parsedTable.fields.length;
|
||||
field.name = column.name;
|
||||
field.type = column.type.type_name.toUpperCase();
|
||||
field.default = column.dbdefault ?? "";
|
||||
field.check = "";
|
||||
field.primary = !!column.pk;
|
||||
field.unique = true;
|
||||
field.notNull = !!column.not_null;
|
||||
field.increment = !!column.increment;
|
||||
field.comment = column.note ?? "";
|
||||
|
||||
parsedTable.fields.push(field);
|
||||
}
|
||||
|
||||
console.log(table);
|
||||
|
||||
tables.push(parsedTable);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(ast);
|
||||
|
||||
const diagram = { tables };
|
||||
|
||||
arrangeTables(diagram);
|
||||
|
||||
return diagram;
|
||||
}
|
@ -1,9 +1,5 @@
|
||||
import {
|
||||
DB,
|
||||
tableColorStripHeight,
|
||||
tableFieldHeight,
|
||||
tableHeaderHeight,
|
||||
} from "../../data/constants";
|
||||
import { DB } from "../../data/constants";
|
||||
import { arrangeTables } from "../arrangeTables";
|
||||
import { fromMariaDB } from "./mariadb";
|
||||
import { fromMSSQL } from "./mssql";
|
||||
import { fromMySQL } from "./mysql";
|
||||
@ -33,25 +29,7 @@ export function importSQL(ast, toDb = DB.MYSQL, diagramDb = DB.GENERIC) {
|
||||
break;
|
||||
}
|
||||
|
||||
let maxHeight = -1;
|
||||
const tableWidth = 200;
|
||||
const gapX = 54;
|
||||
const gapY = 40;
|
||||
diagram.tables.forEach((table, i) => {
|
||||
if (i < diagram.tables.length / 2) {
|
||||
table.x = i * tableWidth + (i + 1) * gapX;
|
||||
table.y = gapY;
|
||||
const height =
|
||||
table.fields.length * tableFieldHeight +
|
||||
tableHeaderHeight +
|
||||
tableColorStripHeight;
|
||||
maxHeight = Math.max(height, maxHeight);
|
||||
} else {
|
||||
const index = diagram.tables.length - i - 1;
|
||||
table.x = index * tableWidth + (index + 1) * gapX;
|
||||
table.y = maxHeight + 2 * gapY;
|
||||
}
|
||||
});
|
||||
arrangeTables(diagram);
|
||||
|
||||
return diagram;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user