diff --git a/package-lock.json b/package-lock.json index 1817f0b..fa64837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { + "@dbml/core": "^2.5.4", "@douyinfe/semi-ui": "^2.36.0", "@monaco-editor/react": "^4.5.1", "@testing-library/jest-dom": "^5.16.5", @@ -2392,6 +2393,16 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@dbml/core": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@dbml/core/-/core-2.5.4.tgz", + "integrity": "sha512-bfLb59z6pExD64eFUZTiRQfVW853v+vsfQd1bOKAZm4fHozGYVyQnM5WI4AahkAy+Jwm9NKr/b0wmrT/Hyft1w==", + "dependencies": { + "lodash": "^4.17.15", + "parsimmon": "^1.13.0", + "pluralize": "^8.0.0" + } + }, "node_modules/@douyinfe/semi-animation": { "version": "2.37.0", "resolved": "https://registry.npmjs.org/@douyinfe/semi-animation/-/semi-animation-2.37.0.tgz", @@ -13210,6 +13221,11 @@ "node": ">= 0.8" } }, + "node_modules/parsimmon": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", + "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==" + }, "node_modules/pascal-case": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", @@ -13424,6 +13440,14 @@ "node": ">=4" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "engines": { + "node": ">=4" + } + }, "node_modules/postcss": { "version": "8.4.24", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", diff --git a/src/components/control_panel.jsx b/src/components/control_panel.jsx index b79d93f..ec133be 100644 --- a/src/components/control_panel.jsx +++ b/src/components/control_panel.jsx @@ -35,6 +35,7 @@ import { exitFullscreen, ddbDiagramIsValid, dataURItoBlob, + jsonToSQL, } from "../utils"; import { AreaContext, @@ -53,6 +54,7 @@ import { useHotkeys } from "react-hotkeys-hook"; import { Validator } from "jsonschema"; import { areaSchema, noteSchema, tableSchema } from "../schemas"; import { Editor } from "@monaco-editor/react"; +// import { Parser } from "node-sql-parser"; export default function ControlPanel(props) { const MODAL = { @@ -69,7 +71,7 @@ export default function ControlPanel(props) { }; const [visible, setVisible] = useState(MODAL.NONE); const [exportData, setExportData] = useState({ - data: "", + data: null, filename: `diagram_${new Date().toISOString()}`, extension: "", }); @@ -726,7 +728,29 @@ export default function ControlPanel(props) { }, "Export source": { children: [ - { MySQL: () => {} }, + { + MySQL: () => { + setVisible(MODAL.CODE); + const src = jsonToSQL({ + tables: tables, + references: relationships, + }); + // try{ + // const parser = new Parser(); + // const ast = parser.astify(src); + // console.log(ast); + // const sql = parser.sqlify(ast); + // console.log(sql); + // } catch(e){ + // console.log(e) + // } + setExportData((prev) => ({ + ...prev, + data: src, + extension: "sql", + })); + }, + }, { PostgreSQL: () => {} }, { DBML: () => {} }, ], @@ -863,7 +887,10 @@ export default function ControlPanel(props) { "Tweet us": { function: () => {}, }, - "Found a bug": { + "Report a bug": { + function: () => {}, + }, + "Suggest a feature": { function: () => {}, }, }, @@ -1193,7 +1220,7 @@ export default function ControlPanel(props) { )} diff --git a/src/pages/editor.jsx b/src/pages/editor.jsx index 5c48c9d..b2d4a96 100644 --- a/src/pages/editor.jsx +++ b/src/pages/editor.jsx @@ -80,7 +80,7 @@ export default function Editor(props) { fields: [ { name: "id", - type: "UUID", + type: "INT", default: "", check: "", primary: true, diff --git a/src/utils/index.js b/src/utils/index.js index ed8b6d8..730508f 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,7 +1,7 @@ import { Validator } from "jsonschema"; import { ddbSchema, jsonSchema } from "../schemas"; -const enterFullscreen = () => { +function enterFullscreen() { const element = document.documentElement; if (element.requestFullscreen) { element.requestFullscreen(); @@ -12,9 +12,9 @@ const enterFullscreen = () => { } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } -}; +} -const exitFullscreen = () => { +function exitFullscreen() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { @@ -24,15 +24,15 @@ const exitFullscreen = () => { } else if (document.msExitFullscreen) { document.msExitFullscreen(); } -}; +} -const jsonDiagramIsValid = (obj) => { +function jsonDiagramIsValid(obj) { return new Validator().validate(obj, jsonSchema).valid; -}; +} -const ddbDiagramIsValid = (obj) => { +function ddbDiagramIsValid(obj) { return new Validator().validate(obj, ddbSchema).valid; -}; +} function dataURItoBlob(dataUrl) { const byteString = atob(dataUrl.split(",")[1]); @@ -47,10 +47,33 @@ function dataURItoBlob(dataUrl) { return new Blob([intArray], { type: mimeString }); } +function jsonToSQL(obj) { + return obj.tables + .map( + (table) => + `${ + table.comment === "" ? "" : `/* ${table.comment} */\n` + }CREATE TABLE \`${table.name}\` (\n${table.fields + .map( + (field) => + `${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t\`${ + field.name + }\` ${field.type} ${field.notNull ? "NOT NULL" : ""} ${ + field.increment ? "AUTO_INCREMENT" : "" + } ${field.unique ? "UNIQUE" : ""},` + ) + .join("\n")}\n\tPRIMARY KEY(${table.fields.map((f) => + f.primary ? `${f.name}` : "" + )})\n);` + ) + .join("\n"); +} + export { enterFullscreen, exitFullscreen, jsonDiagramIsValid, ddbDiagramIsValid, dataURItoBlob, + jsonToSQL, };