2024-06-03 09:15:52 +02:00
|
|
|
namespace _sindri.outputs.database.postgresql
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
function value_encode(
|
|
|
|
|
value : any
|
|
|
|
|
) : string
|
|
|
|
|
{
|
|
|
|
|
if (value === null) {
|
|
|
|
|
return "NULL";
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
switch (typeof(value)) {
|
|
|
|
|
case "boolean": {
|
|
|
|
|
return (value ? "TRUE" : "FALSE");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "number": {
|
|
|
|
|
return value.toString();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "string": {
|
|
|
|
|
return ("'" + value + "'");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
throw (new Error("unhandled"));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
export function render(
|
|
|
|
|
input_data
|
|
|
|
|
) : string
|
|
|
|
|
{
|
|
|
|
|
return (
|
|
|
|
|
input_data.domains
|
|
|
|
|
.map(
|
|
|
|
|
(domain) => lib_plankton.string.coin(
|
|
|
|
|
"CREATE TABLE\n\t{{name}}(\n{{entries}}\n\t)\n;\n{{comments}}",
|
|
|
|
|
{
|
|
|
|
|
"name": domain.name,
|
|
|
|
|
"entries": (
|
|
|
|
|
(
|
|
|
|
|
[]
|
|
|
|
|
// key field
|
|
|
|
|
.concat(
|
|
|
|
|
(domain.key_field === null)
|
|
|
|
|
? []
|
|
|
|
|
: lib_plankton.string.coin(
|
|
|
|
|
"{{name}} {{parameters}}",
|
|
|
|
|
{
|
2024-10-25 11:26:43 +02:00
|
|
|
"name": ('"' + domain.key_field.name + '"'),
|
2024-06-03 09:15:52 +02:00
|
|
|
"parameters": (
|
|
|
|
|
[
|
|
|
|
|
"SERIAL",
|
|
|
|
|
]
|
|
|
|
|
.join(" ")
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
// data fields
|
|
|
|
|
.concat(
|
|
|
|
|
domain.data_fields
|
|
|
|
|
.map(
|
|
|
|
|
(data_field) => lib_plankton.string.coin(
|
|
|
|
|
"{{name}} {{parameters}}",
|
|
|
|
|
{
|
2024-10-25 11:26:43 +02:00
|
|
|
"name": ('"' + data_field.name + '"'),
|
2024-06-03 09:15:52 +02:00
|
|
|
"parameters": (
|
|
|
|
|
(
|
|
|
|
|
// type
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"boolean": "BOOLEAN",
|
|
|
|
|
"integer": "INTEGER",
|
|
|
|
|
"string_short": "VARCHAR(63)",
|
|
|
|
|
"string_medium": "VARCHAR(255)",
|
|
|
|
|
"string_long": "TEXT",
|
|
|
|
|
}[data_field.type],
|
|
|
|
|
]
|
|
|
|
|
// nullability
|
|
|
|
|
.concat(
|
|
|
|
|
data_field.nullable
|
2024-06-03 09:33:24 +02:00
|
|
|
? []
|
|
|
|
|
: ["NOT NULL"]
|
2024-06-03 09:15:52 +02:00
|
|
|
)
|
|
|
|
|
// default
|
|
|
|
|
.concat(
|
|
|
|
|
(data_field.default === undefined)
|
|
|
|
|
? []
|
|
|
|
|
: [
|
|
|
|
|
lib_plankton.string.coin(
|
|
|
|
|
"DEFAULT {{value}}",
|
|
|
|
|
{
|
|
|
|
|
"value": value_encode(data_field.default),
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.join(" ")
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
// constraints
|
|
|
|
|
.concat(
|
|
|
|
|
domain["constraints"]
|
2024-10-25 11:26:43 +02:00
|
|
|
.concat(
|
|
|
|
|
(domain.key_field === null)
|
|
|
|
|
?
|
|
|
|
|
[]
|
|
|
|
|
:
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
"kind": "unique",
|
|
|
|
|
"parameters": {
|
|
|
|
|
"fields": [
|
|
|
|
|
domain.key_field.name,
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
)
|
2024-06-03 09:15:52 +02:00
|
|
|
.map(
|
|
|
|
|
(constraint) => {
|
|
|
|
|
switch (constraint.kind) {
|
|
|
|
|
default: {
|
|
|
|
|
throw (new Error("unhandled constraint kind: " + constraint.kind));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "foreign_key": {
|
|
|
|
|
return lib_plankton.string.coin(
|
|
|
|
|
"FOREIGN KEY ({{fields}}) REFERENCES {{reference_name}}({{reference_fields}})",
|
|
|
|
|
{
|
|
|
|
|
"fields": (
|
|
|
|
|
constraint.parameters["fields"]
|
2024-10-25 11:26:43 +02:00
|
|
|
.map(x => ('"' + x + '"'))
|
2024-06-03 09:15:52 +02:00
|
|
|
.join(",")
|
|
|
|
|
),
|
2024-10-25 11:26:43 +02:00
|
|
|
"reference_name": ('"' + constraint.parameters["reference"]["name"] + '"'),
|
2024-06-03 09:15:52 +02:00
|
|
|
"reference_fields": (
|
|
|
|
|
constraint.parameters["reference"]["fields"]
|
2024-10-25 11:26:43 +02:00
|
|
|
.map(x => ('"' + x + '"'))
|
2024-06-03 09:15:52 +02:00
|
|
|
.join(",")
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case "unique": {
|
|
|
|
|
return lib_plankton.string.coin(
|
|
|
|
|
"UNIQUE ({{fields}})",
|
|
|
|
|
{
|
|
|
|
|
"fields": (
|
|
|
|
|
constraint.parameters["fields"]
|
2024-10-25 11:26:43 +02:00
|
|
|
.map(x => ('"' + x + '"'))
|
2024-06-03 09:15:52 +02:00
|
|
|
.join(",")
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.map(x => ("\t\t" + x))
|
|
|
|
|
.join(",\n")
|
|
|
|
|
),
|
|
|
|
|
"comments": (
|
|
|
|
|
(
|
|
|
|
|
[]
|
|
|
|
|
.concat(
|
2024-06-03 09:33:24 +02:00
|
|
|
(! (domain.description === null))
|
|
|
|
|
? [
|
2024-06-03 09:15:52 +02:00
|
|
|
{
|
|
|
|
|
"kind": "TABLE",
|
|
|
|
|
"subject": domain.name,
|
|
|
|
|
"value": domain.description,
|
|
|
|
|
}
|
|
|
|
|
]
|
2024-06-03 09:33:24 +02:00
|
|
|
: []
|
2024-06-03 09:15:52 +02:00
|
|
|
)
|
|
|
|
|
.concat(
|
2024-06-03 09:33:24 +02:00
|
|
|
(
|
|
|
|
|
(! (domain.key_field === null))
|
|
|
|
|
&&
|
|
|
|
|
(! (domain.key_field.description === null))
|
|
|
|
|
)
|
|
|
|
|
? [
|
2024-06-03 09:15:52 +02:00
|
|
|
{
|
|
|
|
|
"kind": "COLUMN",
|
|
|
|
|
"subject": (domain.name + "." + domain.key_field.name),
|
2024-06-03 09:33:24 +02:00
|
|
|
"value": domain.key_field.description,
|
2024-06-03 09:15:52 +02:00
|
|
|
}
|
|
|
|
|
]
|
2024-06-03 09:33:24 +02:00
|
|
|
: []
|
2024-06-03 09:15:52 +02:00
|
|
|
)
|
|
|
|
|
.concat(
|
|
|
|
|
domain.data_fields
|
|
|
|
|
.filter(
|
|
|
|
|
data_field => (! (data_field.description === null))
|
|
|
|
|
)
|
|
|
|
|
.map(
|
|
|
|
|
data_field => ({
|
|
|
|
|
"kind": "COLUMN",
|
|
|
|
|
"subject": (domain.name + "." + data_field.name),
|
|
|
|
|
"value": data_field.description,
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.map(
|
|
|
|
|
entry => lib_plankton.string.coin(
|
|
|
|
|
"COMMENT ON {{kind}} {{subject}} IS '{{value}}';",
|
|
|
|
|
{
|
|
|
|
|
"kind": entry.kind,
|
|
|
|
|
"subject": entry.subject,
|
|
|
|
|
"value": entry.value,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.join("\n")
|
|
|
|
|
),
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
.map(x => (x + "\n"))
|
|
|
|
|
.join("\n")
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*/
|
|
|
|
|
_sindri.add_output(
|
|
|
|
|
_sindri.enum_realm.database,
|
|
|
|
|
"postgresql",
|
|
|
|
|
{
|
|
|
|
|
"render": (x) => Promise.resolve<string>(_sindri.outputs.database.postgresql.render(x)),
|
|
|
|
|
}
|
|
|
|
|
);
|