Quote and escape identifiers with spaces or non-ascii chars in dbml (#582)

Co-authored-by: Lopes Lenny <lenny.lopes@litecom.ch>
This commit is contained in:
Lenny Lopes
2025-09-17 11:45:48 +02:00
committed by GitHub
parent c5e0415ea3
commit 283df0a4e4

View File

@@ -4,6 +4,18 @@ import i18n from "../../i18n/i18n";
import { escapeQuotes } from "../exportSQL/shared";
import { isFunction, isKeyword } from "../utils";
const IDENT_SAFE_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
function escapeIdentifier(s) {
return String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
}
function quoteIdentifier(name) {
if (name == null) return name;
const s = String(name);
return IDENT_SAFE_RE.test(s) ? s : `"${escapeIdentifier(s)}"`;
}
function parseDefaultDbml(field, database) {
if (isFunction(field.default)) {
return `\`${field.default}\``;
@@ -96,7 +108,7 @@ export function toDBML(diagram) {
(f) => f.id === rel.endFieldId,
);
return `Ref ${rel.name} {\n\t${startTableName}.${startFieldName} ${cardinality(rel)} ${endTableName}.${endFieldName} [ delete: ${rel.deleteConstraint.toLowerCase()}, update: ${rel.updateConstraint.toLowerCase()} ]\n}`;
return `Ref ${rel.name} {\n\t${quoteIdentifier(startTableName)}.${quoteIdentifier(startFieldName)} ${cardinality(rel)} ${quoteIdentifier(endTableName)}.${quoteIdentifier(endFieldName)} [ delete: ${rel.deleteConstraint.toLowerCase()}, update: ${rel.updateConstraint.toLowerCase()} ]\n}`;
};
let enumDefinitions = "";
@@ -107,7 +119,7 @@ export function toDBML(diagram) {
(field.type === "ENUM" || field.type === "SET") &&
Array.isArray(field.values)
) {
enumDefinitions += `enum ${field.name}_${field.values.join("_")}_t {\n\t${field.values.join("\n\t")}\n}\n\n`;
enumDefinitions += `enum ${quoteIdentifier(`${field.name}_${field.values.join("_")}_t`)} {\n\t${field.values.map((v) => quoteIdentifier(v)).join("\n\t")}\n}\n\n`;
}
}
}
@@ -115,17 +127,17 @@ export function toDBML(diagram) {
return `${diagram.enums
.map(
(en) =>
`enum ${en.name} {\n${en.values.map((v) => `\t${v}`).join("\n")}\n}\n\n`,
`enum ${quoteIdentifier(en.name)} {\n${en.values.map((v) => `\t${quoteIdentifier(v)}`).join("\n")}\n}\n\n`,
)
.join("\n\n")}${enumDefinitions}${diagram.tables
.map(
(table) =>
`Table ${table.name} [headercolor: ${table.color}] {\n${table.fields
`Table ${quoteIdentifier(table.name)} [headercolor: ${table.color}] {\n${table.fields
.map(
(field) =>
`\t${field.name} ${
`\t${quoteIdentifier(field.name)} ${
field.type === "ENUM" || field.type === "SET"
? `${field.name}_${field.values.join("_")}_t`
? quoteIdentifier(`${field.name}_${field.values.join("_")}_t`)
: field.type.toLowerCase()
}${fieldSize(
field,
@@ -138,7 +150,9 @@ export function toDBML(diagram) {
table.indices
.map(
(index) =>
`\t\t(${index.fields.join(", ")}) [ name: '${
`\t\t(${index.fields
.map((f) => quoteIdentifier(f))
.join(", ")}) [ name: '${
index.name
}'${index.unique ? ", unique" : ""} ]`,
)