perf(chat): ingest a message batch in one transaction
Ingesting a scan's worth of chat messages persisted each new message with its own append() call, so a batch of fresh messages opened and committed one SQLite transaction per row. - A new appendBatch persists many messages in a single transaction, using the same INSERT OR IGNORE dedup key as append() and preserving input order so load()'s rowid ordering is unchanged. - Every message is serialized and encrypted before the transaction opens, so a message with a non-UTF-8 body is skipped on its own without leaving a transaction open; the valid siblings still persist. - Ingest collects the newly stored messages and writes them once after the loop instead of per message. It is inert (returns 0) while locked or on empty input. Tests cover a batch insert, dedup on re-insert, empty input, bad-UTF-8 isolation with a valid sibling and a following append(), insert order, and the locked no-op. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,12 @@ public:
|
||||
// Returns true if newly inserted; false on duplicate or while locked.
|
||||
bool append(const ChatMessage& message);
|
||||
|
||||
// Persist many messages in ONE transaction (INSERT OR IGNORE, same dedup key as append()).
|
||||
// Serializes+encrypts every message BEFORE opening the transaction, so a non-UTF-8 body is
|
||||
// skipped without leaving a transaction open. Preserves input order (load() relies on rowid).
|
||||
// Returns the number of rows actually inserted. No-op (returns 0) while locked or on empty input.
|
||||
int appendBatch(const std::vector<ChatMessage>& messages);
|
||||
|
||||
// Persist-or-overwrite one message by its (txid+position) dedup key. Unlike append(), this
|
||||
// updates an existing row's payload — used for outgoing echoes whose delivery status changes
|
||||
// (Sending → Sent/Failed). Returns true on success; false while locked / on error.
|
||||
|
||||
Reference in New Issue
Block a user