|
|
|
@ -2304,6 +2304,11 @@ Cache::saveTimelineMessages(lmdb::txn &txn, |
|
|
|
|
|
|
|
|
|
lmdb::val event_id = event_id_val; |
|
|
|
|
|
|
|
|
|
json orderEntry = json::object(); |
|
|
|
|
orderEntry["event_id"] = event_id_val; |
|
|
|
|
if (first && !res.prev_batch.empty()) |
|
|
|
|
orderEntry["prev_batch"] = res.prev_batch; |
|
|
|
|
|
|
|
|
|
lmdb::val txn_order; |
|
|
|
|
if (!txn_id.empty() && |
|
|
|
|
lmdb::dbi_get(txn, evToOrderDb, lmdb::val(txn_id), txn_order)) { |
|
|
|
@ -2317,7 +2322,7 @@ Cache::saveTimelineMessages(lmdb::txn &txn, |
|
|
|
|
lmdb::dbi_del(txn, msg2orderDb, lmdb::val(txn_id)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
lmdb::dbi_put(txn, orderDb, txn_order, event_id); |
|
|
|
|
lmdb::dbi_put(txn, orderDb, txn_order, lmdb::val(orderEntry.dump())); |
|
|
|
|
lmdb::dbi_put(txn, evToOrderDb, event_id, txn_order); |
|
|
|
|
lmdb::dbi_del(txn, evToOrderDb, lmdb::val(txn_id)); |
|
|
|
|
|
|
|
|
@ -2389,10 +2394,6 @@ Cache::saveTimelineMessages(lmdb::txn &txn, |
|
|
|
|
|
|
|
|
|
++index; |
|
|
|
|
|
|
|
|
|
json orderEntry = json::object(); |
|
|
|
|
orderEntry["event_id"] = event_id_val; |
|
|
|
|
if (first && !res.prev_batch.empty()) |
|
|
|
|
orderEntry["prev_batch"] = res.prev_batch; |
|
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
nhlog::db()->debug("saving '{}'", orderEntry.dump()); |
|
|
|
@ -2440,6 +2441,7 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message |
|
|
|
|
auto relationsDb = getRelationsDb(txn, room_id); |
|
|
|
|
|
|
|
|
|
auto orderDb = getEventOrderDb(txn, room_id); |
|
|
|
|
auto evToOrderDb = getEventToOrderDb(txn, room_id); |
|
|
|
|
auto msg2orderDb = getMessageToOrderDb(txn, room_id); |
|
|
|
|
auto order2msgDb = getOrderToMessageDb(txn, room_id); |
|
|
|
|
|
|
|
|
@ -2483,6 +2485,7 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message |
|
|
|
|
|
|
|
|
|
lmdb::dbi_put( |
|
|
|
|
txn, orderDb, lmdb::val(&index, sizeof(index)), lmdb::val(orderEntry.dump())); |
|
|
|
|
lmdb::dbi_put(txn, evToOrderDb, event_id, lmdb::val(&index, sizeof(index))); |
|
|
|
|
|
|
|
|
|
// TODO(Nico): Allow blacklisting more event types in UI
|
|
|
|
|
if (event["type"] != "m.reaction" && event["type"] != "m.dummy") { |
|
|
|
@ -2516,6 +2519,94 @@ Cache::saveOldMessages(const std::string &room_id, const mtx::responses::Message |
|
|
|
|
return msgIndex; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
Cache::clearTimeline(const std::string &room_id) |
|
|
|
|
{ |
|
|
|
|
auto txn = lmdb::txn::begin(env_); |
|
|
|
|
auto eventsDb = getEventsDb(txn, room_id); |
|
|
|
|
auto relationsDb = getRelationsDb(txn, room_id); |
|
|
|
|
|
|
|
|
|
auto orderDb = getEventOrderDb(txn, room_id); |
|
|
|
|
auto evToOrderDb = getEventToOrderDb(txn, room_id); |
|
|
|
|
auto msg2orderDb = getMessageToOrderDb(txn, room_id); |
|
|
|
|
auto order2msgDb = getOrderToMessageDb(txn, room_id); |
|
|
|
|
|
|
|
|
|
lmdb::val indexVal, val; |
|
|
|
|
auto cursor = lmdb::cursor::open(txn, orderDb); |
|
|
|
|
|
|
|
|
|
bool start = true; |
|
|
|
|
bool passed_pagination_token = false; |
|
|
|
|
while (cursor.get(indexVal, val, start ? MDB_LAST : MDB_PREV)) { |
|
|
|
|
start = false; |
|
|
|
|
json obj; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
obj = json::parse(std::string_view(val.data(), val.size())); |
|
|
|
|
} catch (std::exception &) { |
|
|
|
|
// workaround bug in the initial db format, where we sometimes didn't store
|
|
|
|
|
// json...
|
|
|
|
|
obj = {{"event_id", std::string(val.data(), val.size())}}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (passed_pagination_token) { |
|
|
|
|
if (obj.count("event_id") != 0) { |
|
|
|
|
lmdb::val event_id = obj["event_id"].get<std::string>(); |
|
|
|
|
lmdb::dbi_del(txn, evToOrderDb, event_id); |
|
|
|
|
lmdb::dbi_del(txn, eventsDb, event_id); |
|
|
|
|
|
|
|
|
|
lmdb::dbi_del(txn, relationsDb, event_id); |
|
|
|
|
|
|
|
|
|
lmdb::val order{}; |
|
|
|
|
bool exists = lmdb::dbi_get(txn, msg2orderDb, event_id, order); |
|
|
|
|
if (exists) { |
|
|
|
|
lmdb::dbi_del(txn, order2msgDb, order); |
|
|
|
|
lmdb::dbi_del(txn, msg2orderDb, event_id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
lmdb::cursor_del(cursor); |
|
|
|
|
} else { |
|
|
|
|
if (obj.count("prev_batch") != 0) |
|
|
|
|
passed_pagination_token = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
auto msgCursor = lmdb::cursor::open(txn, order2msgDb); |
|
|
|
|
start = true; |
|
|
|
|
while (msgCursor.get(indexVal, val, start ? MDB_LAST : MDB_PREV)) { |
|
|
|
|
start = false; |
|
|
|
|
|
|
|
|
|
lmdb::val eventId; |
|
|
|
|
bool innerStart = true; |
|
|
|
|
bool found = false; |
|
|
|
|
while (cursor.get(indexVal, eventId, innerStart ? MDB_LAST : MDB_PREV)) { |
|
|
|
|
innerStart = false; |
|
|
|
|
|
|
|
|
|
json obj; |
|
|
|
|
try { |
|
|
|
|
obj = json::parse(std::string_view(eventId.data(), eventId.size())); |
|
|
|
|
} catch (std::exception &) { |
|
|
|
|
obj = {{"event_id", std::string(eventId.data(), eventId.size())}}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (obj["event_id"] == std::string(val.data(), val.size())) { |
|
|
|
|
found = true; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!found) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
lmdb::cursor_del(msgCursor); |
|
|
|
|
} while (msgCursor.get(indexVal, val, MDB_PREV)); |
|
|
|
|
|
|
|
|
|
cursor.close(); |
|
|
|
|
msgCursor.close(); |
|
|
|
|
txn.commit(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
mtx::responses::Notifications |
|
|
|
|
Cache::getTimelineMentionsForRoom(lmdb::txn &txn, const std::string &room_id) |
|
|
|
|
{ |
|
|
|
@ -2655,9 +2746,11 @@ Cache::deleteOldMessages() |
|
|
|
|
|
|
|
|
|
for (const auto &room_id : room_ids) { |
|
|
|
|
auto orderDb = getEventOrderDb(txn, room_id); |
|
|
|
|
auto evToOrderDb = getEventToOrderDb(txn, room_id); |
|
|
|
|
auto o2m = getOrderToMessageDb(txn, room_id); |
|
|
|
|
auto m2o = getMessageToOrderDb(txn, room_id); |
|
|
|
|
auto eventsDb = getEventsDb(txn, room_id); |
|
|
|
|
auto relationsDb = getRelationsDb(txn, room_id); |
|
|
|
|
auto cursor = lmdb::cursor::open(txn, orderDb); |
|
|
|
|
|
|
|
|
|
uint64_t first, last; |
|
|
|
@ -2678,14 +2771,17 @@ Cache::deleteOldMessages() |
|
|
|
|
|
|
|
|
|
bool start = true; |
|
|
|
|
while (cursor.get(indexVal, val, start ? MDB_FIRST : MDB_NEXT) && |
|
|
|
|
message_count-- < MAX_RESTORED_MESSAGES) { |
|
|
|
|
message_count-- > MAX_RESTORED_MESSAGES) { |
|
|
|
|
start = false; |
|
|
|
|
auto obj = json::parse(std::string_view(val.data(), val.size())); |
|
|
|
|
|
|
|
|
|
if (obj.count("event_id") != 0) { |
|
|
|
|
lmdb::val event_id = obj["event_id"].get<std::string>(); |
|
|
|
|
lmdb::dbi_del(txn, evToOrderDb, event_id); |
|
|
|
|
lmdb::dbi_del(txn, eventsDb, event_id); |
|
|
|
|
|
|
|
|
|
lmdb::dbi_del(txn, relationsDb, event_id); |
|
|
|
|
|
|
|
|
|
lmdb::val order{}; |
|
|
|
|
bool exists = lmdb::dbi_get(txn, m2o, event_id, order); |
|
|
|
|
if (exists) { |
|
|
|
|