diff --git a/packages/api/src/controllers/databaseConnections.js b/packages/api/src/controllers/databaseConnections.js index 3da5c8d6e..2b32f8b6c 100644 --- a/packages/api/src/controllers/databaseConnections.js +++ b/packages/api/src/controllers/databaseConnections.js @@ -85,6 +85,16 @@ module.exports = { return res; }, + status_meta: 'get', + async status({ conid, database }) { + const existing = this.opened.find((x) => x.conid == conid && x.database == database); + if (existing) return existing.status; + return { + name: 'error', + message: 'Not connected', + }; + }, + ping_meta: 'post', async ping({ conid, database }) { const existing = this.opened.find((x) => x.conid == conid && x.database == database); diff --git a/packages/api/src/proc/databaseConnectionProcess.js b/packages/api/src/proc/databaseConnectionProcess.js index 04a97454e..984aa9fc6 100644 --- a/packages/api/src/proc/databaseConnectionProcess.js +++ b/packages/api/src/proc/databaseConnectionProcess.js @@ -10,16 +10,31 @@ let analysedStructure = null; let lastPing = null; let lastStatus = null; +async function checkedAsyncCall(promise) { + try { + const res = await promise; + return res; + } catch (err) { + setStatus({ + name: 'error', + message: err.message, + }); + // console.error(err); + setTimeout(() => process.exit(1), 1000); + throw err; + } +} + async function handleFullRefresh() { const driver = engines(storedConnection); - analysedStructure = await driver.analyseFull(systemConnection); + analysedStructure = await checkedAsyncCall(driver.analyseFull(systemConnection)); process.send({ msgtype: 'structure', structure: analysedStructure }); setStatusName('ok'); } async function handleIncrementalRefresh() { const driver = engines(storedConnection); - const newStructure = await driver.analyseIncremental(systemConnection, analysedStructure); + const newStructure = await checkedAsyncCall(driver.analyseIncremental(systemConnection, analysedStructure)); if (newStructure != null) { analysedStructure = newStructure; process.send({ msgtype: 'structure', structure: analysedStructure }); @@ -43,9 +58,8 @@ async function handleConnect({ connection, structure }) { lastPing = new Date().getTime(); if (!structure) setStatusName('pending'); - else setStatusName('ok'); const driver = engines(storedConnection); - systemConnection = await driverConnect(driver, storedConnection); + systemConnection = await checkedAsyncCall(driverConnect(driver, storedConnection)); if (structure) { analysedStructure = structure; handleIncrementalRefresh(); diff --git a/packages/web/src/utility/metadataLoaders.js b/packages/web/src/utility/metadataLoaders.js index 1ccef509f..576519310 100644 --- a/packages/web/src/utility/metadataLoaders.js +++ b/packages/web/src/utility/metadataLoaders.js @@ -27,6 +27,12 @@ const sqlObjectListLoader = ({ conid, database }) => ({ reloadTrigger: [`database-structure-changed-${conid}-${database}`, `database-status-changed-${conid}-${database}`], }); +const databaseStatusLoader = ({ conid, database }) => ({ + url: 'database-connections/status', + params: { conid, database }, + reloadTrigger: `database-status-changed-${conid}-${database}`, +}); + const databaseListLoader = ({ conid }) => ({ url: 'server-connections/list-databases', params: { conid }, @@ -125,6 +131,13 @@ export function useSqlObjectList(args) { return useCore(sqlObjectListLoader, args); } +export function getDatabaseStatus(args) { + return getCore(databaseStatusLoader, args); +} +export function useDatabaseStatus(args) { + return useCore(databaseStatusLoader, args); +} + export function getDatabaseList(args) { return getCore(databaseListLoader, args); } diff --git a/packages/web/src/widgets/StatusBar.js b/packages/web/src/widgets/StatusBar.js index 87f2cb9ef..623cfff5e 100644 --- a/packages/web/src/widgets/StatusBar.js +++ b/packages/web/src/widgets/StatusBar.js @@ -3,6 +3,8 @@ import styled from 'styled-components'; import { getEngineIcon } from '../icons'; import { useCurrentDatabase } from '../utility/globalState'; +import { useDatabaseStatus } from '../utility/metadataLoaders'; +import { FontIcon } from '../icons'; const Container = styled.div` display: flex; @@ -18,6 +20,7 @@ const Item = styled.div` export default function StatusBar() { const { name, connection } = useCurrentDatabase() || {}; + const status = useDatabaseStatus(connection ? { conid: connection._id, database: name } : {}); const { displayName, server, user, engine } = connection || {}; const EngineIcon = getEngineIcon(engine); return ( @@ -38,6 +41,26 @@ export default function StatusBar() { {user} )} + + {status && ( + + {status.name == 'pending' && ( + <> + Loading + + )} + {status.name == 'ok' && ( + <> + Connected + + )} + {status.name == 'error' && ( + <> + Error + + )} + + )} ); }