Handle simple sql table parsing
This commit is contained in:
parent
6c65134c93
commit
b0d262e2a0
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user