diff --git a/package-lock.json b/package-lock.json
index f3536c74..6aa2215a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,6 +32,7 @@
"lexical": "^0.12.5",
"node-sql-parser": "^5.3.6",
"octokit": "^4.0.2",
+ "oracle-sql-parser": "^0.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.4.1",
@@ -5097,6 +5098,12 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/oracle-sql-parser": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/oracle-sql-parser/-/oracle-sql-parser-0.1.0.tgz",
+ "integrity": "sha512-8MLYOJIKaOY1cWvnMFuYPxWcDH5GfmJMh/f1Tyow0bydC31heO+eSoexZW+NJBSdK87lNJl8nsQ/SY//ZGOwcQ==",
+ "license": "MIT"
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
diff --git a/package.json b/package.json
index 9303e029..00a0c286 100644
--- a/package.json
+++ b/package.json
@@ -34,6 +34,7 @@
"lexical": "^0.12.5",
"node-sql-parser": "^5.3.6",
"octokit": "^4.0.2",
+ "oracle-sql-parser": "^0.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.4.1",
diff --git a/src/assets/oraclesql-icon.png b/src/assets/oraclesql-icon.png
new file mode 100644
index 00000000..cdeb3a31
Binary files /dev/null and b/src/assets/oraclesql-icon.png differ
diff --git a/src/assets/oraclesql.png b/src/assets/oraclesql.png
new file mode 100644
index 00000000..cb7686e4
Binary files /dev/null and b/src/assets/oraclesql.png differ
diff --git a/src/components/EditorHeader/ControlPanel.jsx b/src/components/EditorHeader/ControlPanel.jsx
index 40afb068..b62dd970 100644
--- a/src/components/EditorHeader/ControlPanel.jsx
+++ b/src/components/EditorHeader/ControlPanel.jsx
@@ -30,6 +30,7 @@ import {
jsonToSQLite,
jsonToMariaDB,
jsonToSQLServer,
+ jsonToOracleSQL,
} from "../../utils/exportSQL/generic";
import {
ObjectType,
@@ -836,6 +837,12 @@ export default function ControlPanel({
setImportDb(DB.MSSQL);
},
},
+ {
+ Oracle: () => {
+ setModal(MODAL.IMPORT_SRC);
+ setImportDb(DB.ORACLESQL);
+ },
+ },
],
}),
function: () => {
@@ -927,6 +934,22 @@ export default function ControlPanel({
}));
},
},
+ {
+ OracleSQL: () => {
+ setModal(MODAL.CODE);
+ const src = jsonToOracleSQL({
+ tables: tables,
+ references: relationships,
+ types: types,
+ database: database,
+ });
+ setExportData((prev) => ({
+ ...prev,
+ data: src,
+ extension: "sql",
+ }));
+ },
+ },
],
}),
function: () => {
diff --git a/src/components/EditorHeader/Modal/Modal.jsx b/src/components/EditorHeader/Modal/Modal.jsx
index 270172e6..34cb7127 100644
--- a/src/components/EditorHeader/Modal/Modal.jsx
+++ b/src/components/EditorHeader/Modal/Modal.jsx
@@ -20,6 +20,7 @@ import {
} from "../../../hooks";
import { saveAs } from "file-saver";
import { Parser } from "node-sql-parser";
+import { Parser as OracleParser } from "oracle-sql-parser";
import {
getModalTitle,
getModalWidth,
@@ -131,12 +132,21 @@ export default function Modal({
};
const parseSQLAndLoadDiagram = () => {
- const parser = new Parser();
+ const targetDatabase = database === DB.GENERIC ? importDb : database;
+
let ast = null;
try {
- ast = parser.astify(importSource.src, {
- database: database === DB.GENERIC ? importDb : database,
- });
+ if (targetDatabase === DB.ORACLESQL) {
+ const oracleParser = new OracleParser();
+
+ ast = oracleParser.parse(importSource.src);
+ } else {
+ const parser = new Parser();
+
+ ast = parser.astify(importSource.src, {
+ database: targetDatabase,
+ });
+ }
} catch (error) {
const message = error.location
? `${error.name} [Ln ${error.location.start.line}, Col ${error.location.start.column}]: ${error.message}`
diff --git a/src/data/constants.js b/src/data/constants.js
index 0dbe0f84..f734eb2f 100644
--- a/src/data/constants.js
+++ b/src/data/constants.js
@@ -113,6 +113,7 @@ export const DB = {
MSSQL: "transactsql",
SQLITE: "sqlite",
MARIADB: "mariadb",
+ ORACLESQL: "oraclesql",
GENERIC: "generic",
};
diff --git a/src/data/databases.js b/src/data/databases.js
index 58ffe764..7169b311 100644
--- a/src/data/databases.js
+++ b/src/data/databases.js
@@ -3,6 +3,7 @@ import postgresImage from "../assets/postgres-icon.png";
import sqliteImage from "../assets/sqlite-icon.png";
import mariadbImage from "../assets/mariadb-icon.png";
import mssqlImage from "../assets/mssql-icon.png";
+import oraclesqlImage from "../assets/oraclesql-icon.png";
import i18n from "../i18n/i18n";
import { DB } from "./constants";
@@ -42,6 +43,14 @@ export const databases = new Proxy(
image: mssqlImage,
hasTypes: false,
},
+ [DB.ORACLESQL]: {
+ name: "Oracle SQL",
+ label: DB.ORACLESQL,
+ image: oraclesqlImage,
+ hasTypes: false,
+ hasEnums: false,
+ hasArrays: false,
+ },
[DB.GENERIC]: {
name: i18n.t("generic"),
label: DB.GENERIC,
diff --git a/src/data/datatypes.js b/src/data/datatypes.js
index 9fda287a..1a6d6b10 100644
--- a/src/data/datatypes.js
+++ b/src/data/datatypes.js
@@ -55,6 +55,16 @@ const defaultTypesBase = {
isSized: false,
hasPrecision: true,
},
+ NUMBER: {
+ type: "NUMBER",
+ checkDefault: (field) => {
+ return /^-?\d+(\.\d+)?$/.test(field.default);
+ },
+ hasCheck: true,
+ isSized: false,
+ hasPrecision: true,
+ canIncrement: false,
+ },
FLOAT: {
type: "FLOAT",
checkDefault: (field) => {
@@ -110,6 +120,20 @@ const defaultTypesBase = {
defaultSize: 255,
hasQuotes: true,
},
+ VARCHAR2: {
+ type: "VARCHAR2",
+ checkDefault: (field) => {
+ if (strHasQuotes(field.default)) {
+ return field.default.length - 2 <= field.size;
+ }
+ return field.default.length <= field.size;
+ },
+ hasCheck: true,
+ isSized: true,
+ hasPrecision: false,
+ defaultSize: 225,
+ hasQuotes: true,
+ },
TEXT: {
type: "TEXT",
checkDefault: (field) => true,
@@ -223,6 +247,22 @@ const defaultTypesBase = {
hasPrecision: false,
noDefault: true,
},
+ CLOB: {
+ type: "CLOB",
+ checkDefault: (field) => true,
+ isSized: false,
+ hasCheck: false,
+ hasPrecision: false,
+ noDefault: true,
+ },
+ NCLOB: {
+ type: "NCLOB",
+ checkDefault: (field) => true,
+ isSized: false,
+ hasCheck: false,
+ hasPrecision: false,
+ noDefault: true,
+ },
JSON: {
type: "JSON",
checkDefault: (field) => true,
@@ -1747,6 +1787,155 @@ export const mssqlTypes = new Proxy(mssqlTypesBase, {
get: (target, prop) => (prop in target ? target[prop] : false),
});
+const oraclesqlTypesBase = {
+ NUMBER: {
+ type: "NUMBER",
+ checkDefault: (field) => {
+ return /^-?\d+(\.\d+)?$/.test(field.default);
+ },
+ hasCheck: true,
+ isSized: false,
+ hasPrecision: true,
+ canIncrement: false,
+ },
+ VARCHAR2: {
+ type: "VARCHAR2",
+ checkDefault: (field) => {
+ if (strHasQuotes(field.default)) {
+ return field.default.length - 2 <= field.size;
+ }
+ return field.default.length <= field.size;
+ },
+ hasCheck: true,
+ isSized: true,
+ hasPrecision: false,
+ defaultSize: 4000,
+ hasQuotes: true,
+ },
+ CHAR: {
+ type: "CHAR",
+ checkDefault: (field) => {
+ if (strHasQuotes(field.default)) {
+ return field.default.length - 2 <= field.size;
+ }
+ return field.default.length <= field.size;
+ },
+ hasCheck: true,
+ isSized: true,
+ hasPrecision: false,
+ defaultSize: 1,
+ hasQuotes: true,
+ },
+ CLOB: {
+ type: "CLOB",
+ checkDefault: (field) => true,
+ isSized: false,
+ hasCheck: false,
+ hasPrecision: false,
+ noDefault: true,
+ },
+ NCLOB: {
+ type: "NCLOB",
+ checkDefault: (field) => true,
+ isSized: false,
+ hasCheck: false,
+ hasPrecision: false,
+ noDefault: true,
+ },
+ BLOB: {
+ type: "BLOB",
+ checkDefault: (field) => true,
+ isSized: false,
+ hasCheck: false,
+ hasPrecision: false,
+ noDefault: true,
+ },
+ DATE: {
+ type: "DATE",
+ checkDefault: (field) => {
+ return /^\d{4}-\d{2}-\d{2}$/.test(field.default);
+ },
+ hasCheck: false,
+ isSized: false,
+ hasPrecision: false,
+ hasQuotes: true,
+ },
+ TIMESTAMP: {
+ type: "TIMESTAMP",
+ checkDefault: (field) => {
+ if (field.default.toUpperCase() === "CURRENT_TIMESTAMP") {
+ return true;
+ }
+ return /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?$/.test(
+ field.default,
+ );
+ },
+ hasCheck: false,
+ isSized: false,
+ hasPrecision: true,
+ hasQuotes: true,
+ },
+ INTERVAL: {
+ type: "INTERVAL",
+ checkDefault: (field) => {
+ return /^INTERVAL\s'\d+'(\s+DAY|HOUR|MINUTE|SECOND)?$/.test(
+ field.default,
+ );
+ },
+ hasCheck: false,
+ isSized: false,
+ hasPrecision: false,
+ hasQuotes: true,
+ },
+ FLOAT: {
+ type: "FLOAT",
+ checkDefault: (field) => {
+ return /^-?\d+(\.\d+)?$/.test(field.default);
+ },
+ hasCheck: true,
+ isSized: false,
+ hasPrecision: true,
+ },
+ DOUBLE: {
+ type: "DOUBLE",
+ checkDefault: (field) => {
+ return /^-?\d+(\.\d+)?$/.test(field.default);
+ },
+ hasCheck: true,
+ isSized: false,
+ hasPrecision: true,
+ },
+ BOOLEAN: {
+ type: "BOOLEAN",
+ checkDefault: (field) => {
+ return (
+ field.default === "0" ||
+ field.default === "1" ||
+ field.default.toUpperCase() === "TRUE" ||
+ field.default.toUpperCase() === "FALSE"
+ );
+ },
+ hasCheck: false,
+ isSized: false,
+ hasPrecision: false,
+ },
+ RAW: {
+ type: "RAW",
+ checkDefault: (field) => {
+ return /^[0-9A-Fa-f]+$/.test(field.default);
+ },
+ hasCheck: false,
+ isSized: true,
+ hasPrecision: false,
+ defaultSize: 2000,
+ hasQuotes: false,
+ },
+};
+
+export const oraclesqlTypes = new Proxy(oraclesqlTypesBase, {
+ get: (target, prop) => (prop in target ? target[prop] : false),
+});
+
const dbToTypesBase = {
[DB.GENERIC]: defaultTypes,
[DB.MYSQL]: mysqlTypes,
@@ -1754,6 +1943,7 @@ const dbToTypesBase = {
[DB.SQLITE]: sqliteTypes,
[DB.MSSQL]: mssqlTypes,
[DB.MARIADB]: mysqlTypes,
+ [DB.ORACLESQL]: oraclesqlTypes,
};
export const dbToTypes = new Proxy(dbToTypesBase, {
diff --git a/src/pages/LandingPage.jsx b/src/pages/LandingPage.jsx
index 0398cb88..f3d1a82a 100644
--- a/src/pages/LandingPage.jsx
+++ b/src/pages/LandingPage.jsx
@@ -8,6 +8,7 @@ import mysql_icon from "../assets/mysql.png";
import postgres_icon from "../assets/postgres.png";
import sqlite_icon from "../assets/sqlite.png";
import mariadb_icon from "../assets/mariadb.png";
+import oraclesql_icon from "../assets/oraclesql.png";
import sql_server_icon from "../assets/sql-server.png";
import discord from "../assets/discord.png";
import github from "../assets/github.png";
@@ -150,7 +151,7 @@ export default function LandingPage() {
Design for your database
-
+
{dbs.map((s, i) => (
![]()
`'${v}'`)
+ .join(", ")}))`;
+ }
+
+ return oracleType;
}
}
@@ -375,7 +445,7 @@ export function jsonToMariaDB(obj) {
(field) =>
`\t\`${
field.name
- }\` ${getTypeString(field, obj.database)}${field.notNull ? " NOT NULL" : ""}${
+ }\` ${getTypeString(field, obj.database, "oraclesql")}${field.notNull ? " NOT NULL" : ""}${
field.increment ? " AUTO_INCREMENT" : ""
}${field.unique ? " UNIQUE" : ""}${
field.default !== ""
@@ -491,3 +561,55 @@ export function jsonToSQLServer(obj) {
)
.join("\n")}`;
}
+
+export function jsonToOracleSQL(obj) {
+ return `${obj.tables
+ .map(
+ (table) =>
+ `${
+ table.comment === "" ? "" : `/* ${table.comment} */\n`
+ }CREATE TABLE "${table.name}" (\n${table.fields
+ .map(
+ (field) =>
+ `${field.comment === "" ? "" : ` -- ${field.comment}\n`} "${
+ field.name
+ }" ${getTypeString(field, obj.database, "oraclesql")}${field.primary ? "" : field.notNull ? (table.indices.some((index) => index.fields.some((f) => f === field.name)) ? " NOT NULL" : field.unique ? " NOT NULL UNIQUE" : " UNIQUE") : ""}${
+ field.default !== ""
+ ? ` DEFAULT ${parseDefault(field, obj.database)}`
+ : ""
+ }${
+ field.check === "" ||
+ !dbToTypes[obj.database][field.type].hasCheck
+ ? ""
+ : ` CHECK (${field.check})`
+ }`,
+ )
+ .join(",\n")}${
+ table.fields.filter((f) => f.primary).length > 0
+ ? `,\n PRIMARY KEY (${table.fields
+ .filter((f) => f.primary)
+ .map((f) => `"${f.name}"`)
+ .join(", ")})`
+ : ""
+ }\n);\n${table.indices
+ .map(
+ (i) =>
+ `\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX "${i.name}"\n ON "${
+ table.name
+ }" (${i.fields.map((f) => `"${f}"`).join(", ")});`,
+ )
+ .join("\n")}`,
+ )
+ .join("\n\n")}\n${obj.references
+ .map(
+ (r) =>
+ `ALTER TABLE "${obj.tables[r.startTableId].name}"\nADD CONSTRAINT fk_${
+ r.startTableId
+ }_${r.endTableId} FOREIGN KEY ("${
+ obj.tables[r.startTableId].fields[r.startFieldId].name
+ }") REFERENCES "${obj.tables[r.endTableId].name}"("${
+ obj.tables[r.endTableId].fields[r.endFieldId].name
+ }");`,
+ )
+ .join("\n")}`;
+}
diff --git a/src/utils/exportSQL/index.js b/src/utils/exportSQL/index.js
index ad877daf..002e7745 100644
--- a/src/utils/exportSQL/index.js
+++ b/src/utils/exportSQL/index.js
@@ -2,6 +2,7 @@ import { DB } from "../../data/constants";
import { toMariaDB } from "./mariadb";
import { toMSSQL } from "./mssql";
import { toMySQL } from "./mysql";
+import { toOracleSQL } from "./oraclesql";
import { toPostgres } from "./postgres";
import { toSqlite } from "./sqlite";
@@ -17,6 +18,8 @@ export function exportSQL(diagram) {
return toMariaDB(diagram);
case DB.MSSQL:
return toMSSQL(diagram);
+ case DB.ORACLE:
+ return toOracleSQL(diagram);
default:
return "";
}
diff --git a/src/utils/exportSQL/oraclesql.js b/src/utils/exportSQL/oraclesql.js
new file mode 100644
index 00000000..308caaf3
--- /dev/null
+++ b/src/utils/exportSQL/oraclesql.js
@@ -0,0 +1,56 @@
+import { dbToTypes } from "../../data/datatypes";
+import { parseDefault } from "./shared";
+
+export function toOracleSQL(diagram) {
+ return `${diagram.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.size !== undefined && field.size !== "" ? "(" + field.size + ")" : ""}${
+ field.notNull ? " NOT NULL" : ""
+ }${
+ field.increment ? " GENERATED ALWAYS AS IDENTITY" : ""
+ }${field.unique ? " UNIQUE" : ""}${
+ field.default !== ""
+ ? ` DEFAULT ${parseDefault(field, diagram.database)}`
+ : ""
+ }${
+ field.check === "" ||
+ !dbToTypes[diagram.database][field.type].hasCheck
+ ? ""
+ : ` CHECK(${field.check})`
+ }${field.comment ? ` -- ${field.comment}` : ""}`,
+ )
+ .join(",\n")}${
+ table.fields.filter((f) => f.primary).length > 0
+ ? `,\n\tPRIMARY KEY(${table.fields
+ .filter((f) => f.primary)
+ .map((f) => `"${f.name}"`)
+ .join(", ")})`
+ : ""
+ }\n)${table.comment ? ` -- ${table.comment}` : ""};\n${`\n${table.indices
+ .map(
+ (i) =>
+ `\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX "${i.name}"\nON "${table.name}" (${i.fields
+ .map((f) => `"${f}"`)
+ .join(", ")});`,
+ )
+ .join("")}`}`,
+ )
+ .join("\n")}\n${diagram.references
+ .map(
+ (r) =>
+ `ALTER TABLE "${diagram.tables[r.startTableId].name}"\nADD CONSTRAINT "${r.name}" FOREIGN KEY ("${
+ diagram.tables[r.startTableId].fields[r.startFieldId].name
+ }") REFERENCES "${diagram.tables[r.endTableId].name}" ("${
+ diagram.tables[r.endTableId].fields[r.endFieldId].name
+ }")\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`,
+ )
+ .join("\n")}`;
+}
diff --git a/src/utils/importSQL/index.js b/src/utils/importSQL/index.js
index fb849e43..e92ea724 100644
--- a/src/utils/importSQL/index.js
+++ b/src/utils/importSQL/index.js
@@ -3,6 +3,7 @@ import { arrangeTables } from "../arrangeTables";
import { fromMariaDB } from "./mariadb";
import { fromMSSQL } from "./mssql";
import { fromMySQL } from "./mysql";
+import { fromOracleSQL } from "./oraclesql";
import { fromPostgres } from "./postgres";
import { fromSQLite } from "./sqlite";
@@ -24,6 +25,9 @@ export function importSQL(ast, toDb = DB.MYSQL, diagramDb = DB.GENERIC) {
case DB.MSSQL:
diagram = fromMSSQL(ast, diagramDb);
break;
+ case DB.ORACLESQL:
+ diagram = fromOracleSQL(ast, diagramDb);
+ break;
default:
diagram = { tables: [], relationships: [] };
break;
diff --git a/src/utils/importSQL/oraclesql.js b/src/utils/importSQL/oraclesql.js
new file mode 100644
index 00000000..dd8fa9a9
--- /dev/null
+++ b/src/utils/importSQL/oraclesql.js
@@ -0,0 +1,218 @@
+export function fromOracleSQL(ast) {
+ const tables = [];
+ const relationships = [];
+ const enums = [];
+
+ const parseSingleStatement = (e) => {
+ console.log(e);
+ if (e.operation === "create") {
+ if (e.object === "table") {
+ const table = {};
+ table.name = e.name.name;
+ table.comment = "";
+ table.color = "#175e7a";
+ table.fields = [];
+ table.indices = [];
+ table.id = tables.length;
+ e.table.relational_properties.forEach((d) => {
+ if (d.resource === "column") {
+ const field = {};
+ field.name = d.name;
+
+ let type = d.type.type.toUpperCase();
+ field.type = type;
+ field.comment = "";
+ field.unique = false;
+ field.increment = false;
+ field.notNull = false;
+ field.primary = false;
+
+ field.default = "";
+ // if (d.default_val) {
+ // let defaultValue = "";
+ // if (d.default_val.value.type === "function") {
+ // defaultValue = d.default_val.value.name.name[0].value;
+ // if (d.default_val.value.args) {
+ // defaultValue +=
+ // "(" +
+ // d.default_val.value.args.value
+ // .map((v) => {
+ // if (
+ // v.type === "single_quote_string" ||
+ // v.type === "double_quote_string"
+ // )
+ // return "'" + v.value + "'";
+ // return v.value;
+ // })
+ // .join(", ") +
+ // ")";
+ // }
+ // } else if (d.default_val.value.type === "null") {
+ // defaultValue = "NULL";
+ // } else {
+ // defaultValue = d.default_val.value.value.toString();
+ // }
+ // field.default = defaultValue;
+ // }
+ // if (d.definition["length"]) {
+ // if (d.definition.scale) {
+ // field.size = d.definition["length"] + "," + d.definition.scale;
+ // } else {
+ // field.size = d.definition["length"];
+ // }
+ // }
+ // field.check = "";
+ // if (d.check) {
+ // field.check = buildSQLFromAST(d.check.definition[0], DB.MYSQL);
+ // }
+
+ 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;
+ // }
+ // });
+ // });
+ // } else if (d.constraint_type.toLowerCase() === "foreign key") {
+ // const relationship = {};
+ // const startTableId = table.id;
+ // const startTable = e.table[0].table;
+ // const startField = d.definition[0].column;
+ // const endTable = d.reference_definition.table[0].table;
+ // const endField = d.reference_definition.definition[0].column;
+
+ // const endTableId = tables.findIndex((t) => t.name === endTable);
+ // if (endTableId === -1) return;
+
+ // const endFieldId = tables[endTableId].fields.findIndex(
+ // (f) => f.name === endField,
+ // );
+ // if (endFieldId === -1) return;
+
+ // const startFieldId = table.fields.findIndex(
+ // (f) => f.name === startField,
+ // );
+ // if (startFieldId === -1) return;
+
+ // relationship.name =
+ // "fk_" + startTable + "_" + startField + "_" + endTable;
+ // relationship.startTableId = startTableId;
+ // relationship.endTableId = endTableId;
+ // relationship.endFieldId = endFieldId;
+ // relationship.startFieldId = startFieldId;
+ // let updateConstraint = "No action";
+ // let deleteConstraint = "No action";
+ // d.reference_definition.on_action.forEach((c) => {
+ // if (c.type === "on update") {
+ // updateConstraint = c.value.value;
+ // updateConstraint =
+ // updateConstraint[0].toUpperCase() +
+ // updateConstraint.substring(1);
+ // } else if (c.type === "on delete") {
+ // deleteConstraint = c.value.value;
+ // deleteConstraint =
+ // deleteConstraint[0].toUpperCase() +
+ // deleteConstraint.substring(1);
+ // }
+ // });
+
+ // relationship.updateConstraint = updateConstraint;
+ // relationship.deleteConstraint = deleteConstraint;
+
+ // if (table.fields[startFieldId].unique) {
+ // relationship.cardinality = Cardinality.ONE_TO_ONE;
+ // } else {
+ // relationship.cardinality = Cardinality.MANY_TO_ONE;
+ // }
+
+ // relationships.push(relationship);
+ // }
+ // }
+ });
+ table.fields.forEach((f, j) => {
+ f.id = j;
+ });
+ tables.push(table);
+ }
+ }
+ // else if (e.type === "alter") {
+ // e.expr.forEach((expr) => {
+ // if (
+ // expr.action === "add" &&
+ // expr.create_definitions.constraint_type.toLowerCase() ===
+ // "foreign key"
+ // ) {
+ // const relationship = {};
+ // const startTable = e.table[0].table;
+ // const startField = expr.create_definitions.definition[0].column;
+ // const endTable =
+ // expr.create_definitions.reference_definition.table[0].table;
+ // const endField =
+ // expr.create_definitions.reference_definition.definition[0].column;
+ // let updateConstraint = "No action";
+ // let deleteConstraint = "No action";
+ // expr.create_definitions.reference_definition.on_action.forEach(
+ // (c) => {
+ // if (c.type === "on update") {
+ // updateConstraint = c.value.value;
+ // updateConstraint =
+ // updateConstraint[0].toUpperCase() +
+ // updateConstraint.substring(1);
+ // } else if (c.type === "on delete") {
+ // deleteConstraint = c.value.value;
+ // deleteConstraint =
+ // deleteConstraint[0].toUpperCase() +
+ // deleteConstraint.substring(1);
+ // }
+ // },
+ // );
+
+ // const startTableId = tables.findIndex((t) => t.name === startTable);
+ // if (startTable === -1) return;
+
+ // const endTableId = tables.findIndex((t) => t.name === endTable);
+ // if (endTableId === -1) return;
+
+ // const endFieldId = tables[endTableId].fields.findIndex(
+ // (f) => f.name === endField,
+ // );
+ // if (endFieldId === -1) return;
+
+ // const startFieldId = tables[startTableId].fields.findIndex(
+ // (f) => f.name === startField,
+ // );
+ // if (startFieldId === -1) return;
+
+ // relationship.name =
+ // "fk_" + startTable + "_" + startField + "_" + endTable;
+ // relationship.startTableId = startTableId;
+ // relationship.startFieldId = startFieldId;
+ // relationship.endTableId = endTableId;
+ // relationship.endFieldId = endFieldId;
+ // relationship.updateConstraint = updateConstraint;
+ // relationship.deleteConstraint = deleteConstraint;
+
+ // if (tables[startTableId].fields[startFieldId].unique) {
+ // relationship.cardinality = Cardinality.ONE_TO_ONE;
+ // } else {
+ // relationship.cardinality = Cardinality.MANY_TO_ONE;
+ // }
+
+ // relationships.push(relationship);
+
+ // relationships.forEach((r, i) => (r.id = i));
+ // }
+ // });
+ // }
+ };
+
+ ast.forEach((e) => parseSingleStatement(e));
+
+ relationships.forEach((r, i) => (r.id = i));
+
+ return { tables, relationships, enums };
+}