Files
drawdb/src/utils/exportSQL/postgres.js
Kishan_Singh 47caa29f78 Add support for PostgreSQL "CREATE TABLE INHERITS" (#524)
* feat: add support for PostgreSQL table inheritance in schema export

* fixed the suggested changes in the inheritance feature

* Update src/components/EditorSidePanel/TablesTab/TableField.jsx

Co-authored-by: 1ilit <1ilit@proton.me>

* fixed all the comments

* feat: finalize Postgres table inheritance support with fixes and formatting

---------

Co-authored-by: kishansinghifs1 <kishansingh956196@gmai.com>
Co-authored-by: 1ilit <1ilit@proton.me>
2025-07-04 14:57:20 +04:00

115 lines
3.8 KiB
JavaScript

import { escapeQuotes, exportFieldComment, parseDefault } from "./shared";
import { dbToTypes } from "../../data/datatypes";
export function toPostgres(diagram) {
const enumStatements = diagram.enums
.map(
(e) =>
`CREATE TYPE "${e.name}" AS ENUM (\n${e.values
.map((v) => `\t'${v}'`)
.join(",\n")}\n);\n`,
)
.join("\n");
const typeStatements = diagram.types
.map(
(type) =>
`CREATE TYPE ${type.name} AS (\n${type.fields
.map((f) => `\t${f.name} ${f.type}`)
.join(",\n")}\n);\n\n${
type.comment?.trim()
? `COMMENT ON TYPE "${type.name}" IS '${escapeQuotes(type.comment)}';\n`
: ""
}`,
)
.join("\n");
const tableStatements = diagram.tables
.map((table) => {
const inheritsClause =
Array.isArray(table.inherits) && table.inherits.length > 0
? `\n) INHERITS (${table.inherits.map((parent) => `"${parent}"`).join(", ")})`
: "\n)";
const fieldDefinitions = table.fields
.map(
(field) =>
`${exportFieldComment(field.comment)}\t"${
field.name
}" ${field.type}${
field.size ? `(${field.size})` : ""
}${field.isArray ? " ARRAY" : ""}${field.notNull ? " NOT NULL" : ""}${
field.unique ? " UNIQUE" : ""
}${field.increment ? " GENERATED BY DEFAULT AS IDENTITY" : ""}${
field.default?.trim()
? ` DEFAULT ${parseDefault(field, diagram.database)}`
: ""
}${
field.check && dbToTypes[diagram.database][field.type]?.hasCheck
? ` CHECK(${field.check})`
: ""
}`,
)
.join(",\n");
const primaryKeyClause = table.fields.some((f) => f.primary)
? `,\n\tPRIMARY KEY(${table.fields
.filter((f) => f.primary)
.map((f) => `"${f.name}"`)
.join(", ")})`
: "";
const commentStatements = [
table.comment?.trim()
? `COMMENT ON TABLE "${table.name}" IS '${escapeQuotes(table.comment)}';`
: "",
...table.fields
.map((field) =>
field.comment?.trim()
? `COMMENT ON COLUMN "${table.name}"."${field.name}" IS '${escapeQuotes(field.comment)}';`
: "",
)
.filter(Boolean),
].join("\n");
const indexStatements = table.indices
.map(
(i) =>
`CREATE ${i.unique ? "UNIQUE " : ""}INDEX "${i.name}"\nON "${table.name}" (${i.fields
.map((f) => `"${f}"`)
.join(", ")});`,
)
.join("\n");
return `CREATE TABLE "${table.name}" (\n${fieldDefinitions}${primaryKeyClause}${inheritsClause};\n\n${commentStatements}\n${indexStatements}`;
})
.join("\n\n");
const foreignKeyStatements = diagram.references
.map((r) => {
const startTable = diagram.tables.find((t) => t.id === r.startTableId);
const endTable = diagram.tables.find((t) => t.id === r.endTableId);
const startField = startTable?.fields.find(
(f) => f.id === r.startFieldId,
);
const endField = endTable?.fields.find((f) => f.id === r.endFieldId);
if (!startTable || !endTable || !startField || !endField) return "";
return `ALTER TABLE "${startTable.name}"\nADD FOREIGN KEY("${startField.name}") REFERENCES "${endTable.name}"("${endField.name}")\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`;
})
.filter(Boolean)
.join("\n");
return [
enumStatements,
enumStatements.trim() && typeStatements
? "\n" + typeStatements
: typeStatements,
tableStatements,
foreignKeyStatements,
]
.filter(Boolean)
.join("\n");
}