fix(redis): refresh sidebar db key counts after write commands

Redis write commands (SET/DEL/...) ran from the query editor or the
key-browser terminal did not update the dbN (count) labels in the left
tree until a manual refresh. Add refreshRedisDbKeyCounts(), which re-fetches
authoritative per-db counts via INFO keyspace and patches the labels in place
without rebuilding the tree (preserving expanded key nodes), then trigger it
fire-and-forget after any mutating command in both execution paths.
This commit is contained in:
haipengno1 2026-06-17 10:35:01 +08:00 committed by GitHub
parent b2617039fa
commit b575ec2729
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 0 deletions

View File

@ -447,6 +447,9 @@ async function runRedisCommand(command: string) {
// reflects keys added/removed/renamed by SET/DEL/RENAME/...
if (isRedisMutatingCommand(command)) {
connectionStore.invalidateCompletionCache(props.connectionId, String(executedDb));
// Refresh the sidebar db key counts (INFO keyspace) so `dbN (count)` stays accurate
// after the write. Fire-and-forget so the terminal stays responsive.
void connectionStore.refreshRedisDbKeyCounts(props.connectionId);
}
// Persist to history
persistRedisHistory(command, true, result.value);

View File

@ -1067,6 +1067,24 @@ export const useConnectionStore = defineStore("connection", () => {
node.label = redisDbLabel(db, node.loadedKeyCount, node.totalKeyCount);
}
// Re-fetch the authoritative per-db key counts (INFO keyspace, lightweight) and update
// the sidebar db nodes' counts in place — WITHOUT rebuilding the tree, so already-loaded
// key trees under expanded db nodes are preserved. Used after a Redis write command so the
// `dbN (count)` labels reflect the new reality without a manual refresh.
async function refreshRedisDbKeyCounts(connectionId: string) {
const connNode = findNode(treeNodes.value, connectionId);
if (!connNode) return;
try {
await ensureConnected(connectionId);
const dbs = await api.redisListDatabases(connectionId);
for (const db of dbs) {
updateRedisDbKeyStats(connectionId, db.db, { total: db.keys });
}
} catch {
// Best-effort: a failed count refresh must not disrupt the result view.
}
}
async function loadMongoDatabases(connectionId: string) {
const node = findNode(treeNodes.value, connectionId);
if (!node) return;
@ -2759,6 +2777,7 @@ export const useConnectionStore = defineStore("connection", () => {
initFromDisk,
loadDatabases,
loadRedisDatabases,
refreshRedisDbKeyCounts,
loadEtcdRoot,
loadMqTenants,
updateRedisDbKeyStats,

View File

@ -1197,6 +1197,7 @@ export const useQueryStore = defineStore("query", () => {
const allResults: QueryResult[] = [];
const skipSafety = options?.skipRedisSafetyCheck;
let hadMutatingCommand = false;
for (const command of commands) {
try {
const result = await api.redisExecuteCommand(tab.connectionId, currentDb, command, skipSafety);
@ -1206,6 +1207,7 @@ export const useQueryStore = defineStore("query", () => {
// Write commands (SET/DEL/...) mutate the key set — drop the cached key-name completion
// for the db this command ran on so the next autocomplete fetch reflects the new keys.
if (isRedisMutatingCommand(command)) {
hadMutatingCommand = true;
connStore.invalidateCompletionCache(tab.connectionId, String(currentDb));
}
} catch (e: any) {
@ -1241,6 +1243,12 @@ export const useQueryStore = defineStore("query", () => {
current.database = String(currentDb);
}
}
// Refresh the sidebar db key counts (INFO keyspace) when at least one command in
// this batch mutated the key set, so `dbN (count)` stays accurate without a manual
// refresh. Fire-and-forget: never block result display.
if (hadMutatingCommand) {
void connStore.refreshRedisDbKeyCounts(tab.connectionId);
}
return;
}