#ifndef PCANBRIDGE_CAN_DB_STORE_H #define PCANBRIDGE_CAN_DB_STORE_H #include #include #include #include struct sqlite3; struct sqlite3_stmt; namespace canbridge { //============================================================================ // CanDbStore:CAN 帧 SQLite 存储。 // // 设计参考 src/pCCU/store/DbStore(原始帧日志模式): // - 收到的每个 CAN 帧逐条落库(can_frame 表), // 存原始帧信息/ID/DLC/十六进制数据,语义解析交给下游。 // - 预处理语句 + WAL + synchronous=NORMAL,满足 ~60 帧/秒持续写入。 // - 内部互斥锁:接收线程写入,Iterate 线程查询/统计。 // 复用仓库内 src/pPowerManger/sqlit3/sqlite3.c 与 sqlite3.h。 //============================================================================ struct CanFrameRow { long long id; double time; // unix 时间(含小数秒) std::string channel; // 通道名(CAN0~CAN7) int frameInfo; // 原始帧信息字节 byte0(bit7 FF / bit6 RTR / bit3~0 DLC) uint32_t canId; // CAN ID int dlc; std::string hex; // 数据十六进制 }; class CanDbStore { public: explicit CanDbStore(const std::string& dbPath); ~CanDbStore(); bool open(); void close(); bool isOpen() const { return m_db != nullptr; } std::string lastError() const { return m_lastError; } // 收帧落库(CanEndpoint 接收线程调用,内部加锁) void onFrame(const std::string& channel, uint8_t frameInfo, uint32_t canId, const uint8_t* data, int dlc); // 查询最近 N 条(canId=0 表示不过滤;limit<=0 表示默认 100) std::vector queryRecent(uint32_t canId, int limit); long long count() const; private: bool exec(const char* sql); bool prepareInsert(); std::string m_dbPath; sqlite3* m_db = nullptr; sqlite3_stmt* m_stmtInsert = nullptr; mutable std::mutex m_mutex; std::string m_lastError; }; } // namespace canbridge #endif // PCANBRIDGE_CAN_DB_STORE_H