diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts
index c3aba307e..05580b5f0 100644
--- a/packages/datalib/src/GridDisplay.ts
+++ b/packages/datalib/src/GridDisplay.ts
@@ -29,7 +29,7 @@ export interface DisplayColumn {
foreignKey?: ForeignKeyInfo;
isExpandable?: boolean;
isChecked?: boolean;
- hintColumnName?: string;
+ hintColumnNames?: string[];
dataType?: string;
filterType?: boolean;
isStructured?: boolean;
diff --git a/packages/datalib/src/TableFormViewDisplay.ts b/packages/datalib/src/TableFormViewDisplay.ts
index 7c6bb292f..1c568c349 100644
--- a/packages/datalib/src/TableFormViewDisplay.ts
+++ b/packages/datalib/src/TableFormViewDisplay.ts
@@ -15,6 +15,7 @@ import {
import { TableGridDisplay } from './TableGridDisplay';
import stableStringify from 'json-stable-stringify';
import { ChangeSetFieldDefinition, ChangeSetRowDefinition } from './ChangeSet';
+import { DictionaryDescriptionFunc } from '.';
export class TableFormViewDisplay extends FormViewDisplay {
// use utility functions from GridDisplay and publish result in FromViewDisplay interface
@@ -29,7 +30,8 @@ export class TableFormViewDisplay extends FormViewDisplay {
setCache: ChangeCacheFunc,
dbinfo: DatabaseInfo,
displayOptions,
- serverVersion
+ serverVersion,
+ getDictionaryDescription: DictionaryDescriptionFunc = null
) {
super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion);
this.gridDisplay = new TableGridDisplay(
@@ -41,7 +43,8 @@ export class TableFormViewDisplay extends FormViewDisplay {
setCache,
dbinfo,
displayOptions,
- serverVersion
+ serverVersion,
+ getDictionaryDescription
);
this.gridDisplay.addAllExpandedColumnsToSelected = true;
diff --git a/packages/datalib/src/TableGridDisplay.ts b/packages/datalib/src/TableGridDisplay.ts
index 044f5aa65..cd8227a2b 100644
--- a/packages/datalib/src/TableGridDisplay.ts
+++ b/packages/datalib/src/TableGridDisplay.ts
@@ -1,9 +1,25 @@
import _ from 'lodash';
import { filterName } from 'dbgate-tools';
import { GridDisplay, ChangeCacheFunc, DisplayColumn, DisplayedColumnInfo, ChangeConfigFunc } from './GridDisplay';
-import { TableInfo, EngineDriver, ViewInfo, ColumnInfo, NamedObjectInfo, DatabaseInfo } from 'dbgate-types';
+import {
+ TableInfo,
+ EngineDriver,
+ ViewInfo,
+ ColumnInfo,
+ NamedObjectInfo,
+ DatabaseInfo,
+ ForeignKeyInfo,
+} from 'dbgate-types';
import { GridConfig, GridCache, createGridCache } from './GridConfig';
-import { Expression, Select, treeToSql, dumpSqlSelect } from 'dbgate-sqltree';
+import { Expression, Select, treeToSql, dumpSqlSelect, ColumnRefExpression } from 'dbgate-sqltree';
+
+export interface DictionaryDescription {
+ expression: string;
+ columns: string[];
+ delimiter: string;
+}
+
+export type DictionaryDescriptionFunc = (table: TableInfo) => DictionaryDescription;
export class TableGridDisplay extends GridDisplay {
public table: TableInfo;
@@ -19,7 +35,8 @@ export class TableGridDisplay extends GridDisplay {
setCache: ChangeCacheFunc,
dbinfo: DatabaseInfo,
public displayOptions: any,
- serverVersion
+ serverVersion,
+ public getDictionaryDescription: DictionaryDescriptionFunc = null
) {
super(config, setConfig, cache, setCache, driver, dbinfo, serverVersion);
@@ -61,7 +78,11 @@ export class TableGridDisplay extends GridDisplay {
?.map(col => ({
...col,
isChecked: this.isColumnChecked(col),
- hintColumnName: col.foreignKey ? `hint_${col.uniqueName}` : null,
+ hintColumnNames:
+ this.getFkDictionaryDescription(col.foreignKey)?.columns?.map(
+ columnName => `hint_${col.uniqueName}_${columnName}`
+ ) || null,
+ hintColumnDelimiter: this.getFkDictionaryDescription(col.foreignKey)?.delimiter,
isExpandable: !!col.foreignKey,
})) || []
);
@@ -116,6 +137,19 @@ export class TableGridDisplay extends GridDisplay {
}
}
+ getFkDictionaryDescription(foreignKey: ForeignKeyInfo) {
+ if (!foreignKey) return null;
+ const pureName = foreignKey.refTableName;
+ const schemaName = foreignKey.refSchemaName;
+ const table = this.findTable({ schemaName, pureName });
+
+ if (table && table.columns && table.columns.length > 0 && table.primaryKey) {
+ const hintDescription = this.getDictionaryDescription(table);
+ return hintDescription;
+ }
+ return null;
+ }
+
addHintsToSelect(select: Select): boolean {
let res = false;
const groupColumns = this.groupColumns;
@@ -126,17 +160,23 @@ export class TableGridDisplay extends GridDisplay {
}
const table = this.getFkTarget(column);
if (table && table.columns && table.columns.length > 0 && table.primaryKey) {
- const hintColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char'));
- if (hintColumn) {
+ // const hintColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char'));
+ const hintDescription = this.getDictionaryDescription(table);
+ if (hintDescription) {
const parentUniqueName = column.uniquePath.slice(0, -1).join('.');
this.addReferenceToSelect(select, parentUniqueName ? `${parentUniqueName}_ref` : 'basetbl', column);
const childAlias = `${column.uniqueName}_ref`;
- select.columns.push({
- exprType: 'column',
- columnName: hintColumn.columnName,
- alias: `hint_${column.uniqueName}`,
- source: { alias: childAlias },
- });
+ select.columns.push(
+ ...hintDescription.columns.map(
+ columnName =>
+ ({
+ exprType: 'column',
+ columnName,
+ alias: `hint_${column.uniqueName}_${columnName}`,
+ source: { alias: childAlias },
+ } as ColumnRefExpression)
+ )
+ );
res = true;
}
}
diff --git a/packages/web/src/datagrid/DataGridCell.svelte b/packages/web/src/datagrid/DataGridCell.svelte
index 75945192a..7e509608d 100644
--- a/packages/web/src/datagrid/DataGridCell.svelte
+++ b/packages/web/src/datagrid/DataGridCell.svelte
@@ -113,8 +113,10 @@
{value.toString()}
{/if}
- {#if allowHintField && rowData && rowData[col.hintColumnName]}
- {rowData[col.hintColumnName]}
+ {#if allowHintField && rowData && _.some(col.hintColumnNames, hintColumnName => rowData[hintColumnName])}
+ {col.hintColumnNames.map(hintColumnName => rowData[hintColumnName]).join(col.hintColumnDelimiter || ' ')}
{/if}
{#if col.foreignKey && rowData && rowData[col.uniqueName]}
diff --git a/packages/web/src/datagrid/DataGridRow.svelte b/packages/web/src/datagrid/DataGridRow.svelte
index 1b44b8a05..72974e05b 100644
--- a/packages/web/src/datagrid/DataGridRow.svelte
+++ b/packages/web/src/datagrid/DataGridRow.svelte
@@ -26,7 +26,7 @@
$: hintFieldsAllowed = visibleRealColumns
.filter(col => {
- if (!col.hintColumnName) return false;
+ if (!col.hintColumnNames) return false;
if (rowStatus.modifiedFields && rowStatus.modifiedFields.has(col.uniqueName)) return false;
return true;
})
diff --git a/packages/web/src/datagrid/TableDataGrid.svelte b/packages/web/src/datagrid/TableDataGrid.svelte
index af7da844b..9f792b7a7 100644
--- a/packages/web/src/datagrid/TableDataGrid.svelte
+++ b/packages/web/src/datagrid/TableDataGrid.svelte
@@ -26,6 +26,7 @@
import SqlDataGridCore from './SqlDataGridCore.svelte';
import SqlFormView from '../formview/SqlFormView.svelte';
import { getBoolSettingsValue } from '../settings/settingsTools';
+ import { getDictionaryDescription } from '../utility/dictionaryDescriptionTools';
export let conid;
export let database;
@@ -64,7 +65,8 @@
setCache,
$dbinfo,
{ showHintColumns: getBoolSettingsValue('dataGrid.showHintColumns', true) },
- $serverVersion
+ $serverVersion,
+ table => getDictionaryDescription(table, conid, database)
)
: null;
@@ -79,7 +81,8 @@
setCache,
$dbinfo,
{ showHintColumns: getBoolSettingsValue('dataGrid.showHintColumns', true) },
- $serverVersion
+ $serverVersion,
+ table => getDictionaryDescription(table, conid, database)
)
: null;
diff --git a/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte b/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte
index 12e3e9efc..ce2992b95 100644
--- a/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte
+++ b/packages/web/src/modals/DefineDictionaryDescriptionModal.svelte
@@ -12,6 +12,7 @@
import FormProviderCore from '../forms/FormProviderCore.svelte';
import {
changeDelimitedColumnList,
+ checkDescriptionExpression,
getDictionaryDescription,
parseDelimitedColumnList,
saveDictionaryDescription,
@@ -27,7 +28,7 @@
$: tableInfo = useTableInfo({ conid, database, schemaName, pureName });
- $: descriptionInfo = getDictionaryDescription($tableInfo, conid, database);
+ $: descriptionInfo = getDictionaryDescription($tableInfo, conid, database, true);
const values = writable({});
@@ -78,6 +79,7 @@
{
closeCurrentModal();
saveDictionaryDescription(
diff --git a/packages/web/src/utility/dictionaryDescriptionTools.ts b/packages/web/src/utility/dictionaryDescriptionTools.ts
index 84b0e684a..4c2a271d5 100644
--- a/packages/web/src/utility/dictionaryDescriptionTools.ts
+++ b/packages/web/src/utility/dictionaryDescriptionTools.ts
@@ -1,26 +1,27 @@
+import { DictionaryDescription } from 'dbgate-datalib';
import { TableInfo } from 'dbgate-types';
import _ from 'lodash';
import { getLocalStorage, setLocalStorage, removeLocalStorage } from './storageCache';
-interface DictionaryDescription {
- expression: string;
- columns: string[];
- delimiter: string;
+function checkDescriptionColumns(columns: string[], table: TableInfo) {
+ return columns.length > 0 && columns.every(x => table.columns.find(y => y.columnName == x));
}
-function checkDescription(desc: DictionaryDescription, table: TableInfo) {
- return desc.columns.length > 0 && desc.columns.every(x => table.columns.find(y => y.columnName == x));
-}
-
-export function getDictionaryDescription(table: TableInfo, conid: string, database: string): DictionaryDescription {
+export function getDictionaryDescription(
+ table: TableInfo,
+ conid: string,
+ database: string,
+ skipCheckSaved: boolean = false
+): DictionaryDescription {
const keySpecific = `dictionary_spec_${table.schemaName}||${table.pureName}||${conid}||${database}`;
const keyCommon = `dictionary_spec_${table.schemaName}||${table.pureName}`;
const cachedSpecific = getLocalStorage(keySpecific);
const cachedCommon = getLocalStorage(keyCommon);
- if (cachedSpecific && checkDescription(cachedSpecific, table)) return cachedSpecific;
- if (cachedCommon && checkDescription(cachedCommon, table)) return cachedCommon;
+ if (cachedSpecific && (skipCheckSaved || checkDescriptionColumns(cachedSpecific.columns, table)))
+ return cachedSpecific;
+ if (cachedCommon && (skipCheckSaved || checkDescriptionColumns(cachedCommon.columns, table))) return cachedCommon;
const descColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char'));
if (descColumn) {
@@ -34,10 +35,16 @@ export function getDictionaryDescription(table: TableInfo, conid: string, databa
return null;
}
-export function parseDelimitedColumnList(columns) {
+export function parseDelimitedColumnList(columns): string[] {
return _.compact((columns || '').split(',').map(x => x.trim()));
}
+export function checkDescriptionExpression(expression: string, table: TableInfo) {
+ if (!expression) return false;
+ if (!table) return false;
+ return checkDescriptionColumns(parseDelimitedColumnList(expression), table);
+}
+
export function changeDelimitedColumnList(columns, columnName, isChecked) {
const parsed = parseDelimitedColumnList(columns);
const includes = parsed.includes(columnName);