diff --git a/src/components/canvas.jsx b/src/components/canvas.jsx index 5cf59bc..2461271 100644 --- a/src/components/canvas.jsx +++ b/src/components/canvas.jsx @@ -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, }); diff --git a/src/components/issues.jsx b/src/components/issues.jsx index 6033e9d..bcb822a 100644 --- a/src/components/issues.jsx +++ b/src/components/issues.jsx @@ -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"; @@ -7,7 +7,7 @@ export default function Issues() { const { settings } = useContext(SettingsContext); const { tables, relationships } = useContext(TableContext); const [issues, setIssues] = useState([]); - + useEffect(() => { const findIssues = async () => { const newIssues = validateDiagram({ @@ -27,10 +27,17 @@ export default function Issues() { - {" "} - Issues - + 0 ? "danger" : "primary"} + count={settings.strictMode ? null : issues.length} + overflowCount={99} + className="mt-1" + > +
+ + Issues +
+
} itemKey="1" > @@ -39,14 +46,16 @@ export default function Issues() {
Strict mode is off so no issues will be displayed.
- ) : ( -
+ ) : issues.length > 0 ? ( + <> {issues.map((e, i) => (
{e}
))} -
+ + ) : ( +
No issues were detected.
)}
diff --git a/src/components/relationship.jsx b/src/components/relationship.jsx index 0a75339..e734fac 100644 --- a/src/components/relationship.jsx +++ b/src/components/relationship.jsx @@ -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 + }`; } } diff --git a/src/utils/index.js b/src/utils/index.js index c44debc..f00e645 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -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();