Skip to content

Commit 1499bbe

Browse files
committed
Add parser
1 parent 8d69030 commit 1499bbe

File tree

6 files changed

+250
-4
lines changed

6 files changed

+250
-4
lines changed

package-lock.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"lexical": "^0.12.5",
3535
"node-sql-parser": "^5.3.6",
3636
"octokit": "^4.0.2",
37+
"oracle-sql-parser": "^0.1.0",
3738
"react": "^18.2.0",
3839
"react-dom": "^18.2.0",
3940
"react-hotkeys-hook": "^4.4.1",

src/components/EditorHeader/ControlPanel.jsx

+6
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,12 @@ export default function ControlPanel({
837837
setImportDb(DB.MSSQL);
838838
},
839839
},
840+
{
841+
Oracle: () => {
842+
setModal(MODAL.IMPORT_SRC);
843+
setImportDb(DB.ORACLESQL);
844+
},
845+
},
840846
],
841847
}),
842848
function: () => {

src/components/EditorHeader/Modal/Modal.jsx

+14-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from "../../../hooks";
2121
import { saveAs } from "file-saver";
2222
import { Parser } from "node-sql-parser";
23+
import { Parser as OracleParser } from "oracle-sql-parser";
2324
import {
2425
getModalTitle,
2526
getModalWidth,
@@ -131,12 +132,21 @@ export default function Modal({
131132
};
132133

133134
const parseSQLAndLoadDiagram = () => {
134-
const parser = new Parser();
135+
const targetDatabase = database === DB.GENERIC ? importDb : database;
136+
135137
let ast = null;
136138
try {
137-
ast = parser.astify(importSource.src, {
138-
database: database === DB.GENERIC ? importDb : database,
139-
});
139+
if (targetDatabase === DB.ORACLESQL) {
140+
const oracleParser = new OracleParser();
141+
142+
ast = oracleParser.parse(importSource.src);
143+
} else {
144+
const parser = new Parser();
145+
146+
ast = parser.astify(importSource.src, {
147+
database: targetDatabase,
148+
});
149+
}
140150
} catch (error) {
141151
const message = error.location
142152
? `${error.name} [Ln ${error.location.start.line}, Col ${error.location.start.column}]: ${error.message}`

src/utils/importSQL/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { arrangeTables } from "../arrangeTables";
33
import { fromMariaDB } from "./mariadb";
44
import { fromMSSQL } from "./mssql";
55
import { fromMySQL } from "./mysql";
6+
import { fromOracleSQL } from "./oraclesql";
67
import { fromPostgres } from "./postgres";
78
import { fromSQLite } from "./sqlite";
89

@@ -24,6 +25,9 @@ export function importSQL(ast, toDb = DB.MYSQL, diagramDb = DB.GENERIC) {
2425
case DB.MSSQL:
2526
diagram = fromMSSQL(ast, diagramDb);
2627
break;
28+
case DB.ORACLESQL:
29+
diagram = fromOracleSQL(ast, diagramDb);
30+
break;
2731
default:
2832
diagram = { tables: [], relationships: [] };
2933
break;

src/utils/importSQL/oraclesql.js

+218
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
export function fromOracleSQL(ast) {
2+
const tables = [];
3+
const relationships = [];
4+
const enums = [];
5+
6+
const parseSingleStatement = (e) => {
7+
console.log(e);
8+
if (e.operation === "create") {
9+
if (e.object === "table") {
10+
const table = {};
11+
table.name = e.name.name;
12+
table.comment = "";
13+
table.color = "#175e7a";
14+
table.fields = [];
15+
table.indices = [];
16+
table.id = tables.length;
17+
e.table.relational_properties.forEach((d) => {
18+
if (d.resource === "column") {
19+
const field = {};
20+
field.name = d.name;
21+
22+
let type = d.type.type.toUpperCase();
23+
field.type = type;
24+
field.comment = "";
25+
field.unique = false;
26+
field.increment = false;
27+
field.notNull = false;
28+
field.primary = false;
29+
30+
field.default = "";
31+
// if (d.default_val) {
32+
// let defaultValue = "";
33+
// if (d.default_val.value.type === "function") {
34+
// defaultValue = d.default_val.value.name.name[0].value;
35+
// if (d.default_val.value.args) {
36+
// defaultValue +=
37+
// "(" +
38+
// d.default_val.value.args.value
39+
// .map((v) => {
40+
// if (
41+
// v.type === "single_quote_string" ||
42+
// v.type === "double_quote_string"
43+
// )
44+
// return "'" + v.value + "'";
45+
// return v.value;
46+
// })
47+
// .join(", ") +
48+
// ")";
49+
// }
50+
// } else if (d.default_val.value.type === "null") {
51+
// defaultValue = "NULL";
52+
// } else {
53+
// defaultValue = d.default_val.value.value.toString();
54+
// }
55+
// field.default = defaultValue;
56+
// }
57+
// if (d.definition["length"]) {
58+
// if (d.definition.scale) {
59+
// field.size = d.definition["length"] + "," + d.definition.scale;
60+
// } else {
61+
// field.size = d.definition["length"];
62+
// }
63+
// }
64+
// field.check = "";
65+
// if (d.check) {
66+
// field.check = buildSQLFromAST(d.check.definition[0], DB.MYSQL);
67+
// }
68+
69+
table.fields.push(field);
70+
}
71+
// else if (d.resource === "constraint") {
72+
// if (d.constraint_type === "primary key") {
73+
// d.definition.forEach((c) => {
74+
// table.fields.forEach((f) => {
75+
// if (f.name === c.column && !f.primary) {
76+
// f.primary = true;
77+
// }
78+
// });
79+
// });
80+
// } else if (d.constraint_type.toLowerCase() === "foreign key") {
81+
// const relationship = {};
82+
// const startTableId = table.id;
83+
// const startTable = e.table[0].table;
84+
// const startField = d.definition[0].column;
85+
// const endTable = d.reference_definition.table[0].table;
86+
// const endField = d.reference_definition.definition[0].column;
87+
88+
// const endTableId = tables.findIndex((t) => t.name === endTable);
89+
// if (endTableId === -1) return;
90+
91+
// const endFieldId = tables[endTableId].fields.findIndex(
92+
// (f) => f.name === endField,
93+
// );
94+
// if (endFieldId === -1) return;
95+
96+
// const startFieldId = table.fields.findIndex(
97+
// (f) => f.name === startField,
98+
// );
99+
// if (startFieldId === -1) return;
100+
101+
// relationship.name =
102+
// "fk_" + startTable + "_" + startField + "_" + endTable;
103+
// relationship.startTableId = startTableId;
104+
// relationship.endTableId = endTableId;
105+
// relationship.endFieldId = endFieldId;
106+
// relationship.startFieldId = startFieldId;
107+
// let updateConstraint = "No action";
108+
// let deleteConstraint = "No action";
109+
// d.reference_definition.on_action.forEach((c) => {
110+
// if (c.type === "on update") {
111+
// updateConstraint = c.value.value;
112+
// updateConstraint =
113+
// updateConstraint[0].toUpperCase() +
114+
// updateConstraint.substring(1);
115+
// } else if (c.type === "on delete") {
116+
// deleteConstraint = c.value.value;
117+
// deleteConstraint =
118+
// deleteConstraint[0].toUpperCase() +
119+
// deleteConstraint.substring(1);
120+
// }
121+
// });
122+
123+
// relationship.updateConstraint = updateConstraint;
124+
// relationship.deleteConstraint = deleteConstraint;
125+
126+
// if (table.fields[startFieldId].unique) {
127+
// relationship.cardinality = Cardinality.ONE_TO_ONE;
128+
// } else {
129+
// relationship.cardinality = Cardinality.MANY_TO_ONE;
130+
// }
131+
132+
// relationships.push(relationship);
133+
// }
134+
// }
135+
});
136+
table.fields.forEach((f, j) => {
137+
f.id = j;
138+
});
139+
tables.push(table);
140+
}
141+
}
142+
// else if (e.type === "alter") {
143+
// e.expr.forEach((expr) => {
144+
// if (
145+
// expr.action === "add" &&
146+
// expr.create_definitions.constraint_type.toLowerCase() ===
147+
// "foreign key"
148+
// ) {
149+
// const relationship = {};
150+
// const startTable = e.table[0].table;
151+
// const startField = expr.create_definitions.definition[0].column;
152+
// const endTable =
153+
// expr.create_definitions.reference_definition.table[0].table;
154+
// const endField =
155+
// expr.create_definitions.reference_definition.definition[0].column;
156+
// let updateConstraint = "No action";
157+
// let deleteConstraint = "No action";
158+
// expr.create_definitions.reference_definition.on_action.forEach(
159+
// (c) => {
160+
// if (c.type === "on update") {
161+
// updateConstraint = c.value.value;
162+
// updateConstraint =
163+
// updateConstraint[0].toUpperCase() +
164+
// updateConstraint.substring(1);
165+
// } else if (c.type === "on delete") {
166+
// deleteConstraint = c.value.value;
167+
// deleteConstraint =
168+
// deleteConstraint[0].toUpperCase() +
169+
// deleteConstraint.substring(1);
170+
// }
171+
// },
172+
// );
173+
174+
// const startTableId = tables.findIndex((t) => t.name === startTable);
175+
// if (startTable === -1) return;
176+
177+
// const endTableId = tables.findIndex((t) => t.name === endTable);
178+
// if (endTableId === -1) return;
179+
180+
// const endFieldId = tables[endTableId].fields.findIndex(
181+
// (f) => f.name === endField,
182+
// );
183+
// if (endFieldId === -1) return;
184+
185+
// const startFieldId = tables[startTableId].fields.findIndex(
186+
// (f) => f.name === startField,
187+
// );
188+
// if (startFieldId === -1) return;
189+
190+
// relationship.name =
191+
// "fk_" + startTable + "_" + startField + "_" + endTable;
192+
// relationship.startTableId = startTableId;
193+
// relationship.startFieldId = startFieldId;
194+
// relationship.endTableId = endTableId;
195+
// relationship.endFieldId = endFieldId;
196+
// relationship.updateConstraint = updateConstraint;
197+
// relationship.deleteConstraint = deleteConstraint;
198+
199+
// if (tables[startTableId].fields[startFieldId].unique) {
200+
// relationship.cardinality = Cardinality.ONE_TO_ONE;
201+
// } else {
202+
// relationship.cardinality = Cardinality.MANY_TO_ONE;
203+
// }
204+
205+
// relationships.push(relationship);
206+
207+
// relationships.forEach((r, i) => (r.id = i));
208+
// }
209+
// });
210+
// }
211+
};
212+
213+
ast.forEach((e) => parseSingleStatement(e));
214+
215+
relationships.forEach((r, i) => (r.id = i));
216+
217+
return { tables, relationships, enums };
218+
}

0 commit comments

Comments
 (0)