feat(usable): integrate current dbtool implementation snapshot
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -5,7 +5,7 @@ use std::process::ExitCode;
|
||||
|
||||
use db_app::{
|
||||
self, AppError, ColumnItem, ConnectResponse, ExportResponse, InspectPayload, InspectResponse,
|
||||
OperationState, QueryResponse, SchemaItem, TableItem,
|
||||
OperationState, QueryResponse, SchemaAvailability, SchemaItem, TableItem,
|
||||
};
|
||||
use db_config::ConnectionProfile;
|
||||
use db_core::{
|
||||
@@ -794,7 +794,13 @@ fn render_query_text(response: &QueryResponse) -> String {
|
||||
}
|
||||
|
||||
fn render_schema(schema: &SchemaItem) -> String {
|
||||
schema.name.clone()
|
||||
match schema.availability {
|
||||
SchemaAvailability::Ready => schema.name.clone(),
|
||||
SchemaAvailability::Restricted => match &schema.note {
|
||||
Some(note) => format!("{} [restricted] - {}", schema.name, note),
|
||||
None => format!("{} [restricted]", schema.name),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn render_table(table: &TableItem) -> String {
|
||||
@@ -820,6 +826,22 @@ mod tests {
|
||||
#[cfg(unix)]
|
||||
use std::{fs::Permissions, os::unix::fs::PermissionsExt};
|
||||
|
||||
#[test]
|
||||
fn render_schema_marks_restricted_entries() {
|
||||
let rendered = render_schema(&SchemaItem {
|
||||
name: String::from("restricted_probe"),
|
||||
availability: SchemaAvailability::Restricted,
|
||||
note: Some(String::from(
|
||||
"schema access is restricted: restricted_probe",
|
||||
)),
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
rendered,
|
||||
"restricted_probe [restricted] - schema access is restricted: restricted_probe"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_query_args_collects_params() {
|
||||
let args = vec![
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
- 独立 `dbtool-tui` 应用入口
|
||||
- 稳定的六区工作台布局
|
||||
- 顶部视图切换与底部快捷键提示
|
||||
- 连接管理列表、当前连接上下文和失败连接可视化区分
|
||||
- 基于 shared profile store 的连接管理列表、当前连接上下文和失败连接可视化区分
|
||||
- `Connections` 视图内的分步式新增 / 编辑 / 删除 / 测试 / 保存并激活工作流
|
||||
- session-only secret 输入与复用;密码不会写入持久化 profile 文件
|
||||
- 键盘驱动的连接切换工作流,以及连接 `loading / success / failure` 可视状态
|
||||
- `sqlite-local` 的真实 connect / inspect 路径,schema browser 可展示 live schema / table / column
|
||||
- `sqlite-local` 的真实 query / results / export 工作流,直接复用 `crates/db-app`
|
||||
- PostgreSQL / MySQL 的 Docker demo live activation / query / export 路径
|
||||
- shared inspect 返回 schema-level availability 时,`Schema Browser` / `Inspector` / `Status & Activity` 可稳定区分 `ready / empty / restricted`
|
||||
- 查询草稿切换、基础键入编辑、执行触发与执行状态反馈
|
||||
- 成功 / 空结果 / 错误三类查询结果展示,以及宽表列分页提示
|
||||
- 当前结果集导出到 `/tmp` 的 CSV / JSON 反馈
|
||||
@@ -25,8 +28,8 @@
|
||||
当前不包含:
|
||||
|
||||
- 多连接并发会话
|
||||
- 自定义新增 / 编辑连接表单
|
||||
- 非 demo 自定义 network profile
|
||||
- 跨重启持久化 secret 管理
|
||||
- 多步向导之外的复杂连接模板或批量导入
|
||||
- 完整 SQL 编辑器能力
|
||||
|
||||
## usable-v1 口径边界
|
||||
@@ -54,6 +57,7 @@ cargo run -p dbtool-tui
|
||||
当前默认 live 路径是 `sqlite-local`,底层使用 `examples/tmp/dbtool-demo.sqlite`。
|
||||
启动后会自动对 `sqlite-local` 执行 connect + inspect;切换连接时会重新触发 live activation。
|
||||
内置 `reporting-postgres` / `orders-mysql` profile 默认走 `host.docker.internal:55432/53306`,并分别复用 `dbtool_demo` / `qa_demo` demo 数据。
|
||||
保存的 profile 默认写入 `~/.config/dbtool/tui-profiles.json`;若需要隔离测试,可在启动前设置 `DBTOOL_TUI_PROFILE_STORE=/tmp/dbtool-tui-profiles.json`。
|
||||
|
||||
如果当前 runner 缺少 Rust 工具链,可先使用已有产物:
|
||||
|
||||
@@ -98,42 +102,49 @@ scripts/tui/smoke-tty.sh ./target/debug/dbtool-tui 20 90 /tmp/dbtool-tui-small.l
|
||||
- `Tab` / `Shift+Tab`:切换焦点面板
|
||||
- `←` / `→` 或 `1` / `2` / `3`:切换顶部视图
|
||||
- `↑` / `↓`:移动连接、schema/object 或结果行选择
|
||||
- `Enter`:在 `Connections` 焦点下激活所选连接;在 `Schema Browser` 焦点下展开 / 折叠 schema 或确认对象;在 `Query Editor` 焦点下执行当前查询
|
||||
- `i`:在 `Query Editor` 中进入基础插入模式
|
||||
- `Enter`:在 `Connections` 焦点下激活所选连接;在 `Connections` 视图的 `Query Editor` 下循环 driver 或提交字段编辑;在 `Schema Browser` 焦点下展开 / 折叠 schema 或确认对象;在 `Query Editor` 焦点下执行当前查询
|
||||
- `n` / `e` / `d`:在 `Connections` 视图中新增 / 编辑 / 删除保存的 profile
|
||||
- `i`:在 `Connections` 视图中编辑当前字段;在工作区 `Query Editor` 中进入 SQL 基础插入模式
|
||||
- `t`:在连接表单中测试当前 staged profile(connect + inspect)
|
||||
- `s`:在连接表单中保存并激活当前 staged profile
|
||||
- `x`:将当前结果集导出为 CSV 到 `/tmp`
|
||||
- `j`:将当前结果集导出为 JSON 到 `/tmp`
|
||||
- `[` / `]`:在 `Query Editor` 中切换查询草稿;在 `Results` 中横向翻页宽表列
|
||||
- `r`:清空当前 query / export 反馈,回到 `Ready`
|
||||
- `Esc`:回到默认工作台
|
||||
- `Esc`:取消当前连接管理动作,或回到默认工作台
|
||||
- `q`:退出
|
||||
|
||||
## 状态恢复与键位一致性
|
||||
|
||||
- `Esc` 在两个场景下都承担“回到稳定态”的职责:编辑模式下先退回 navigate mode;普通导航下回到默认 `Workspace` + `Query Editor` 焦点。
|
||||
- `Esc` 在三个场景下都承担“回到稳定态”的职责:连接表单 / 删除确认时先取消当前动作;编辑模式下退回 navigate mode;普通导航下回到默认 `Workspace` + `Query Editor` 焦点。
|
||||
- `r` 是唯一的显式恢复键:会同时清空 query 结果、query 错误、export 成功/失败反馈,并把界面状态收口回 `Ready`。
|
||||
- `[` / `]` 只在两个焦点区生效:`Query Editor` 下切换草稿,`Results` 下横向翻页;其他面板按下不会触发隐藏状态变化。
|
||||
- `[` / `]` 只在工作区的两个焦点区生效:`Query Editor` 下切换草稿,`Results` 下横向翻页;其他面板按下不会触发隐藏状态变化。
|
||||
- `x` / `j` 只在当前工作区已有“成功且可导出”的结果集时成立;若查询仍在运行或当前没有可导出结果,会保留明确错误/提示,而不是静默失败。
|
||||
- `Enter` 的语义由当前焦点决定:`Connections` = 激活连接,`Schema Browser` = 展开/确认对象,`Query Editor` = 执行查询;插入模式下 `Enter` 只插入换行。
|
||||
- `Enter` 的语义由当前视图和焦点共同决定:`Connections` = 激活连接,连接表单中的 `Query Editor` = 提交字段 / 循环 driver,`Schema Browser` = 展开/确认对象,工作区 `Query Editor` = 执行查询;插入模式下 `Enter` 只提交当前字段或插入换行。
|
||||
|
||||
## 快速测试路径
|
||||
|
||||
如果你只是想快速走通一遍当前可见工作流,推荐按下面步骤操作:
|
||||
|
||||
1. 启动 `cargo run -p dbtool-tui`
|
||||
2. 等待默认连接 `sqlite-local` 从 `Loading` 变成可用状态
|
||||
3. 按 `Tab` 把焦点切到 `Schema Browser`
|
||||
4. 用 `↑` / `↓` 选择 `main.accounts` 或 `main.tickets`
|
||||
5. 按 `Tab` 切到 `Query Editor`
|
||||
6. 先不要按 `i`,直接按 `[` / `]` 切换草稿
|
||||
7. 选中 `account_ticket_summary.sql` 后按 `Enter`,确认成功结果
|
||||
8. 切到 `empty_recent_tickets.sql` 后按 `Enter`,确认空结果
|
||||
9. 切到 `bad_syntax.sql` 后按 `Enter`,确认错误结果持续留在工作区
|
||||
10. 切到 `ticket_export_preview.sql` 后按 `Enter`,成功后按 `x` 或 `j`,确认导出反馈和 `/tmp` 路径
|
||||
2. 按 `2` 进入 `Connections` 视图,确认左侧列表来自 profile store
|
||||
3. 按 `n` 新建 profile,在中间 `Query Editor` 里用 `i` 编辑字段、`t` 测试连接、`s` 保存并激活
|
||||
4. 等待活动连接从 `Loading` 变成 `Healthy`
|
||||
5. 按 `Tab` 把焦点切到 `Schema Browser`
|
||||
6. 用 `↑` / `↓` 选择 `main.accounts` 或 `main.tickets`
|
||||
7. 按 `Tab` 切到 `Query Editor`
|
||||
8. 先不要按 `i`,直接按 `[` / `]` 切换草稿
|
||||
9. 选中 `account_ticket_summary.sql` 后按 `Enter`,确认成功结果
|
||||
10. 切到 `empty_recent_tickets.sql` 后按 `Enter`,确认空结果
|
||||
11. 切到 `bad_syntax.sql` 后按 `Enter`,确认错误结果持续留在工作区
|
||||
12. 切到 `ticket_export_preview.sql` 后按 `Enter`,成功后按 `x` 或 `j`,确认导出反馈和 `/tmp` 路径
|
||||
|
||||
## 常见困惑
|
||||
|
||||
- `Inserted a newline. Press Esc, then Enter to run.`:表示你已经按了 `i` 进入编辑模式,然后按了 `Enter`;这时 `Enter` 不会执行查询,而是插入换行。按 `Esc` 退出编辑模式后,再按 `Enter` 才是执行查询。
|
||||
- 当前不能自定义输入数据库连接:这是当前范围外能力。当前 TUI 只提供内置的 `sqlite-local`、Postgres、MySQL 示例连接,用于验证工作台流程和状态反馈。
|
||||
- 当前保存的 profile 文件不包含密码:界面里的 `Session password` 只在本次 TUI 进程中可用;如果需要跨重启复用,请配置 `Password env`。
|
||||
- 如果修改了 profile store 路径,建议用临时文件如 `DBTOOL_TUI_PROFILE_STORE=/tmp/dbtool-tui-profiles.json` 做 smoke,避免污染长期配置。
|
||||
- 若 GUI host 或宿主机需要把 demo network host 从 `host.docker.internal` 改到 `127.0.0.1`,只能在启动前设置 `DBTOOL_TUI_POSTGRES_HOST` / `DBTOOL_TUI_POSTGRES_PORT` 与 `DBTOOL_TUI_MYSQL_HOST` / `DBTOOL_TUI_MYSQL_PORT`;这属于 operator fallback,不等于连接管理已交付。
|
||||
- 如果觉得界面文字偏多:本轮已先做一轮 Help / Status / Connections 文案收敛;当前版本仍偏向 QA / 契约验证界面,后续再继续收敛文案。
|
||||
|
||||
## 界面验收
|
||||
@@ -142,20 +153,22 @@ QA 可按以下步骤复核:
|
||||
|
||||
1. 启动后能看到 `Connections`、`Schema Browser`、`Query Editor`、`Results`、`Inspector`、`Status & Activity` 六个区域
|
||||
2. 默认活动连接应为 `sqlite-local`,且 `Connections` 列表中能区分当前连接、可选连接和失败连接
|
||||
3. 使用 `2` 进入 `Connections` 视图后,可用 `↑` / `↓` 移动连接选择
|
||||
4. 在 `Connections` 焦点下按 `Enter` 激活失败连接时,`Status & Activity` 与 `Inspector` 会持续显示可读错误,而不是只给瞬时提示
|
||||
5. 启动后或回到 `sqlite-local` 后,连接状态会先进入 `Loading`,随后在 `Schema Browser` 焦点下可浏览 `main.accounts` 和 `main.tickets`
|
||||
6. 选中对象后,`Results` 会展示列定义,`Inspector` 会展示当前 schema / object / column 上下文
|
||||
7. 在 `Query Editor` 焦点下可用 `[` / `]` 切换查询草稿,`i` 进入基础输入模式,`Enter` 触发执行
|
||||
8. `account_ticket_summary.sql` 应返回真实结果行,`empty_recent_tickets.sql` 应显示空结果,`bad_syntax.sql` 应显示结构化错误
|
||||
9. `ticket_export_preview.sql` 执行成功后,按 `x` 或 `j` 应在工作区内看到导出成功反馈和 `/tmp` 输出路径
|
||||
10. 成功结果在 `Results` 中以表格方式展示,宽表会给出列分页提示,长结果仍可用 `↑` / `↓` 浏览
|
||||
11. 错误状态会保留可读错误信息,不退化成空白或瞬时提示
|
||||
12. 使用 `Tab` / `Shift+Tab` 时,当前焦点区域边框高亮会移动
|
||||
13. 使用 `←` / `→` 或 `1` / `2` / `3` 时,中间内容区会随视图切换
|
||||
14. 使用 `r` 时,query / export 反馈会清空并回到 `Ready`
|
||||
15. 将终端缩小到低于 `100x28` 时,会出现尺寸不足提示而不是错乱布局
|
||||
16. 使用 `Esc` 可恢复默认工作台,使用 `q` 可稳定退出
|
||||
3. 使用 `2` 进入 `Connections` 视图后,可用 `↑` / `↓` 移动连接选择,并在 `Results` / `Inspector` 里看到 profile store 与 secret source 摘要
|
||||
4. 按 `n` 可进入新增流程;中间 `Query Editor` 会切换成分步式字段表单,`i` 进入字段编辑,`t` 测试连接,`s` 保存并激活
|
||||
5. 编辑流程下 `Session password` 只显示 session-only 提示,不会回显明文密码
|
||||
6. 在 `Connections` 焦点下按 `Enter` 激活失败连接时,`Status & Activity` 与 `Inspector` 会持续显示可读错误,而不是只给瞬时提示
|
||||
7. 启动后或回到 `sqlite-local` 后,连接状态会先进入 `Loading`,随后在 `Schema Browser` 焦点下可浏览 `main.accounts` 和 `main.tickets`
|
||||
8. 选中对象后,`Results` 会展示列定义,`Inspector` 会展示当前 schema / object / column 上下文
|
||||
9. 在工作区 `Query Editor` 焦点下可用 `[` / `]` 切换查询草稿,`i` 进入基础输入模式,`Enter` 触发执行
|
||||
10. `account_ticket_summary.sql` 应返回真实结果行,`empty_recent_tickets.sql` 应显示空结果,`bad_syntax.sql` 应显示结构化错误
|
||||
11. `ticket_export_preview.sql` 执行成功后,按 `x` 或 `j` 应在工作区内看到导出成功反馈和 `/tmp` 输出路径
|
||||
12. 成功结果在 `Results` 中以表格方式展示,宽表会给出列分页提示,长结果仍可用 `↑` / `↓` 浏览
|
||||
13. 错误状态会保留可读错误信息,不退化成空白或瞬时提示
|
||||
14. 使用 `Tab` / `Shift+Tab` 时,当前焦点区域边框高亮会移动
|
||||
15. 使用 `←` / `→` 或 `1` / `2` / `3` 时,中间内容区会随视图切换
|
||||
16. 使用 `r` 时,query / export 反馈会清空并回到 `Ready`
|
||||
17. 将终端缩小到低于 `100x28` 时,会出现尺寸不足提示而不是错乱布局
|
||||
18. 使用 `Esc` 可取消当前连接管理动作或恢复默认工作台,使用 `q` 可稳定退出
|
||||
|
||||
## 当前限制
|
||||
|
||||
|
||||
1648
apps/tui/src/main.rs
1648
apps/tui/src/main.rs
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user