205 lines
8.5 KiB
Markdown
205 lines
8.5 KiB
Markdown
# dbtool-cli-v1
|
||
|
||
`dbtool-cli-v1` 是一个面向 PostgreSQL、MySQL 和 SQLite 的跨数据库 CLI 工具。
|
||
|
||
当前仓库已经具备 Rust workspace 基线,并已落地 PostgreSQL、MySQL 与 SQLite 的首个 happy path:
|
||
|
||
- 根 `Cargo` workspace
|
||
- `apps/cli` 可执行入口
|
||
- `crates/db-core` 领域模型与输入校验
|
||
- `crates/db-config` 连接 profile 与脱敏摘要
|
||
- `crates/db-drivers` 驱动边界与 PostgreSQL / MySQL / SQLite 实现
|
||
|
||
## 当前状态
|
||
|
||
当前已实现:
|
||
|
||
- PostgreSQL `connect`
|
||
- PostgreSQL `inspect`
|
||
- PostgreSQL `query`
|
||
- MySQL `connect`
|
||
- MySQL `inspect`
|
||
- MySQL `query`
|
||
- SQLite `connect`
|
||
- SQLite `inspect`
|
||
- SQLite `query`
|
||
- `export` 到 CSV
|
||
- `export` 到 JSON
|
||
- `.sql` 文件读取
|
||
- `--password-env` 密码注入且保持输出脱敏
|
||
|
||
已验证:
|
||
|
||
- 标准环境:`cargo build`
|
||
- 标准环境:`cargo test`
|
||
- 标准环境:`cargo run -p dbtool-cli -- --help`
|
||
- 链接器受限的 Linux 环境:使用 `zig cc` 作为 host linker 执行 `cargo check` / `cargo test`
|
||
|
||
当前 `connect` / `inspect` / `query` / `export` 在 PostgreSQL、MySQL 与 SQLite 的共享抽象上都已经可用;当前剩余工作主要是 Docker 环境下的跨数据库 smoke 与发布链路。
|
||
同时,仓库现已提供 `crates/db-app` 作为 CLI / TUI 共享应用层,并为各命令新增 `--result-format json` 以输出结构化结果;当前还补充了 `AppOperation`、`OperationState` 与 `AppEvent<T>` 作为 TUI worker/channel 的稳定执行契约,详见 `TUI_BACKEND_CONTRACT.md`。
|
||
|
||
## TUI Shell Baseline
|
||
|
||
仓库现已补充 `apps/tui`,用于承载 `dbtool-tui-v1` 的终端工作台骨架,不改变当前 CLI 首发范围。
|
||
|
||
当前 TUI baseline 提供:
|
||
|
||
- 独立 `dbtool-tui` 入口
|
||
- 顶部导航、六区主布局和底部快捷键提示
|
||
- 面板焦点管理与基础键盘导航
|
||
- `sqlite-local` 的真实 connect / inspect 路径
|
||
- `sqlite-local` 的真实 query / results / export 工作流
|
||
- PostgreSQL / MySQL 的 Docker demo live activation / query / export 路径
|
||
- `Ready` / `Loading` / `Error` 基础状态框架
|
||
|
||
当前这组能力在 `dbtool-usable-v1` 口径下需要分层理解:
|
||
|
||
- TUI / shell baseline:已有直接执行证据
|
||
- TUI / `sqlite-local` local live:只能记为 `partial`
|
||
- TUI / PostgreSQL & MySQL network live:已具备 runner 内可重复 demo path
|
||
|
||
因此,`sqlite-local` 继续承担本地单机验证,而 PostgreSQL / MySQL 已可通过 `host.docker.internal` 与 `scripts/tui/live-network-smoke.sh` 完成 runner 内真实 network live 复验。
|
||
|
||
运行方式:
|
||
|
||
```bash
|
||
cargo run -p dbtool-tui
|
||
```
|
||
|
||
若当前环境缺少 Rust 工具链,可先使用已有二进制:
|
||
|
||
```bash
|
||
./target/debug/dbtool-tui
|
||
```
|
||
|
||
最小可重复 smoke 入口:
|
||
|
||
```bash
|
||
scripts/tui/smoke-tty.sh ./target/debug/dbtool-tui
|
||
```
|
||
|
||
`dbtool-tui` 需要真实 TTY;`--help` 不是有效 smoke 入口。详细范围与验收说明见 `apps/tui/README.md`、`TUI_SMOKE_RUNBOOK.md`,共享 UI 方案见 `plans/2026-03-26-dbtool-tui-shell-ui-scope.md`。
|
||
|
||
## GUI Foundation Preview
|
||
|
||
仓库当前没有正式 Web / Desktop 前端工程,但已经提供最小可见展示层,用于评审未来 GUI 的信息架构与工作台交互:
|
||
|
||
- `gui/index.html`:GUI foundation 入口页
|
||
- `gui/prototype/index.html`:静态数据库工作台原型
|
||
- `gui/preview-server.mjs`:本地预览服务
|
||
- `gui/README.md`:运行方式、范围说明与界面验收要点
|
||
|
||
运行方式:
|
||
|
||
```bash
|
||
node gui/preview-server.mjs
|
||
```
|
||
|
||
然后访问:
|
||
|
||
```text
|
||
http://127.0.0.1:4173
|
||
```
|
||
|
||
如果只想快速查看静态界面,也可以直接打开 `gui/index.html`。
|
||
|
||
## Workspace 结构
|
||
|
||
```text
|
||
dbtool-cli-v1/
|
||
Cargo.toml
|
||
README.md
|
||
DEVELOPING.md
|
||
apps/
|
||
cli/
|
||
Cargo.toml
|
||
src/main.rs
|
||
crates/
|
||
db-core/
|
||
db-config/
|
||
db-drivers/
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
cargo run -p dbtool-cli -- --help
|
||
export DBTOOL_PASSWORD=dbtool
|
||
cargo run -p dbtool-cli -- connect --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD
|
||
cargo run -p dbtool-cli -- inspect --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --schema qa_demo
|
||
cargo run -p dbtool-cli -- query --driver postgres --host 127.0.0.1 --port 55432 --database dbtool_demo --username dbtool --password-env DBTOOL_PASSWORD --file examples/sql/postgres/happy_path_query.sql
|
||
cargo run -p dbtool-cli -- connect --driver mysql --host 127.0.0.1 --port 53306 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD
|
||
cargo run -p dbtool-cli -- inspect --driver mysql --host 127.0.0.1 --port 53306 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD --schema qa_demo
|
||
cargo run -p dbtool-cli -- query --driver mysql --host 127.0.0.1 --port 53306 --database qa_demo --username dbtool --password-env DBTOOL_PASSWORD --file examples/sql/mysql/happy_path_query.sql
|
||
cargo run -p dbtool-cli -- connect --driver sqlite --path examples/tmp/dbtool-demo.sqlite
|
||
cargo run -p dbtool-cli -- inspect --driver sqlite --path examples/tmp/dbtool-demo.sqlite --schema main
|
||
cargo run -p dbtool-cli -- query --driver sqlite --path examples/tmp/dbtool-demo.sqlite --file examples/sql/sqlite/happy_path_query.sql
|
||
cargo run -p dbtool-cli -- export --driver sqlite --path examples/tmp/dbtool-demo.sqlite --file examples/sql/sqlite/export_query.sql --format csv --output examples/tmp/export.csv
|
||
```
|
||
|
||
PostgreSQL demo 当前保留 `postgres` 作为超级用户(密码 `dbtoolroot`)供 QA seed 与创建 restricted probe;应用侧继续使用非超级用户 `dbtool`(密码 `dbtool`)。如果本地 demo 容器是旧配置初始化的,先执行 `docker compose -f docker-compose.demo.yml down -v` 或 `scripts/tui/demo-stack.sh reset` 再重建,否则 `dbtool` 仍可能保留历史超级权限。
|
||
|
||
如果当前 Linux 环境没有系统 `cc` / `ar`,可以改用 `zig cc` + `zig ar`。对 bundled SQLite 路径,linker 包装器需要兼容 Cargo 传入的 GNU target flag:
|
||
|
||
```bash
|
||
cat > /tmp/zig-cc <<'EOF'
|
||
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
args=()
|
||
for arg in "$@"; do
|
||
case "$arg" in
|
||
--target=x86_64-unknown-linux-gnu)
|
||
args+=("--target=x86_64-linux-gnu")
|
||
;;
|
||
*)
|
||
args+=("$arg")
|
||
;;
|
||
esac
|
||
done
|
||
exec zig cc "${args[@]}"
|
||
EOF
|
||
cat > /tmp/zig-ar <<'EOF'
|
||
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
exec zig ar "$@"
|
||
EOF
|
||
chmod +x /tmp/zig-cc
|
||
chmod +x /tmp/zig-ar
|
||
export CC=/tmp/zig-cc
|
||
export AR=/tmp/zig-ar
|
||
export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=/tmp/zig-cc
|
||
|
||
# 如果当前环境的 rustup 没有默认 toolchain,可显式指定 stable 工具链
|
||
export RUSTC="$(rustup which --toolchain stable rustc)"
|
||
export RUSTDOC="$(rustup which --toolchain stable rustdoc)"
|
||
"$(dirname "$RUSTC")/cargo" test --workspace
|
||
"$(dirname "$RUSTC")/cargo" build --release --bin dbtool
|
||
./target/release/dbtool --help
|
||
```
|
||
|
||
最小发布与产物 smoke 已定义在 `.github/workflows/release-smoke.yml` 与 `RELEASE_RUNBOOK.md`;当前 Linux 还可本地执行 `scripts/release/smoke-binary.sh` 和 `scripts/release/package-unix.sh` 复核产物命名与 checksum。
|
||
|
||
Git 仓库初始化、agent 提交规范与远程接入方式见 `GIT_WORKFLOW.md`。
|
||
|
||
## PostgreSQL / MySQL / SQLite 行为说明
|
||
|
||
- 非参数化 `query` 会走 PostgreSQL simple query 协议,因此支持包含多条语句的 `.sql` 文件,例如 `SET search_path ...; SELECT ...`
|
||
- 非参数化 `query` 在 MySQL 上走 text protocol,因此也支持包含多条语句的 `.sql` 文件,例如 `USE qa_demo; SELECT ...`
|
||
- 带 `--param` 的 `query` 会切换到 prepared execution,当前要求 SQL 为单条参数化语句
|
||
- 凭据只通过 `--password-env` 注入,错误和成功输出都不会回显密码
|
||
- MySQL `inspect` 里的 `schema` 参数当前映射到数据库名;顶层 `inspect` 返回的是数据库列表
|
||
- SQLite 顶层 `inspect` 返回附加数据库列表,demo happy path 使用 `main`;`--schema main` 会列出表,`--schema main --table <table>` 会列出列
|
||
- SQLite 当前使用单条 statement 执行模型;若传入多语句 SQL,会明确返回 `Multiple statements provided`
|
||
- `export` 只接受返回结果集的查询;若 SQL 只有 rows affected 而没有结果集,会明确报错
|
||
- `export` 不会静默覆盖已有文件,且会在父目录不存在时给出显式下一步提示
|
||
|
||
## 设计原则
|
||
|
||
- CLI、未来 GUI 与自动化场景共享同一套核心语义
|
||
- 先稳定领域边界、错误模型和可测试输入校验
|
||
- 驱动差异留在 `db-drivers`,不污染公共 crate
|
||
|
||
## 下一步
|
||
|
||
- `CMP-12`:在此 workspace 基线之上接入跨平台打包与 smoke
|