Some final fixes based on comments, adding foreign key type checking for through tables.

This commit is contained in:
mike12345567 2023-02-02 17:25:02 +00:00
parent 2807fbd4b6
commit 01edfba90e
2 changed files with 60 additions and 40 deletions

View File

@ -65,16 +65,8 @@
$: isManyToOne = relationshipType === RelationshipTypes.MANY_TO_ONE $: isManyToOne = relationshipType === RelationshipTypes.MANY_TO_ONE
$: toRelationship.relationshipType = fromRelationship?.relationshipType $: toRelationship.relationshipType = fromRelationship?.relationshipType
function getFromTable() { function getTable(id) {
return plusTables.find(table => table._id === fromId) return plusTables.find(table => table._id === id)
}
function getToTable() {
return plusTables.find(table => table._id === toId)
}
function getThroughTable() {
return plusTables.find(table => table._id === throughId)
} }
function invalidThroughTable() { function invalidThroughTable() {
@ -97,16 +89,16 @@
if ( if (
originalFromTable && originalFromTable &&
originalToTable && originalToTable &&
originalFromTable === getFromTable() && originalFromTable === getTable(fromId) &&
originalToTable === getToTable() originalToTable === getTable(toId)
) { ) {
return false return false
} }
let fromThroughLinks = Object.values( let fromThroughLinks = Object.values(
datasource.entities[getFromTable().name].schema datasource.entities[getTable(fromId).name].schema
).filter(value => value.through) ).filter(value => value.through)
let toThroughLinks = Object.values( let toThroughLinks = Object.values(
datasource.entities[getToTable().name].schema datasource.entities[getTable(toId).name].schema
).filter(value => value.through) ).filter(value => value.through)
const matchAgainstUserInput = (fromTableId, toTableId) => const matchAgainstUserInput = (fromTableId, toTableId) =>
@ -127,11 +119,11 @@
} }
function allRequiredAttributesSet() { function allRequiredAttributesSet() {
const base = getFromTable() && getToTable() && fromColumn && toColumn const base = getTable(fromId) && getTable(toId) && fromColumn && toColumn
if (relationshipType === RelationshipTypes.MANY_TO_ONE) { if (relationshipType === RelationshipTypes.MANY_TO_ONE) {
return base && fromPrimary && fromForeign return base && fromPrimary && fromForeign
} else { } else {
return base && getThroughTable() && throughFromKey && throughToKey return base && getTable(throughId) && throughFromKey && throughToKey
} }
} }
@ -141,9 +133,9 @@
} }
hasValidated = true hasValidated = true
errorChecker.setType(relationshipType) errorChecker.setType(relationshipType)
const fromTable = getFromTable(), const fromTable = getTable(fromId),
toTable = getToTable(), toTable = getTable(toId),
throughTable = getThroughTable() throughTable = getTable(throughId)
errors = { errors = {
relationshipType: errorChecker.relationshipTypeSet(relationshipType), relationshipType: errorChecker.relationshipTypeSet(relationshipType),
fromTable: fromTable:
@ -158,8 +150,22 @@
errorChecker.throughTableSet(throughTable) || errorChecker.throughTableSet(throughTable) ||
errorChecker.throughIsNullable() || errorChecker.throughIsNullable() ||
errorChecker.differentTables(throughId, fromId, toId), errorChecker.differentTables(throughId, fromId, toId),
throughFromKey: errorChecker.manyForeignKeySet(throughFromKey), throughFromKey:
throughToKey: errorChecker.manyForeignKeySet(throughToKey), errorChecker.manyForeignKeySet(throughFromKey) ||
errorChecker.manyTypeMismatch(
fromTable,
throughTable,
fromTable.primary[0],
throughFromKey
),
throughToKey:
errorChecker.manyForeignKeySet(throughToKey) ||
errorChecker.manyTypeMismatch(
toTable,
throughTable,
toTable.primary[0],
throughToKey
),
fromForeign: fromForeign:
errorChecker.foreignKeySet(fromForeign) || errorChecker.foreignKeySet(fromForeign) ||
errorChecker.typeMismatch(fromTable, toTable, fromPrimary, fromForeign), errorChecker.typeMismatch(fromTable, toTable, fromPrimary, fromForeign),
@ -216,13 +222,13 @@
if (manyToMany) { if (manyToMany) {
relateFrom = { relateFrom = {
...relateFrom, ...relateFrom,
through: getThroughTable()._id, through: getTable(throughId)._id,
fieldName: getToTable().primary[0], fieldName: getTable(toId).primary[0],
} }
relateTo = { relateTo = {
...relateTo, ...relateTo,
through: getThroughTable()._id, through: getTable(throughId)._id,
fieldName: getFromTable().primary[0], fieldName: getTable(fromId).primary[0],
throughFrom: relateFrom.throughTo, throughFrom: relateFrom.throughTo,
throughTo: relateFrom.throughFrom, throughTo: relateFrom.throughFrom,
} }
@ -271,10 +277,10 @@
removeExistingRelationship() removeExistingRelationship()
// source of relationship // source of relationship
datasource.entities[getFromTable().name].schema[fromRelationship.name] = datasource.entities[getTable(fromId).name].schema[fromRelationship.name] =
fromRelationship fromRelationship
// save other side of relationship in the other schema // save other side of relationship in the other schema
datasource.entities[getToTable().name].schema[toRelationship.name] = datasource.entities[getTable(toId).name].schema[toRelationship.name] =
toRelationship toRelationship
await save() await save()
@ -351,8 +357,8 @@
{/if} {/if}
{#if isManyToOne && fromId} {#if isManyToOne && fromId}
<Select <Select
label={`Primary Key (${getFromTable().name})`} label={`Primary Key (${getTable(fromId).name})`}
options={Object.keys(getFromTable().schema)} options={Object.keys(getTable(fromId).schema)}
bind:value={fromPrimary} bind:value={fromPrimary}
bind:error={errors.fromPrimary} bind:error={errors.fromPrimary}
on:change={changed} on:change={changed}
@ -384,8 +390,8 @@
/> />
{#if fromId && toId && throughId} {#if fromId && toId && throughId}
<Select <Select
label={`Foreign Key (${getFromTable()?.name})`} label={`Foreign Key (${getTable(fromId)?.name})`}
options={Object.keys(getThroughTable()?.schema)} options={Object.keys(getTable(throughId)?.schema)}
bind:value={throughToKey} bind:value={throughToKey}
bind:error={errors.throughToKey} bind:error={errors.throughToKey}
on:change={e => on:change={e =>
@ -396,8 +402,8 @@
})} })}
/> />
<Select <Select
label={`Foreign Key (${getToTable()?.name})`} label={`Foreign Key (${getTable(toId)?.name})`}
options={Object.keys(getThroughTable()?.schema)} options={Object.keys(getTable(throughId)?.schema)}
bind:value={throughFromKey} bind:value={throughFromKey}
bind:error={errors.throughFromKey} bind:error={errors.throughFromKey}
on:change={e => on:change={e =>
@ -410,8 +416,8 @@
{/if} {/if}
{:else if isManyToOne && toId} {:else if isManyToOne && toId}
<Select <Select
label={`Foreign Key (${getToTable()?.name})`} label={`Foreign Key (${getTable(toId)?.name})`}
options={Object.keys(getToTable()?.schema)} options={Object.keys(getTable(toId)?.schema)}
bind:value={fromForeign} bind:value={fromForeign}
bind:error={errors.fromForeign} bind:error={errors.fromForeign}
on:change={changed} on:change={changed}

View File

@ -20,6 +20,15 @@ function isColumnNameBeingUsed(table, columnName, originalName) {
return keys.indexOf(columnName.toLowerCase()) !== -1 return keys.indexOf(columnName.toLowerCase()) !== -1
} }
function typeMismatchCheck(fromTable, toTable, primary, foreign) {
let fromType, toType
if (primary && foreign) {
fromType = fromTable?.schema[primary]?.type
toType = toTable?.schema[foreign]?.type
}
return fromType && toType && fromType !== toType ? typeMismatch : null
}
export class RelationshipErrorChecker { export class RelationshipErrorChecker {
constructor(invalidThroughTableFn, relationshipExistsFn) { constructor(invalidThroughTableFn, relationshipExistsFn) {
this.invalidThroughTable = invalidThroughTableFn this.invalidThroughTable = invalidThroughTableFn
@ -79,11 +88,16 @@ export class RelationshipErrorChecker {
} }
typeMismatch(fromTable, toTable, primary, foreign) { typeMismatch(fromTable, toTable, primary, foreign) {
let fromType, toType if (this.isMany()) {
if (primary && foreign) { return null
fromType = fromTable?.schema[primary]?.type
toType = toTable?.schema[foreign]?.type
} }
return fromType && toType && fromType !== toType ? typeMismatch : null return typeMismatchCheck(fromTable, toTable, primary, foreign)
}
manyTypeMismatch(table, throughTable, primary, foreign) {
if (!this.isMany()) {
return null
}
return typeMismatchCheck(table, throughTable, primary, foreign)
} }
} }