model age in statusbar, sync model is not automatic by default

This commit is contained in:
Jan Prochazka
2021-05-16 20:14:46 +02:00
parent 6dfe9b798b
commit 70d06deeb0
7 changed files with 77 additions and 5 deletions

View File

@@ -18,6 +18,12 @@ module.exports = {
existing.structure = structure; existing.structure = structure;
socket.emitChanged(`database-structure-changed-${conid}-${database}`); socket.emitChanged(`database-structure-changed-${conid}-${database}`);
}, },
handle_structureTime(conid, database, { analysedTime }) {
const existing = this.opened.find(x => x.conid == conid && x.database == database);
if (!existing) return;
existing.analysedTime = analysedTime;
socket.emitChanged(`database-status-changed-${conid}-${database}`);
},
handle_version(conid, database, { version }) { handle_version(conid, database, { version }) {
const existing = this.opened.find(x => x.conid == conid && x.database == database); const existing = this.opened.find(x => x.conid == conid && x.database == database);
if (!existing) return; if (!existing) return;
@@ -123,9 +129,19 @@ module.exports = {
status_meta: 'get', status_meta: 'get',
async status({ conid, database }) { async status({ conid, database }) {
const existing = this.opened.find(x => x.conid == conid && x.database == database); const existing = this.opened.find(x => x.conid == conid && x.database == database);
if (existing) return existing.status; if (existing) {
return {
...existing.status,
analysedTime: existing.analysedTime,
};
}
const lastClosed = this.closed[`${conid}/${database}`]; const lastClosed = this.closed[`${conid}/${database}`];
if (lastClosed) return lastClosed.status; if (lastClosed) {
return {
...lastClosed.status,
analysedTime: lastClosed.analysedTime,
};
}
return { return {
name: 'error', name: 'error',
message: 'Not connected', message: 'Not connected',
@@ -156,6 +172,13 @@ module.exports = {
return { status: 'ok' }; return { status: 'ok' };
}, },
syncModel_meta: 'post',
async syncModel({ conid, database }) {
const conn = await this.ensureOpened(conid, database);
conn.subprocess.send({ msgtype: 'syncModel' });
return { status: 'ok' };
},
close(conid, database, kill = true) { close(conid, database, kill = true) {
const existing = this.opened.find(x => x.conid == conid && x.database == database); const existing = this.opened.find(x => x.conid == conid && x.database == database);
if (existing) { if (existing) {

View File

@@ -12,6 +12,7 @@ let afterConnectCallbacks = [];
let analysedStructure = null; let analysedStructure = null;
let lastPing = null; let lastPing = null;
let lastStatus = null; let lastStatus = null;
let analysedTime = 0;
async function checkedAsyncCall(promise) { async function checkedAsyncCall(promise) {
try { try {
@@ -28,23 +29,38 @@ async function checkedAsyncCall(promise) {
} }
} }
let loadingModel = false;
async function handleFullRefresh() { async function handleFullRefresh() {
loadingModel = true;
const driver = requireEngineDriver(storedConnection); const driver = requireEngineDriver(storedConnection);
setStatusName('loadStructure'); setStatusName('loadStructure');
analysedStructure = await checkedAsyncCall(driver.analyseFull(systemConnection)); analysedStructure = await checkedAsyncCall(driver.analyseFull(systemConnection));
analysedTime = new Date().getTime();
process.send({ msgtype: 'structure', structure: analysedStructure }); process.send({ msgtype: 'structure', structure: analysedStructure });
process.send({ msgtype: 'structureTime', analysedTime });
setStatusName('ok'); setStatusName('ok');
loadingModel = false;
} }
async function handleIncrementalRefresh() { async function handleIncrementalRefresh() {
loadingModel = true;
const driver = requireEngineDriver(storedConnection); const driver = requireEngineDriver(storedConnection);
setStatusName('checkStructure'); setStatusName('checkStructure');
const newStructure = await checkedAsyncCall(driver.analyseIncremental(systemConnection, analysedStructure)); const newStructure = await checkedAsyncCall(driver.analyseIncremental(systemConnection, analysedStructure));
analysedTime = new Date().getTime();
if (newStructure != null) { if (newStructure != null) {
analysedStructure = newStructure; analysedStructure = newStructure;
process.send({ msgtype: 'structure', structure: analysedStructure }); process.send({ msgtype: 'structure', structure: analysedStructure });
} }
process.send({ msgtype: 'structureTime', analysedTime });
setStatusName('ok'); setStatusName('ok');
loadingModel = false;
}
function handleSyncModel() {
if (loadingModel) return;
handleIncrementalRefresh();
} }
function setStatus(status) { function setStatus(status) {
@@ -80,7 +96,7 @@ async function handleConnect({ connection, structure, globalSettings }) {
handleFullRefresh(); handleFullRefresh();
} }
if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', true)) { if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', false)) {
setInterval( setInterval(
handleIncrementalRefresh, handleIncrementalRefresh,
extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 3, 3600) * 1000 extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 3, 3600) * 1000
@@ -172,6 +188,7 @@ const messageHandlers = {
collectionData: handleCollectionData, collectionData: handleCollectionData,
sqlPreview: handleSqlPreview, sqlPreview: handleSqlPreview,
ping: handlePing, ping: handlePing,
syncModel: handleSyncModel,
// runCommand: handleRunCommand, // runCommand: handleRunCommand,
}; };

View File

@@ -61,7 +61,7 @@ async function handleConnect(connection) {
systemConnection = await connectUtility(driver, storedConnection); systemConnection = await connectUtility(driver, storedConnection);
readVersion(); readVersion();
handleRefresh(); handleRefresh();
if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', true)) { if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', false)) {
setInterval(handleRefresh, extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 5, 3600) * 1000); setInterval(handleRefresh, extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 5, 3600) * 1000);
} }
} catch (err) { } catch (err) {

View File

@@ -4,6 +4,7 @@ export interface OpenedDatabaseConnection {
conid: string; conid: string;
database: string; database: string;
structure: DatabaseInfo; structure: DatabaseInfo;
analysedTime?: number;
serverVersion?: any; serverVersion?: any;
subprocess: ChildProcess; subprocess: ChildProcess;
disconnected?: boolean; disconnected?: boolean;

View File

@@ -40,6 +40,7 @@
'icon home': 'mdi mdi-home', 'icon home': 'mdi mdi-home',
'icon query-design': 'mdi mdi-vector-polyline-edit', 'icon query-design': 'mdi mdi-vector-polyline-edit',
'icon form': 'mdi mdi-form-select', 'icon form': 'mdi mdi-form-select',
'icon history': 'mdi mdi-history',
'icon edit': 'mdi mdi-pencil', 'icon edit': 'mdi mdi-pencil',
'icon delete': 'mdi mdi-delete', 'icon delete': 'mdi mdi-delete',

View File

@@ -50,7 +50,7 @@
<FormCheckboxField <FormCheckboxField
name="connection.autoRefresh" name="connection.autoRefresh"
label="Automatic refresh of database model on background" label="Automatic refresh of database model on background"
defaultValue={true} defaultValue={false}
/> />
<FormTextField <FormTextField
name="connection.autoRefreshInterval" name="connection.autoRefreshInterval"

View File

@@ -7,16 +7,19 @@
[tabid]: info, [tabid]: info,
})); }));
} }
</script> </script>
<script lang="ts"> <script lang="ts">
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import moment from 'moment';
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
import { activeTabId, currentDatabase } from '../stores'; import { activeTabId, currentDatabase } from '../stores';
import getConnectionLabel from '../utility/getConnectionLabel'; import getConnectionLabel from '../utility/getConnectionLabel';
import { useDatabaseServerVersion, useDatabaseStatus } from '../utility/metadataLoaders'; import { useDatabaseServerVersion, useDatabaseStatus } from '../utility/metadataLoaders';
import axiosInstance from '../utility/axiosInstance';
$: databaseName = $currentDatabase && $currentDatabase.name; $: databaseName = $currentDatabase && $currentDatabase.name;
$: connection = $currentDatabase && $currentDatabase.connection; $: connection = $currentDatabase && $currentDatabase.connection;
@@ -25,6 +28,19 @@
$: contextItems = $statusBarTabInfo[$activeTabId] as any[]; $: contextItems = $statusBarTabInfo[$activeTabId] as any[];
$: connectionLabel = getConnectionLabel(connection, { allowExplicitDatabase: false }); $: connectionLabel = getConnectionLabel(connection, { allowExplicitDatabase: false });
let timerValue = 1;
setInterval(() => {
timerValue++;
}, 10000);
async function handleSyncModel() {
if (connection && databaseName) {
await axiosInstance.post('database-connections/sync-model', { conid: connection._id, database: databaseName });
}
}
</script> </script>
<div class="main"> <div class="main">
@@ -75,6 +91,18 @@
</div> </div>
</div> </div>
{/if} {/if}
{#if $status?.analysedTime}
<div
class="item flex"
title={`DB model for current DB was analysed at ${new Date($status?.analysedTime)}`}
on:click={handleSyncModel}
>
<FontIcon icon="icon history" />
<div class="version ml-1">
{moment($status?.analysedTime).fromNow() + (timerValue ? '' : '')}
</div>
</div>
{/if}
</div> </div>
<div class="container"> <div class="container">
{#each contextItems || [] as item} {#each contextItems || [] as item}
@@ -94,6 +122,7 @@
color: var(--theme-font-inv-1); color: var(--theme-font-inv-1);
align-items: stretch; align-items: stretch;
justify-content: space-between; justify-content: space-between;
cursor: default;
} }
.container { .container {
display: flex; display: flex;
@@ -108,4 +137,5 @@
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
</style> </style>