From 66c13a2a77c9cc86f3d16adbc15599a4239c5acd Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 11:47:09 +0000 Subject: [PATCH 01/14] Try to match primary key or take first --- .../backend/Datasources/CreateEditRelationship.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index ec39cc6d71..d83f3bf9a7 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -127,7 +127,10 @@ let fromPrimary $: { if (!fromPrimary && fromTable) { - fromPrimary = fromTable.primary[0] + const relationshipKey = fromRelationship?.fieldName + fromPrimary = + fromTable.primary.filter(val => val === relationshipKey)[0] || + fromTable.primary[0] } } $: isManyToMany = From d7ae20ce2193498827d5039bbb1273ca50b3f4dd Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 12:41:41 +0000 Subject: [PATCH 02/14] Use foreign key instead of parimary[0] --- .../backend/Datasources/CreateEditRelationship.svelte | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index d83f3bf9a7..74bba33baa 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -127,10 +127,7 @@ let fromPrimary $: { if (!fromPrimary && fromTable) { - const relationshipKey = fromRelationship?.fieldName - fromPrimary = - fromTable.primary.filter(val => val === relationshipKey)[0] || - fromTable.primary[0] + fromPrimary = fromRelationship?.foreignKey } } $: isManyToMany = From dfd6575aeab8cb2febfc80e96d331f704a4ac9b6 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 15:01:21 +0000 Subject: [PATCH 03/14] Validation improvements --- .../Datasources/CreateEditRelationship.svelte | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 74bba33baa..b18809e980 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -84,10 +84,10 @@ errObj.foreign = "Please pick the foreign key" } const colNotSet = "Please specify a column name" - if ($touched.fromCol && !fromRelate.name) { + if ($touched.fromCol && !toRelate.name) { errObj.fromCol = colNotSet } - if ($touched.toCol && !toRelate.name) { + if ($touched.toCol && !fromRelate.name) { errObj.toCol = colNotSet } if ($touched.primary && !fromPrimary) { @@ -143,7 +143,10 @@ $: through = plusTables.find(table => table._id === fromRelationship?.through) $: checkForErrors(fromRelationship, toRelationship) $: valid = - Object.keys(errors).length === 0 && Object.keys($touched).length !== 0 + Object.keys(errors).length === 0 && + Object.keys($touched).length !== 0 && + fromTable && + toTable $: linkTable = through || toTable $: relationshipTypes = [ { @@ -293,7 +296,10 @@ label="Select from table" options={tableOptions} disabled={!!selectedFromTable} - on:change={() => ($touched.from = true)} + on:change={() => { + $touched.from = true + $touched.primary = true + }} bind:error={errors.from} bind:value={toRelationship.tableId} /> @@ -309,7 +315,10 @@ ($touched.through = true)} + on:change={() => { + $touched.through = true + $touched.fromForeign = true + $touched.toForeign = true + }} bind:error={errors.through} bind:value={fromRelationship.through} /> @@ -355,15 +368,17 @@ ($touched.fromCol = true)} + on:change={() => ($touched.fromCol = true)} bind:error={errors.fromCol} label="From table column" - bind:value={fromRelationship.name} + bind:value={toRelationship.name} /> ($touched.toCol = true)} + on:change={() => ($touched.toCol = true)} bind:error={errors.toCol} label="To table column" - bind:value={toRelationship.name} + bind:value={fromRelationship.name} />
{#if originalFromName != null} From 889376003d7750a4464fc4bf3adc3755f9bc36f9 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 16:18:46 +0000 Subject: [PATCH 04/14] Use original relationship names on delete --- .../backend/Datasources/CreateEditRelationship.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index b18809e980..426f1ad289 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -254,8 +254,8 @@ } async function deleteRelationship() { - delete datasource.entities[fromTable.name].schema[fromRelationship.name] - delete datasource.entities[toTable.name].schema[toRelationship.name] + delete datasource.entities[fromTable.name].schema[originalFromName] + delete datasource.entities[toTable.name].schema[originalToName] await save() await tables.fetch() close() From 5be6c241b7e312f68d298011b11eef6ed100d476 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 16:42:29 +0000 Subject: [PATCH 05/14] Use original table names in delete --- .../backend/Datasources/CreateEditRelationship.svelte | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 426f1ad289..078bf093ef 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -22,6 +22,12 @@ let originalFromName = fromRelationship.name, originalToName = toRelationship.name + let originalFromTable = plusTables.find( + table => table._id === toRelationship?.tableId + ) + let originalToTable = plusTables.find( + table => table._id === fromRelationship?.tableId + ) let fromTable, toTable, through, linkTable, tableOptions let isManyToMany, isManyToOne, relationshipTypes let errors, valid @@ -254,8 +260,8 @@ } async function deleteRelationship() { - delete datasource.entities[fromTable.name].schema[originalFromName] - delete datasource.entities[toTable.name].schema[originalToName] + delete datasource.entities[originalFromTable.name].schema[originalFromName] + delete datasource.entities[originalToTable.name].schema[originalToName] await save() await tables.fetch() close() From db29b131eb10f1e6968758ad8d6cbd8e96ffb632 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 17:22:04 +0000 Subject: [PATCH 06/14] Delete original relationship if table changes --- .../Datasources/CreateEditRelationship.svelte | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 078bf093ef..6263a3925a 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -267,13 +267,21 @@ close() } + function hasTableChanged(fromTbl, toTbl) { + const areRelationshipsSet = + (originalFromName || originalToName) && + originalFromTable?.name === fromTbl?.name && + originalToTable?.name === toTbl?.name + + return ( + currentTables?.from?._id !== fromTbl?._id || + currentTables?.to?._id !== toTbl?._id || + !areRelationshipsSet + ) + } + function tableChanged(fromTbl, toTbl) { - if ( - (currentTables?.from?._id === fromTbl?._id && - currentTables?.to?._id === toTbl?._id) || - originalFromName || - originalToName - ) { + if (!hasTableChanged(fromTbl, toTbl)) { return } fromRelationship.name = toTbl?.name || "" From 30905d35efca86013727435d0dbbc65596ca5d5c Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Fri, 13 Jan 2023 18:14:34 +0000 Subject: [PATCH 07/14] Remove existing relationships if table changed --- .../Datasources/CreateEditRelationship.svelte | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 6263a3925a..1be842280f 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -245,12 +245,22 @@ datasource.entities[toTable.name].schema[toRelationship.name] = toRelationship - // If relationship has been renamed - if (originalFromName !== fromRelationship.name) { - delete datasource.entities[fromTable.name].schema[originalFromName] + // If relationship has been renamed or a different table selected + if ( + originalFromTable?.name && + (originalFromName !== fromRelationship.name || + hasTableChanged(fromTable, toTable)) + ) { + delete datasource.entities[originalFromTable.name].schema[ + originalFromName + ] } - if (originalToName !== toRelationship.name) { - delete datasource.entities[toTable.name].schema[originalToName] + if ( + originalToTable?.name && + (originalToName !== toRelationship.name || + hasTableChanged(fromTable, toTable)) + ) { + delete datasource.entities[originalToTable.name].schema[originalToName] } // store the original names so it won't cause an error From b4dcdfa84f709d2a4d3a569ed26270fc58fe7b9e Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 14:14:29 +0000 Subject: [PATCH 08/14] Update through table error message --- .../backend/Datasources/CreateEditRelationship.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 1be842280f..d2f707a6e0 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -83,8 +83,7 @@ errObj.through = tableNotSet } if ($touched.through && invalidThroughTable(fromRelate)) { - errObj.through = - "Ensure all columns in table are nullable or auto generated" + errObj.through = "Ensure non-key columns are nullable or auto-generated" } if ($touched.foreign && !isMany && !fromRelate.fieldName) { errObj.foreign = "Please pick the foreign key" From 50e571c1de3e86a156589223537ee935f599687c Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 14:29:47 +0000 Subject: [PATCH 09/14] Ignore primary touched if isMany --- .../backend/Datasources/CreateEditRelationship.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index d2f707a6e0..2000d45dde 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -95,7 +95,7 @@ if ($touched.toCol && !fromRelate.name) { errObj.toCol = colNotSet } - if ($touched.primary && !fromPrimary) { + if ($touched.primary && !isMany && !fromPrimary) { errObj.primary = "Please pick the primary key" } // currently don't support relationships back onto the table itself, needs to relate out @@ -152,6 +152,8 @@ Object.keys($touched).length !== 0 && fromTable && toTable + + $: console.log("Errors ", errors) $: linkTable = through || toTable $: relationshipTypes = [ { From a6e7ef398530e57b6b32596ce926f42349dd6464 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 14:38:26 +0000 Subject: [PATCH 10/14] Remove console log --- .../components/backend/Datasources/CreateEditRelationship.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 2000d45dde..7110374569 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -153,7 +153,6 @@ fromTable && toTable - $: console.log("Errors ", errors) $: linkTable = through || toTable $: relationshipTypes = [ { From fc73a2f3586180ceb9b720b432909f23f604a7d2 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 21:09:13 +0000 Subject: [PATCH 11/14] Saving. TODO - Validation --- .../CreateEditRelationshipCopy.svelte | 271 ++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte new file mode 100644 index 0000000000..5ab099e61b --- /dev/null +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte @@ -0,0 +1,271 @@ + + + + { + fromColumn = tableOptions.find(opt => opt.value === e.detail).label + }} + /> + {#if isManyToOne && fromTable} + { + toColumn = tableOptions.find(opt => opt.value === e.detail).label + }} + /> + {#if isManyToMany} + + + {/if} +
+ Column names +
+ + Budibase manages SQL relationships as a new column in the table, please + provide a name for these columns. + + + +
+ {#if originalFromColumnName != null} + + {/if} +
+
+ + From 8a4c0c6acd28e34f833d90bde5138021cee7342e Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 22:54:06 +0000 Subject: [PATCH 12/14] Overhaul of CreateEditRelationship modal --- .../Datasources/CreateEditRelationship.svelte | 417 +++++++++--------- 1 file changed, 211 insertions(+), 206 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 7110374569..1454408017 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -10,7 +10,6 @@ } from "@budibase/bbui" import { tables } from "stores/backend" import { Helpers } from "@budibase/bbui" - import { writable } from "svelte/store" export let save export let datasource @@ -18,47 +17,95 @@ export let fromRelationship = {} export let toRelationship = {} export let close - export let selectedFromTable - let originalFromName = fromRelationship.name, - originalToName = toRelationship.name + const colNotSet = "Please specify a column name" + const relationshipTypes = [ + { + label: "One to Many", + value: RelationshipTypes.MANY_TO_ONE, + }, + { + label: "Many to Many", + value: RelationshipTypes.MANY_TO_MANY, + }, + ] + + let originalFromColumnName = fromRelationship.name, + originalToColumnName = toRelationship.name let originalFromTable = plusTables.find( table => table._id === toRelationship?.tableId ) let originalToTable = plusTables.find( table => table._id === fromRelationship?.tableId ) - let fromTable, toTable, through, linkTable, tableOptions - let isManyToMany, isManyToOne, relationshipTypes - let errors, valid - let currentTables = {} - if (fromRelationship && !fromRelationship.relationshipType) { - fromRelationship.relationshipType = RelationshipTypes.MANY_TO_ONE - } + let tableOptions + let errors = {} + let hasClickedSave = !!fromRelationship.relationshipType + let fromPrimary, + fromForeign, + fromTable, + toTable, + throughTable, + fromColumn, + toColumn + let fromId, toId, throughId, throughToKey, throughFromKey + let isManyToMany, isManyToOne, relationshipType - if (toRelationship && selectedFromTable) { - toRelationship.tableId = selectedFromTable._id - } - - function inSchema(table, prop, ogName) { - if (!table || !prop || prop === ogName) { - return false + $: { + if (!fromPrimary) { + fromPrimary = fromRelationship.foreignKey + fromForeign = toRelationship.foreignKey + } + if (!fromColumn && !errors.fromColumn) { + fromColumn = toRelationship.name + } + if (!toColumn && !errors.toColumn) { + toColumn = fromRelationship.name + } + if (!fromId) { + fromId = toRelationship.tableId + } + if (!toId) { + toId = fromRelationship.tableId + } + if (!throughId) { + throughId = fromRelationship.through + throughFromKey = fromRelationship.throughFrom + throughToKey = fromRelationship.throughTo + } + if (!relationshipType) { + relationshipType = fromRelationship.relationshipType } - const keys = Object.keys(table.schema).map(key => key.toLowerCase()) - return keys.indexOf(prop.toLowerCase()) !== -1 } - const touched = writable({}) + $: tableOptions = plusTables.map(table => ({ + label: table.name, + value: table._id, + })) + $: valid = getErrorCount(errors) === 0 || !hasClickedSave - function invalidThroughTable({ through, throughTo, throughFrom }) { + $: isManyToMany = relationshipType === RelationshipTypes.MANY_TO_MANY + $: isManyToOne = relationshipType === RelationshipTypes.MANY_TO_ONE + $: fromTable = plusTables.find(table => table._id === fromId) + $: toTable = plusTables.find(table => table._id === toId) + $: throughTable = plusTables.find(table => table._id === throughId) + + $: toRelationship.relationshipType = fromRelationship?.relationshipType + + const getErrorCount = errors => + Object.entries(errors) + .filter(entry => !!entry[1]) + .map(entry => entry[0]).length + + function invalidThroughTable() { // need to know the foreign key columns to check error - if (!through || !throughTo || !throughFrom) { + if (!throughId || !throughToKey || !throughFromKey) { return false } - const throughTable = plusTables.find(tbl => tbl._id === through) - const otherColumns = Object.values(throughTable.schema).filter( - col => col.name !== throughFrom && col.name !== throughTo + const throughTbl = plusTables.find(tbl => tbl._id === throughId) + const otherColumns = Object.values(throughTbl.schema).filter( + col => col.name !== throughFromKey && col.name !== throughToKey ) for (let col of otherColumns) { if (col.constraints?.presence && !col.autocolumn) { @@ -68,145 +115,134 @@ return false } - function checkForErrors(fromRelate, toRelate) { - const isMany = - fromRelate.relationshipType === RelationshipTypes.MANY_TO_MANY + function validate() { + const isMany = relationshipType === RelationshipTypes.MANY_TO_MANY const tableNotSet = "Please specify a table" + const foreignKeyNotSet = "Please pick a foreign key" const errObj = {} - if ($touched.from && !fromTable) { - errObj.from = tableNotSet + if (!relationshipType) { + errObj.relationshipType = "Please specify a relationship type" } - if ($touched.to && !toTable) { - errObj.to = tableNotSet + if (!fromTable) { + errObj.fromTable = tableNotSet } - if ($touched.through && isMany && !fromRelate.through) { - errObj.through = tableNotSet + if (!toTable) { + errObj.toTable = tableNotSet } - if ($touched.through && invalidThroughTable(fromRelate)) { - errObj.through = "Ensure non-key columns are nullable or auto-generated" + if (isMany && !throughTable) { + errObj.throughTable = tableNotSet } - if ($touched.foreign && !isMany && !fromRelate.fieldName) { - errObj.foreign = "Please pick the foreign key" + if (isMany && !throughFromKey) { + errObj.throughFromKey = foreignKeyNotSet } - const colNotSet = "Please specify a column name" - if ($touched.fromCol && !toRelate.name) { - errObj.fromCol = colNotSet + if (isMany && !throughToKey) { + errObj.throughToKey = foreignKeyNotSet } - if ($touched.toCol && !fromRelate.name) { - errObj.toCol = colNotSet + if (invalidThroughTable()) { + errObj.throughTable = + "Ensure non-key columns are nullable or auto-generated" } - if ($touched.primary && !isMany && !fromPrimary) { - errObj.primary = "Please pick the primary key" + if (!isMany && !fromForeign) { + errObj.fromForeign = foreignKeyNotSet } + if (!fromColumn) { + errObj.fromColumn = colNotSet + } + if (!toColumn) { + errObj.toColumn = colNotSet + } + if (!isMany && !fromPrimary) { + errObj.fromPrimary = "Please pick the primary key" + } + // currently don't support relationships back onto the table itself, needs to relate out const tableError = "From/to/through tables must be different" - if (fromTable && (fromTable === toTable || fromTable === through)) { - errObj.from = tableError + if (fromTable && (fromTable === toTable || fromTable === throughTable)) { + errObj.fromTable = tableError } - if (toTable && (toTable === fromTable || toTable === through)) { - errObj.to = tableError + if (toTable && (toTable === fromTable || toTable === throughTable)) { + errObj.toTable = tableError } - if (through && (through === fromTable || through === toTable)) { - errObj.through = tableError + if ( + throughTable && + (throughTable === fromTable || throughTable === toTable) + ) { + errObj.throughTable = tableError } const colError = "Column name cannot be an existing column" - if (inSchema(fromTable, fromRelate.name, originalFromName)) { - errObj.fromCol = colError + if (isColumnNameBeingUsed(fromTable, fromColumn, originalFromColumnName)) { + errObj.fromColumn = colError } - if (inSchema(toTable, toRelate.name, originalToName)) { - errObj.toCol = colError + if (isColumnNameBeingUsed(toTable, toColumn, originalToColumnName)) { + errObj.toColumn = colError } let fromType, toType - if (fromPrimary && fromRelate.fieldName) { + if (fromPrimary && fromForeign) { fromType = fromTable?.schema[fromPrimary]?.type - toType = toTable?.schema[fromRelate.fieldName]?.type + toType = toTable?.schema[fromForeign]?.type } if (fromType && toType && fromType !== toType) { - errObj.foreign = + errObj.fromForeign = "Column type of the foreign key must match the primary key" } + errors = errObj + return getErrorCount(errors) === 0 } - let fromPrimary - $: { - if (!fromPrimary && fromTable) { - fromPrimary = fromRelationship?.foreignKey - } - } - $: isManyToMany = - fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_MANY - $: isManyToOne = - fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_ONE - $: tableOptions = plusTables.map(table => ({ - label: table.name, - value: table._id, - })) - $: fromTable = plusTables.find(table => table._id === toRelationship?.tableId) - $: toTable = plusTables.find(table => table._id === fromRelationship?.tableId) - $: through = plusTables.find(table => table._id === fromRelationship?.through) - $: checkForErrors(fromRelationship, toRelationship) - $: valid = - Object.keys(errors).length === 0 && - Object.keys($touched).length !== 0 && - fromTable && - toTable - - $: linkTable = through || toTable - $: relationshipTypes = [ - { - label: "Many", - value: RelationshipTypes.MANY_TO_MANY, - }, - { - label: "One", - value: RelationshipTypes.MANY_TO_ONE, - }, - ] - $: updateRelationshipType(fromRelationship?.relationshipType) - $: tableChanged(fromTable, toTable) - - function updateRelationshipType(fromType) { - if (fromType === RelationshipTypes.MANY_TO_MANY) { - toRelationship.relationshipType = RelationshipTypes.MANY_TO_MANY - } else { - toRelationship.relationshipType = RelationshipTypes.MANY_TO_ONE + function isColumnNameBeingUsed(table, columnName, originalName) { + if (!table || !columnName || columnName === originalName) { + return false } + const keys = Object.keys(table.schema).map(key => key.toLowerCase()) + return keys.indexOf(columnName.toLowerCase()) !== -1 } function buildRelationships() { - // if any to many only need to check from - const manyToMany = - fromRelationship.relationshipType === RelationshipTypes.MANY_TO_MANY - // main is simply used to know this is the side the user configured it from const id = Helpers.uuid() - if (!manyToMany) { - delete fromRelationship.through - delete toRelationship.through - } + //Map temporary variables let relateFrom = { ...fromRelationship, + tableId: toId, + name: toColumn, + relationshipType, + fieldName: fromForeign, + through: throughId, + throughFrom: throughFromKey, + throughTo: throughToKey, type: "link", main: true, _id: id, } - let relateTo = { + let relateTo = (toRelationship = { ...toRelationship, + tableId: fromId, + name: fromColumn, + through: throughId, type: "link", _id: id, + }) + + // if any to many only need to check from + const manyToMany = + relateFrom.relationshipType === RelationshipTypes.MANY_TO_MANY + + if (!manyToMany) { + delete relateFrom.through + delete relateTo.through } // [0] is because we don't support composite keys for relationships right now if (manyToMany) { relateFrom = { ...relateFrom, - through: through._id, + through: throughTable._id, fieldName: toTable.primary[0], } relateTo = { ...relateTo, - through: through._id, + through: throughTable._id, fieldName: fromTable.primary[0], throughFrom: relateFrom.throughTo, throughTo: relateFrom.throughFrom, @@ -235,9 +271,27 @@ toRelationship = relateTo } - // save the relationship on to the datasource + function removeExistingRelationship() { + if (originalFromTable && originalFromColumnName) { + delete datasource.entities[originalFromTable.name].schema[ + originalFromColumnName + ] + } + if (originalToTable && originalToColumnName) { + delete datasource.entities[originalToTable.name].schema[ + originalToColumnName + ] + } + } + async function saveRelationship() { + hasClickedSave = true + if (!validate()) { + return false + } buildRelationships() + removeExistingRelationship() + // source of relationship datasource.entities[fromTable.name].schema[fromRelationship.name] = fromRelationship @@ -245,61 +299,14 @@ datasource.entities[toTable.name].schema[toRelationship.name] = toRelationship - // If relationship has been renamed or a different table selected - if ( - originalFromTable?.name && - (originalFromName !== fromRelationship.name || - hasTableChanged(fromTable, toTable)) - ) { - delete datasource.entities[originalFromTable.name].schema[ - originalFromName - ] - } - if ( - originalToTable?.name && - (originalToName !== toRelationship.name || - hasTableChanged(fromTable, toTable)) - ) { - delete datasource.entities[originalToTable.name].schema[originalToName] - } - - // store the original names so it won't cause an error - originalToName = toRelationship.name - originalFromName = fromRelationship.name await save() } - async function deleteRelationship() { - delete datasource.entities[originalFromTable.name].schema[originalFromName] - delete datasource.entities[originalToTable.name].schema[originalToName] + removeExistingRelationship() await save() await tables.fetch() close() } - - function hasTableChanged(fromTbl, toTbl) { - const areRelationshipsSet = - (originalFromName || originalToName) && - originalFromTable?.name === fromTbl?.name && - originalToTable?.name === toTbl?.name - - return ( - currentTables?.from?._id !== fromTbl?._id || - currentTables?.to?._id !== toTbl?._id || - !areRelationshipsSet - ) - } - - function tableChanged(fromTbl, toTbl) { - if (!hasTableChanged(fromTbl, toTbl)) { - return - } - fromRelationship.name = toTbl?.name || "" - errors.fromCol = "" - toRelationship.name = fromTbl?.name || "" - errors.toCol = "" - currentTables = { from: fromTbl, to: toTbl } - } (errors.relationshipType = null)} />
Tables @@ -319,68 +328,64 @@ ($touched.primary = true)} - bind:error={errors.primary} + label={`Primary Key (${fromTable.name})`} + options={Object.keys(fromTable.schema)} bind:value={fromPrimary} + bind:error={errors.fromPrimary} + on:change={e => (errors.fromPrimary = null)} /> {/if} { - $touched.through = true - $touched.fromForeign = true - $touched.toForeign = true - }} - bind:error={errors.through} - bind:value={fromRelationship.through} + bind:value={throughId} + bind:error={errors.throughTable} /> - {#if fromTable && toTable && through} + {#if fromTable && toTable && throughTable} ($touched.toForeign = true)} - bind:error={errors.toForeign} - bind:value={fromRelationship.throughFrom} + options={Object.keys(throughTable?.schema)} + bind:value={throughFromKey} + bind:error={errors.throughFromKey} + on:change={e => (errors.throughFromKey = null)} /> {/if} {:else if isManyToOne && toTable} ($touched.fromCol = true)} - on:change={() => ($touched.fromCol = true)} - bind:error={errors.fromCol} label="From table column" - bind:value={toRelationship.name} + bind:value={fromColumn} + bind:error={errors.fromColumn} + on:change={e => { + errors.fromColumn = e.detail?.length > 0 ? null : colNotSet + }} /> ($touched.toCol = true)} - on:change={() => ($touched.toCol = true)} - bind:error={errors.toCol} label="To table column" - bind:value={fromRelationship.name} + bind:value={toColumn} + bind:error={errors.toColumn} + on:change={e => (errors.toColumn = e.detail?.length > 0 ? null : colNotSet)} />
- {#if originalFromName != null} + {#if originalFromColumnName != null} {/if}
From 738e0f28d719f6ac8eaa0bae241ff76b19bc8a3b Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 22:54:46 +0000 Subject: [PATCH 13/14] lint --- .../backend/Datasources/CreateEditRelationship.svelte | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 1454408017..76fcd36720 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -320,7 +320,7 @@ options={relationshipTypes} bind:value={relationshipType} bind:error={errors.relationshipType} - on:change={e => (errors.relationshipType = null)} + on:change={() => (errors.relationshipType = null)} />
Tables @@ -342,7 +342,7 @@ options={Object.keys(fromTable.schema)} bind:value={fromPrimary} bind:error={errors.fromPrimary} - on:change={e => (errors.fromPrimary = null)} + on:change={() => (errors.fromPrimary = null)} /> {/if} (errors.throughFromKey = null)} + on:change={() => (errors.throughFromKey = null)} /> {/if} {:else if isManyToOne && toTable} @@ -385,7 +385,7 @@ options={Object.keys(toTable?.schema)} bind:value={fromForeign} bind:error={errors.fromForeign} - on:change={e => (errors.fromForeign = null)} + on:change={() => (errors.fromForeign = null)} /> {/if}
From 382db8ac78416f97cd1c886794948fd8d0104398 Mon Sep 17 00:00:00 2001 From: Mel O'Hagan Date: Thu, 19 Jan 2023 22:57:19 +0000 Subject: [PATCH 14/14] Delete file copy --- .../CreateEditRelationshipCopy.svelte | 271 ------------------ 1 file changed, 271 deletions(-) delete mode 100644 packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte deleted file mode 100644 index 5ab099e61b..0000000000 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationshipCopy.svelte +++ /dev/null @@ -1,271 +0,0 @@ - - - - { - fromColumn = tableOptions.find(opt => opt.value === e.detail).label - }} - /> - {#if isManyToOne && fromTable} - { - toColumn = tableOptions.find(opt => opt.value === e.detail).label - }} - /> - {#if isManyToMany} - - - {/if} -
- Column names -
- - Budibase manages SQL relationships as a new column in the table, please - provide a name for these columns. - - - -
- {#if originalFromColumnName != null} - - {/if} -
-
- -