From bdb6e6b79e9beeaabfbde99cd760de77247d11a4 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 10 Feb 2021 01:03:20 +0100 Subject: Fix stuck notifications because of edits Does not fix the read status yet, for that we need to compare read receipts for all events after the last visible event. --- src/Cache.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'src/Cache.cpp') diff --git a/src/Cache.cpp b/src/Cache.cpp index 49861a9a..109fc60d 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1896,6 +1896,84 @@ Cache::getTimelineIndex(const std::string &room_id, std::string_view event_id) return *val.data(); } +std::optional +Cache::getEventIndex(const std::string &room_id, std::string_view event_id) +{ + if (event_id.empty()) + return {}; + + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + lmdb::dbi orderDb{0}; + try { + orderDb = getEventToOrderDb(txn, room_id); + } catch (lmdb::runtime_error &e) { + nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", + room_id, + e.what()); + return {}; + } + + lmdb::val indexVal{event_id.data(), event_id.size()}, val; + + bool success = lmdb::dbi_get(txn, orderDb, indexVal, val); + if (!success) { + nhlog::db()->critical("Could not find event id: {}", event_id); + return {}; + } + + return *val.data(); +} + +std::optional> +Cache::lastInvisibleEventAfter(const std::string &room_id, std::string_view event_id) +{ + if (event_id.empty()) + return {}; + + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + lmdb::dbi orderDb{0}; + lmdb::dbi eventOrderDb{0}; + lmdb::dbi timelineDb{0}; + try { + orderDb = getEventToOrderDb(txn, room_id); + eventOrderDb = getEventOrderDb(txn, room_id); + timelineDb = getMessageToOrderDb(txn, room_id); + } catch (lmdb::runtime_error &e) { + nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", + room_id, + e.what()); + return {}; + } + + lmdb::val eventIdVal{event_id.data(), event_id.size()}, indexVal; + + bool success = lmdb::dbi_get(txn, orderDb, eventIdVal, indexVal); + if (!success) { + return {}; + } + uint64_t prevIdx = *indexVal.data(); + std::string prevId{eventIdVal.data(), eventIdVal.size()}; + + auto cursor = lmdb::cursor::open(txn, eventOrderDb); + cursor.get(indexVal, MDB_SET); + while (cursor.get(indexVal, eventIdVal, MDB_NEXT)) { + std::string evId = + json::parse(std::string_view(eventIdVal.data(), eventIdVal.size()))["event_id"] + .get(); + lmdb::val temp; + if (lmdb::dbi_get(txn, timelineDb, lmdb::val(evId.data(), evId.size()), temp)) { + return std::pair{prevIdx, std::string(prevId)}; + } else { + prevIdx = *indexVal.data(); + prevId = std::move(evId); + } + } + + return std::pair{prevIdx, std::string(prevId)}; +} + std::optional Cache::getArrivalIndex(const std::string &room_id, std::string_view event_id) { @@ -4253,6 +4331,18 @@ readReceipts(const QString &event_id, const QString &room_id) return instance_->readReceipts(event_id, room_id); } +std::optional +getEventIndex(const std::string &room_id, std::string_view event_id) +{ + return instance_->getEventIndex(room_id, event_id); +} + +std::optional> +lastInvisibleEventAfter(const std::string &room_id, std::string_view event_id) +{ + return instance_->lastInvisibleEventAfter(room_id, event_id); +} + QByteArray image(const QString &url) { -- cgit 1.5.1