2024-03-15 22:37:22 +08:00
|
|
|
import { sqlDataTypes } from "../data/constants";
|
2024-04-10 09:57:07 +08:00
|
|
|
import { strHasQuotes } from "./utils";
|
2023-09-19 20:49:28 +08:00
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function getJsonType(f) {
|
2024-02-05 20:38:38 +08:00
|
|
|
if (!sqlDataTypes.includes(f.type)) {
|
|
|
|
return '{ "type" : "object", additionalProperties : true }';
|
|
|
|
}
|
2023-09-19 20:51:37 +08:00
|
|
|
switch (f.type) {
|
|
|
|
case "INT":
|
|
|
|
case "SMALLINT":
|
|
|
|
case "BIGINT":
|
|
|
|
case "DECIMAL":
|
|
|
|
case "NUMERIC":
|
|
|
|
case "REAL":
|
|
|
|
case "FLOAT":
|
|
|
|
return '{ "type" : "number" }';
|
|
|
|
case "BOOLEAN":
|
|
|
|
return '{ "type" : "boolean" }';
|
|
|
|
case "JSON":
|
|
|
|
return '{ "type" : "object", "additionalProperties" : true }';
|
|
|
|
case "ENUM":
|
|
|
|
return `{\n\t\t\t\t\t"type" : "string",\n\t\t\t\t\t"enum" : [${f.values
|
|
|
|
.map((v) => `"${v}"`)
|
|
|
|
.join(", ")}]\n\t\t\t\t}`;
|
|
|
|
case "SET":
|
|
|
|
return `{\n\t\t\t\t\t"type": "array",\n\t\t\t\t\t"items": {\n\t\t\t\t\t\t"type": "string",\n\t\t\t\t\t\t"enum": [${f.values
|
|
|
|
.map((v) => `"${v}"`)
|
|
|
|
.join(", ")}]\n\t\t\t\t\t}\n\t\t\t\t}`;
|
|
|
|
default:
|
|
|
|
return '{ "type" : "string"}';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function generateSchema(type) {
|
2024-02-05 20:38:38 +08:00
|
|
|
return `{\n\t\t\t"$schema": "http://json-schema.org/draft-04/schema#",\n\t\t\t"type": "object",\n\t\t\t"properties": {\n\t\t\t\t${type.fields
|
2023-09-19 20:51:37 +08:00
|
|
|
.map((f) => `"${f.name}" : ${getJsonType(f)}`)
|
|
|
|
.join(
|
2024-04-10 09:57:07 +08:00
|
|
|
",\n\t\t\t\t",
|
2023-09-19 20:51:37 +08:00
|
|
|
)}\n\t\t\t},\n\t\t\t"additionalProperties": false\n\t\t}`;
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function getTypeString(field, dbms = "mysql", baseType = false) {
|
2023-09-19 20:51:26 +08:00
|
|
|
if (dbms === "mysql") {
|
|
|
|
if (field.type === "UUID") {
|
|
|
|
return `VARCHAR(36)`;
|
|
|
|
}
|
|
|
|
if (isSized(field.type)) {
|
|
|
|
return `${field.type}(${field.size})`;
|
|
|
|
}
|
2024-01-18 18:45:58 +08:00
|
|
|
if (hasPrecision(field.type)) {
|
|
|
|
return `${field.type}${field.size ? `(${field.size})` : ""}`;
|
2023-09-19 20:51:26 +08:00
|
|
|
}
|
|
|
|
if (field.type === "SET" || field.type === "ENUM") {
|
|
|
|
return `${field.type}(${field.values.map((v) => `"${v}"`).join(", ")})`;
|
|
|
|
}
|
2023-09-19 20:51:37 +08:00
|
|
|
if (!sqlDataTypes.includes(field.type)) {
|
|
|
|
return "JSON";
|
|
|
|
}
|
2023-09-19 20:51:26 +08:00
|
|
|
return field.type;
|
|
|
|
} else if (dbms === "postgres") {
|
|
|
|
if (field.type === "SMALLINT" && field.increment) {
|
|
|
|
return "smallserial";
|
|
|
|
}
|
|
|
|
if (field.type === "INT" && field.increment) {
|
|
|
|
return "serial";
|
|
|
|
}
|
|
|
|
if (field.type === "BIGINT" && field.increment) {
|
|
|
|
return "bigserial";
|
|
|
|
}
|
|
|
|
if (field.type === "ENUM") {
|
|
|
|
return `${field.name}_t`;
|
|
|
|
}
|
|
|
|
if (field.type === "SET") {
|
|
|
|
return `${field.name}_t[]`;
|
|
|
|
}
|
|
|
|
if (field.type === "TIMESTAMP") {
|
|
|
|
return "TIMESTAMPTZ";
|
|
|
|
}
|
|
|
|
if (field.type === "DATETIME") {
|
|
|
|
return `timestamp`;
|
|
|
|
}
|
|
|
|
if (isSized(field.type)) {
|
|
|
|
const type =
|
|
|
|
field.type === "BINARY"
|
|
|
|
? "bit"
|
|
|
|
: field.type === "VARBINARY"
|
2024-04-10 09:57:07 +08:00
|
|
|
? "bit varying"
|
|
|
|
: field.type.toLowerCase();
|
2023-09-19 20:51:26 +08:00
|
|
|
return `${type}(${field.size})`;
|
|
|
|
}
|
|
|
|
if (hasPrecision(field.type) && field.size !== "") {
|
|
|
|
return `${field.type}${field.size}`;
|
|
|
|
}
|
|
|
|
return field.type.toLowerCase();
|
2024-02-15 01:52:58 +08:00
|
|
|
} else if (dbms === "mssql") {
|
|
|
|
let type = field.type;
|
|
|
|
switch (field.type) {
|
|
|
|
case "ENUM":
|
|
|
|
return baseType
|
|
|
|
? "NVARCHAR(255)"
|
|
|
|
: `NVARCHAR(255) CHECK([${field.name}] in (${field.values
|
|
|
|
.map((v) => `'${v}'`)
|
|
|
|
.join(", ")}))`;
|
|
|
|
case "VARCHAR":
|
|
|
|
type = `NVARCHAR`;
|
|
|
|
break;
|
|
|
|
case "UUID":
|
|
|
|
type = "UNIQUEIDENTIFIER";
|
|
|
|
break;
|
|
|
|
case "DOUBLE":
|
|
|
|
type = "FLOAT";
|
|
|
|
break;
|
|
|
|
case "BOOLEAN":
|
|
|
|
return "BIT";
|
|
|
|
case "SET":
|
|
|
|
return "NVARCHAR(255)";
|
|
|
|
case "BLOB":
|
|
|
|
return "VARBINARY(MAX)";
|
|
|
|
case "JSON":
|
|
|
|
return "NVARCHAR(MAX)";
|
|
|
|
case "TEXT":
|
|
|
|
return "TEXT";
|
|
|
|
default:
|
|
|
|
type = field.type;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (isSized(field.type)) {
|
|
|
|
return `${type}(${field.size})`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
2023-09-19 20:51:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function hasQuotes(type) {
|
2023-09-19 20:51:22 +08:00
|
|
|
return [
|
|
|
|
"CHAR",
|
|
|
|
"VARCHAR",
|
|
|
|
"BINARY",
|
|
|
|
"VARBINARY",
|
|
|
|
"ENUM",
|
|
|
|
"DATE",
|
|
|
|
"TIME",
|
|
|
|
"TIMESTAMP",
|
|
|
|
"DATETIME",
|
|
|
|
].includes(type);
|
|
|
|
}
|
|
|
|
|
2024-04-10 09:57:07 +08:00
|
|
|
export function parseDefault(field) {
|
|
|
|
if (strHasQuotes(field.default)) {
|
|
|
|
return field.default;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hasQuotes(field.type) && field.default.toLowerCase() !== "null"
|
|
|
|
? `'${field.default}'`
|
|
|
|
: `${field.default}`;
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function jsonToMySQL(obj) {
|
2023-09-19 20:50:46 +08:00
|
|
|
return `${obj.tables
|
2023-09-19 20:50:39 +08:00
|
|
|
.map(
|
|
|
|
(table) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${
|
|
|
|
table.comment === "" ? "" : `/* ${table.comment} */\n`
|
2023-09-19 20:50:39 +08:00
|
|
|
}CREATE TABLE \`${table.name}\` (\n${table.fields
|
|
|
|
.map(
|
|
|
|
(field) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t\`${
|
|
|
|
field.name
|
|
|
|
}\` ${getTypeString(field)}${field.notNull ? " NOT NULL" : ""}${
|
|
|
|
field.increment ? " AUTO_INCREMENT" : ""
|
|
|
|
}${field.unique ? " UNIQUE" : ""}${
|
2024-04-10 09:57:07 +08:00
|
|
|
field.default !== "" ? ` DEFAULT ${parseDefault(field)}` : ""
|
2024-02-15 01:52:58 +08:00
|
|
|
}${
|
|
|
|
field.check === "" || !hasCheck(field.type)
|
|
|
|
? !sqlDataTypes.includes(field.type)
|
|
|
|
? ` CHECK(\n\t\tJSON_SCHEMA_VALID("${generateSchema(
|
|
|
|
obj.types.find(
|
2024-04-10 09:57:07 +08:00
|
|
|
(t) => t.name === field.type.toLowerCase(),
|
|
|
|
),
|
2024-02-15 01:52:58 +08:00
|
|
|
)}", \`${field.name}\`))`
|
|
|
|
: ""
|
|
|
|
: ` CHECK(${field.check})`
|
2024-04-24 15:13:46 +08:00
|
|
|
}${field.comment ? ` COMMENT '${field.comment}'` : ''}`,
|
2023-09-19 20:50:39 +08:00
|
|
|
)
|
2024-02-15 01:52:58 +08:00
|
|
|
.join(",\n")}${
|
|
|
|
table.fields.filter((f) => f.primary).length > 0
|
2023-09-19 20:50:45 +08:00
|
|
|
? `,\n\tPRIMARY KEY(${table.fields
|
2024-02-15 01:52:58 +08:00
|
|
|
.filter((f) => f.primary)
|
|
|
|
.map((f) => `\`${f.name}\``)
|
|
|
|
.join(", ")})`
|
|
|
|
: ""
|
2024-04-24 15:13:46 +08:00
|
|
|
}\n)${table.comment ? ` COMMENT='${table.comment}'` : ''};\n${
|
2024-02-15 01:52:58 +08:00
|
|
|
table.indices.length > 0
|
|
|
|
? `\n${table.indices.map(
|
|
|
|
(i) =>
|
|
|
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX \`${
|
|
|
|
i.name
|
|
|
|
}\`\nON \`${table.name}\` (${i.fields
|
|
|
|
.map((f) => `\`${f}\``)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)}`
|
2023-09-19 20:50:45 +08:00
|
|
|
: ""
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2023-09-19 20:50:39 +08:00
|
|
|
)
|
2023-09-19 20:50:46 +08:00
|
|
|
.join("\n")}\n${obj.references
|
2024-02-15 01:52:58 +08:00
|
|
|
.map(
|
|
|
|
(r) =>
|
|
|
|
`ALTER TABLE \`${
|
|
|
|
obj.tables[r.startTableId].name
|
|
|
|
}\`\nADD FOREIGN KEY(\`${
|
|
|
|
obj.tables[r.startTableId].fields[r.startFieldId].name
|
|
|
|
}\`) REFERENCES \`${obj.tables[r.endTableId].name}\`(\`${
|
|
|
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
2024-04-10 09:57:07 +08:00
|
|
|
}\`)\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}`;
|
2023-09-19 20:50:39 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function jsonToPostgreSQL(obj) {
|
2023-09-19 20:51:37 +08:00
|
|
|
return `${obj.types.map((type) => {
|
|
|
|
const typeStatements = type.fields
|
|
|
|
.filter((f) => f.type === "ENUM" || f.type === "SET")
|
|
|
|
.map(
|
|
|
|
(f) =>
|
|
|
|
`CREATE TYPE "${f.name}_t" AS ENUM (${f.values
|
|
|
|
.map((v) => `'${v}'`)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});\n`,
|
2023-09-19 20:51:37 +08:00
|
|
|
);
|
|
|
|
if (typeStatements.length > 0) {
|
|
|
|
return (
|
|
|
|
typeStatements.join("") +
|
2024-02-15 01:52:58 +08:00
|
|
|
`${
|
|
|
|
type.comment === "" ? "" : `/**\n${type.comment}\n*/\n`
|
2023-09-19 20:51:37 +08:00
|
|
|
}CREATE TYPE ${type.name} AS (\n${type.fields
|
|
|
|
.map((f) => `\t${f.name} ${getTypeString(f, "postgres")}`)
|
|
|
|
.join("\n")}\n);`
|
|
|
|
);
|
|
|
|
} else {
|
2024-02-15 01:52:58 +08:00
|
|
|
return `${
|
|
|
|
type.comment === "" ? "" : `/**\n${type.comment}\n*/\n`
|
|
|
|
}CREATE TYPE ${type.name} AS (\n${type.fields
|
|
|
|
.map((f) => `\t${f.name} ${getTypeString(f, "postgres")}`)
|
|
|
|
.join("\n")}\n);`;
|
2023-09-19 20:51:37 +08:00
|
|
|
}
|
|
|
|
})}\n${obj.tables
|
2023-09-19 20:51:26 +08:00
|
|
|
.map(
|
|
|
|
(table) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${table.comment === "" ? "" : `/**\n${table.comment}\n*/\n`}${
|
|
|
|
table.fields.filter((f) => f.type === "ENUM" || f.type === "SET")
|
|
|
|
.length > 0
|
|
|
|
? `${table.fields
|
|
|
|
.filter((f) => f.type === "ENUM" || f.type === "SET")
|
|
|
|
.map(
|
|
|
|
(f) =>
|
|
|
|
`CREATE TYPE "${f.name}_t" AS ENUM (${f.values
|
|
|
|
.map((v) => `'${v}'`)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});\n\n`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)}`
|
|
|
|
: ""
|
2023-09-19 20:51:26 +08:00
|
|
|
}CREATE TABLE "${table.name}" (\n${table.fields
|
|
|
|
.map(
|
|
|
|
(field) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t"${
|
|
|
|
field.name
|
|
|
|
}" ${getTypeString(field, "postgres")}${
|
|
|
|
field.notNull ? " NOT NULL" : ""
|
|
|
|
}${
|
2024-04-10 09:57:07 +08:00
|
|
|
field.default !== "" ? ` DEFAULT ${parseDefault(field)}` : ""
|
2024-02-15 01:52:58 +08:00
|
|
|
}${
|
|
|
|
field.check === "" || !hasCheck(field.type)
|
|
|
|
? ""
|
|
|
|
: ` CHECK(${field.check})`
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2023-09-19 20:51:26 +08:00
|
|
|
)
|
2024-02-15 01:52:58 +08:00
|
|
|
.join(",\n")}${
|
|
|
|
table.fields.filter((f) => f.primary).length > 0
|
2023-09-19 20:51:26 +08:00
|
|
|
? `,\n\tPRIMARY KEY(${table.fields
|
2024-02-15 01:52:58 +08:00
|
|
|
.filter((f) => f.primary)
|
|
|
|
.map((f) => `"${f.name}"`)
|
|
|
|
.join(", ")})`
|
|
|
|
: ""
|
|
|
|
}\n);\n${
|
|
|
|
table.indices.length > 0
|
|
|
|
? `${table.indices.map(
|
|
|
|
(i) =>
|
|
|
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX "${
|
|
|
|
i.name
|
|
|
|
}"\nON "${table.name}" (${i.fields
|
|
|
|
.map((f) => `"${f}"`)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)}`
|
2023-09-19 20:51:26 +08:00
|
|
|
: ""
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2023-09-19 20:51:26 +08:00
|
|
|
)
|
|
|
|
.join("\n")}\n${obj.references
|
2024-02-15 01:52:58 +08:00
|
|
|
.map(
|
|
|
|
(r) =>
|
|
|
|
`ALTER TABLE "${obj.tables[r.startTableId].name}"\nADD FOREIGN KEY("${
|
|
|
|
obj.tables[r.startTableId].fields[r.startFieldId].name
|
|
|
|
}") REFERENCES "${obj.tables[r.endTableId].name}"("${
|
|
|
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
2024-04-10 09:57:07 +08:00
|
|
|
}")\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}`;
|
2023-09-19 20:51:26 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function getSQLiteType(field) {
|
2024-01-31 23:00:15 +08:00
|
|
|
switch (field.type) {
|
|
|
|
case "INT":
|
|
|
|
case "SMALLINT":
|
|
|
|
case "BIGINT":
|
|
|
|
case "BOOLEAN":
|
|
|
|
return "INTEGER";
|
|
|
|
case "DECIMAL":
|
|
|
|
case "NUMERIC":
|
|
|
|
case "FLOAT":
|
|
|
|
case "DOUBLE":
|
|
|
|
case "REAL":
|
|
|
|
return "REAL";
|
|
|
|
case "CHAR":
|
|
|
|
case "VARCHAR":
|
|
|
|
case "UUID":
|
|
|
|
case "TEXT":
|
|
|
|
case "DATE":
|
|
|
|
case "TIME":
|
|
|
|
case "TIMESTAMP":
|
|
|
|
case "DATETIME":
|
|
|
|
case "BINARY":
|
|
|
|
case "VARBINARY":
|
|
|
|
return "TEXT";
|
|
|
|
case "ENUM":
|
2024-02-15 01:52:58 +08:00
|
|
|
return `TEXT CHECK("${field.name}" in (${field.values
|
|
|
|
.map((v) => `'${v}'`)
|
|
|
|
.join(", ")}))`;
|
2024-01-31 23:00:15 +08:00
|
|
|
default:
|
|
|
|
return "BLOB";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function getInlineFK(table, obj) {
|
2024-01-31 23:00:15 +08:00
|
|
|
let fk = "";
|
2024-02-15 01:52:58 +08:00
|
|
|
obj.references.forEach((r) => {
|
2024-01-31 23:00:15 +08:00
|
|
|
if (fk !== "") return;
|
|
|
|
if (r.startTableId === table.id) {
|
2024-02-15 01:52:58 +08:00
|
|
|
fk = `FOREIGN KEY ("${table.fields[r.startFieldId].name}") REFERENCES "${
|
|
|
|
obj.tables[r.endTableId].name
|
|
|
|
}"("${
|
|
|
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
|
|
|
}")\n\tON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()}`;
|
2024-01-31 23:00:15 +08:00
|
|
|
}
|
2024-02-15 01:52:58 +08:00
|
|
|
});
|
2024-01-31 23:00:15 +08:00
|
|
|
return fk;
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function jsonToSQLite(obj) {
|
2024-01-31 23:00:15 +08:00
|
|
|
return obj.tables
|
2024-02-15 01:52:58 +08:00
|
|
|
.map((table) => {
|
|
|
|
const inlineFK = getInlineFK(table, obj);
|
|
|
|
return `${
|
|
|
|
table.comment === "" ? "" : `/* ${table.comment} */\n`
|
|
|
|
}CREATE TABLE IF NOT EXISTS "${table.name}" (\n${table.fields
|
|
|
|
.map(
|
|
|
|
(field) =>
|
|
|
|
`${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t"${
|
|
|
|
field.name
|
|
|
|
}" ${getSQLiteType(field)}${field.notNull ? " NOT NULL" : ""}${
|
|
|
|
field.unique ? " UNIQUE" : ""
|
2024-04-10 09:57:07 +08:00
|
|
|
}${field.default !== "" ? ` DEFAULT ${parseDefault(field)}` : ""}${
|
2024-02-15 01:52:58 +08:00
|
|
|
field.check === "" || !hasCheck(field.type)
|
|
|
|
? ""
|
|
|
|
: ` CHECK(${field.check})`
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join(",\n")}${
|
|
|
|
table.fields.filter((f) => f.primary).length > 0
|
|
|
|
? `,\n\tPRIMARY KEY(${table.fields
|
|
|
|
.filter((f) => f.primary)
|
|
|
|
.map((f) => `"${f.name}"`)
|
|
|
|
.join(", ")})${inlineFK !== "" ? ",\n" : ""}`
|
|
|
|
: ""
|
|
|
|
}\t${inlineFK}\n);\n${
|
|
|
|
table.indices.length > 0
|
|
|
|
? `${table.indices
|
|
|
|
.map(
|
|
|
|
(i) =>
|
|
|
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX IF NOT EXISTS "${
|
|
|
|
i.name
|
|
|
|
}"\nON "${table.name}" (${i.fields
|
|
|
|
.map((f) => `"${f}"`)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}`
|
|
|
|
: ""
|
|
|
|
}`;
|
|
|
|
})
|
|
|
|
.join("\n");
|
2024-01-31 23:00:15 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function jsonToMariaDB(obj) {
|
2024-02-05 19:40:59 +08:00
|
|
|
return `${obj.tables
|
|
|
|
.map(
|
|
|
|
(table) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${
|
|
|
|
table.comment === "" ? "" : `/* ${table.comment} */\n`
|
2024-02-05 19:40:59 +08:00
|
|
|
}CREATE OR REPLACE TABLE \`${table.name}\` (\n${table.fields
|
|
|
|
.map(
|
|
|
|
(field) =>
|
2024-02-15 01:52:58 +08:00
|
|
|
`${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t\`${
|
|
|
|
field.name
|
|
|
|
}\` ${getTypeString(field)}${field.notNull ? " NOT NULL" : ""}${
|
|
|
|
field.increment ? " AUTO_INCREMENT" : ""
|
|
|
|
}${field.unique ? " UNIQUE" : ""}${
|
2024-04-10 09:57:07 +08:00
|
|
|
field.default !== "" ? ` DEFAULT ${parseDefault(field)}` : ""
|
2024-02-15 01:52:58 +08:00
|
|
|
}${
|
|
|
|
field.check === "" || !hasCheck(field.type)
|
|
|
|
? !sqlDataTypes.includes(field.type)
|
|
|
|
? ` CHECK(\n\t\tJSON_SCHEMA_VALID('${generateSchema(
|
|
|
|
obj.types.find(
|
2024-04-10 09:57:07 +08:00
|
|
|
(t) => t.name === field.type.toLowerCase(),
|
|
|
|
),
|
2024-02-15 01:52:58 +08:00
|
|
|
)}', \`${field.name}\`))`
|
|
|
|
: ""
|
|
|
|
: ` CHECK(${field.check})`
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2024-02-05 19:40:59 +08:00
|
|
|
)
|
2024-02-15 01:52:58 +08:00
|
|
|
.join(",\n")}${
|
|
|
|
table.fields.filter((f) => f.primary).length > 0
|
2024-02-05 19:40:59 +08:00
|
|
|
? `,\n\tPRIMARY KEY(${table.fields
|
2024-02-15 01:52:58 +08:00
|
|
|
.filter((f) => f.primary)
|
|
|
|
.map((f) => `\`${f.name}\``)
|
|
|
|
.join(", ")})`
|
|
|
|
: ""
|
|
|
|
}\n);${
|
|
|
|
table.indices.length > 0
|
|
|
|
? `\n${table.indices.map(
|
|
|
|
(i) =>
|
|
|
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX \`${
|
|
|
|
i.name
|
|
|
|
}\`\nON \`${table.name}\` (${i.fields
|
|
|
|
.map((f) => `\`${f}\``)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)}`
|
2024-02-05 19:40:59 +08:00
|
|
|
: ""
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2024-02-05 19:40:59 +08:00
|
|
|
)
|
|
|
|
.join("\n")}\n${obj.references
|
2024-02-15 01:52:58 +08:00
|
|
|
.map(
|
|
|
|
(r) =>
|
|
|
|
`ALTER TABLE \`${
|
|
|
|
obj.tables[r.startTableId].name
|
|
|
|
}\`\nADD FOREIGN KEY(\`${
|
|
|
|
obj.tables[r.startTableId].fields[r.startFieldId].name
|
|
|
|
}\`) REFERENCES \`${obj.tables[r.endTableId].name}\`(\`${
|
|
|
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
2024-04-10 09:57:07 +08:00
|
|
|
}\`)\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}`;
|
2024-02-05 19:40:59 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function jsonToSQLServer(obj) {
|
2024-02-15 01:52:58 +08:00
|
|
|
return `${obj.types
|
|
|
|
.map((type) => {
|
|
|
|
return `${
|
|
|
|
type.comment === "" ? "" : `/**\n${type.comment}\n*/\n`
|
|
|
|
}CREATE TYPE [${type.name}] FROM ${
|
|
|
|
type.fields.length < 0
|
|
|
|
? ""
|
|
|
|
: `${getTypeString(type.fields[0], "mssql", true)}`
|
|
|
|
};\nGO\n`;
|
|
|
|
})
|
|
|
|
.join("\n")}\n${obj.tables
|
|
|
|
.map(
|
|
|
|
(table) =>
|
|
|
|
`${
|
|
|
|
table.comment === "" ? "" : `/**\n${table.comment}\n*/\n`
|
|
|
|
}CREATE TABLE [${table.name}] (\n${table.fields
|
|
|
|
.map(
|
|
|
|
(field) =>
|
|
|
|
`${field.comment === "" ? "" : `\t-- ${field.comment}\n`}\t[${
|
|
|
|
field.name
|
|
|
|
}] ${getTypeString(field, "mssql")}${
|
|
|
|
field.notNull ? " NOT NULL" : ""
|
|
|
|
}${field.increment ? " IDENTITY" : ""}${
|
|
|
|
field.unique ? " UNIQUE" : ""
|
|
|
|
}${
|
2024-04-10 09:57:07 +08:00
|
|
|
field.default !== "" ? ` DEFAULT ${parseDefault(field)}` : ""
|
2024-02-15 01:52:58 +08:00
|
|
|
}${
|
|
|
|
field.check === "" || !hasCheck(field.type)
|
|
|
|
? ""
|
|
|
|
: ` CHECK(${field.check})`
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join(",\n")}${
|
|
|
|
table.fields.filter((f) => f.primary).length > 0
|
|
|
|
? `,\n\tPRIMARY KEY(${table.fields
|
|
|
|
.filter((f) => f.primary)
|
|
|
|
.map((f) => `[${f.name}]`)
|
|
|
|
.join(", ")})`
|
|
|
|
: ""
|
|
|
|
}\n);\nGO\n${
|
|
|
|
table.indices.length > 0
|
|
|
|
? `${table.indices.map(
|
|
|
|
(i) =>
|
|
|
|
`\nCREATE ${i.unique ? "UNIQUE " : ""}INDEX [${
|
|
|
|
i.name
|
|
|
|
}]\nON [${table.name}] (${i.fields
|
|
|
|
.map((f) => `[${f}]`)
|
2024-04-10 09:57:07 +08:00
|
|
|
.join(", ")});\nGO\n`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)}`
|
|
|
|
: ""
|
2024-04-10 09:57:07 +08:00
|
|
|
}`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}\n${obj.references
|
|
|
|
.map(
|
|
|
|
(r) =>
|
|
|
|
`ALTER TABLE [${obj.tables[r.startTableId].name}]\nADD FOREIGN KEY([${
|
|
|
|
obj.tables[r.startTableId].fields[r.startFieldId].name
|
|
|
|
}]) REFERENCES [${obj.tables[r.endTableId].name}]([${
|
|
|
|
obj.tables[r.endTableId].fields[r.endFieldId].name
|
2024-04-10 09:57:07 +08:00
|
|
|
}])\nON UPDATE ${r.updateConstraint.toUpperCase()} ON DELETE ${r.deleteConstraint.toUpperCase()};\nGO`,
|
2024-02-15 01:52:58 +08:00
|
|
|
)
|
|
|
|
.join("\n")}`;
|
2024-02-06 06:42:11 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function isSized(type) {
|
2024-02-15 01:52:58 +08:00
|
|
|
return ["CHAR", "VARCHAR", "BINARY", "VARBINARY", "TEXT"].includes(type);
|
2023-09-19 20:51:22 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function hasPrecision(type) {
|
2024-01-18 18:45:58 +08:00
|
|
|
return ["DOUBLE", "NUMERIC", "DECIMAL", "FLOAT"].includes(type);
|
2023-09-19 20:51:22 +08:00
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function hasCheck(type) {
|
2023-09-19 20:51:25 +08:00
|
|
|
return [
|
|
|
|
"INT",
|
|
|
|
"SMALLINT",
|
|
|
|
"BIGINT",
|
|
|
|
"CHAR",
|
|
|
|
"VARCHAR",
|
|
|
|
"FLOAT",
|
|
|
|
"DECIMAL",
|
|
|
|
"DOUBLE",
|
|
|
|
"NUMERIC",
|
|
|
|
"REAL",
|
|
|
|
].includes(type);
|
|
|
|
}
|
|
|
|
|
2024-03-16 02:55:43 +08:00
|
|
|
export function getSize(type) {
|
2023-09-19 20:51:22 +08:00
|
|
|
switch (type) {
|
|
|
|
case "CHAR":
|
|
|
|
case "BINARY":
|
|
|
|
return 1;
|
|
|
|
case "VARCHAR":
|
|
|
|
case "VARBINARY":
|
|
|
|
return 255;
|
|
|
|
case "TEXT":
|
|
|
|
return 65535;
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|