-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathpostgres.js
More file actions
120 lines (108 loc) · 3.96 KB
/
postgres.js
File metadata and controls
120 lines (108 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { EMPTY_ENUM_PLACEHOLDER } from "../../data/constants";
import {
escapeQuotes,
exportFieldComment,
parseDefault,
} from "./shared";
import { dbToTypes } from "../../data/datatypes";
export function toPostgres(diagram) {
const enumStatements = diagram.enums
.map((e) => {
const values =
e.values?.length > 0 ? e.values : [EMPTY_ENUM_PLACEHOLDER];
return `CREATE TYPE "${e.name}" AS ENUM (\n${values
.map((v) => `\t'${escapeQuotes(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 IF NOT EXISTS "${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");
}