Handle simple sql table parsing

This commit is contained in:
1ilit 2024-01-21 09:05:43 +02:00
parent 6c65134c93
commit b0d262e2a0

View File

@ -29,6 +29,8 @@ import {
Toast, Toast,
SideSheet, SideSheet,
List, List,
Select,
Checkbox,
} from "@douyinfe/semi-ui"; } from "@douyinfe/semi-ui";
import timeLine from "../assets/process.png"; import timeLine from "../assets/process.png";
import timeLineDark from "../assets/process_dark.png"; import timeLineDark from "../assets/process_dark.png";
@ -830,7 +832,10 @@ export default function ControlPanel({
shortcut: "Ctrl+I", shortcut: "Ctrl+I",
}, },
"Import from source": { "Import from source": {
function: () => setVisible(MODAL.IMPORT_SRC) function: () => {
setData({ src: "", overwrite: true, dbms: "MySQL" });
setVisible(MODAL.IMPORT_SRC)
}
}, },
"Export as": { "Export as": {
children: [ children: [
@ -1217,6 +1222,165 @@ export default function ControlPanel({
} }
}; };
/**
*
* {
"id": 0,
"name": "table_4",
"x": 50,
"y": 83,
"fields": [
{
"name": "id",
"type": "INT",
"default": "",
"check": "",
"primary": true,
"unique": true,
"notNull": true,
"increment": true,
"comment": "",
"id": 0
},
{
"name": "name",
"type": "NUMERIC",
"default": "",
"check": "",
"primary": false,
"unique": false,
"notNull": false,
"increment": false,
"comment": "",
"id": 1,
"size": ""
}
],
"comment": "",
"indices": [],
"color": "#175e7a"
},
{
"id": 1,
"name": "table_1",
"x": 360,
"y": 181,
"fields": [
{
"name": "id",
"type": "INT",
"default": "",
"check": "",
"primary": true,
"unique": true,
"notNull": true,
"increment": true,
"comment": "",
"id": 0
},
{
"name": "kk",
"type": "INT",
"default": "",
"check": "",
"primary": false,
"unique": false,
"notNull": false,
"increment": false,
"comment": "",
"id": 1
},
{
"id": 2,
"size": "12"
}
],
"comment": "",
"indices": [],
"color": "#175e7a"
}
*/
const parseSQLAndLoadDiagram = () => {
const parser = new Parser();
let ast = null;
try {
console.log(data.dbms)
ast = parser.astify(data.src, { database: data.dbms });
} catch (err) {
Toast.error("Could not parse the sql file. Make sure there are no syntax errors.");
console.log(err);
return;
}
const tables = [];
ast.forEach(((e) => {
console.log(JSON.stringify(e))
if (e.type === "create" && e.keyword === "table") {
const table = {};
table.name = e.table[0].table;
table.color = "#175e7a";
table.fields = [];
table.indices = [];
table.x = 0;
table.y = 0;
e.create_definitions.forEach((d) => {
if (d.resource === "column") {
const field = {};
field.name = d.column.column;
field.type = d.definition.dataType;
field.comment = "";
field.unique = false;
if (d.unique) field.unique = true;
field.auto_increment = false;
if (d.auto_increment) field.auto_increment = true;
field.notNull = false;
if (d.nullable) field.notNull = true;
field.primary = false;
if (d.primary_key) field.primary = true;
field.default = "";
if (d.default_val) field.default = d.default_val.value.value;
if (d.definition["length"]) field.size = d.definition["length"];
if (d.check) {
let check = "";
if (d.check.definition[0].left.column) {
check = d.check.definition[0].left.column + " " + d.check.definition[0].operator + " " + d.check.definition[0].right.value;
} else {
check = d.check.definition[0].left.value + " " + d.check.definition[0].operator + " " + d.check.definition[0].right.column;
}
field.check = check;
}
table.fields.push(field);
} else if (d.resource === "constraint") {
if (d.constraint_type === "primary key") {
d.definition.forEach(c => {
table.fields.forEach((f) => {
if (f.name === c.column && !f.primary) {
f.primary = true;
}
})
});
}
}
});
tables.push(table);
}
}))
tables.forEach((e, i) => {
e.id = i;
e.fields.forEach((f, j) => {
f.id = j;
})
})
setTables(tables)
console.log(tables);
}
const getModalOnOk = async () => { const getModalOnOk = async () => {
switch (visible) { switch (visible) {
case MODAL.IMG: case MODAL.IMG:
@ -1243,6 +1407,7 @@ export default function ControlPanel({
} }
return; return;
case MODAL.IMPORT_SRC: case MODAL.IMPORT_SRC:
parseSQLAndLoadDiagram();
setVisible(MODAL.NONE) setVisible(MODAL.NONE)
return; return;
case MODAL.OPEN: case MODAL.OPEN:
@ -1395,10 +1560,7 @@ export default function ControlPanel({
} }
const reader = new FileReader(); const reader = new FileReader();
reader.onload = async (e) => { reader.onload = async (e) => {
console.log(e.target.result); setData(prev => ({ ...prev, src: e.target.result }))
const parser = new Parser();
const ast = parser.astify(e.target.result);
console.log(ast);
}; };
reader.readAsText(f); reader.readAsText(f);
@ -1413,11 +1575,13 @@ export default function ControlPanel({
dragMainText="Drag and drop the file here or click to upload." dragMainText="Drag and drop the file here or click to upload."
dragSubText="Upload an sql file to autogenerate your tables and columns." dragSubText="Upload an sql file to autogenerate your tables and columns."
accept=".sql" accept=".sql"
onRemove={() => onRemove={() => {
setError({ setError({
type: STATUS.NONE, type: STATUS.NONE,
message: "", message: "",
}) });
setData(prev => ({ ...prev, src: "" }));
}
} }
onFileChange={() => onFileChange={() =>
setError({ setError({
@ -1427,28 +1591,23 @@ export default function ControlPanel({
} }
limit={1} limit={1}
></Upload> ></Upload>
<div className="my-2">
{error.type === STATUS.ERROR ? ( <div className="text-sm font-semibold mb-1">Select DBMS</div>
<Banner <Select defaultValue="MySQL"
type="danger" optionList={[
fullMode={false} { value: 'MySQL', label: 'MySQL' },
description={<div className="text-red-800">{error.message}</div>} { value: 'Postgresql', label: 'PostgreSQL' },
/> ]}
) : error.type === STATUS.OK ? ( onChange={(e) => setData(prev => ({ ...prev, dbms: e }))}
<Banner className="w-full"></Select>
type="info" <Checkbox aria-label="overwrite checkbox"
fullMode={false} checked={data.overwrite}
description={<div>{error.message}</div>} defaultChecked
/> onChange={e => setData(prev => ({ ...prev, overwrite: e.target.checked }))}
) : ( className="my-2">
error.type === STATUS.WARNING && ( Overwrite existing diagram
<Banner </Checkbox>
type="warning" </div>
fullMode={false}
description={<div>{error.message}</div>}
/>
)
)}
</> </>
); );
}; };
@ -1642,13 +1801,14 @@ export default function ControlPanel({
closeOnEsc={true} closeOnEsc={true}
okText={getOkText()} okText={getOkText()}
okButtonProps={{ okButtonProps={{
disabled: disabled: (error && error.type && error.type === STATUS.ERROR) ||
(visible === MODAL.IMPORT && (visible === MODAL.IMPORT &&
(error.type === STATUS.ERROR || !data)) || (error.type === STATUS.ERROR || !data)) ||
((visible === MODAL.IMG || visible === MODAL.CODE) && ((visible === MODAL.IMG || visible === MODAL.CODE) &&
!exportData.data) || !exportData.data) ||
(visible === MODAL.RENAME && title === "") || (visible === MODAL.RENAME && title === "") ||
(visible === MODAL.SAVEAS && saveAsTitle === ""), (visible === MODAL.SAVEAS && saveAsTitle === "") ||
(visible === MODAL.IMPORT_SRC && data.src === ""),
}} }}
cancelText="Cancel" cancelText="Cancel"
width={600} width={600}