Skip to content

feat(db_view): SQL 执行增加运行态指示,修复大查询期间界面无反馈 - #427

Merged
feigeCode merged 1 commit into
feigeCode:mainfrom
ekovovo:feat/sql-editor-running-indicator
Oct 20, 2026
Merged

feigeCode merged 1 commit into
feigeCode:mainfrom
ekovovo:feat/sql-editor-running-indicator

Conversation

@ekovovo

@ekovovo ekovovo commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Closes #[423]

背景

用户反馈:查询数据量较大时,SQL 已经提交执行,但界面上没有任何指示,容易误以为执行没有成功。此前结果面板内其实已实现“执行中”加载态(Spinner、正在解析并执行查询...、运行时间),但绝大多数大查询场景下它根本不会被渲染出来。

根因

  1. 结果面板在执行期间被整体隐藏
    SqlEditorTab::render 仅在 has_results && results_visible 时渲染结果面板;而每次执行开始都会先 clear_results。因此执行期间 has_results == false,面板连同内部的加载态一起消失。单条大 SELECT 要等结果全部返回才出现面板,期间界面零反馈。
  2. 会话(session)执行路径没有实时计时
    提取公共逻辑时发现:脚本执行路径有 100ms 计时任务,但 Auto 粘性会话 / 手动事务会话的执行路径只重置了开始时间,没有启动计时,运行时间 整段停在 0.000s。
  3. 建会话阶段完全静默
    首次连接、或手动事务新建会话时,从点击运行到 SQL 真正送出之间可能有数秒,这期间没有任何“执行中”指示。
  4. 取消键在建会话阶段无效
    面板进入运行态后工具栏显示停止键,但 Auto 建会话阶段尚未安装会话,cancel_execution 无法作废该次建立,查询仍会在会话就绪后照常执行。

改动

crates/db_view/src/sql_editor_view.rs

  • 新增纯函数 result_panel_visible(has_results, is_visible, is_executing),语义:
    执行中无条件渲染面板;非执行态沿用“有结果且用户未隐藏”。Render 与 render_sql_editor 统一使用该判定,执行时即使无结果、用户此前关过面板,也会强制展开结果面板。
  • 工具栏在 QueryToolbarAction::Stop(运行中)时,在动作按钮旁显示 Spinner + 运行中...(复用已有 Query.running i18n,无需新增文案)。这里刻意不读 total_elapsed_ms,避免计时器每 100ms 触发包含 SQL 输入框的整个编辑器重绘;滚动耗时由结果面板内的“运行时间”展示。
  • Auto 建会话(start_auto_session_and_run)与手动事务建会话(start_manual_transaction_and_run)在发起时调用 container.begin_run_pending(cx),进入可见运行态。
  • 建会话的 7 个中断分支统一调用 container.end_run_pending(pending_run, cx),保证指示器有始有终、不会卡在“运行中”:
    • Auto:创建会话失败、代次/上下文过期、会话未安装(3 处)
    • Manual:创建会话失败、代次/上下文过期、prepare 失败、会话未安装(4 处)
  • handle_stop_query:Auto 建会话阶段被取消时,显式自增 auto_session_generation 并复位 auto_session_starting,作废该次建立,避免“停不掉的查询”。

crates/db_view/src/sql_result_tab.rs

  • 抽出 enter_running_state(started_at, cx):清空结果后统一完成
    Executing { 0, 0 } 状态、切回摘要页、面板置可见、重置并启动 100ms 计时任务。
    脚本执行与会话执行两条路径共用,会话执行因此也获得实时运行时间。
  • 新增 begin_run_pending(cx) -> u64:进入“已提交、SQL 尚未送出”的运行态,返回本次执行代次。该阶段不清空上一轮结果,真正开始执行时才清;会话建立失败时旧结果得以保留。
  • 新增 end_run_pending(generation, cx):建会话失败/被打断时撤下运行态。仅当代次仍匹配且仍在执行时才收尾,避免误清已经开始的新查询。
  • handle_run_query / handle_run_query_with_session 改为复用 enter_running_state,删除重复的计时器样板代码(净减约 90 行)。

行为变化

场景 改动前 改动后
大查询执行中、尚无结果 无任何指示 面板自动展开,Spinner + 实时运行时间
执行中且用户此前关闭了结果面板 无任何指示 强制展开面板并显示运行态
首次连接 / 手动事务建会话 静默数秒 立即显示运行中
会话执行中的运行时间 停在 0.000s 每 100ms 滚动更新
建会话期间点击停止 无效,查询仍会执行 作废本次建会话
建会话失败 — 运行态撤下,旧结果保留

测试

  • 新增 executing_query_keeps_the_result_panel_visible:覆盖面板可见性真值表(执行中无结果/有结果、面板隐藏、非执行态)。
  • 新增 session_start_run_feedback_is_started_and_always_ended:断言 Auto/Manual 两条路径都启动运行指示,且 7 个中断分支都收尾(仅扫描生产代码,排除测试自身字符串)。
  • cargo test -p db_view --lib:946 个测试,945 通过,0 失败,1 ignored。
  • cargo check -p main --all-targets、cargo clippy -p db_view --all-targets 均无告警。

风险与说明

  • 不涉及数据库协议、DDL 或持久化结构,回滚仅需回退这两个文件。
  • 计时任务只驱动结果面板自身重绘,工具栏指示为状态驱动,避免大查询期间编辑器输入卡顿。
  • 已知取舍:查询被取消且此前无结果时,面板会重新隐藏(沿用原语义)。如需“已取消”空面板作为反馈,可作为后续增量调整。

Checklist

  • 执行中结果面板始终可见并给出加载指示
  • 建会话阶段纳入运行态,且有明确收尾
  • 会话执行路径运行时间实时更新
  • 建会话阶段可被停止
  • 新增/更新测试并通过
  • clippy / check 无告警

@feigeCode
feigeCode merged commit da78b5d into feigeCode:main Oct 20, 2026
8 checks passed
@feigeCode feigeCode mentioned this pull request Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants