diff --git a/packages/api/src/controllers/databaseConnections.js b/packages/api/src/controllers/databaseConnections.js
index 5fc2bed2f..2b6867021 100644
--- a/packages/api/src/controllers/databaseConnections.js
+++ b/packages/api/src/controllers/databaseConnections.js
@@ -229,9 +229,9 @@ module.exports = {
},
loadKeys_meta: true,
- async loadKeys({ conid, database, root, filter }, req) {
+ async loadKeys({ conid, database, root, filter, limit }, req) {
testConnectionPermission(conid, req);
- return this.loadDataCore('loadKeys', { conid, database, root, filter });
+ return this.loadDataCore('loadKeys', { conid, database, root, filter, limit });
},
exportKeys_meta: true,
diff --git a/packages/api/src/proc/databaseConnectionProcess.js b/packages/api/src/proc/databaseConnectionProcess.js
index d4a887e9c..840510695 100644
--- a/packages/api/src/proc/databaseConnectionProcess.js
+++ b/packages/api/src/proc/databaseConnectionProcess.js
@@ -258,8 +258,8 @@ async function handleCollectionData({ msgid, options }) {
return handleDriverDataCore(msgid, driver => driver.readCollection(dbhan, options), { logName: 'readCollection' });
}
-async function handleLoadKeys({ msgid, root, filter }) {
- return handleDriverDataCore(msgid, driver => driver.loadKeys(dbhan, root, filter), { logName: 'loadKeys' });
+async function handleLoadKeys({ msgid, root, filter, limit }) {
+ return handleDriverDataCore(msgid, driver => driver.loadKeys(dbhan, root, filter, limit), { logName: 'loadKeys' });
}
async function handleExportKeys({ msgid, options }) {
diff --git a/packages/web/src/widgets/DbKeysSubTree.svelte b/packages/web/src/widgets/DbKeysSubTree.svelte
index b5e14b1c9..e82d470b3 100644
--- a/packages/web/src/widgets/DbKeysSubTree.svelte
+++ b/packages/web/src/widgets/DbKeysSubTree.svelte
@@ -5,7 +5,7 @@
import LoadingInfo from '../elements/LoadingInfo.svelte';
import { apiCall } from '../utility/api';
- const SHOW_INCREMENT = 500;
+ const SHOW_INCREMENT = 100;
import DbKeysTreeNode from './DbKeysTreeNode.svelte';
@@ -20,18 +20,46 @@
export let filter;
let reloadToken2 = 0;
-
let maxShowCount = SHOW_INCREMENT;
+ let loading = false;
+ let loadingWhole = false;
+ let items = [];
- // $: items = useDatabaseKeys({ conid, database, root, reloadToken });
+ async function loadData() {
+ loading = true;
+ const result = await apiCall('database-connections/load-keys', {
+ conid,
+ database,
+ root,
+ filter,
+ limit: maxShowCount + 1,
+ });
+ items = result;
+ loading = false;
+ loadingWhole = false;
+ }
+
+ $: {
+ conid;
+ database;
+ root;
+ filter;
+ reloadToken;
+ reloadToken2;
+ maxShowCount;
+ loadData();
+ }
+
+ $: {
+ reloadToken;
+ loadingWhole = true;
+ }
-{#await apiCall('database-connections/load-keys', { conid, database, root, filter, reloadToken, reloadToken2 })}
+{#if loadingWhole}
-{:then items}
- {@const itemsSorted = _.sortBy(items || [], 'text')}
-
- {#each itemsSorted.slice(0, maxShowCount) as item}
+{:else}
+ {#each items.slice(0, maxShowCount) as item}
{/each}
- {#if itemsSorted.length > maxShowCount}
+ {#if loading}
+
+ {:else if items.length > maxShowCount}
{/if}
-{/await}
+{/if}
diff --git a/plugins/dbgate-plugin-redis/src/backend/driver.js b/plugins/dbgate-plugin-redis/src/backend/driver.js
index d3d119f19..111f24ffb 100644
--- a/plugins/dbgate-plugin-redis/src/backend/driver.js
+++ b/plugins/dbgate-plugin-redis/src/backend/driver.js
@@ -169,12 +169,14 @@ const driver = {
return _.range(16).map((index) => ({ name: `db${index}`, extInfo: info[`db${index}`], sortOrder: index }));
},
- async loadKeys(dbhan, root = '', filter = null) {
+ async loadKeys(dbhan, root = '', filter = null, limit = null) {
const keys = await this.getKeys(dbhan, root ? `${root}${dbhan.treeKeySeparator}*` : '*');
const keysFiltered = keys.filter((x) => filterName(filter, x));
- const res = this.extractKeysFromLevel(dbhan, root, keysFiltered);
- await this.enrichKeyInfo(dbhan, res);
- return res;
+ const keysSorted = _.sortBy(keysFiltered, 'text');
+ const res = this.extractKeysFromLevel(dbhan, root, keysSorted);
+ const resLimited = limit ? res.slice(0, limit) : res;
+ await this.enrichKeyInfo(dbhan, resLimited);
+ return resLimited;
},
async exportKeys(dbhan, options) {
@@ -192,14 +194,36 @@ const driver = {
},
async getKeys(dbhan, keyQuery = '*') {
- const res = [];
- let cursor = 0;
- do {
- const [strCursor, keys] = await dbhan.client.scan(cursor, 'MATCH', keyQuery, 'COUNT', 100);
- res.push(...keys);
- cursor = parseInt(strCursor);
- } while (cursor > 0);
- return res;
+ const stream = dbhan.client.scanStream({
+ match: keyQuery,
+ count: 1000,
+ });
+
+ const keys = [];
+
+ stream.on('data', (resultKeys) => {
+ for (const key of resultKeys) {
+ keys.push(key);
+ }
+ });
+
+ return new Promise((resolve, reject) => {
+ stream.on('end', () => {
+ resolve(keys);
+ });
+ stream.on('error', (err) => {
+ reject(err);
+ });
+ });
+
+ // const res = [];
+ // let cursor = 0;
+ // do {
+ // const [strCursor, keys] = await dbhan.client.scan(cursor, 'MATCH', keyQuery, 'COUNT', 100);
+ // res.push(...keys);
+ // cursor = parseInt(strCursor);
+ // } while (cursor > 0);
+ // return res;
},
extractKeysFromLevel(dbhan, root, keys) {