From 93d2e7dc18dd8ab07653711a259e19f1d6d6cd7d Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sun, 14 Jun 2026 15:43:27 +0800 Subject: [PATCH] fix(redis): split multi-line commands before execution --- .../src/composables/useSqlExecution.ts | 16 +++++--- apps/desktop/src/stores/queryStore.ts | 38 +++++++++++++++---- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/apps/desktop/src/composables/useSqlExecution.ts b/apps/desktop/src/composables/useSqlExecution.ts index c2788ae1eb..21ec61333a 100644 --- a/apps/desktop/src/composables/useSqlExecution.ts +++ b/apps/desktop/src/composables/useSqlExecution.ts @@ -62,12 +62,18 @@ export function useSqlExecution(deps: { const tab = deps.activeTab.value; const sql = sqlOverride ?? (await resolvedExecutableSql()); if (!tab || !sql.trim()) return; - // Redis: block dangerous commands when toggle is on + // Redis: block dangerous commands when toggle is on (check each line for multi-line input) if (deps.activeConnection.value?.db_type === "redis" && deps.blockDangerousRedisCommands?.value !== false) { - const safety = classifyRedisCommandSafety(sql); - if (safety === "blocked") { - toast(t("redis.blockedCommand", { command: firstRedisCommandToken(sql) }), 5000); - return; + const commands = sql + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0); + for (const cmd of commands) { + const safety = classifyRedisCommandSafety(cmd); + if (safety === "blocked") { + toast(t("redis.blockedCommand", { command: firstRedisCommandToken(cmd) }), 5000); + return; + } } } if (isDangerousSql(sql) && settingsStore.editorSettings.confirmDangerousSqlExecution) { diff --git a/apps/desktop/src/stores/queryStore.ts b/apps/desktop/src/stores/queryStore.ts index 64880821a1..4aa26df1f3 100644 --- a/apps/desktop/src/stores/queryStore.ts +++ b/apps/desktop/src/stores/queryStore.ts @@ -1154,18 +1154,42 @@ export const useQueryStore = defineStore("query", () => { const settingsStore = useSettingsStore(); await previousResultSessionClose; - // Redis command execution + // Redis command execution — split multi-line input into individual commands if (conn?.db_type === "redis") { await connStore.ensureConnected(tab.connectionId); const redisDb = Number(tab.database) || 0; - console.info("[DBX][executeTabSql:redis:start]", { traceId, db: redisDb, sql }); - const result = await api.redisExecuteCommand(tab.connectionId, redisDb, sql, options?.skipRedisSafetyCheck); - console.info("[DBX][executeTabSql:redis:done]", { traceId, elapsed: elapsed() }); + const commands = sql + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0); + if (commands.length === 0) return; + console.info("[DBX][executeTabSql:redis:start]", { traceId, db: redisDb, commandCount: commands.length, sql }); + + const allResults: QueryResult[] = []; + const skipSafety = options?.skipRedisSafetyCheck; + for (const command of commands) { + try { + const result = await api.redisExecuteCommand(tab.connectionId, redisDb, command, skipSafety); + allResults.push(markQueryResultRowsRaw(redisCommandResultToQueryResult(result.value, performance.now() - startedAt, result.command))); + } catch (e: any) { + allResults.push({ columns: ["Error"], rows: [[e?.message ?? String(e)]], affected_rows: 0, execution_time_ms: 0 }); + } + } + console.info("[DBX][executeTabSql:redis:done]", { traceId, commandCount: commands.length, elapsed: elapsed() }); + const current = tabs.value.find((t) => t.id === id); if (current?.executionId === executionId) { - current.results = undefined; - current.activeResultIndex = undefined; - current.result = markQueryResultRowsRaw(redisCommandResultToQueryResult(result.value, performance.now() - startedAt, result.command)); + if (allResults.length > 1) { + const activeResultIndex = allResults.findIndex((r) => !r.columns.includes("Error")); + const resultIndex = activeResultIndex >= 0 ? activeResultIndex : 0; + current.results = allResults; + current.activeResultIndex = resultIndex; + current.result = allResults[resultIndex]; + } else { + current.results = undefined; + current.activeResultIndex = undefined; + current.result = allResults[0]; + } touchResult(current); current.queryAnalysis = undefined; current.querySourceColumns = undefined;