macOS 本地 SQLite
本地 SQLite 是桌面端“冷启动即可用”的基础:会话列表、历史消息、草稿、未读与投递游标都落在主进程的数据库里,由主进程独占写入。渲染进程只能通过 preload 桥读取,不直接打开数据库。
库位置与 dbPath 语义
| 项 | 值 |
|---|---|
| dbPath 含义 | **目录**(不是文件路径);SDK 在其下创建 im-electron/<appkey>/<userId>.db |
| 推荐值 | app.getPath('userData') |
| 实际库文件 | <dbPath>/im-electron/<appkey>/<userId>.db(每个用户一个库) |
| 默认值 | 未传 dbPath 时为 process.cwd()/im-electron-data,可用环境变量 NI_PAAS_IM_DATA_DIR 覆盖 |
| 日志模式 | WAL(并发读 + 单写者,崩溃恢复更稳) |
| 备份 | 同时复制 .db、.db-wal、.db-shm |
| 加密 | 需要落盘加密时由业务层提供加密卷 / 系统 FileVault;SDK 不内置数据库加密 |
JavaScript
// 主进程:dbPath 传目录
const service = initService({
appkey: 'demo',
serverUrl: 'https://im.example.com',
dbPath: app.getPath('userData'),
});
// 实际库文件示例:
// ~/Library/Application Support/<appName>/im-electron/<appkey>/<userId>.db表结构(逻辑视图)
| 表 | 内容 | 关键列 |
|---|---|---|
| conversation | 会话读模型:最后一条消息、未读、置顶、免打扰、草稿 | conversationType, targetId, unreadCount, isTop, draft, updatedAt |
| message | 消息:按会话与 seq 排序,含发送状态与撤回标记 | messageId, clientMsgId, conversationType, targetId, seq, status |
| message_index | 搜索索引(文本、文件名、@ 提及) | messageId, keyword |
| sync_cursor | 设备级投递游标与已 ack 位点 | deviceId, conversationType, targetId, seq |
| meta | 库版本、appkey、迁移记录 | key, value |
表结构以 SDK 版本迁移脚本为准;业务侧不要直接写这些表,升级时会被迁移覆盖。
写入与读取
JavaScript
// 主进程:冷启动先读本地库(不依赖网络)
const conversations = await service.client.getConversationList(); // 本地读模型
const page = await service.client.getHistoryMessages(1, 'user2', 20, 0); // 本地历史 + 云端补齐
// 渲染进程:只经 preload 桥
const list = await window.niPaasIMBridge.imlib.getConversationList();
const history = await window.niPaasIMBridge.imlib.getHistoryMessages(1, 'user2', 20, 0);本地库与云端的关系
连接建立后 SDK 按设备游标补收离线消息并写入本地库;补收完成后触发 CONNECTED。
本地库是读模型与离线缓存,不是唯一事实源:多端一致性以服务端会话/消息为准,必要时调用重同步。
清空本地数据等于换设备:下次连接会重新补收未 ack 消息;多用户共用一个 dbPath 时库文件按 userId 隔离。
迁移与升级
- SDK 升级时自动执行库迁移;迁移失败会保留旧库并回滚到只读模式,避免数据损坏。
- 大版本升级前建议提供“导出诊断包”(库统计 + 版本 + 最近日志)。
- 卸载应用不会自动删除 `userData` 下的库;需要彻底重置时手动删除 `
/im-electron`。
备份与恢复
Shell
# 退出应用后备份(WAL 三个文件一起)
APP_DATA="$HOME/Library/Application Support/My App"
mkdir -p ~/Desktop/im-backup
find "$APP_DATA/im-electron" -type f \( -name '*.db' -o -name '*.db-wal' -o -name '*.db-shm' \) -exec cp {} ~/Desktop/im-backup/ \;
# 恢复:退出应用 → 覆盖回原目录 → 重新启动性能建议
| 场景 | 建议 |
|---|---|
| 会话列表 | 首屏只查 50 条会话;未读数走索引列,避免全表扫描 |
| 历史消息 | 按 `(conversationType, targetId, seq)` 复合索引分页,每页 20~50 条 |
| 搜索 | 本地搜索限制关键词长度 ≥ 2,输入 300ms 防抖;大库定期 `ANALYZE` |
| 批量写入 | 补收离线消息使用事务批量提交,避免逐条 fsync |
| 体积 | 长期使用后可在设置页提供“压缩数据库”(`VACUUM`),在空闲时执行 |