diff --git a/packages/api/src/controllers/apps.js b/packages/api/src/controllers/apps.js
index 5a124d57..7e057d80 100644
--- a/packages/api/src/controllers/apps.js
+++ b/packages/api/src/controllers/apps.js
@@ -186,13 +186,19 @@ module.exports = {
} catch (err) {
res.virtualReferences = [];
}
+ try {
+ res.dictionaryDescriptions = JSON.parse(
+ await fs.readFile(path.join(dir, 'dictionary-descriptions.config.json'), { encoding: 'utf-8' })
+ );
+ } catch (err) {
+ res.dictionaryDescriptions = [];
+ }
return res;
},
- saveVfk_meta: true,
- async saveVfk({ appFolder, schemaName, pureName, refSchemaName, refTableName, columns }) {
- const file = path.join(appdir(), appFolder, 'virtual-references.config.json');
+ async saveConfigFile(appFolder, filename, filterFunc, newItem) {
+ const file = path.join(appdir(), appFolder, filename);
let json;
try {
@@ -201,33 +207,57 @@ module.exports = {
json = [];
}
- if (columns.length == 1) {
- json = json.filter(
- x =>
- !(
- x.schemaName == schemaName &&
- x.pureName == pureName &&
- x.columns.length == 1 &&
- x.columns[0].columnName == columns[0].columnName
- )
- );
+ if (filterFunc) {
+ json = json.filter(filterFunc);
}
- json = [
- ...json,
+ json = [...json, newItem];
+
+ await fs.writeFile(file, JSON.stringify(json, undefined, 2));
+
+ socket.emitChanged(`app-files-changed-${appFolder}`);
+ socket.emitChanged('used-apps-changed');
+ },
+
+ saveVirtualReference_meta: true,
+ async saveVirtualReference({ appFolder, schemaName, pureName, refSchemaName, refTableName, columns }) {
+ await this.saveConfigFile(
+ appFolder,
+ 'virtual-references.config.json',
+ columns.length == 1
+ ? x =>
+ !(
+ x.schemaName == schemaName &&
+ x.pureName == pureName &&
+ x.columns.length == 1 &&
+ x.columns[0].columnName == columns[0].columnName
+ )
+ : null,
{
schemaName,
pureName,
refSchemaName,
refTableName,
columns,
- },
- ];
+ }
+ );
+ return true;
+ },
- await fs.writeFile(file, JSON.stringify(json, undefined, 2));
-
- socket.emitChanged(`app-files-changed-${appFolder}`);
- socket.emitChanged('used-apps-changed');
+ saveDictionaryDescription_meta: true,
+ async saveDictionaryDescription({ appFolder, pureName, schemaName, expresssion, columns, delimiter }) {
+ await this.saveConfigFile(
+ appFolder,
+ 'dictionary-descriptions.config.json',
+ x => !(x.schemaName == schemaName && x.pureName == pureName),
+ {
+ schemaName,
+ pureName,
+ expresssion,
+ columns,
+ delimiter,
+ }
+ );
return true;
},
diff --git a/packages/tools/src/structureTools.ts b/packages/tools/src/structureTools.ts
index a49f3a76..f3d08351 100644
--- a/packages/tools/src/structureTools.ts
+++ b/packages/tools/src/structureTools.ts
@@ -101,10 +101,10 @@ export function extendDatabaseInfoFromApps(db: DatabaseInfo, apps: ApplicationDe
...(table.foreignKeys || []),
..._flatten(apps.map(app => app.virtualReferences || []))
.filter(fk => fk.pureName == table.pureName && fk.schemaName == table.schemaName)
- .map(fk => ({ ...fk, isVirtual: true })),
+ .map(fk => ({ ...fk, constraintType: 'foreignKey', isVirtual: true })),
],
})),
- };
+ } as DatabaseInfo;
return addTableDependencies(dbExt);
}
diff --git a/packages/types/appdefs.d.ts b/packages/types/appdefs.d.ts
index 6fdd2822..d88559d7 100644
--- a/packages/types/appdefs.d.ts
+++ b/packages/types/appdefs.d.ts
@@ -19,10 +19,10 @@ interface VirtualReferenceDefinition {
}[];
}
-interface ColumnDescriptionDefinition {
+interface DictionaryDescriptionDefinition {
pureName: string;
schemaName?: string;
- expresssion?: string;
+ expresssion: string;
columns: string[];
delimiter: string;
}
@@ -33,5 +33,5 @@ export interface ApplicationDefinition {
queries: ApplicationQuery[];
commands: ApplicationCommand[];
virtualReferences: VirtualReferenceDefinition[];
- columnDescriptions: ColumnDescriptionDefinition[];
+ dictionaryDescriptions: DictionaryDescriptionDefinition[];
}
diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte
index b77d962c..a0527321 100644
--- a/packages/web/src/App.svelte
+++ b/packages/web/src/App.svelte
@@ -15,6 +15,7 @@
import { subscribeConnectionPingers } from './utility/connectionsPinger';
import { subscribePermissionCompiler } from './utility/hasPermission';
import { apiCall } from './utility/api';
+ import { getUsedApps } from './utility/metadataLoaders';
let loadedApi = false;
@@ -30,7 +31,8 @@
const settings = await apiCall('config/get-settings');
const connections = await apiCall('connections/list');
const config = await apiCall('config/get');
- loadedApi = settings && connections && config;
+ const apps = await getUsedApps();
+ loadedApi = settings && connections && config && apps;
if (loadedApi) {
subscribeApiDependendStores();
diff --git a/packages/web/src/appobj/DatabaseAppObject.svelte b/packages/web/src/appobj/DatabaseAppObject.svelte
index b483f315..7611f0fc 100644
--- a/packages/web/src/appobj/DatabaseAppObject.svelte
+++ b/packages/web/src/appobj/DatabaseAppObject.svelte
@@ -1,11 +1,6 @@
-
- export async function saveDbToApp(conid, database, app) {
- if (app == '#new') {
- const folder = await apiCall('apps/create-folder', { folder: database });
-
- await apiCall('connections/update-database', {
- conid,
- database,
- values: {
- [`useApp:${folder}`]: true,
- },
- });
-
- return folder;
- }
-
- await apiCall('connections/update-database', {
- conid,
- database,
- values: {
- [`useApp:${app}`]: true,
- },
- });
-
- return app;
- }
-
-
@@ -75,7 +103,14 @@
-
+
+
+
{
const appFolder = await saveDbToApp(conid, database, dstApp);
- await apiCall('apps/save-vfk', {
+ await apiCall('apps/save-virtual-reference', {
appFolder,
schemaName,
pureName,
diff --git a/packages/web/src/utility/appTools.ts b/packages/web/src/utility/appTools.ts
new file mode 100644
index 00000000..506e1aaa
--- /dev/null
+++ b/packages/web/src/utility/appTools.ts
@@ -0,0 +1,33 @@
+import { ApplicationDefinition, StoredConnection } from 'dbgate-types';
+import { apiCall } from '../utility/api';
+
+export async function saveDbToApp(conid: string, database: string, app: string) {
+ if (app == '#new') {
+ const folder = await apiCall('apps/create-folder', { folder: database });
+
+ await apiCall('connections/update-database', {
+ conid,
+ database,
+ values: {
+ [`useApp:${folder}`]: true,
+ },
+ });
+
+ return folder;
+ }
+
+ await apiCall('connections/update-database', {
+ conid,
+ database,
+ values: {
+ [`useApp:${app}`]: true,
+ },
+ });
+
+ return app;
+}
+
+export function filterAppsForDatabase(connection, database: string, $apps): ApplicationDefinition[] {
+ const db = (connection?.databases || []).find(x => x.name == database);
+ return $apps.filter(app => db && db[`useApp:${app.name}`]);
+}
diff --git a/packages/web/src/utility/dictionaryDescriptionTools.ts b/packages/web/src/utility/dictionaryDescriptionTools.ts
index 0454ccc7..87cc9557 100644
--- a/packages/web/src/utility/dictionaryDescriptionTools.ts
+++ b/packages/web/src/utility/dictionaryDescriptionTools.ts
@@ -1,7 +1,8 @@
import { DictionaryDescription } from 'dbgate-datalib';
-import { TableInfo } from 'dbgate-types';
+import { ApplicationDefinition, TableInfo } from 'dbgate-types';
import _ from 'lodash';
-import { getLocalStorage, setLocalStorage, removeLocalStorage } from './storageCache';
+import { apiCall } from './api';
+import { filterAppsForDatabase, saveDbToApp } from './appTools';
function checkDescriptionColumns(columns: string[], table: TableInfo) {
if (!columns?.length) return false;
@@ -14,17 +15,20 @@ export function getDictionaryDescription(
table: TableInfo,
conid: string,
database: string,
+ apps: ApplicationDefinition[],
+ connections,
skipCheckSaved: boolean = false
): DictionaryDescription {
- const keySpecific = `dictionary_spec_${table.schemaName}||${table.pureName}||${conid}||${database}`;
- const keyCommon = `dictionary_spec_${table.schemaName}||${table.pureName}`;
+ const conn = connections.find(x => x._id == conid);
+ const dbApps = filterAppsForDatabase(conn, database, apps);
- const cachedSpecific = getLocalStorage(keySpecific);
- const cachedCommon = getLocalStorage(keyCommon);
+ const cached = _.flatten(dbApps.map(x => x.dictionaryDescriptions || [])).find(
+ x => x.pureName == table.pureName && x.schemaName == table.schemaName
+ );
- if (cachedSpecific && (skipCheckSaved || checkDescriptionColumns(cachedSpecific.columns, table)))
- return cachedSpecific;
- if (cachedCommon && (skipCheckSaved || checkDescriptionColumns(cachedCommon.columns, table))) return cachedCommon;
+ if (cached && (skipCheckSaved || checkDescriptionColumns(cached.columns, table))) {
+ return cached;
+ }
const descColumn = table.columns.find(x => x?.dataType?.toLowerCase()?.includes('char'));
if (descColumn) {
@@ -57,29 +61,22 @@ export function changeDelimitedColumnList(columns, columnName, isChecked) {
return parsed.join(',');
}
-export function saveDictionaryDescription(
+export async function saveDictionaryDescription(
table: TableInfo,
conid: string,
database: string,
expression: string,
delimiter: string,
- useForAllDatabases: boolean
+ targetApplication: string
) {
- const keySpecific = `dictionary_spec_${table.schemaName}||${table.pureName}||${conid}||${database}`;
- const keyCommon = `dictionary_spec_${table.schemaName}||${table.pureName}`;
+ const appFolder = await saveDbToApp(conid, database, targetApplication);
- removeLocalStorage(keySpecific);
- if (useForAllDatabases) removeLocalStorage(keyCommon);
-
- const description = {
+ await apiCall('apps/save-dictionary-description', {
+ appFolder,
+ schemaName: table.schemaName,
+ pureName: table.pureName,
columns: parseDelimitedColumnList(expression),
expression,
delimiter,
- };
-
- if (useForAllDatabases) {
- setLocalStorage(keyCommon, description);
- } else {
- setLocalStorage(keySpecific, description);
- }
+ });
}