drawDB/src/utils/issues.js

240 lines
5.9 KiB
JavaScript
Raw Normal View History

2024-06-10 07:17:43 +08:00
import { dbToTypes } from "../data/datatypes";
import i18n from "../i18n/i18n";
2024-06-10 07:17:43 +08:00
import { isFunction } from "./utils";
2024-06-10 07:17:43 +08:00
function checkDefault(field, database) {
2024-03-12 19:52:01 +08:00
if (field.default === "") return true;
2024-04-24 16:49:00 +08:00
if (isFunction(field.default)) return true;
2024-04-24 23:37:50 +08:00
if (!field.notNull && field.default.toLowerCase() === "null") return true;
2024-07-04 07:10:24 +08:00
if (!dbToTypes[database][field.type].checkDefault) return true;
2024-06-30 20:38:25 +08:00
2024-06-10 07:17:43 +08:00
return dbToTypes[database][field.type].checkDefault(field);
2024-03-12 19:52:01 +08:00
}
2024-03-16 02:55:43 +08:00
export function getIssues(diagram) {
2024-03-12 19:52:01 +08:00
const issues = [];
const duplicateTableNames = {};
diagram.tables.forEach((table) => {
if (table.name === "") {
issues.push(i18n.t("table_w_no_name"));
2024-03-12 19:52:01 +08:00
}
if (duplicateTableNames[table.name]) {
issues.push(i18n.t("duplicate_table_by_name", { tableName: table.name }));
2024-03-12 19:52:01 +08:00
} else {
duplicateTableNames[table.name] = true;
}
const duplicateFieldNames = {};
let hasPrimaryKey = false;
table.fields.forEach((field) => {
if (field.primary) {
hasPrimaryKey = true;
}
if (field.name === "") {
issues.push(i18n.t("empty_field_name", { tableName: table.name }));
2024-03-12 19:52:01 +08:00
}
if (field.type === "") {
issues.push(i18n.t("empty_field_type", { tableName: table.name }));
2024-03-12 19:52:01 +08:00
} else if (field.type === "ENUM" || field.type === "SET") {
if (!field.values || field.values.length === 0) {
issues.push(
i18n.t("no_values_for_field", {
tableName: table.name,
fieldName: field.name,
type: field.type,
}),
2024-03-12 19:52:01 +08:00
);
}
}
2024-06-10 07:17:43 +08:00
if (!checkDefault(field, diagram.database)) {
2024-03-12 19:52:01 +08:00
issues.push(
i18n.t("default_doesnt_match_type", {
tableName: table.name,
fieldName: field.name,
}),
2024-03-12 19:52:01 +08:00
);
}
if (field.notNull && field.default.toLowerCase() === "null") {
issues.push(
i18n.t("not_null_is_null", {
tableName: table.name,
fieldName: field.name,
}),
2024-03-12 19:52:01 +08:00
);
}
if (duplicateFieldNames[field.name]) {
issues.push(
i18n.t("duplicate_fields", {
tableName: table.name,
fieldName: field.name,
}),
);
2024-03-12 19:52:01 +08:00
} else {
duplicateFieldNames[field.name] = true;
}
});
const duplicateIndices = {};
table.indices.forEach((index) => {
if (duplicateIndices[index.name]) {
issues.push(
i18n.t("duplicate_index", {
tableName: table.name,
indexName: index.name,
}),
);
2024-03-12 19:52:01 +08:00
} else {
duplicateIndices[index.name] = true;
}
});
table.indices.forEach((index) => {
2024-06-07 19:18:05 +08:00
if (index.name.trim() === "") {
issues.push(
i18n.t("empty_index_name", {
tableName: table.name,
}),
);
}
2024-03-12 19:52:01 +08:00
if (index.fields.length === 0) {
issues.push(
i18n.t("empty_index", {
tableName: table.name,
}),
);
2024-03-12 19:52:01 +08:00
}
});
if (!hasPrimaryKey) {
issues.push(i18n.t("no_primary_key", { tableName: table.name }));
2024-03-12 19:52:01 +08:00
}
});
const duplicateTypeNames = {};
diagram.types.forEach((type) => {
if (type.name === "") {
issues.push(i18n.t("type_with_no_name"));
2024-03-12 19:52:01 +08:00
}
if (duplicateTypeNames[type.name]) {
issues.push(i18n.t("duplicate_types", { typeName: type.name }));
2024-03-12 19:52:01 +08:00
} else {
duplicateTypeNames[type.name] = true;
}
if (type.fields.length === 0) {
issues.push(i18n.t("type_w_no_fields", { typeName: type.name }));
2024-03-12 19:52:01 +08:00
return;
}
const duplicateFieldNames = {};
type.fields.forEach((field) => {
if (field.name === "") {
issues.push(
i18n.t("empty_type_field_name", {
typeName: type.name,
}),
);
2024-03-12 19:52:01 +08:00
}
if (field.type === "") {
issues.push(
i18n.t("empty_type_field_type", {
typeName: type.name,
}),
);
2024-03-12 19:52:01 +08:00
} else if (field.type === "ENUM" || field.type === "SET") {
if (!field.values || field.values.length === 0) {
issues.push(
i18n.t("no_values_for_type_field", {
typeName: type.name,
fieldName: field.name,
type: field.type,
}),
2024-03-12 19:52:01 +08:00
);
}
}
if (duplicateFieldNames[field.name]) {
i18n.t("duplicate_type_fields", {
typeName: type.name,
fieldName: field.name,
});
2024-03-12 19:52:01 +08:00
} else {
duplicateFieldNames[field.name] = true;
}
});
});
2024-07-04 07:10:24 +08:00
const duplicateEnumNames = {};
diagram.enums.forEach((e) => {
if (e.name === "") {
issues.push(i18n.t("enum_w_no_name"));
}
if (duplicateEnumNames[e.name]) {
issues.push(i18n.t("duplicate_enums", { enumName: e.name }));
} else {
duplicateEnumNames[e.name] = true;
}
if (e.values.length === 0) {
issues.push(i18n.t("enum_w_no_values", { enumName: e.name }));
return;
}
});
2024-03-12 19:52:01 +08:00
const duplicateFKName = {};
diagram.relationships.forEach((r) => {
if (duplicateFKName[r.name]) {
issues.push(
i18n.t("duplicate_reference", {
refName: r.name,
}),
);
2024-03-12 19:52:01 +08:00
} else {
duplicateFKName[r.name] = true;
}
});
const visitedTables = new Set();
function checkCircularRelationships(tableId, visited = []) {
if (visited.includes(tableId)) {
issues.push(
i18n.t("circular_dependency", {
refName: diagram.tables[tableId].name,
}),
2024-03-12 19:52:01 +08:00
);
return;
}
visited.push(tableId);
visitedTables.add(tableId);
diagram.relationships.forEach((r) => {
if (r.startTableId === tableId && r.startTableId !== r.endTableId) {
checkCircularRelationships(r.endTableId, [...visited]);
}
});
}
diagram.tables.forEach((table) => {
if (!visitedTables.has(table.id)) {
checkCircularRelationships(table.id);
}
});
return issues;
}