preventing relationship overrides
This commit is contained in:
parent
0d4c3fd854
commit
cae1a20411
|
@ -8,10 +8,10 @@
|
||||||
export let from
|
export let from
|
||||||
export let plusTables
|
export let plusTables
|
||||||
export let relationship = {}
|
export let relationship = {}
|
||||||
|
export let close
|
||||||
|
|
||||||
let originalName = relationship.name
|
let originalName = relationship.name
|
||||||
|
|
||||||
$: console.log(relationship)
|
|
||||||
$: tableOptions = plusTables.map(table => ({ label: table.name, value: table._id }))
|
$: tableOptions = plusTables.map(table => ({ label: table.name, value: table._id }))
|
||||||
$: valid = relationship.name && relationship.tableId && relationship.relationshipType
|
$: valid = relationship.name && relationship.tableId && relationship.relationshipType
|
||||||
$: from = plusTables.find(table => table._id === relationship.source)
|
$: from = plusTables.find(table => table._id === relationship.source)
|
||||||
|
@ -19,18 +19,6 @@
|
||||||
$: through = plusTables.find(table => table._id === relationship.through)
|
$: through = plusTables.find(table => table._id === relationship.through)
|
||||||
$: linkTable = through || to
|
$: linkTable = through || to
|
||||||
|
|
||||||
$: relationshipOptions = from && to ? [
|
|
||||||
{
|
|
||||||
name: `Many ${from.name} rows → many ${to.name} rows`,
|
|
||||||
alt: `Many ${from.name} rows → many ${to.name} rows`,
|
|
||||||
value: RelationshipTypes.MANY_TO_MANY,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: `One ${from.name} row → many ${to.name} rows`,
|
|
||||||
alt: `One ${from.name} rows → many ${to.name} rows`,
|
|
||||||
value: RelationshipTypes.ONE_TO_MANY,
|
|
||||||
}
|
|
||||||
] : []
|
|
||||||
|
|
||||||
$: relationshipTypes = [
|
$: relationshipTypes = [
|
||||||
{
|
{
|
||||||
|
@ -51,25 +39,44 @@
|
||||||
|
|
||||||
// save the relationship on to the datasource
|
// save the relationship on to the datasource
|
||||||
async function saveRelationship() {
|
async function saveRelationship() {
|
||||||
|
const manyToMany = relationship.relationshipType === RelationshipTypes.MANY_TO_MANY
|
||||||
// source of relationship
|
// source of relationship
|
||||||
datasource.entities[from.name].schema[relationship.name] = {
|
datasource.entities[from.name].schema[relationship.name] = {
|
||||||
type: "link",
|
type: "link",
|
||||||
...relationship
|
...relationship
|
||||||
}
|
}
|
||||||
// if (originalName !== from.name) {
|
|
||||||
// delete datasource.entities[from.name].schema[originalName]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// save other side of relationship in the other schema
|
// save other side of relationship in the other schema
|
||||||
datasource.entities[to.name].schema[relationship.name] = {
|
datasource.entities[to.name].schema[relationship.name] = {
|
||||||
|
name: relationship.name,
|
||||||
type: "link",
|
type: "link",
|
||||||
relationshipType: relationship.relationshipType === RelationshipTypes.MANY_TO_MANY ? RelationshipTypes.MANY_TO_MANY : RelationshipTypes.MANY_TO_ONE,
|
relationshipType: manyToMany ? RelationshipTypes.MANY_TO_MANY : RelationshipTypes.MANY_TO_ONE,
|
||||||
tableId: to._id
|
tableId: from._id,
|
||||||
|
fieldName: relationship.fieldName,
|
||||||
|
foreignKey: relationship.foreignKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If relationship has been renamed
|
||||||
|
if (originalName !== relationship.name) {
|
||||||
|
delete datasource.entities[from.name].schema[originalName]
|
||||||
|
delete datasource.entities[to.name].schema[originalName]
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log({
|
||||||
|
from: datasource.entities[from.name].schema[relationship.name],
|
||||||
|
to: datasource.entities[to.name].schema[relationship.name],
|
||||||
|
})
|
||||||
|
|
||||||
await save()
|
await save()
|
||||||
await tables.fetch()
|
await tables.fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deleteRelationship() {
|
||||||
|
delete datasource.entities[from.name].schema[relationship.name]
|
||||||
|
delete datasource.entities[to.name].schema[relationship.name]
|
||||||
|
await save()
|
||||||
|
await tables.fetch()
|
||||||
|
close()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
|
@ -108,71 +115,19 @@
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if relationship?.relationshipType === RelationshipTypes.ONE_TO_MANY}
|
{#if relationship?.relationshipType === RelationshipTypes.ONE_TO_MANY && to}
|
||||||
<Select
|
<Select
|
||||||
label={"Foreign Key"}
|
label={`Foreign Key (${to.name})`}
|
||||||
options={Object.keys(linkTable.schema)}
|
options={Object.keys(to.schema)}
|
||||||
bind:value={relationship.foreignKey}
|
bind:value={relationship.foreignKey}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- <Menu>
|
<div slot="footer">
|
||||||
<MenuSection heading="From">
|
{#if originalName !== null}
|
||||||
{#each plusTables as table}
|
<Button warning text on:click={deleteRelationship}>Delete</Button>
|
||||||
<MenuItem noClose icon="Table" on:click={() => (relationship.source = table._id)}>
|
{/if}
|
||||||
{table.name}
|
|
||||||
{#if relationship.source === table._id}
|
|
||||||
<Icon size="S" name="Checkmark" />
|
|
||||||
{/if}
|
|
||||||
</MenuItem>
|
|
||||||
{/each}
|
|
||||||
</MenuSection>
|
|
||||||
</Menu> -->
|
|
||||||
<!-- <Menu>
|
|
||||||
<MenuSection heading="To">
|
|
||||||
{#each plusTables as table}
|
|
||||||
<MenuItem noClose icon="Table" on:click={() => (relationship.tableId = table._id)}>
|
|
||||||
{table.name}
|
|
||||||
{#if relationship.tableId === table._id}
|
|
||||||
<Icon size="S" name="Checkmark" />
|
|
||||||
{/if}
|
|
||||||
</MenuItem>
|
|
||||||
{/each}
|
|
||||||
</MenuSection>
|
|
||||||
</Menu> -->
|
|
||||||
{#if from && to}
|
|
||||||
<!-- <div class="cardinality">
|
|
||||||
<RadioGroup
|
|
||||||
label="Define the relationship"
|
|
||||||
bind:value={relationship.relationshipType}
|
|
||||||
on:change={onChangeRelationshipType}
|
|
||||||
options={relationshipOptions}
|
|
||||||
getOptionLabel={option => option.name}
|
|
||||||
getOptionValue={option => option.value}
|
|
||||||
/>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- <Select
|
|
||||||
label={`${linkTable.name} Column`}
|
|
||||||
options={Object.keys(linkTable.schema)}
|
|
||||||
bind:value={relationship.fieldName}
|
|
||||||
/> -->
|
|
||||||
|
|
||||||
<!-- <div class="table-selector">
|
|
||||||
<Menu>
|
|
||||||
<MenuSection heading={`${linkTable.name} Column`}>
|
|
||||||
{#each Object.keys(linkTable.schema) as column}
|
|
||||||
<MenuItem noClose icon="Table" on:click={() => (relationship.fieldName = column)}>
|
|
||||||
{column}
|
|
||||||
{#if relationship.fieldName === column}
|
|
||||||
<Icon size="S" name="Checkmark" />
|
|
||||||
{/if}
|
|
||||||
</MenuItem>
|
|
||||||
{/each}
|
|
||||||
</MenuSection>
|
|
||||||
</Menu>
|
|
||||||
</div> -->
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { goto, beforeUrlChange } from "@roxi/routify"
|
import { goto, beforeUrlChange } from "@roxi/routify"
|
||||||
import { Button, Heading, Body, Divider, Layout, Modal } from "@budibase/bbui"
|
import { Button, Heading, Body, Divider, Layout, Modal } from "@budibase/bbui"
|
||||||
import { datasources, integrations, queries, tables } from "stores/backend"
|
import { datasources, integrations, queries, tables } from "stores/backend"
|
||||||
|
import { RelationshipTypes } from "constants/backend"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
|
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
|
||||||
import CreateEditRelationship from "./CreateEditRelationship/CreateEditRelationship.svelte"
|
import CreateEditRelationship from "./CreateEditRelationship/CreateEditRelationship.svelte"
|
||||||
|
@ -66,7 +67,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function openRelationshipModal(relationship) {
|
function openRelationshipModal(relationship) {
|
||||||
selectedRelationship = relationship
|
if (relationship.type === "link") {
|
||||||
|
selectedRelationship = relationship
|
||||||
|
}
|
||||||
relationshipModal.show()
|
relationshipModal.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +85,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal bind:this={relationshipModal}>
|
<Modal bind:this={relationshipModal}>
|
||||||
<CreateEditRelationship {datasource} save={saveDatasource} {plusTables} relationship={selectedRelationship} />
|
<CreateEditRelationship {datasource} save={saveDatasource} close={relationshipModal.hide} {plusTables} relationship={selectedRelationship} />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
{#if datasource && integration}
|
{#if datasource && integration}
|
||||||
|
@ -151,7 +154,7 @@
|
||||||
<div class="query-list">
|
<div class="query-list">
|
||||||
{#each plusTables as table}
|
{#each plusTables as table}
|
||||||
{#each Object.keys(table.schema) as column}
|
{#each Object.keys(table.schema) as column}
|
||||||
{#if table.schema[column].type === "link"}
|
{#if table.schema[column].type === "link" && table.schema[column].relationshipType !== RelationshipTypes.MANY_TO_ONE}
|
||||||
<div
|
<div
|
||||||
class="query-list-item"
|
class="query-list-item"
|
||||||
on:click={() => openRelationshipModal(table.schema[column])}>
|
on:click={() => openRelationshipModal(table.schema[column])}>
|
||||||
|
|
|
@ -13,15 +13,6 @@
|
||||||
"preLaunchTask": "npm: build",
|
"preLaunchTask": "npm: build",
|
||||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "TS",
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"runtimeExecutable": "node",
|
|
||||||
"runtimeArgs": ["--nolazy", "-r", "ts-node/register/transpile-only"],
|
|
||||||
"args": ["src/index.ts"],
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
|
|
|
@ -135,7 +135,10 @@ module PostgresModule {
|
||||||
* Fetches the tables from the postgres table and assigns them to the datasource.
|
* Fetches the tables from the postgres table and assigns them to the datasource.
|
||||||
* @param {*} datasourceId - datasourceId to fetch
|
* @param {*} datasourceId - datasourceId to fetch
|
||||||
*/
|
*/
|
||||||
async buildSchema(datasourceId: string) {
|
async buildSchema(
|
||||||
|
datasourceId: string,
|
||||||
|
entities: Record<string, Table>
|
||||||
|
) {
|
||||||
let tableKeys: { [key: string]: string[] } = {}
|
let tableKeys: { [key: string]: string[] } = {}
|
||||||
try {
|
try {
|
||||||
const primaryKeysResponse = await this.client.query(
|
const primaryKeysResponse = await this.client.query(
|
||||||
|
@ -167,6 +170,20 @@ module PostgresModule {
|
||||||
name: tableName,
|
name: tableName,
|
||||||
schema: {},
|
schema: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add the existing relationships from the entities if they exist, to prevent them from being overridden
|
||||||
|
if (entities) {
|
||||||
|
const existingTableSchema = entities[tableName].schema
|
||||||
|
for (let key in existingTableSchema) {
|
||||||
|
if (existingTableSchema[key].type === "link") {
|
||||||
|
tables[tableName].schema[key] = existingTableSchema[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log({
|
||||||
|
existingTableSchema,
|
||||||
|
tables
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const type: string = convertType(column.data_type, TYPE_MAP)
|
const type: string = convertType(column.data_type, TYPE_MAP)
|
||||||
|
|
Loading…
Reference in New Issue