Skip to content

✨ feat(storage): 搭建 SQLite 日程持久化链路 - #224

Open
HuXiaohui424 wants to merge 2 commits into
1024XEngineer:mainfrom
HuXiaohui424:dev/sqlite-base
Open

✨ feat(storage): 搭建 SQLite 日程持久化链路#224
HuXiaohui424 wants to merge 2 commits into
1024XEngineer:mainfrom
HuXiaohui424:dev/sqlite-base

Conversation

@HuXiaohui424

@HuXiaohui424 HuXiaohui424 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

结论

本 PR 搭建日程模块最小 SQLite 持久化链路:

ScheduleService -> ScheduleRepository -> SqliteScheduleRepository -> SqliteDatabase/SqliteStatement -> SQLite

希望 Reviewer 重点确认:

  • Service、Repository、Database 和 SQL/Mapper 的依赖边界是否清晰;
  • SQLite C API 是否被完整限制在 Database 层;
  • 单连接、单写者约束及 Statement 生命周期是否符合当前阶段要求;
  • 仅接入创建、查询是否符合本次阶段性交付范围。

Refs #225

变更

  • 新增 ScheduleRepository,让 ScheduleService 可注入持久化实现;
  • 新增 SqliteDatabaseSqliteStatement,封装连接、预编译语句、参数绑定和事务入口;
  • 新增 SqliteScheduleRepository,跑通日程写入和查询;
  • 将建表、写入、查询 SQL 集中到 src/sql,字段映射集中到 src/mapping
  • 删除 storage_protocol.h/.ccStorageTransactionPort 及旧协议测试;
  • 新增模块内真实 SQLite 文件集成测试,覆盖写入、查询、事务锁、行号隔离和重连持久化;
  • 补充 SQLite 构建依赖、CI 开发库和架构文档。

明确未包含:

  • ESP32 Runtime 中的 SQLite 实例组装;
  • FATFS/Wear Levelling 正式挂载;
  • 日程修改、取消、操作记录和撤销持久化;
  • 多写者事务调度和跨领域原子事务;
  • 真机 SQLite 验证及生产数据库迁移。

架构与兼容

删除通用 StorageTransactionPort,改为日程领域拥有的 ScheduleRepository。SQLite Adapter 依赖日程接口,日程业务不依赖 SQLite。

SQLite C API 只出现在 sqlite_database.cc;Repository 只使用 Database/Statement 和独立 SQL、Mapper。

voicelife_storage_sqlite 新增对 voicelife_schedule 的公开依赖,启用设备端 SQLite 时增加 sqlite3 私有依赖。主机 CI 增加 libsqlite3-dev

未修改现有 Profile。无 Repository 注入时,ScheduleService 仍保留原模拟数据路径,因此原有日程行为和测试保持兼容。

验证

  • ./scripts/run_pre_submit_checks.sh
  • 远端 CI 的工作流、格式、IM Gateway、主机测试、架构、ESP-IDF 和 CodeQL 均通过;依赖图已启用时依赖审查也通过,未启用时已记录跳过原因
  • ESP-IDF 对应 Profile 构建
  • 真机或外部服务验证(如适用)

证据:

  • scripts/check_format.sh:通过,17 个 C/C++ 文件符合 clang-format 18;
  • scripts/check_code_size.py:通过,12 个变更源码文件符合规模限制;
  • scripts/run_checks.sh:39 个主机测试、架构检查、双端契约、3 个固件 Profile 配置校验、50 个 Python 测试通过;
  • sqlite_schedule_repository_test:真实 .db 写入、Service 查询、关闭重连及字段恢复通过;
  • run_pre_submit_checks.sh 前述阶段均通过,但 IM Gateway 阶段因本机 Corepack 调用 pnpm 11.12.0、项目要求 pnpm 10.17.1 而失败;
  • 远端 CI、ESP-IDF 实际 Profile 构建和真机验证尚未执行。

风险与回退

当前真实 SQLite 链路只在主机集成测试中启用,设备 Runtime 仍使用 memory。创建冲突检查和写入尚未形成多写者原子操作,当前仅支持文档约束的单连接、单写者模型。

正式启用设备端 SQLite 前,仍需完成 FATFS/WL 挂载、固定 SQLite 组件准备、Runtime 组装、数据库迁移及真机恢复验证。

可通过回退提交 2fbdd42 恢复旧协议骨架。本 PR 未启用生产 Profile,也未产生需要回滚的设备数据库格式。

@HuXiaohui424 HuXiaohui424 linked an issue Aug 11, 2026 that may be closed by this pull request
11 tasks
@HuXiaohui424 HuXiaohui424 self-assigned this Aug 11, 2026
@HuXiaohui424 HuXiaohui424 added the FullSpec 规格粒度-影响面大的完整规格 label Aug 11, 2026

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fixed PR diff builds successfully, and the focused schedule/SQLite tests pass. One correctness finding is included inline.

} // namespace

SqliteScheduleRepository::SqliteScheduleRepository(SqliteDatabase& database) : database_(database) {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repository only rejects an empty event, then BindSchedule casts schedule.status to an integer without validating it, while ReadSchedule rejects every value other than the three known enum values. A caller can therefore successfully insert a Schedule containing an invalid enum value, after which FindAll() fails with 数据库中的日程状态无效 and the repository cannot read its own row. Validate the status before insert (and ideally enforce the same invariant in the schema with a CHECK) so invalid domain data cannot be persisted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FullSpec 规格粒度-影响面大的完整规格

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Storage] 搭建 SQLite 数据持久化基础设施

1 participant