DBeaver Community 鸿蒙 PC 适配全记录:在 HarmonyOS PC 上运行原生数据库管理工具

DBeaver Community 鸿蒙 PC 适配全记录:在 HarmonyOS PC 上运行原生数据库管理工具

  • [DBeaver Community 鸿蒙 PC 适配全记录:在 HarmonyOS PC 上运行原生数据库管理工具](#DBeaver Community 鸿蒙 PC 适配全记录:在 HarmonyOS PC 上运行原生数据库管理工具)
    • [一、为什么要适配 DBeaver Community](#一、为什么要适配 DBeaver Community)
    • 二、先确定适配路线:原生重实现,替换数据库底座
    • 三、适配工程的目录组织
    • [四、HarmonyOS PC 核心功能](#四、HarmonyOS PC 核心功能)
      • [1. 会话管理:连接的起点](#1. 会话管理:连接的起点)
      • [2. 数据库树:从实例到字段的分层导航](#2. 数据库树:从实例到字段的分层导航)
      • [3. 数据网格:浏览、过滤与事务化编辑](#3. 数据网格:浏览、过滤与事务化编辑)
      • [4. SQL 编辑器:语法高亮与多语句执行](#4. SQL 编辑器:语法高亮与多语句执行)
      • [5. 结构管理、导入导出与偏好设置](#5. 结构管理、导入导出与偏好设置)
    • 五、适配过程中遇到的主要困难
      • [难点一:JVM / OSGi / SWT 运行时缺失,只能重写而非搬运](#难点一:JVM / OSGi / SWT 运行时缺失,只能重写而非搬运)
      • [难点二:把 glibc 假设的 C 客户端库编进 musl 世界](#难点二:把 glibc 假设的 C 客户端库编进 musl 世界)
      • [难点三:musl 缺失的符号与两套构建体系的三元组陷阱](#难点三:musl 缺失的符号与两套构建体系的三元组陷阱)
      • [难点四:NAPI 桥接层------三种数据库协议收敛成一个接口面](#难点四:NAPI 桥接层——三种数据库协议收敛成一个接口面)
      • [难点五:PC 窗口的 px / vp 密度换算](#难点五:PC 窗口的 px / vp 密度换算)
      • [难点六:桌面交互习惯在 ArkUI 上的重建](#难点六:桌面交互习惯在 ArkUI 上的重建)
    • 六、关键适配改动
      • [1. 三层原生架构与统一 provider 接口](#1. 三层原生架构与统一 provider 接口)
      • [2. 独立的客户端库交叉编译体系](#2. 独立的客户端库交叉编译体系)
      • [3. musl 兼容桩集中注入](#3. musl 兼容桩集中注入)
      • [4. NAPI 模块的组包细节](#4. NAPI 模块的组包细节)
      • [5. PC 窗口与主题适配](#5. PC 窗口与主题适配)
      • [6. 右键菜单与键鼠交互组件化](#6. 右键菜单与键鼠交互组件化)
      • [7. HUKS 安全存储与会话持久化](#7. HUKS 安全存储与会话持久化)
    • 七、编译、安装与启动
      • [1. 准备项目依赖](#1. 准备项目依赖)
      • [2. 构建 HarmonyOS PC 版本](#2. 构建 HarmonyOS PC 版本)
      • [3. 安装并启动](#3. 安装并启动)
    • 八、当前可用范围与能力边界
    • 九、调试实战记录:SQL「执行」无结果问题的定位与修复
      • [1. 一个"看起来都成功"的问题](#1. 一个"看起来都成功"的问题)
      • [2. 想复现,先得有个能连的库](#2. 想复现,先得有个能连的库)
      • [3. 两个「执行」按钮,只有一个是真的](#3. 两个「执行」按钮,只有一个是真的)
      • [4. 修法:把编辑器的执行能力"登记"给工具栏](#4. 修法:把编辑器的执行能力"登记"给工具栏)
      • [5. 回归](#5. 回归)
    • 十、总结

DBeaver Community 鸿蒙 PC 适配全记录:在 HarmonyOS PC 上运行原生数据库管理工具

欢迎加入开源鸿蒙PC社区:https://harmonypc.csdn.net/

欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper

适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_dbeaver_community

一、为什么要适配 DBeaver Community

DBeaver Community 是全球范围内使用最广的开源通用数据库工具之一:开发者、SQL 程序员、数据库管理员和数据分析人员用它可以连接主流数据库,完成连接会话管理、数据浏览与编辑、SQL 查询、结构管理、数据导入导出等日常工作。它基于 Eclipse RCP 框架构建,依托 JDBC 生态支持上百种数据源,是很多工程师装机必备的基础工具。

把 DBeaver Community 带到 HarmonyOS PC,价值不只是补齐一个工具:数据库管理工具是桌面操作系统的「基础设施级」应用,它的有无直接影响开发者能否在鸿蒙 PC 上形成完整的业务开发闭环。同时,这个项目能系统性检验鸿蒙 PC 对复杂桌面应用的承载能力:多窗格工作台布局、大规模数据表格渲染、右键菜单与鼠标键盘交互、C/C++ 第三方库的交叉编译与 NAPI 桥接、密码等敏感数据的安全存储------这些链路都需要在真机上连续工作,才能支撑更多专业桌面软件后续跟进移植。

本次适配以上游 DBeaver Community(Java / Eclipse RCP,Apache-2.0)的功能规格与交互模型为参照。需要先说明一个与常规移植不同的前提:鸿蒙 PC 上既没有 JVM、OSGi,也没有 SWT 桌面运行时,JDBC 驱动体系更是无从谈起,把 Eclipse RCP 应用整体搬过来在工程上不成立。因此适配没有搬运上游任何源码、图标与素材,而是采用「规格参照 + 全新原生实现」的路线:UI 与领域逻辑用 ArkTS + ArkUI 声明式范式重写,数据库访问层把 C 客户端库交叉编译成 aarch64 musl 动态库、通过 NAPI 桥接给 ArkTS 调用。最终交付形态是 arm64-v8a 签名 HAP,Bundle Name 为 com.dbeavercommunity.ohos,版本 1.0.0,compatibleSdkVersion 5.0.0(12) / targetSdkVersion 6.1.1(24)

二、先确定适配路线:原生重实现,替换数据库底座

Theia 那类 Electron 应用可以「保留前端、替换宿主」,DBeaver 不行------它的界面、领域逻辑、数据库驱动全部长在 Java 体系上,鸿蒙没有可复用的运行时层。但换一个角度看,DBeaver 的核心价值在工作流而不在 SWT 控件:连接管理、树形导航、表格编辑、SQL 执行这些交互模型本身是平台无关的,完全可以用 ArkUI 重建。真正不能重建的是「跟数据库对话」的部分------这部分用交叉编译的 C 客户端库原样保留协议实现。

层次 上游实现 HarmonyOS PC 侧处理
UI 框架 Eclipse RCP / SWT ArkTS + ArkUI 声明式范式重写(22 个页面/视图),State Management V1
领域逻辑 Java 插件(OSGi) ArkTS 分层:viewmodel / catalog / editor / model / dbclient
数据库驱动 JDBC 驱动(Java) 交叉编译 C 客户端库:libmariadb 3.3.3、libpq 15.7、sqlite3 3.46.0
数据库桥接 JDBC API NAPI C++ 统一 provider 接口(libdbclient.so
TLS JDK / JSSE OpenSSL 3.3.1 交叉编译(libmariadb / libpq 共用)
字符编码 JVM 内置 libiconv 1.17 + gettext 0.22.5(libintl,libpq 依赖)
密码存储 Eclipse secure storage HUKS(@ohos.security.huks)加密存储
桌面交互 SWT 菜单与鼠标事件 bindContextMenu 右键菜单、onHover / onMouse、列宽拖拽
交付形态 Windows/macOS/Linux 安装包 arm64-v8a 签名 HAP,deviceTypes2in1

适配后的调用链路如下:

text 复制代码
EntryAbility(UIAbility,窗口 1280×800 vp,强制深色)
    └── MainWindowPage(ArkUI 主窗口)
          ├── SessionManagerPage        # 连接会话管理(新建/编辑/复制/测试连接)
          └── WorkbenchPage             # 多窗格工作台
                ├── DbTreeView          # 数据库树(catalog 目录服务)
                ├── DataGridPage        # 数据网格(浏览/编辑/过滤/事务)
                ├── SqlEditorPage       # SQL 编辑器(高亮/多语句/历史/格式化)
                ├── StructurePage 等    # 结构与对象管理
                └── dbclient(ArkTS 连接注册表)
                      └── NAPI:libdbclient.so(C++17)
                            ├── mysql_provider    → libmariadb.so(+ OpenSSL)
                            ├── postgres_provider → libpq.so(+ OpenSSL / libiconv / libintl)
                            └── sqlite_provider   → libsqlite3.so

这条路线的边界同样是明确的:界面全部原创重写,功能按上游规格逐项对齐;数据库访问走真实客户端协议而非退化实现;上游依赖 Java 生态的部分(JDBC 海量驱动、OSGi 扩展体系)不在本次范围内,后文能力边界一节如实列出。

三、适配工程的目录组织

鸿蒙工程即为仓库根目录,DevEco Studio 直接打开即可构建;数据库客户端库的交叉编译体系独立放在 native/,与 App 构建解耦。UI 与领域逻辑按「pages / viewmodel / catalog / editor / model / dbclient / common」分层,平台相关代码收敛在 cpp/native/EntryAbility 三处。

text 复制代码
ohos_DBeaver_Community/
├── AppScope/                          # 应用级配置(包名 com.dbeavercommunity.ohos、图标)
├── build-profile.json5                # 工程级构建配置(SDK 版本、模块列表)
├── hvigorfile.ts                      # hvigor 工程脚本
├── README.md / README.OpenHarmony_CN.md
├── entry/                             # 唯一业务模块
│   └── src/main/
│       ├── ets/
│       │   ├── pages/                 # 22 个 ArkUI 页面/视图(会话管理/工作台/数据网格/SQL 编辑器...)
│       │   ├── viewmodel/             # 领域逻辑:SQL 构建、事务编排、导入导出、行编辑缓冲
│       │   ├── catalog/               # 数据库树目录服务、字段类型注册表
│       │   ├── editor/                # SQL 语法高亮内核与关键字表
│       │   ├── model/                 # 会话、连接参数、错误映射、HUKS 安全存储、查询历史
│       │   ├── dbclient/              # 连接注册表(NAPI 的 ArkTS 封装)
│       │   ├── common/                # 主题色板 Theme.ets、品牌常量、右键菜单辅助
│       │   └── entryability/          # EntryAbility(PC 窗口与主题配置)
│       ├── cpp/                       # NAPI 桥接层 → libdbclient.so
│       │   ├── db_provider.h/cpp      # 统一 provider 接口与工厂
│       │   ├── mysql_provider.cpp     # libmariadb 实现
│       │   ├── postgres_provider.cpp  # libpq 实现
│       │   ├── sqlite_provider.cpp    # sqlite3 实现
│       │   ├── napi_init.cpp          # 模块注册
│       │   └── CMakeLists.txt         # 链接 NAPI 运行时 + 预编译客户端库
│       └── module.json5               # deviceTypes 含 2in1、INTERNET 权限
└── native/                            # 数据库客户端库交叉编译(独立于 App 构建)
    ├── build/
    │   ├── env.sh                     # 工具链环境(clang target/sysroot/lld)
    │   └── build_libs.sh              # 主构建脚本:按依赖顺序编 7 个库
    ├── compat/
    │   └── musl_compat.h              # glibc 扩展符号在 musl 下的兼容桩(-include 注入)
    └── prebuilt/arm64-v8a/            # 交叉编译产物:lib/(.so)+ include/(头文件,随仓库附带)

native/prebuilt/arm64-v8a/ 的预编译产物随仓库分发,日常开发无需重跑交叉编译;entry 的 NAPI 构建通过 CMake 指向该目录链接,并在打包时把依赖 .so 一并带进 HAP。

四、HarmonyOS PC 核心功能

以下按用户使用路径整理应用的核心能力。

1. 会话管理:连接的起点

应用启动后先进入会话管理页。新建连接时选择数据库类型(MySQL / MariaDB / PostgreSQL / SQLite),填写主机、端口、用户名、密码,或指定 SQLite 本地数据库文件;连接前可以先「测试连接」,确认连通后再保存。会话支持编辑、复制、删除;密码经系统 HUKS 安全能力加密存储,不以明文落盘。

2. 数据库树:从实例到字段的分层导航

进入工作台后,左侧数据库树按「实例 → 数据库 → 表 / 视图」分层展开,支持按名称过滤;树节点绑定统一的右键菜单(刷新、新建对象、编辑、删除等),菜单项支持可用态与分隔线。

3. 数据网格:浏览、过滤与事务化编辑

数据网格是日常使用频次最高的视图。浏览 / 编辑双模式切换;列宽支持鼠标拖拽调整(拖拽把手带悬停高亮);提供快速过滤与条件过滤(等于 / 包含 / 大小比较 / IS NULL)。行内编辑进入编辑缓冲区,配合批量事务提交 / 回滚------所有改动要么一起提交、要么一起撤销;切换前有脏数据守卫拦截未保存修改;对无主键表启用编辑前给出风险告警;BLOB / TEXT 大字段有专用编辑器,支持文本 / 十六进制双视图。

4. SQL 编辑器:语法高亮与多语句执行

顶部标签切换到 SQL 编辑器:关键字语法高亮(支持主题切换)、多 SQL 语句一次提交执行、结果面板按语句分区展示、执行模式可切换、查询历史可回溯,另提供 SQL 格式化。

5. 结构管理、导入导出与偏好设置

结构视图支持表字段编辑、索引与外键 DDL 编辑、DDL 查看、字段类型映射;对象编辑器覆盖视图 / 存储过程 / 触发器 / 事件管理,另有用户管理。数据可导出为 SQL 文件或 CSV 文件,CSV 亦可导入。偏好设置提供字体、字号、每页行数、NULL 显示、驱动、超时、高亮主题等个性化项。

五、适配过程中遇到的主要困难

难点一:JVM / OSGi / SWT 运行时缺失,只能重写而非搬运

上游 DBeaver 的 74+ 个插件全部构建在 Eclipse RCP 之上:UI 是 SWT,服务是 OSGi,数据库访问是 JDBC。鸿蒙 PC 上这三样东西一样都没有,官方也没有提供 Java 运行时。任何「塞一个 JRE 进 HAP」的方案都会带来体积、性能和许可的三重问题。适配最终选择把交互模型当作规格、把代码全部重写:这要求在 ArkTS 严格模式下(禁用 any、对象字面量类型推断、动态属性访问)重建数据网格、树控件、SQL 解析这类本应属于框架的能力,工作量集中在 pages/ 22 个视图和 viewmodel/ 的领域逻辑上。

难点二:把 glibc 假设的 C 客户端库编进 musl 世界

libmariadb、libpq、OpenSSL 都是按 Linux/glibc 习惯写的代码,而鸿蒙的 native 环境是 musl libc。问题逐个出现:OpenSSL 的 Configure 要走 linux-aarch64 目标,再靠 -D__MUSL__ 让源码切换 musl 分支;libmariadb 的 CMake 在 macOS 构建机上会把系统检测成 Darwin,必须显式指定 CMAKE_SYSTEM_NAME=Linux 才能编对方向;libpq 链接时找不到刚编出来的 libssl / libiconv,需要补 -Wl,-rpath-link 指向产物目录。这些解决方案统一记录在 native/build/build_libs.sh 的注释里。

难点三:musl 缺失的符号与两套构建体系的三元组陷阱

glibc 有不少扩展符号 musl 里没有,例如调用栈回溯用的 <execinfo.h> 在 musl 上不存在,直接编译会 undefined reference。解法是写了 native/compat/musl_compat.h 兼容桩,通过 -include 强制注入到每个编译单元,补丁集中一处、不散落修改第三方源码。另一个隐蔽的坑在三元组上:autoconf 系工程(libiconv、gettext)的 --host 必须写标准三元组 aarch64-linux-gnu------autoconf 不认识 ohos;而 clang 的 --target 才用 aarch64-linux-ohos。两个变量不一致是故意的,全局编译开关还要带上 -D__linux__,否则 musl 头文件里的部分 API 不会暴露。

难点四:NAPI 桥接层------三种数据库协议收敛成一个接口面

ArkTS 层不应该感知「底下是 MySQL 还是 PostgreSQL」。cpp/db_provider.h 定义了统一的 provider 接口(连接、执行、游标取数、事务、元数据),三个 provider 各自实现,napi_init.cpp 注册成 ArkTS 模块,跨语言的错误码映射收敛到 model/ErrorUtils.ets。工程细节上,libdbclient.so-Wl,-rpath,$ORIGIN 从自身所在目录定位依赖库;CMake 增加 POST_BUILD 命令把 prebuilt/arm64-v8a/lib 整体拷贝进产物目录(含 libmariadb 插件子目录),保证 HAP 打包时依赖 .so 一个不少。

难点五:PC 窗口的 px / vp 密度换算

窗口默认 1280×800 vp,看似一行 win.resize(1280, 800) 就完事,但 resize 的单位是 px 不是 vp 。在鸿蒙 PC 的高密度屏上直接传 1280,得到的窗口只有一半大,结果 480×520 vp 的模态对话框超出窗口被裁剪,底部「保存 / 取消」按钮不可见也不可点------初看像个玄学 bug。正确做法是先用 display.getDefaultDisplaySync()densityPixels,按 vp × density 换算成 px 再 resize。配套的还有两处:启动时把窗口底色设为与主题一致的 #2B2B2B(消除启动白闪),应用级 setColorMode(COLOR_MODE_DARK) 让系统弹窗与未显式着色的控件不残留浅色样式。

难点六:桌面交互习惯在 ArkUI 上的重建

数据库工具的重度操作都长在鼠标上:右键菜单、悬停反馈、拖拽调列宽。适配把这些做成组件化能力:common/ContextMenuHelper.ets 封装统一的右键菜单构建器(bindContextMenu + ResponseType.RightClick + @Builder 动态渲染),数据库树、数据网格、工作台接入同一套;数据网格的行与列在 onMouse 里区分按键触发不同行为,列宽拖拽把手(ColResizeHandle)用 onHover 提供悬停高亮。所有交互同时保持触控可用,避免 2in1 设备形态切换时操作断档。

六、关键适配改动

1. 三层原生架构与统一 provider 接口

UI(pages)→ 领域逻辑(viewmodel / catalog / editor / model / dbclient)→ NAPI 桥接(cpp)三层解耦。db_provider.h 是数据库无关的接口面,新增数据库类型只需在 C++ 侧增加一个 provider 并在工厂注册,ArkTS 上层不动。

2. 独立的客户端库交叉编译体系

native/build/env.sh 定义工具链(SDK 自带 LLVM clang + ld.lld,musl sysroot),build_libs.sh 按依赖顺序编 sqlite3 → libiconv → libintl → OpenSSL → libpq → libmariadb,版本号写死保证可复现,产物落在 prebuilt/arm64-v8a/ 并随仓库分发。

3. musl 兼容桩集中注入

native/compat/musl_compat.h 通过 -include 进入所有编译单元,集中提供 glibc 扩展符号的空实现或回退路径,避免修改第三方库源码。

4. NAPI 模块的组包细节

链接 ace_napi.z / hilog_ndk.z 与 sqlite3 / mariadb / ssl / crypto;$ORIGIN rpath 保证设备端依赖定位;POST_BUILD 拷贝预编译库与插件目录;C++17 标准。

5. PC 窗口与主题适配

EntryAbility 按屏幕密度换算窗口尺寸(1280×800 vp)、设置深色窗口底色、应用级强制深色模式;全部颜色引用 common/Theme.ets 集中语义色板,品牌常量收敛在 Brand.ets,禁止散落硬编码。

6. 右键菜单与键鼠交互组件化

ContextMenuHelper 统一右键菜单协议;onMouse / onHover 覆盖树节点、数据行、列把手;列宽拖拽独立组件。

7. HUKS 安全存储与会话持久化

连接密码经 @ohos.security.huks 加密存储;会话列表、查询历史、偏好设置分别有独立持久化 store,随应用生命周期管理。

七、编译、安装与启动

1. 准备项目依赖

需要 DevEco Studio(含 HarmonyOS SDK,默认 /Applications/DevEco-Studio.app)。仓库已附带预编译客户端库,常规开发直接进入第 2 步;如需重编或升级库版本:

bash 复制代码
cd native/build
./build_libs.sh all          # 按依赖顺序编 7 个库,产物落 native/prebuilt/arm64-v8a/
# 也可单独编:./build_libs.sh sqlite | libpq | libmariadb

2. 构建 HarmonyOS PC 版本

DevEco Studio(推荐) :打开工程根目录,在 File > Project Structure > Signing Configs 生成调试签名,连接 2in1 真机后点 Run。

命令行(可接 CI)

bash 复制代码
export JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
export PATH="$JAVA_HOME/bin:/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin:$PATH"
hvigorw assembleHap

若本机 hvigorw 不在上述路径,可在 DevEco Studio 内置终端中直接执行,或使用工程自带的 hvigorw 包装脚本。

命令行签名:安装 DevEco Code CLI 后执行 devecocli signature generate --product default(需先 devecocli auth login,且模拟器/真机在线),工具会生成本机签名材料并自动把 signingConfigs 写入 build-profile.json5;若设备上已装过旧签名版本,先 hdc shell bm uninstall -n <bundleName> 再安装,否则报 install sign info inconsistent

签名产物位于:

text 复制代码
entry/build/default/outputs/default/entry-default-signed.hap

注意:若要修改 AppScope/app.json5 中的 bundleName,需先在 Signing Configs 中重新生成签名、再改包名,顺序颠倒会导致签名与包名不匹配、无法安装。

3. 安装并启动

bash 复制代码
hdc list targets
hdc install -r entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.dbeavercommunity.ohos

启动后窗口默认 1280×800 vp、深色主题。首次使用在会话管理页新建连接(测试连接通过后再保存),双击会话进入工作台,即可进行数据库树导航、数据网格编辑、SQL 执行与导入导出。

八、当前可用范围与能力边界

当前版本已在工程实现并纳入构建 / 运行验证的能力:

  • 签名 HAP 可以安装,EntryAbility 可以启动,窗口为 1280×800 vp 桌面形态;
  • ArkTS + NAPI 混合构建闭环:libdbclient.so 链接预编译客户端库、依赖随 HAP 自包含;
  • MySQL / MariaDB(libmariadb,TCP + TLS)、PostgreSQL(libpq,TCP + TLS)、SQLite(本地文件)三类连接;
  • 会话管理(新建 / 编辑 / 复制 / 删除 / 测试连接)、密码 HUKS 加密存储;
  • 数据库树分层导航、名称过滤、右键菜单;
  • 数据网格浏览 / 编辑双模式、列宽拖拽、快速过滤与条件过滤、行内编辑 + 批量事务提交 / 回滚、脏数据守卫、无主键表风险告警、BLOB / TEXT 专用编辑器;
  • SQL 编辑器语法高亮、多语句执行、结果面板、执行模式切换、查询历史、格式化;
  • 结构管理(字段 / 索引 / 外键 DDL / DDL 查看)、视图 / 存储过程 / 触发器 / 事件管理、用户管理;
  • SQL 文件与 CSV 导出、CSV 导入;偏好设置。

以下能力属于未适配或按场景裁剪的范围:

  • SSH 隧道 / 代理连接(当前版本以直连为主);
  • 其余数据库驱动(Oracle、SQL Server、DB2 等上游 JDBC 生态支持的几十种数据源),新增类型按 provider 模式扩展;
  • ER 图、仪表盘、Mock 数据等上游可视化增值功能;
  • 跨库数据传输、任务调度等自动化套件;
  • Eclipse / OSGi 插件体系,与原生架构不兼容,以源码级贡献替代;
  • 用户自选驱动版本------客户端库为预编译随包分发,暂不支持在线下载驱动。

九、调试实战记录:SQL「执行」无结果问题的定位与修复

1. 一个"看起来都成功"的问题

有用户反馈:在 SQL 编辑器里写好查询,点「执行」,日志面板里冒出「切换到数据库 XXX」「已打开脚本标签」几行,然后就没有然后了------结果面板永远是空的。

这种问题比崩溃难缠。崩溃好歹有 faultlog 可翻,这里没有任何报错,所有日志看起来都是"正常"的,SQL 像是发出去之后消失在了链路的某一环。

我先把从按钮到结果面板的整条链路静态读了一遍:SqlEditorPage 的 runExecute → SqlExecutor 的多语句拆分 → DbConnection → NAPI → C++ 侧的 query,结果一路填回 _results/_summary,再用一个自增 tick 强制刷新结果面板。光看代码,执行和渲染每一环都该工作;唯一可疑的是工具栏那个「执行」按钮------它似乎只做了标签路由。但读码读出来的只能算嫌疑,定不了案,还是得让问题在真机上自己跑一遍。

2. 想复现,先得有个能连的库

复现环境选了模拟器 + SQLite:不依赖外部服务器,链路最短。结果第一步就撞墙------新建 SQLite 会话,填好文件路径,点「连接」,界面毫无反应。

翻代码才看到,sqlite_provider.cpp 居然是个桩:Connect() 上来就返回「SQLite provider 未集成」。有点哭笑不得的是,仓库里 native/prebuilt/arm64-v8a/ 下交叉编译好的 libsqlite3.so 一直躺着,CMakeLists.txt 的链接配置也早就写好了,就差 provider 这最后一段代码没人接。填坑本身不难,照着 MySQL provider 的形状,用 sqlite3_open_v2prepare_v2/step 把连接、取列、逐行读数、affectedRows 这些补齐,NULL 沿用"空串 + 标记位"的老约定。写完 SQLite 在模拟器上就全通了,建表、插数、查询、多语句都没问题。

现在回头看,这堵墙撞得不算冤------它逼着我把复现环境搭完整了。

3. 两个「执行」按钮,只有一个是真的

有了能用的 SQLite,对照实验很快就把嫌疑变成了实锤。

先在编辑器里输入 SELECT 1 AS one, 2 AS two,点编辑器侧边栏那个 ▶:结果面板立刻刷出「2 列 × 1 行」的表格,日志打印「执行 1 条 SQL,成功 1」。执行链路、结果渲染,全都是好的。

再换一条 SELECT 99 AS bar,这回点顶部工具栏的「▶ 执行」:结果面板纹丝不动,日志只多了一行「请在脚本编辑器内完成执行」。

问题就在这。界面上其实有两个「执行」入口,长得几乎一样,行为完全不同。工具栏那个绑定的函数叫 routeToScriptTab('执行'),看名字就明白了------它只负责把最近一个脚本标签激活,顺便打一条提示日志,从头到尾没打算执行任何 SQL。真正干活的只有编辑器侧边栏的 ▶。用户从工具栏点执行,一条 SQL 都不会跑,而日志里那些"正常"的输出------切库、开脚本标签------全是别的阶段打的,跟执行半点关系没有。

这个 bug 本身不难找,难的是先排除"是不是结果渲染丢了数据"这类干扰项。对照实验的价值就在这:两个入口、同一条 SQL、两种结果,结论不用猜。

4. 修法:把编辑器的执行能力"登记"给工具栏

工程里其实有现成的解法。数据网格为了让工具栏的「提交/回滚」作用到当前表格,用了 GridActions 注册表:子组件就绪时把自己能干的活登记给宿主,宿主按标签 id 查表调用。SQL 编辑器照搬这套:

SqlEditorPage 在 aboutToAppear 里通过新增的 onActionsReady 回调,把自己的 execute 交给 WorkbenchPage;WorkbenchPage 用一个 scriptActionsRegistrytab.id → 动作)收着,标签关闭时同步删掉。工具栏「▶ 执行」和菜单里的「执行 SQL (F9)」都改走 executeActiveScript()------当前激活的是脚本标签就直接调它的 execute(和侧边栏 ▶ 完全等效),不是脚本标签才回退到原来的路由逻辑。

顺手还修了个不起眼但挺典型的问题。失败日志那行是这么写的:

复制代码
"第 N 条失败:" + r.error || '未知错误' + " [" + r.sqlState || '' + ...

+ 的优先级比 || 高,整串字符串拼接完永远是真值,|| 右边的兜底一个都没生效过------真出错的时候,SQLSTATE 和错误码整段丢失。想按设计兜底,就得给两段拼接各补上括号。这种 bug 平时毫无存在感,专挑你最需要看错误详情的时候掉链子。

5. 回归

修完的验证不复杂:工具栏「执行」跑 SELECT,结果表直接出来;CREATE TABLE、INSERT、SELECT 三条连着跑,日志报「共 3 条 | 成功 3 | 失败 0」,INSERT 那条报「影响 1 行」;故意写个语法错误,日志老老实实输出「第 2 条失败:near ... syntax error #1」,并按开关中止了后面的语句。工具栏、侧边栏、错误路径,三条线都闭环了。

这次排查记两件事。一是「界面点了没反应」这类问题,与其反复盯着代码看,不如尽早把复现环境搭起来做对照实验,让每一环的通断变成看得见的事实------这次要不是 SQLite 桩逼着我把环境建好,还真没这么快拿到铁证。二是失败得让人觉得"失败了":桩返回错误信息没错,错的是 UI 把失败悄悄吞进日志面板,用户的感受就是"按了没反应"。关键操作的失败,值得一个更吵闹的呈现方式。

十、总结

DBeaver Community 的 HarmonyOS PC 适配走了一条与 Theia 不同的路:不是保留前端替换宿主,而是「规格参照 + 原生重建」------上层用 ArkTS / ArkUI 重写数据库工具的核心功能面,底层把 libmariadb、libpq、sqlite3 三套真实客户端协议交叉编译进 HAP,中间用 NAPI 的统一 provider 接口做干净的桥。过程中解决的关键问题集中在三处:glibc 假设的 C 库在 musl 上的交叉编译(工具链三元组、兼容桩、逐库的构建修正),ArkTS 严格模式下复杂桌面交互的重建(右键菜单、悬停、拖拽、事务化表格编辑),以及 PC 形态的窗口密度换算。

从结果看,在鸿蒙 PC 上打开它:连接数据库、浏览编辑数据、跑 SQL、导入导出,是一台桌面数据库工具该有的样子。db_provider 的接口设计也为后续扩展留好了口子------补新数据库类型不需要动上层,鸿蒙 PC 的开发者工具链也可以沿着这条路径继续向前长。

相关推荐
长沙三为智能科技2 小时前
⚠️ 内容拦截提示:本次输入含品牌引流型关键词,暂不生成文章
服务器·数据库·oracle
java_logo3 小时前
Docker 部署 MongoDB Community Server:轻松搭建文档数据库平台
数据库·mongodb·docker·nosql·文档数据库·轩辕镜像·mongodb-server
服务端相声演员3 小时前
MySQL的select distinct ..Union all和select..union的区别
数据库·mysql
2501_930472443 小时前
深度复盘|数据库迁移实战(下):从自建 MySQL 5.7 到腾讯云 MySQL 8.0 的 SQL 兼容改造
数据库·mysql·腾讯云
2501_930472443 小时前
深度复盘|数据库迁移实战(上):腾讯云助手解析慢查询日志,定位索引缺失与语法不兼容
数据库·阿里云·ffmpeg·云计算·腾讯云·aws
SelectDB技术团队3 小时前
从 ClickHouse 迁移到 Doris:SQL 兼容、同步与验证清单
数据库·人工智能·sql·clickhouse·apache doris·selectdb·湖仓架构升级
敲代码的嘎仔3 小时前
从零实现视频续播 + 学习进度统计:前端心跳、条件更新、GROUP BY 统计全链路拆解
java·前端·数据库·学习·面试·职场和发展·音视频
HwJack203 小时前
用 HML + CSS + JS 三段式写鸿蒙界面
javascript·css·harmonyos
草莓熊Lotso3 小时前
【Redis 初阶】C++ 客户端实战:从 RESP 协议到 redis-plus-plus 工程化用法
linux·开发语言·网络·数据库·c++·redis·缓存