* @brief Drains the table snapshot queue and writes register changes to the database. */
| 524 | * @brief Drains the table snapshot queue and writes register changes to the database. |
| 525 | */ |
| 526 | void Sessions::ExportWorker::writeTableSnapshots() |
| 527 | { |
| 528 | Q_ASSERT(m_dbOpen); |
| 529 | |
| 530 | if (!m_db || !m_tableSnapshotQuery) [[unlikely]] |
| 531 | return; |
| 532 | |
| 533 | if (!m_snapshotQueue->peek()) |
| 534 | return; |
| 535 | |
| 536 | constexpr size_t kMaxSnapshotBatch = 1000; |
| 537 | TableSnapshotEntry entry; |
| 538 | size_t count = 0; |
| 539 | |
| 540 | m_db->transaction(); |
| 541 | while (count < kMaxSnapshotBatch && m_snapshotQueue->try_dequeue(entry)) { |
| 542 | const auto elapsed = entry.timestamp - m_steadyBaseline; |
| 543 | qint64 ns = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count(); |
| 544 | if (ns < 0) [[unlikely]] |
| 545 | ns = 0; |
| 546 | |
| 547 | const auto& value = entry.value; |
| 548 | m_tableSnapshotQuery->bindValue(0, m_sessionId); |
| 549 | m_tableSnapshotQuery->bindValue(1, ns); |
| 550 | m_tableSnapshotQuery->bindValue(2, entry.tableName); |
| 551 | m_tableSnapshotQuery->bindValue(3, entry.registerName); |
| 552 | m_tableSnapshotQuery->bindValue(4, value.isNumeric ? QVariant(value.numericValue) : QVariant()); |
| 553 | m_tableSnapshotQuery->bindValue(5, value.isNumeric ? QVariant() : QVariant(value.stringValue)); |
| 554 | |
| 555 | if (!m_tableSnapshotQuery->exec()) [[unlikely]] |
| 556 | qWarning() << "[SQLite] Insert table_snapshots failed:" |
| 557 | << m_tableSnapshotQuery->lastError().text(); |
| 558 | |
| 559 | ++count; |
| 560 | } |
| 561 | m_db->commit(); |
| 562 | } |
| 563 | |
| 564 | /** |
| 565 | * @brief Updates the session's ended_at timestamp. |