Skip to content

Commit 1be4fc8

Browse files
janprochDiflow
authored andcommitted
SYNC: Merge pull request #100 from dbgate/feature/stale-loader-fix
1 parent 9a75f94 commit 1be4fc8

5 files changed

Lines changed: 69 additions & 11 deletions

File tree

packages/api/src/proc/databaseConnectionProcess.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ async function checkedAsyncCall(promise) {
6969
}
7070

7171
let loadingModel = false;
72+
let queuedSyncModelFullRefresh = null;
73+
74+
function finishLoadingModel() {
75+
loadingModel = false;
76+
if (queuedSyncModelFullRefresh != null) {
77+
const isFullRefresh = queuedSyncModelFullRefresh;
78+
queuedSyncModelFullRefresh = null;
79+
handleSyncModel({ isFullRefresh });
80+
}
81+
}
7282

7383
async function handleFullRefresh() {
7484
if (storedConnection.useSeparateSchemas && !isCompositeDbName(dbhan?.database)) {
@@ -86,7 +96,7 @@ async function handleFullRefresh() {
8696
process.send({ msgtype: 'structureTime', analysedTime });
8797
setStatusName('ok');
8898

89-
loadingModel = false;
99+
finishLoadingModel();
90100
resolveAnalysedPromises();
91101
}
92102

@@ -111,12 +121,15 @@ async function handleIncrementalRefresh(forceSend) {
111121

112122
process.send({ msgtype: 'structureTime', analysedTime });
113123
setStatusName('ok');
114-
loadingModel = false;
124+
finishLoadingModel();
115125
resolveAnalysedPromises();
116126
}
117127

118128
function handleSyncModel({ isFullRefresh }) {
119-
if (loadingModel) return;
129+
if (loadingModel) {
130+
queuedSyncModelFullRefresh = queuedSyncModelFullRefresh || !!isFullRefresh;
131+
return;
132+
}
120133
if (isFullRefresh) handleFullRefresh();
121134
else handleIncrementalRefresh();
122135
}

packages/web/src/appobj/AppObjectList.svelte

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import { writable } from 'svelte/store';
88
import Link from '../elements/Link.svelte';
99
import { focusedConnectionOrDatabase } from '../stores';
10-
import { tick } from 'svelte';
11-
import { _tval } from '../translations';
10+
import { tick, onDestroy, afterUpdate } from 'svelte';
11+
import { _t, _tval } from '../translations';
1212
1313
export let list;
1414
export let module;
@@ -34,8 +34,13 @@
3434
3535
export let collapsedGroupNames = writable([]);
3636
export let onChangeFilteredList = undefined;
37+
export let initialRenderCount = null;
38+
export let renderBatchSize = 200;
3739
3840
let expandLimited = false;
41+
let renderedCount = null;
42+
let renderTimer = null;
43+
let lastLimitedList = null;
3944
4045
$: matcher = module.createMatcher && module.createMatcher(filter, passProps?.searchSettings);
4146
@@ -82,6 +87,9 @@
8287
$: filtered = dataLabeled.filter(x => x.isMatched).map(x => x.data);
8388
$: childrenMatched = dataLabeled.filter(x => x.isChildMatched).map(x => x.data);
8489
$: mainMatched = dataLabeled.filter(x => x.isMainMatched).map(x => x.data);
90+
$: filteredSet = new Set(filtered);
91+
$: childrenMatchedSet = new Set(childrenMatched);
92+
$: mainMatchedSet = new Set(mainMatched);
8593
8694
// let filtered = [];
8795
@@ -112,12 +120,21 @@
112120
expandLimited = true;
113121
}
114122
115-
$: groups = groupFunc ? extendGroups(_.groupBy(dataLabeled, 'group'), emptyGroupNames) : null;
116-
117123
$: listLimited =
118124
isExpandedBySearch && !expandLimited ? filtered.slice(0, filter.trim().length < 3 ? 1 : 3) : listTranslated;
119125
$: isListLimited = isExpandedBySearch && listLimited.length < filtered.length;
120126
$: listMissingItems = isListLimited ? filtered.slice(listLimited.length) : [];
127+
$: if (initialRenderCount && listLimited !== lastLimitedList) {
128+
lastLimitedList = listLimited;
129+
renderedCount = Math.min(initialRenderCount, listLimited.length);
130+
}
131+
$: listRendered =
132+
initialRenderCount && renderedCount != null ? listLimited.slice(0, renderedCount) : listLimited;
133+
$: hasMoreToRender = initialRenderCount && renderedCount != null && renderedCount < listLimited.length;
134+
$: loadingMoreObjectsMessage = _t('objectsList.loadingMoreObjects', { defaultMessage: 'Loading more objects...' });
135+
$: dataLabeledRendered =
136+
initialRenderCount && renderedCount != null ? dataLabeled.slice(0, renderedCount) : dataLabeled;
137+
$: groups = groupFunc ? extendGroups(_.groupBy(dataLabeledRendered, 'group'), emptyGroupNames) : null;
121138
122139
$: if (
123140
$focusedConnectionOrDatabase &&
@@ -127,6 +144,21 @@
127144
) {
128145
tick().then(setExpandLimited);
129146
}
147+
148+
afterUpdate(() => {
149+
if (hasMoreToRender && !renderTimer) {
150+
renderTimer = setTimeout(() => {
151+
renderTimer = null;
152+
renderedCount = Math.min(listLimited.length, renderedCount + renderBatchSize);
153+
}, 0);
154+
}
155+
});
156+
157+
onDestroy(() => {
158+
if (renderTimer) {
159+
clearTimeout(renderTimer);
160+
}
161+
});
130162
</script>
131163
132164
{#if groupFunc}
@@ -152,10 +184,13 @@
152184
{collapsedGroupNames}
153185
/>
154186
{/each}
187+
{#if hasMoreToRender}
188+
<div class="ml-2 grayed">{loadingMoreObjectsMessage}</div>
189+
{/if}
155190
{:else}
156-
{#each listLimited as data}
191+
{#each listRendered as data}
157192
<AppObjectListItem
158-
isHidden={!filtered.includes(data)}
193+
isHidden={!filteredSet.has(data)}
159194
{module}
160195
{subItemsComponent}
161196
{expandOnClick}
@@ -166,8 +201,8 @@
166201
{checkedObjectsStore}
167202
{disableContextMenu}
168203
{filter}
169-
isExpandedBySearch={filter && childrenMatched.includes(data)}
170-
isMainMatched={filter && mainMatched.includes(data)}
204+
isExpandedBySearch={filter && childrenMatchedSet.has(data)}
205+
isMainMatched={filter && mainMatchedSet.has(data)}
171206
{passProps}
172207
{getIsExpanded}
173208
{setIsExpanded}
@@ -182,4 +217,7 @@
182217
>
183218
</div>
184219
{/if}
220+
{#if hasMoreToRender}
221+
<div class="ml-2 grayed">{loadingMoreObjectsMessage}</div>
222+
{/if}
185223
{/if}

packages/web/src/utility/common.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,17 @@ export async function loadSchemaList(conid, database) {
126126
}
127127
}
128128

129+
let switchCurrentDatabaseRequest = 0;
130+
129131
export async function switchCurrentDatabase(data) {
132+
const request = ++switchCurrentDatabaseRequest;
130133
if (data?.connection?.useSeparateSchemas && !isCompositeDbName(data.name)) {
131134
const conid = data.connection._id;
132135
const database = data.name;
133136
const storageKey = `selected-schema-${conid}-${database}`;
134137
const schemaInStorage = localStorage.getItem(storageKey);
135138
const schemas = await loadSchemaList(conid, database);
139+
if (request != switchCurrentDatabaseRequest) return;
136140
if (!schemas) return;
137141
const driver = findEngineDriver(data.connection, getExtensions());
138142
const defaultSchema = findDefaultSchema(schemas, driver?.dialect, schemaInStorage);

packages/web/src/utility/metadataLoaders.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ function useCore(loader, args) {
265265
}
266266
}
267267
openedCount += 1;
268+
onChange(getCachedValue(cacheKey));
268269
handleReload();
269270

270271
if (reloadTrigger) {

packages/web/src/widgets/SqlObjectList.svelte

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@
371371
list={objectList
372372
.filter(x => x.schemaName == null || ($appliedCurrentSchema ? x.schemaName == $appliedCurrentSchema : true))
373373
.map(x => ({ ...x, conid, database }))}
374+
initialRenderCount={200}
375+
renderBatchSize={200}
374376
module={databaseObjectAppObject}
375377
groupFunc={getAppObjectGroup}
376378
subItemsComponent={(data, { isExpandedBySearch }) =>

0 commit comments

Comments
 (0)