loading schemas indicator + error reporting

This commit is contained in:
SPRINX0\prochazka 2024-09-20 14:40:14 +02:00
parent ce70b2e71a
commit 8aac9cf59d
8 changed files with 46 additions and 6 deletions

View File

@ -214,6 +214,7 @@ async function handleDriverDataCore(msgid, callMethod) {
} }
async function handleSchemaList({ msgid }) { async function handleSchemaList({ msgid }) {
logger.debug('Loading schema list');
return handleDriverDataCore(msgid, driver => driver.listSchemas(dbhan)); return handleDriverDataCore(msgid, driver => driver.listSchemas(dbhan));
} }

View File

@ -262,6 +262,17 @@
}); });
}; };
const handleRefreshSchemas = () => {
const conid = connection._id;
const database = name;
apiCall('database-connections/dispatch-database-changed-event', {
event: 'schema-list-changed',
conid,
database,
});
loadSchemaList(conid, database);
};
async function handleConfirmSql(sql) { async function handleConfirmSql(sql) {
saveScriptToDatabase({ conid: connection._id, database: name }, sql, false); saveScriptToDatabase({ conid: connection._id, database: name }, sql, false);
} }
@ -290,6 +301,8 @@
onClick: handleNewPerspective, onClick: handleNewPerspective,
text: 'Design perspective query', text: 'Design perspective query',
}, },
connection.useSeparateSchemas && { onClick: handleRefreshSchemas, text: 'Refresh schemas' },
{ divider: true }, { divider: true },
isSqlOrDoc && isSqlOrDoc &&
!connection.isReadOnly && !connection.isReadOnly &&
@ -364,6 +377,7 @@
getCurrentDatabase, getCurrentDatabase,
getExtensions, getExtensions,
getOpenedTabs, getOpenedTabs,
loadingSchemaLists,
openedConnections, openedConnections,
openedSingleDatabaseConnections, openedSingleDatabaseConnections,
pinnedDatabases, pinnedDatabases,
@ -391,7 +405,7 @@
import hasPermission from '../utility/hasPermission'; import hasPermission from '../utility/hasPermission';
import { openImportExportTab } from '../utility/importExportTools'; import { openImportExportTab } from '../utility/importExportTools';
import newTable from '../tableeditor/newTable'; import newTable from '../tableeditor/newTable';
import { switchCurrentDatabase } from '../utility/common'; import { loadSchemaList, switchCurrentDatabase } from '../utility/common';
export let data; export let data;
export let passProps; export let passProps;
@ -409,6 +423,7 @@
$: isPinned = !!$pinnedDatabases.find(x => x?.name == data.name && x?.connection?._id == data.connection?._id); $: isPinned = !!$pinnedDatabases.find(x => x?.name == data.name && x?.connection?._id == data.connection?._id);
$: apps = useUsedApps(); $: apps = useUsedApps();
$: isLoadingSchemas = $loadingSchemaLists[`${data?.connection?._id}::${data?.name}`];
</script> </script>
<AppObjectCore <AppObjectCore
@ -431,6 +446,7 @@
.find(x => x.isNewQuery) .find(x => x.isNewQuery)
.onClick(); .onClick();
}} }}
statusIcon={isLoadingSchemas ? 'icon loading' : ''}
menu={createMenu} menu={createMenu}
showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin} showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin}
onPin={isPinned ? null : () => pinnedDatabases.update(list => [...list, data])} onPin={isPinned ? null : () => pinnedDatabases.update(list => [...list, data])}

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import _ from 'lodash';
import { getFormContext } from '../forms/FormProviderCore.svelte'; import { getFormContext } from '../forms/FormProviderCore.svelte';
import FormSelectField from '../forms/FormSelectField.svelte'; import FormSelectField from '../forms/FormSelectField.svelte';
import { useSchemaList } from '../utility/metadataLoaders'; import { useSchemaList } from '../utility/metadataLoaders';
@ -9,7 +10,7 @@
const { values } = getFormContext(); const { values } = getFormContext();
$: schemaList = useSchemaList({ conid: $values[conidName], database: values[databaseName] }); $: schemaList = useSchemaList({ conid: $values[conidName], database: values[databaseName] });
$: schemaOptions = ($schemaList || []).map(schema => ({ $: schemaOptions = (_.isArray($schemaList) ? $schemaList : []).map(schema => ({
value: schema.schemaName, value: schema.schemaName,
label: schema.schemaName, label: schema.schemaName,
})); }));

View File

@ -150,6 +150,7 @@ export const loadingPluginStore = writable({
}); });
export const activeDbKeysStore = writableWithStorage({}, 'activeDbKeysStore'); export const activeDbKeysStore = writableWithStorage({}, 'activeDbKeysStore');
export const appliedCurrentSchema = writable<string>(null); export const appliedCurrentSchema = writable<string>(null);
export const loadingSchemaLists = writable({}); // dict [`${conid}::${database}`]: true
export const currentThemeDefinition = derived([currentTheme, extensions], ([$currentTheme, $extensions]) => export const currentThemeDefinition = derived([currentTheme, extensions], ([$currentTheme, $extensions]) =>
$extensions.themes.find(x => x.themeClassName == $currentTheme) $extensions.themes.find(x => x.themeClassName == $currentTheme)

View File

@ -1,7 +1,8 @@
import { findDefaultSchema, findEngineDriver, isCompositeDbName } from 'dbgate-tools'; import { findDefaultSchema, findEngineDriver, isCompositeDbName } from 'dbgate-tools';
import { currentDatabase, getExtensions, getOpenedTabs, openedTabs } from '../stores'; import { currentDatabase, getExtensions, getOpenedTabs, loadingSchemaLists, openedTabs } from '../stores';
import _ from 'lodash'; import _ from 'lodash';
import { getSchemaList } from './metadataLoaders'; import { getSchemaList } from './metadataLoaders';
import { showSnackbarError } from './snackbar';
export class LoadingToken { export class LoadingToken {
isCanceled = false; isCanceled = false;
@ -85,13 +86,29 @@ export function isCtrlOrCommandKey(event) {
return event.ctrlKey; return event.ctrlKey;
} }
export async function loadSchemaList(conid, database) {
try {
loadingSchemaLists.update(x => ({ ...x, [`${conid}::${database}`]: true }));
const schemas = await getSchemaList({ conid, database });
if (schemas.errorMessage) {
showSnackbarError(`Error loading schemas: ${schemas.errorMessage}`);
console.error('Error loading schemas', schemas.errorMessage);
return;
}
return schemas;
} finally {
loadingSchemaLists.update(x => _.omit(x, [`${conid}::${database}`]));
}
}
export async function switchCurrentDatabase(data) { export async function switchCurrentDatabase(data) {
if (data?.connection?.useSeparateSchemas && !isCompositeDbName(data.name)) { if (data?.connection?.useSeparateSchemas && !isCompositeDbName(data.name)) {
const conid = data.connection._id; const conid = data.connection._id;
const database = data.name; const database = data.name;
const storageKey = `selected-schema-${conid}-${database}`; const storageKey = `selected-schema-${conid}-${database}`;
const schemaInStorage = localStorage.getItem(storageKey); const schemaInStorage = localStorage.getItem(storageKey);
const schemas = await getSchemaList({ conid, database }); const schemas = await loadSchemaList(conid, database);
if (!schemas) return;
const driver = findEngineDriver(data.connection, getExtensions()); const driver = findEngineDriver(data.connection, getExtensions());
const defaultSchema = findDefaultSchema(schemas, driver?.dialect, schemaInStorage); const defaultSchema = findDefaultSchema(schemas, driver?.dialect, schemaInStorage);
currentDatabase.set({ currentDatabase.set({

View File

@ -124,7 +124,7 @@
</WidgetsInnerContainer> </WidgetsInnerContainer>
{:else if objectList.length == 0 && $status && $status.name != 'pending' && $status.name != 'checkStructure' && $status.name != 'loadStructure' && $objects} {:else if objectList.length == 0 && $status && $status.name != 'pending' && $status.name != 'checkStructure' && $status.name != 'loadStructure' && $objects}
<SchemaSelector <SchemaSelector
schemaList={$schemaList} schemaList={_.isArray($schemaList) ? $schemaList : null}
objectList={flatFilteredList} objectList={flatFilteredList}
connection={$connection} connection={$connection}
{conid} {conid}
@ -159,7 +159,7 @@
</InlineButton> </InlineButton>
</SearchBoxWrapper> </SearchBoxWrapper>
<SchemaSelector <SchemaSelector
schemaList={$schemaList} schemaList={_.isArray($schemaList) ? $schemaList : null}
objectList={flatFilteredList} objectList={flatFilteredList}
connection={$connection} connection={$connection}
{conid} {conid}

View File

@ -159,6 +159,8 @@ const driver = {
const defaultSchemaRows = await this.query(dbhan, 'SELECT SCHEMA_NAME() as name'); const defaultSchemaRows = await this.query(dbhan, 'SELECT SCHEMA_NAME() as name');
const defaultSchema = defaultSchemaRows.rows[0]?.name; const defaultSchema = defaultSchemaRows.rows[0]?.name;
logger.debug(`Loaded ${rows.length} mssql schemas`);
return rows.map(x => ({ return rows.map(x => ({
...x, ...x,
isDefault: x.schemaName == defaultSchema, isDefault: x.schemaName == defaultSchema,

View File

@ -280,6 +280,8 @@ const drivers = driverBases.map(driverBase => ({
const defaultSchemaRows = await this.query(dbhan, 'SHOW SEARCH_PATH;'); const defaultSchemaRows = await this.query(dbhan, 'SHOW SEARCH_PATH;');
const searchPath = defaultSchemaRows.rows[0]?.search_path?.replace('"$user",', '')?.trim(); const searchPath = defaultSchemaRows.rows[0]?.search_path?.replace('"$user",', '')?.trim();
logger.debug(`Loaded ${schemaRows.rows.length} postgres schemas`);
const schemas = schemaRows.rows.map(x => ({ const schemas = schemaRows.rows.map(x => ({
schemaName: x.schema_name, schemaName: x.schema_name,
objectId: x.object_id, objectId: x.object_id,