Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:Added support for exporting SQL as OracleDB SQL #192

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Binary file added src/assets/oraclesql-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/oraclesql.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/components/EditorHeader/ControlPanel.jsx
Original file line number Diff line number Diff line change
@@ -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: () => {
18 changes: 14 additions & 4 deletions src/components/EditorHeader/Modal/Modal.jsx
Original file line number Diff line number Diff line change
@@ -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}`
1 change: 1 addition & 0 deletions src/data/constants.js
Original file line number Diff line number Diff line change
@@ -113,6 +113,7 @@ export const DB = {
MSSQL: "transactsql",
SQLITE: "sqlite",
MARIADB: "mariadb",
ORACLESQL: "oraclesql",
GENERIC: "generic",
};

9 changes: 9 additions & 0 deletions src/data/databases.js
Original file line number Diff line number Diff line change
@@ -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,
190 changes: 190 additions & 0 deletions src/data/datatypes.js
Original file line number Diff line number Diff line change
@@ -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,13 +1787,163 @@ 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,
[DB.POSTGRES]: postgresTypes,
[DB.SQLITE]: sqliteTypes,
[DB.MSSQL]: mssqlTypes,
[DB.MARIADB]: mysqlTypes,
[DB.ORACLESQL]: oraclesqlTypes,
};

export const dbToTypes = new Proxy(dbToTypesBase, {
4 changes: 3 additions & 1 deletion src/pages/LandingPage.jsx
Original file line number Diff line number Diff line change
@@ -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() {
<div className="text-lg font-medium text-center mt-12 mb-6">
Design for your database
</div>
<div className="flex justify-center items-center gap-8 md:block">
<div className="grid grid-cols-3 place-items-center sm:grid-cols-1 sm:gap-10">
{dbs.map((s, i) => (
<img
key={"icon-" + i}
@@ -300,6 +301,7 @@ const dbs = [
{ icon: sqlite_icon, height: 64 },
{ icon: mariadb_icon, height: 64 },
{ icon: sql_server_icon, height: 64 },
{ icon: oraclesql_icon, height: 172 },
];

const features = [
Loading