diff options
Diffstat (limited to 'src/Cache.cc')
-rw-r--r-- | src/Cache.cc | 103 |
1 files changed, 98 insertions, 5 deletions
diff --git a/src/Cache.cc b/src/Cache.cc index 06e45f13..e4e700b2 100644 --- a/src/Cache.cc +++ b/src/Cache.cc @@ -36,6 +36,7 @@ Cache::Cache(const QString &userId) , roomDb_{0} , invitesDb_{0} , imagesDb_{0} + , readReceiptsDb_{0} , isMounted_{false} , userId_{userId} {} @@ -89,11 +90,12 @@ Cache::setup() env_.open(statePath.toStdString().c_str()); } - auto txn = lmdb::txn::begin(env_); - stateDb_ = lmdb::dbi::open(txn, "state", MDB_CREATE); - roomDb_ = lmdb::dbi::open(txn, "rooms", MDB_CREATE); - invitesDb_ = lmdb::dbi::open(txn, "invites", MDB_CREATE); - imagesDb_ = lmdb::dbi::open(txn, "images", MDB_CREATE); + auto txn = lmdb::txn::begin(env_); + stateDb_ = lmdb::dbi::open(txn, "state", MDB_CREATE); + roomDb_ = lmdb::dbi::open(txn, "rooms", MDB_CREATE); + invitesDb_ = lmdb::dbi::open(txn, "invites", MDB_CREATE); + imagesDb_ = lmdb::dbi::open(txn, "images", MDB_CREATE); + readReceiptsDb_ = lmdb::dbi::open(txn, "read_receipts", MDB_CREATE); txn.commit(); @@ -449,3 +451,94 @@ Cache::setInvites(const std::map<std::string, mtx::responses::InvitedRoom> &invi unmount(); } } + +std::multimap<uint64_t, std::string> +Cache::readReceipts(const QString &event_id, const QString &room_id) +{ + std::multimap<uint64_t, std::string> receipts; + + ReadReceiptKey receipt_key{event_id.toStdString(), room_id.toStdString()}; + nlohmann::json json_key = receipt_key; + + try { + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + auto key = json_key.dump(); + + lmdb::val value; + + bool res = + lmdb::dbi_get(txn, readReceiptsDb_, lmdb::val(key.data(), key.size()), value); + + txn.commit(); + + if (res) { + auto json_response = json::parse(std::string(value.data(), value.size())); + auto values = json_response.get<std::vector<ReadReceiptValue>>(); + + for (auto v : values) + receipts.emplace(v.ts, v.user_id); + } + + } catch (const lmdb::error &e) { + qCritical() << "readReceipts:" << e.what(); + } + + return receipts; +} + +using Receipts = std::map<std::string, std::map<std::string, uint64_t>>; +void +Cache::updateReadReceipt(const std::string &room_id, const Receipts &receipts) +{ + for (auto receipt : receipts) { + const auto event_id = receipt.first; + auto event_receipts = receipt.second; + + ReadReceiptKey receipt_key{event_id, room_id}; + nlohmann::json json_key = receipt_key; + + try { + auto read_txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + const auto key = json_key.dump(); + + lmdb::val prev_value; + + bool exists = lmdb::dbi_get( + read_txn, readReceiptsDb_, lmdb::val(key.data(), key.size()), prev_value); + + read_txn.commit(); + + std::vector<ReadReceiptValue> saved_receipts; + + // If an entry for the event id already exists, we would + // merge the existing receipts with the new ones. + if (exists) { + auto json_value = + json::parse(std::string(prev_value.data(), prev_value.size())); + + // Retrieve the saved receipts. + saved_receipts = json_value.get<std::vector<ReadReceiptValue>>(); + } + + // Append the new ones. + for (auto event_receipt : event_receipts) + saved_receipts.push_back( + ReadReceiptValue{event_receipt.first, event_receipt.second}); + + // Save back the merged (or only the new) receipts. + nlohmann::json json_updated_value = saved_receipts; + std::string merged_receipts = json_updated_value.dump(); + + auto txn = lmdb::txn::begin(env_); + + lmdb::dbi_put(txn, + readReceiptsDb_, + lmdb::val(key.data(), key.size()), + lmdb::val(merged_receipts.data(), merged_receipts.size())); + + txn.commit(); + } catch (const lmdb::error &e) { + qCritical() << "updateReadReceipts:" << e.what(); + } + } +} |