Merge pull request #1 from drawdb-io/main

merge from drawdb
This commit is contained in:
mag 2024-04-25 11:34:55 +08:00 committed by GitHub
commit d05ba8de65
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 298 additions and 210 deletions

14
package-lock.json generated
View File

@ -25,7 +25,7 @@
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"lexical": "^0.12.5", "lexical": "^0.12.5",
"node-sql-parser": "^4.17.0", "node-sql-parser": "^5.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.4.1", "react-hotkeys-hook": "^4.4.1",
@ -1715,6 +1715,11 @@
"@babel/types": "^7.20.7" "@babel/types": "^7.20.7"
} }
}, },
"node_modules/@types/pegjs": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/@types/pegjs/-/pegjs-0.10.6.tgz",
"integrity": "sha512-eLYXDbZWXh2uxf+w8sXS8d6KSoXTswfps6fvCUuVAGN8eRpfe7h9eSRydxiSJvo9Bf+GzifsDOr9TMQlmJdmkw=="
},
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.11", "version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
@ -4368,10 +4373,11 @@
"dev": true "dev": true
}, },
"node_modules/node-sql-parser": { "node_modules/node-sql-parser": {
"version": "4.17.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/node-sql-parser/-/node-sql-parser-4.17.0.tgz", "resolved": "https://registry.npmjs.org/node-sql-parser/-/node-sql-parser-5.0.0.tgz",
"integrity": "sha512-3IhovpmUBpcETnoKK/KBdkz2mz53kVG5E1dnqz1QuYvtzdxYZW5xaGGEvW9u6Yyy2ivwR3eUZrn9inmEVef02w==", "integrity": "sha512-hkNU1gIT8BNe8vmcsU7uYie0gzow/6AIj5KnGRBJQSZlgEu1NNuLVS11it5gAEdpmvJHelc34BwR439Iela+zQ==",
"dependencies": { "dependencies": {
"@types/pegjs": "^0.10.0",
"big-integer": "^1.6.48" "big-integer": "^1.6.48"
}, },
"engines": { "engines": {

View File

@ -27,7 +27,7 @@
"jsonschema": "^1.4.1", "jsonschema": "^1.4.1",
"jspdf": "^2.5.1", "jspdf": "^2.5.1",
"lexical": "^0.12.5", "lexical": "^0.12.5",
"node-sql-parser": "^4.17.0", "node-sql-parser": "^5.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hotkeys-hook": "^4.4.1", "react-hotkeys-hook": "^4.4.1",

View File

@ -1,7 +1,12 @@
import { Upload, Checkbox } from "@douyinfe/semi-ui"; import { Upload, Checkbox, Banner } from "@douyinfe/semi-ui";
import { STATUS } from "../../../data/constants"; import { STATUS } from "../../../data/constants";
export default function ImportSource({ importData, setImportData, setError }) { export default function ImportSource({
importData,
setImportData,
error,
setError,
}) {
return ( return (
<div> <div>
<Upload <Upload
@ -60,6 +65,29 @@ export default function ImportSource({ importData, setImportData, setError }) {
> >
Overwrite existing diagram Overwrite existing diagram
</Checkbox> </Checkbox>
<div className="mt-2">
{error.type === STATUS.ERROR ? (
<Banner
type="danger"
fullMode={false}
description={<div>{error.message}</div>}
/>
) : error.type === STATUS.OK ? (
<Banner
type="info"
fullMode={false}
description={<div>{error.message}</div>}
/>
) : (
error.type === STATUS.WARNING && (
<Banner
type="warning"
fullMode={false}
description={<div>{error.message}</div>}
/>
)
)}
</div>
</div> </div>
</div> </div>
); );

View File

@ -114,9 +114,17 @@ export default function Modal({
try { try {
ast = parser.astify(importSource.src, { database: "MySQL" }); ast = parser.astify(importSource.src, { database: "MySQL" });
} catch (err) { } catch (err) {
Toast.error( setError({
"Could not parse the sql file. Make sure there are no syntax errors.", type: STATUS.ERROR,
); message:
err.name +
" [Ln " +
err.location.start.line +
", Col " +
err.location.start.column +
"]: " +
err.message,
});
return; return;
} }
@ -124,6 +132,7 @@ export default function Modal({
if (importSource.overwrite) { if (importSource.overwrite) {
setTables(d.tables); setTables(d.tables);
setRelationships(d.relationships); setRelationships(d.relationships);
setTransform((prev) => ({ ...prev, pan: { x: 0, y: 0 } }));
setNotes([]); setNotes([]);
setAreas([]); setAreas([]);
setTypes([]); setTypes([]);
@ -133,6 +142,7 @@ export default function Modal({
setTables((prev) => [...prev, ...d.tables]); setTables((prev) => [...prev, ...d.tables]);
setRelationships((prev) => [...prev, ...d.relationships]); setRelationships((prev) => [...prev, ...d.relationships]);
} }
setModal(MODAL.NONE);
}; };
const createNewDiagram = (id) => { const createNewDiagram = (id) => {
@ -167,7 +177,6 @@ export default function Modal({
return; return;
case MODAL.IMPORT_SRC: case MODAL.IMPORT_SRC:
parseSQLAndLoadDiagram(); parseSQLAndLoadDiagram();
setModal(MODAL.NONE);
return; return;
case MODAL.OPEN: case MODAL.OPEN:
if (selectedDiagramId === 0) return; if (selectedDiagramId === 0) return;
@ -207,6 +216,7 @@ export default function Modal({
<ImportSource <ImportSource
importData={importSource} importData={importSource}
setImportData={setImportSource} setImportData={setImportSource}
error={error}
setError={setError} setError={setError}
/> />
); );

View File

@ -80,7 +80,7 @@ export default function FieldDetails({ data, tid, index }) {
undo: editField, undo: editField,
redo: { values: data.values }, redo: { values: data.values },
message: `Edit table field values to "${JSON.stringify( message: `Edit table field values to "${JSON.stringify(
data.values data.values,
)}"`, )}"`,
}, },
]); ]);
@ -123,9 +123,11 @@ export default function FieldDetails({ data, tid, index }) {
<div className="font-semibold">Precision</div> <div className="font-semibold">Precision</div>
<Input <Input
className="my-2 w-full" className="my-2 w-full"
placeholder="Set precision: (size, d)" placeholder="Set precision: size, d"
validateStatus={ validateStatus={
/^\(\d+,\s*\d+\)$|^$/.test(data.size) ? "default" : "error" !data.size || /^\d+,\s*\d+$|^$/.test(data.size)
? "default"
: "error"
} }
value={data.size} value={data.size}
onChange={(value) => updateField(tid, index, { size: value })} onChange={(value) => updateField(tid, index, { size: value })}

View File

@ -123,7 +123,7 @@ export default function TableField({ data, tid, index }) {
<Col span={3}> <Col span={3}>
<Button <Button
type={data.notNull ? "primary" : "tertiary"} type={data.notNull ? "primary" : "tertiary"}
title="Nullable" title="Not Null"
theme={data.notNull ? "solid" : "light"} theme={data.notNull ? "solid" : "light"}
onClick={() => { onClick={() => {
setUndoStack((prev) => [ setUndoStack((prev) => [

View File

@ -1,9 +1,49 @@
import { Cardinality } from "../data/constants"; import {
Cardinality,
tableColorStripHeight,
tableFieldHeight,
tableHeaderHeight,
} from "../data/constants";
function buildSQLFromAST(ast) {
if (ast.type === "binary_expr") {
const leftSQL = buildSQLFromAST(ast.left);
const rightSQL = buildSQLFromAST(ast.right);
return `${leftSQL} ${ast.operator} ${rightSQL}`;
}
if (ast.type === "function") {
let expr = "";
expr = ast.name;
if (ast.args) {
expr +=
"(" +
ast.args.value
.map((v) => {
if (v.type === "column_ref") return "`" + v.column + "`";
if (
v.type === "single_quote_string" ||
v.type === "double_quote_string"
)
return "'" + v.value + "'";
return v.value;
})
.join(", ") +
")";
}
return expr;
} else if (ast.type === "column_ref") {
return "`" + ast.column + "`";
} else if (ast.type === "expr_list") {
return ast.value.map((v) => v.value).join(" AND ");
} else {
return typeof ast.value === "string" ? "'" + ast.value + "'" : ast.value;
}
}
export function astToDiagram(ast) { export function astToDiagram(ast) {
const tables = []; const tables = [];
const relationships = []; const relationships = [];
const inlineForeignKeys = [];
ast.forEach((e) => { ast.forEach((e) => {
if (e.type === "create") { if (e.type === "create") {
@ -14,13 +54,15 @@ export function astToDiagram(ast) {
table.color = "#175e7a"; table.color = "#175e7a";
table.fields = []; table.fields = [];
table.indices = []; table.indices = [];
table.x = 0; table.id = tables.length;
table.y = 0;
e.create_definitions.forEach((d) => { e.create_definitions.forEach((d) => {
if (d.resource === "column") { if (d.resource === "column") {
const field = {}; const field = {};
field.name = d.column.column; field.name = d.column.column;
field.type = d.definition.dataType; field.type = d.definition.dataType;
if (d.definition.expr && d.definition.expr.type === "expr_list") {
field.values = d.definition.expr.value.map((v) => v.value);
}
field.comment = ""; field.comment = "";
field.unique = false; field.unique = false;
if (d.unique) field.unique = true; if (d.unique) field.unique = true;
@ -31,39 +73,42 @@ export function astToDiagram(ast) {
field.primary = false; field.primary = false;
if (d.primary_key) field.primary = true; if (d.primary_key) field.primary = true;
field.default = ""; field.default = "";
if (d.default_val) field.default = d.default_val.value.value.toString(); if (d.default_val) {
if (d.definition["length"]) field.size = d.definition["length"]; let defaultValue = "";
if (d.default_val.value.type === "function") {
defaultValue = d.default_val.value.name;
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 = ""; field.check = "";
if (d.check) { if (d.check) {
let check = ""; field.check = buildSQLFromAST(d.check.definition[0]);
if (d.check.definition[0].left.column) {
let value = d.check.definition[0].right.value;
if (
d.check.definition[0].right.type === "double_quote_string" ||
d.check.definition[0].right.type === "single_quote_string"
)
value = "'" + value + "'";
check =
d.check.definition[0].left.column +
" " +
d.check.definition[0].operator +
" " +
value;
} else {
let value = d.check.definition[0].right.value;
if (
d.check.definition[0].left.type === "double_quote_string" ||
d.check.definition[0].left.type === "single_quote_string"
)
value = "'" + value + "'";
check =
value +
" " +
d.check.definition[0].operator +
" " +
d.check.definition[0].right.column;
}
field.check = check;
} }
table.fields.push(field); table.fields.push(field);
@ -77,17 +122,58 @@ export function astToDiagram(ast) {
}); });
}); });
} else if (d.constraint_type === "FOREIGN KEY") { } else if (d.constraint_type === "FOREIGN KEY") {
inlineForeignKeys.push({ ...d, startTable: e.table[0].table }); 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 (endField === -1) return;
const startFieldId = table.fields.findIndex(
(f) => f.name === startField,
);
if (startFieldId === -1) return;
relationship.name = startTable + "_" + startField + "_fk";
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;
relationship.cardinality = Cardinality.ONE_TO_ONE;
relationships.push(relationship);
} }
} }
}); });
tables.push(table); table.fields.forEach((f, j) => {
tables.forEach((e, i) => {
e.id = i;
e.fields.forEach((f, j) => {
f.id = j; f.id = j;
}); });
}); tables.push(table);
} else if (e.keyword === "index") { } else if (e.keyword === "index") {
const index = {}; const index = {};
index.name = e.index; index.name = e.index;
@ -108,21 +194,21 @@ export function astToDiagram(ast) {
if (found !== -1) tables[found].indices.forEach((i, j) => (i.id = j)); if (found !== -1) tables[found].indices.forEach((i, j) => (i.id = j));
} }
} else if (e.type === "alter") { } else if (e.type === "alter") {
e.expr.forEach((expr) => {
if ( if (
e.expr[0].action === "add" && expr.action === "add" &&
e.expr[0].create_definitions.constraint_type === "FOREIGN KEY" expr.create_definitions.constraint_type === "FOREIGN KEY"
) { ) {
const relationship = {}; const relationship = {};
const startTable = e.table[0].table; const startTable = e.table[0].table;
const startField = e.expr[0].create_definitions.definition[0].column; const startField = expr.create_definitions.definition[0].column;
const endTable = const endTable =
e.expr[0].create_definitions.reference_definition.table[0].table; expr.create_definitions.reference_definition.table[0].table;
const endField = const endField =
e.expr[0].create_definitions.reference_definition.definition[0] expr.create_definitions.reference_definition.definition[0].column;
.column;
let updateConstraint = "No action"; let updateConstraint = "No action";
let deleteConstraint = "No action"; let deleteConstraint = "No action";
e.expr[0].create_definitions.reference_definition.on_action.forEach( expr.create_definitions.reference_definition.on_action.forEach(
(c) => { (c) => {
if (c.type === "on update") { if (c.type === "on update") {
updateConstraint = c.value.value; updateConstraint = c.value.value;
@ -135,39 +221,24 @@ export function astToDiagram(ast) {
deleteConstraint[0].toUpperCase() + deleteConstraint[0].toUpperCase() +
deleteConstraint.substring(1); deleteConstraint.substring(1);
} }
} },
); );
let startTableId = -1; const startTableId = tables.findIndex((t) => t.name === startTable);
let startFieldId = -1; if (startTable === -1) return;
let endTableId = -1;
let endFieldId = -1;
tables.forEach((t) => { const endTableId = tables.findIndex((t) => t.name === endTable);
if (t.name === startTable) { if (endTableId === -1) return;
startTableId = t.id;
return;
}
if (t.name === endTable) { const endFieldId = tables[endTableId].fields.findIndex(
endTableId = t.id; (f) => f.name === endField,
} );
}); if (endField === -1) return;
if (startTableId === -1 || endTableId === -1) return; const startFieldId = tables[startTableId].fields.findIndex(
(f) => f.name === startField,
tables[startTableId].fields.forEach((f) => { );
if (f.name === startField) { if (startFieldId === -1) return;
startFieldId = f.id;
return;
}
if (f.name === endField) {
endFieldId = f.id;
}
});
if (startFieldId === -1 || endFieldId === -1) return;
relationship.name = startTable + "_" + startField + "_fk"; relationship.name = startTable + "_" + startField + "_fk";
relationship.startTableId = startTableId; relationship.startTableId = startTableId;
@ -181,72 +252,31 @@ export function astToDiagram(ast) {
relationships.forEach((r, i) => (r.id = i)); relationships.forEach((r, i) => (r.id = i));
} }
}
}); });
inlineForeignKeys.forEach((fk) => {
const relationship = {};
const startTable = fk.startTable;
const startField = fk.definition[0].column;
const endTable = fk.reference_definition.table[0].table;
const endField = fk.reference_definition.definition[0].column;
let updateConstraint = "No action";
let deleteConstraint = "No action";
fk.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);
} }
}); });
let startTableId = -1;
let startFieldId = -1;
let endTableId = -1;
let endFieldId = -1;
tables.forEach((t) => {
if (t.name === startTable) {
startTableId = t.id;
return;
}
if (t.name === endTable) {
endTableId = t.id;
}
});
if (startTableId === -1 || endTableId === -1) return;
tables[startTableId].fields.forEach((f) => {
if (f.name === startField) {
startFieldId = f.id;
return;
}
if (f.name === endField) {
endFieldId = f.id;
}
});
if (startFieldId === -1 || endFieldId === -1) return;
relationship.name = startTable + "_" + startField + "_fk";
relationship.startTableId = startTableId;
relationship.startFieldId = startFieldId;
relationship.endTableId = endTableId;
relationship.endFieldId = endFieldId;
relationship.updateConstraint = updateConstraint;
relationship.deleteConstraint = deleteConstraint;
relationship.cardinality = Cardinality.ONE_TO_ONE;
relationships.push(relationship);
});
relationships.forEach((r, i) => (r.id = i)); relationships.forEach((r, i) => (r.id = i));
let maxHeight = -1;
const tableWidth = 200;
const gapX = 54;
const gapY = 40;
tables.forEach((table, i) => {
if (i < tables.length / 2) {
table.x = i * tableWidth + (i + 1) * gapX;
table.y = gapY;
const height =
table.fields.length * tableFieldHeight +
tableHeaderHeight +
tableColorStripHeight;
maxHeight = Math.max(height, maxHeight);
} else {
const index = tables.length - i - 1;
table.x = index * tableWidth + (index + 1) * gapX;
table.y = maxHeight + 2 * gapY;
}
});
return { tables, relationships }; return { tables, relationships };
} }

View File

@ -1,4 +1,4 @@
import { strHasQuotes } from "./utils"; import { isFunction, strHasQuotes } from "./utils";
function validateDateStr(str) { function validateDateStr(str) {
return /^(?!0000)(?!00)(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[01])|(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31))$/.test( return /^(?!0000)(?!00)(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9]|3[01])|(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31))$/.test(
@ -9,13 +9,23 @@ function validateDateStr(str) {
function checkDefault(field) { function checkDefault(field) {
if (field.default === "") return true; if (field.default === "") return true;
if (isFunction(field.default)) return true;
if (!field.notNull && field.default.toLowerCase() === "null") return true;
switch (field.type) { switch (field.type) {
case "INT": case "INT":
case "BIGINT": case "BIGINT":
case "SMALLINT": case "SMALLINT":
return /^-?\d*$/.test(field.default); return /^-?\d*$/.test(field.default);
case "SET": {
const defaultValues = field.default.split(",");
for (let i = 0; i < defaultValues.length; i++) {
if (!field.values.includes(defaultValues[i].trim())) return false;
}
return true;
}
case "ENUM": case "ENUM":
case "SET":
return field.values.includes(field.default); return field.values.includes(field.default);
case "CHAR": case "CHAR":
case "VARCHAR": case "VARCHAR":
@ -30,7 +40,8 @@ function checkDefault(field) {
); );
case "BOOLEAN": case "BOOLEAN":
return ( return (
field.default.trim() === "false" || field.default.trim() === "true" field.default.trim().toLowerCase() === "false" ||
field.default.trim().toLowerCase() === "true"
); );
case "FLOAT": case "FLOAT":
case "DECIMAL": case "DECIMAL":
@ -55,6 +66,9 @@ function checkDefault(field) {
return parseInt(date[0]) >= 1970 && parseInt(date[0]) <= 2038; return parseInt(date[0]) >= 1970 && parseInt(date[0]) <= 2038;
} }
case "DATETIME": { case "DATETIME": {
if (field.default.toUpperCase() === "CURRENT_TIMESTAMP") {
return true;
}
if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(field.default)) { if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(field.default)) {
return false; return false;
} }
@ -116,12 +130,6 @@ export function getIssues(diagram) {
); );
} }
if (field.type === "DOUBLE" && field.size !== "") {
issues.push(
`Specifying number of digits for floating point data types is deprecated.`,
);
}
if (duplicateFieldNames[field.name]) { if (duplicateFieldNames[field.name]) {
issues.push(`Duplicate table fields in table "${table.name}"`); issues.push(`Duplicate table fields in table "${table.name}"`);
} else { } else {
@ -182,12 +190,6 @@ export function getIssues(diagram) {
} }
} }
if (field.type === "DOUBLE" && field.size !== "") {
issues.push(
`Specifying number of digits for floating point data types is deprecated.`,
);
}
if (duplicateFieldNames[field.name]) { if (duplicateFieldNames[field.name]) {
issues.push(`Duplicate type fields in "${type.name}"`); issues.push(`Duplicate type fields in "${type.name}"`);
} else { } else {

View File

@ -1,5 +1,5 @@
import { sqlDataTypes } from "../data/constants"; import { sqlDataTypes } from "../data/constants";
import { strHasQuotes } from "./utils"; import { isFunction, isKeyword, strHasQuotes } from "./utils";
export function getJsonType(f) { export function getJsonType(f) {
if (!sqlDataTypes.includes(f.type)) { if (!sqlDataTypes.includes(f.type)) {
@ -44,10 +44,7 @@ export function getTypeString(field, dbms = "mysql", baseType = false) {
if (field.type === "UUID") { if (field.type === "UUID") {
return `VARCHAR(36)`; return `VARCHAR(36)`;
} }
if (isSized(field.type)) { if (hasPrecision(field.type) || isSized(field.type)) {
return `${field.type}(${field.size})`;
}
if (hasPrecision(field.type)) {
return `${field.type}${field.size ? `(${field.size})` : ""}`; return `${field.type}${field.size ? `(${field.size})` : ""}`;
} }
if (field.type === "SET" || field.type === "ENUM") { if (field.type === "SET" || field.type === "ENUM") {
@ -147,13 +144,16 @@ export function hasQuotes(type) {
} }
export function parseDefault(field) { export function parseDefault(field) {
if (strHasQuotes(field.default)) { if (
strHasQuotes(field.default) ||
isFunction(field.default) ||
isKeyword(field.default) ||
!hasQuotes(field.type)
) {
return field.default; return field.default;
} }
return hasQuotes(field.type) && field.default.toLowerCase() !== "null" return `'${field.default}'`;
? `'${field.default}'`
: `${field.default}`;
} }
export function jsonToMySQL(obj) { export function jsonToMySQL(obj) {

View File

@ -24,3 +24,13 @@ export function strHasQuotes(str) {
(str[0] === str[str.length - 1] && str[0] === "`") (str[0] === str[str.length - 1] && str[0] === "`")
); );
} }
const keywords = ["CURRENT_TIMESTAMP", "NULL"];
export function isKeyword(str) {
return keywords.includes(str.toUpperCase());
}
export function isFunction(str) {
return /\w+\([^)]*\)$/.test(str);
}