Catch empty or duplacate fields, indices, names, relationships

This commit is contained in:
1ilit 2023-09-19 15:51:16 +03:00
parent 794ecdba08
commit 1016c3536e
4 changed files with 81 additions and 14 deletions

View File

@ -337,8 +337,10 @@ export default function Canvas(props) {
endFieldId: onRect.field,
endX: tables[onRect.tableId].x + 15,
endY: tables[onRect.tableId].y + onRect.field * 36 + 69,
name: `${tables[line.startTableId].name}_to_${
tables[onRect.tableId].name
name: `${tables[line.startTableId].name}_FK_${
tables[line.startTableId].fields[line.startFieldId].name
}_to_${
tables[onRect.tableId].fields[onRect.field].name
}`,
id: relationships.length,
});

View File

@ -1,5 +1,5 @@
import React, { useContext, useState, useEffect } from "react";
import { Collapse } from "@douyinfe/semi-ui";
import { Collapse, Badge } from "@douyinfe/semi-ui";
import { SettingsContext, TableContext } from "../pages/editor";
import { validateDiagram, arrayIsEqual } from "../utils";
@ -27,10 +27,17 @@ export default function Issues() {
<Collapse style={{ width: "100%" }}>
<Collapse.Panel
header={
<div>
<i className="fa-solid fa-triangle-exclamation me-1 text-yellow-500"></i>{" "}
Issues
</div>
<Badge
type={issues.length > 0 ? "danger" : "primary"}
count={settings.strictMode ? null : issues.length}
overflowCount={99}
className="mt-1"
>
<div className="pe-3">
<i className="fa-solid fa-triangle-exclamation me-2 text-yellow-500"></i>
Issues
</div>
</Badge>
}
itemKey="1"
>
@ -39,14 +46,16 @@ export default function Issues() {
<div className="mb-1">
Strict mode is off so no issues will be displayed.
</div>
) : (
<div>
) : issues.length > 0 ? (
<>
{issues.map((e, i) => (
<div key={i} className="py-2">
{e}
</div>
))}
</div>
</>
) : (
<div>No issues were detected.</div>
)}
</div>
</Collapse.Panel>

View File

@ -13,9 +13,13 @@ export default function Relationship(props) {
r = Math.abs(y2 - y1) / 3;
if (r <= 2) {
if (x1 + tableWidth <= x2)
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${x2} ${y2}`;
return `M ${x1 + tableWidth - 2 * offsetX} ${y1} L ${x2 + 0.1} ${
y2 + 0.1
}`;
else if (x2 + tableWidth < x1)
return `M ${x2 + tableWidth - 2 * offsetX} ${y2} L ${x1} ${y1}`;
return `M ${x2 + tableWidth - 2 * offsetX} ${y2} L ${x1 + 0.1} ${
y1 + 0.1
}`;
}
}

View File

@ -120,11 +120,63 @@ function validateDiagram(diagram) {
const duplicateTableNames = {};
diagram.tables.forEach((table) => {
if (table.name === "") {
issues.push(`Declared a table with no name`);
}
if (duplicateTableNames[table.name]) {
issues.push(`Duplicate table name: "${table.name}"`);
issues.push(`Duplicate table by the name "${table.name}"`);
} else {
duplicateTableNames[table.name] = true;
}
const duplicateFieldNames = {};
let hasPrimaryKey = false;
table.fields.forEach((field) => {
if (field.primary) {
hasPrimaryKey = true;
}
if (field.name === "") {
issues.push(`Empty field name in table "${table.name}"`);
}
if (field.type === "") {
issues.push(`Empty field type in table "${table.name}"`);
}
if (duplicateFieldNames[field.name]) {
issues.push(`Duplicate table fields in table "${table.name}"`);
} else {
duplicateFieldNames[field.name] = true;
}
});
const duplicateIndices = {};
table.indices.forEach((index) => {
if (duplicateIndices[index.name]) {
issues.push(`Duplicate index by the name "${index.name}"`);
} else {
duplicateIndices[index.name] = true;
}
});
table.indices.forEach((index) => {
if (index.fields.length === 0) {
issues.push(`Empty index type in table "${table.name}"`);
}
});
if (!hasPrimaryKey) {
issues.push(`Table "${table.name}" has no primary key`);
}
});
const duplicateFKName = {};
diagram.relationships.forEach((relationship) => {
if (duplicateFKName[relationship.name]) {
issues.push(`Duplicate relationship by the name "${relationship.name}"`);
} else {
duplicateFKName[relationship.name] = true;
}
});
const visitedTables = new Set();