custom joins

This commit is contained in:
Jan Prochazka
2022-08-27 18:07:49 +02:00
parent b6a0fe6713
commit 33b11eef38
6 changed files with 178 additions and 61 deletions

View File

@@ -8,9 +8,10 @@ import uuidv1 from 'uuid/v1';
// } // }
export interface PerspectiveCustomJoinConfig { export interface PerspectiveCustomJoinConfig {
joinid: string; refNodeDesignerId: string;
referenceDesignerId: string;
joinName: string; joinName: string;
baseUniqueName: string; baseDesignerId: string;
conid?: string; conid?: string;
database?: string; database?: string;
refSchemaName?: string; refSchemaName?: string;
@@ -50,6 +51,8 @@ export interface PerspectiveNodeConfig {
schemaName?: string; schemaName?: string;
pureName: string; pureName: string;
alias?: string;
conid?: string; conid?: string;
database?: string; database?: string;

View File

@@ -952,13 +952,21 @@ export class PerspectiveCustomJoinTreeNode extends PerspectiveTableNode {
} }
get codeName() { get codeName() {
return this.customJoin.joinid; return this.customJoin.refNodeDesignerId;
} }
get customJoinConfig(): PerspectiveCustomJoinConfig { get customJoinConfig(): PerspectiveCustomJoinConfig {
return this.customJoin; return this.customJoin;
} }
get isChecked() {
return this.isCheckedNode;
}
toggleChecked(value?: boolean) {
this.toggleCheckedNode(value);
}
getParentJoinCondition(alias: string, parentAlias: string): Condition[] { getParentJoinCondition(alias: string, parentAlias: string): Condition[] {
return this.customJoin.columns.map(column => { return this.customJoin.columns.map(column => {
const res: Condition = { const res: Condition = {
@@ -1032,15 +1040,15 @@ export function getTableChildPerspectiveNodes(
setConfig: ChangePerspectiveConfigFunc, setConfig: ChangePerspectiveConfigFunc,
dataProvider: PerspectiveDataProvider, dataProvider: PerspectiveDataProvider,
databaseConfig: PerspectiveDatabaseConfig, databaseConfig: PerspectiveDatabaseConfig,
parentColumn: PerspectiveTreeNode parentNode: PerspectiveTreeNode
) { ) {
if (!table) return []; if (!table) return [];
const db = parentColumn.db; const db = parentNode.db;
const columnNodes = table.columns.map(col => const columnNodes = table.columns.map(col =>
findDesignerIdForNode( findDesignerIdForNode(
config, config,
parentColumn, parentNode,
designerId => designerId =>
new PerspectiveTableColumnNode( new PerspectiveTableColumnNode(
col, col,
@@ -1050,7 +1058,7 @@ export function getTableChildPerspectiveNodes(
setConfig, setConfig,
dataProvider, dataProvider,
databaseConfig, databaseConfig,
parentColumn, parentNode,
designerId designerId
) )
) )
@@ -1074,7 +1082,7 @@ export function getTableChildPerspectiveNodes(
dependencies.push( dependencies.push(
findDesignerIdForNode( findDesignerIdForNode(
config, config,
parentColumn, parentNode,
designerId => designerId =>
new PerspectiveTableReferenceNode( new PerspectiveTableReferenceNode(
fk, fk,
@@ -1085,7 +1093,7 @@ export function getTableChildPerspectiveNodes(
dataProvider, dataProvider,
databaseConfig, databaseConfig,
isMultiple, isMultiple,
parentColumn, parentNode,
designerId designerId
) )
) )
@@ -1095,6 +1103,60 @@ export function getTableChildPerspectiveNodes(
} }
res.push(..._sortBy(dependencies, 'title')); res.push(..._sortBy(dependencies, 'title'));
const customs = [];
for (const node of config.nodes) {
if (node.designerId == parentNode.parentNode?.designerId || res.find(x => x.designerId == node.designerId)) {
// already used as FK
continue;
}
for (const ref of config.references) {
if (
(ref.sourceId == parentNode.designerId && ref.targetId == node.designerId) ||
(ref.targetId == parentNode.designerId && ref.sourceId == node.designerId)
) {
const newConfig = { ...databaseConfig };
if (node.conid) newConfig.conid = node.conid;
if (node.database) newConfig.database = node.database;
const db = dbs?.[newConfig.conid]?.[newConfig.database];
const table = db?.tables?.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
const view = db?.views?.find(x => x.pureName == node.pureName && x.schemaName == node.schemaName);
const join: PerspectiveCustomJoinConfig = {
refNodeDesignerId: node.designerId,
referenceDesignerId: ref.designerId,
baseDesignerId: parentNode.designerId,
joinName: node.alias || node.pureName,
refTableName: node.pureName,
refSchemaName: node.schemaName,
conid: node.conid,
database: node.database,
columns:
ref.sourceId == parentNode.designerId
? ref.columns.map(col => ({ baseColumnName: col.source, refColumnName: col.target }))
: ref.columns.map(col => ({ baseColumnName: col.target, refColumnName: col.source })),
};
if (table || view) {
customs.push(
new PerspectiveCustomJoinTreeNode(
join,
table || view,
dbs,
config,
setConfig,
dataProvider,
newConfig,
parentNode,
node.designerId
)
);
}
}
}
}
res.push(..._sortBy(customs, 'title'));
// const customs = []; // const customs = [];
// for (const join of config.customJoins || []) { // for (const join of config.customJoins || []) {
// if (join.baseUniqueName == parentColumn.uniqueName) { // if (join.baseUniqueName == parentColumn.uniqueName) {

View File

@@ -219,14 +219,18 @@
})); }));
updateFromDbInfo(); updateFromDbInfo();
} else { } else {
callChange(current => ({ callChange(
current => ({
...current, ...current,
tables: (current.tables || []).filter(x => x.designerId != table.designerId), tables: (current.tables || []).filter(x => x.designerId != table.designerId),
references: (current.references || []).filter( references: (current.references || []).filter(
x => x.sourceId != table.designerId && x.targetId != table.designerId x => x.sourceId != table.designerId && x.targetId != table.designerId
), ),
columns: (current.columns || []).filter(x => x.designerId != table.designerId), columns: (current.columns || []).filter(x => x.designerId != table.designerId),
})); }),
undefined,
{ removeTables: true }
);
} }
}; };

View File

@@ -18,6 +18,7 @@
import { onMount, tick } from 'svelte'; import { onMount, tick } from 'svelte';
import { import {
ChangePerspectiveConfigFunc, ChangePerspectiveConfigFunc,
createPerspectiveNodeConfig,
PerspectiveConfig, PerspectiveConfig,
PerspectiveCustomJoinConfig, PerspectiveCustomJoinConfig,
PerspectiveTreeNode, PerspectiveTreeNode,
@@ -35,7 +36,6 @@
let conidOverride = editValue?.conid || null; let conidOverride = editValue?.conid || null;
let databaseOverride = editValue?.database || null; let databaseOverride = editValue?.database || null;
let joinid = editValue?.joinid || uuidv1();
// $: fromDbInfo = useDatabaseInfo({ // $: fromDbInfo = useDatabaseInfo({
// conid, // conid,
@@ -68,19 +68,19 @@
let columns = editValue?.columns || []; let columns = editValue?.columns || [];
// let fromTableName = pureName; // let fromTableName = pureName;
// let fromSchemaName = schemaName; // let fromSchemaName = schemaName;
let fromUniuqeName = editValue?.baseUniqueName || root.uniqueName; let fromDesignerId = editValue?.baseDesignerId || root.designerId;
let refTableName = editValue?.refTableName || null; let refTableName = editValue?.refTableName || null;
let refSchemaName = editValue?.refSchemaName || null; let refSchemaName = editValue?.refSchemaName || null;
let joinName = editValue?.joinName || ''; let joinName = editValue?.joinName || '';
onMount(() => { // onMount(() => {
if (editValue) return; // if (editValue) return;
let index = 1; // let index = 1;
while (config.customJoins?.find(x => x.joinName == `Custom join ${index}`)) { // while (config.customJoins?.find(x => x.joinName == `Custom join ${index}`)) {
index += 1; // index += 1;
} // }
joinName = `Custom join ${index}`; // joinName = `Custom join ${index}`;
}); // });
// $: fromTableList = [ // $: fromTableList = [
// ..._.sortBy($fromDbInfo?.tables || [], ['schemaName', 'pureName']), // ..._.sortBy($fromDbInfo?.tables || [], ['schemaName', 'pureName']),
@@ -124,7 +124,7 @@
]; ];
$: fromTableList = root.getBaseTables(); $: fromTableList = root.getBaseTables();
$: fromTableInfo = fromTableList?.find(x => x.node.uniqueName == fromUniuqeName)?.table; $: fromTableInfo = fromTableList?.find(x => x.node.designerId == fromDesignerId)?.table;
$: (async () => { $: (async () => {
// without this has svelte problem, doesn't invalidate SelectField options // without this has svelte problem, doesn't invalidate SelectField options
@@ -134,7 +134,7 @@
fromTableOptions = fromTableList.map(tbl => ({ fromTableOptions = fromTableList.map(tbl => ({
label: fullNameToLabel(tbl.table), label: fullNameToLabel(tbl.table),
value: tbl.node.uniqueName, value: tbl.node.designerId,
})); }));
refTableOptions = refTableList.map(tbl => ({ refTableOptions = refTableList.map(tbl => ({
@@ -173,13 +173,13 @@
<div class="label col-3">Base table</div> <div class="label col-3">Base table</div>
<div class="col-9"> <div class="col-9">
<SelectField <SelectField
value={fromUniuqeName} value={fromDesignerId}
isNative isNative
notSelected notSelected
options={fromTableOptions} options={fromTableOptions}
on:change={e => { on:change={e => {
if (e.detail) { if (e.detail) {
fromUniuqeName = e.detail; fromDesignerId = e.detail;
} }
}} }}
/> />
@@ -321,23 +321,48 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormSubmit <FormSubmit
value={'Save'} value={'Save'}
on:click={async () => { on:click={() => {
const newJoin = { setConfig(cfg => {
joinid, const newNode = createPerspectiveNodeConfig({ pureName: refTableName, schemaName: refSchemaName });
joinName, newNode.designerId = editValue?.refNodeDesignerId || uuidv1();
baseUniqueName: fromUniuqeName, newNode.conid = conidOverride;
refTableName, newNode.database = databaseOverride;
refSchemaName, newNode.position = cfg.nodes.find(x => x.designerId == editValue?.refNodeDesignerId)?.position;
columns, newNode.alias = joinName || refTableName;
conid: conidOverride,
database: databaseOverride, const newRef = {
designerId: editValue?.referenceDesignerId || uuidv1(),
sourceId: fromDesignerId,
targetId: newNode.designerId,
columns: columns.map(col => ({
source: col.baseColumnName,
target: col.refColumnName,
})),
}; };
setConfig(cfg => ({
return {
...cfg, ...cfg,
customJoins: editValue nodes: [...cfg.nodes.filter(x => x.designerId != editValue?.refNodeDesignerId), newNode],
? cfg.customJoins.map(x => (x.joinid == editValue.joinid ? newJoin : x)) references: [...cfg.references.filter(x => x.designerId != editValue?.referenceDesignerId), newRef],
: [...(cfg.customJoins || []), newJoin], };
})); });
// const newJoin = {
// joinid,
// joinName,
// baseDesignerId: fromDesignerId,
// refTableName,
// refSchemaName,
// columns,
// conid: conidOverride,
// database: databaseOverride,
// };
// setConfig(cfg => ({
// ...cfg,
// customJoins: editValue
// ? cfg.customJoins.map(x => (x.joinid == editValue.joinid ? newJoin : x))
// : [...(cfg.customJoins || []), newJoin],
// }));
closeCurrentModal(); closeCurrentModal();
}} }}
/> />

View File

@@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { MultipleDatabaseInfo, PerspectiveConfig } from 'dbgate-datalib'; import { createPerspectiveNodeConfig, MultipleDatabaseInfo, PerspectiveConfig } from 'dbgate-datalib';
import _ from 'lodash'; import _ from 'lodash';
import { tick } from 'svelte'; import { tick } from 'svelte';
import runCommand from '../commands/runCommand'; import runCommand from '../commands/runCommand';
@@ -46,21 +46,43 @@
} }
const res = { const res = {
...oldValue, ...oldValue,
nodes: oldValue.nodes.map(node => { references: newValue.references,
nodes: _.compact(
oldValue.nodes.map(node => {
const table = newValue.tables?.find(x => x.designerId == node.designerId); const table = newValue.tables?.find(x => x.designerId == node.designerId);
if (!table && settings?.removeTables) {
return null;
}
const nodeChanged = {
...node,
alias: table?.alias,
};
if (table && (table.left != node.position?.x || table.top != node.position?.y)) { if (table && (table.left != node.position?.x || table.top != node.position?.y)) {
if (!settings?.isCalledFromArrange) { if (!settings?.isCalledFromArrange) {
isArranged = false; isArranged = false;
} }
return { nodeChanged.position = { x: table.left, y: table.top };
...node,
position: { x: table.left, y: table.top },
};
} }
return node; return nodeChanged;
}), })
),
}; };
for (const table of newValue.tables) {
if (res.nodes.find(x => x.designerId == table.designerId)) {
continue;
}
const newNode = createPerspectiveNodeConfig(table);
newNode.designerId = table.designerId;
newNode.position = { x: table.left, y: table.top };
isArranged = false;
res.nodes.push(newNode);
}
res.isArranged = isArranged; res.isArranged = isArranged;
return res; return res;
}); });
} }
@@ -81,10 +103,10 @@
showTableCloseButton: true, showTableCloseButton: true,
allowColumnOperations: true, allowColumnOperations: true,
allowCreateRefByDrag: true, allowCreateRefByDrag: true,
allowTableAlias: true,
allowScrollColumns: true, allowScrollColumns: true,
canSelectColumns: true, canSelectColumns: true,
canCheckTables: true, canCheckTables: true,
allowTableAlias: true,
arrangeAlg: 'tree', arrangeAlg: 'tree',
referenceMenu: ({ designer, reference, onChangeReference, onRemoveReference }) => { referenceMenu: ({ designer, reference, onChangeReference, onRemoveReference }) => {
return [{ text: 'Remove', onClick: () => onRemoveReference(reference) }]; return [{ text: 'Remove', onClick: () => onRemoveReference(reference) }];

View File

@@ -89,7 +89,8 @@ export function getPerspectiveNodeMenu(props: PerspectiveNodeMenuProps) {
onClick: () => onClick: () =>
setConfig(cfg => ({ setConfig(cfg => ({
...cfg, ...cfg,
customJoins: (cfg.customJoins || []).filter(x => x.joinid != customJoin.joinid), nodes: (cfg.nodes || []).filter(x => x.designerId != customJoin.refNodeDesignerId),
references: (cfg.references || []).filter(x => x.designerId != customJoin.referenceDesignerId),
})), })),
}, },
customJoin && { customJoin && {