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`),在空闲时执行