diff --git a/src/Cache_p.h b/src/Cache_p.h
index ff2f31e5..a15010e6 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -32,694 +32,658 @@
class Cache : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- Cache(const QString &userId, QObject *parent = nullptr);
-
- std::string displayName(const std::string &room_id, const std::string &user_id);
- QString displayName(const QString &room_id, const QString &user_id);
- QString avatarUrl(const QString &room_id, const QString &user_id);
-
- // presence
- mtx::presence::PresenceState presenceState(const std::string &user_id);
- std::string statusMessage(const std::string &user_id);
-
- // user cache stores user keys
- std::map<std::string, std::optional<UserKeyCache>> getMembersWithKeys(
- const std::string &room_id,
- bool verified_only);
- void updateUserKeys(const std::string &sync_token,
- const mtx::responses::QueryKeys &keyQuery);
- void markUserKeysOutOfDate(lmdb::txn &txn,
- lmdb::dbi &db,
- const std::vector<std::string> &user_ids,
- const std::string &sync_token);
- void query_keys(const std::string &user_id,
- std::function<void(const UserKeyCache &, mtx::http::RequestErr)> cb);
-
- // device & user verification cache
- std::optional<UserKeyCache> userKeys(const std::string &user_id);
- VerificationStatus verificationStatus(const std::string &user_id);
- void markDeviceVerified(const std::string &user_id, const std::string &device);
- void markDeviceUnverified(const std::string &user_id, const std::string &device);
- crypto::Trust roomVerificationStatus(const std::string &room_id);
-
- std::vector<std::string> joinedRooms();
-
- QMap<QString, RoomInfo> roomInfo(bool withInvites = true);
- std::optional<mtx::events::state::CanonicalAlias> getRoomAliases(const std::string &roomid);
- QHash<QString, RoomInfo> invites();
- std::optional<RoomInfo> invite(std::string_view roomid);
- QMap<QString, std::optional<RoomInfo>> spaces();
-
- //! Calculate & return the name of the room.
- QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
- //! Get room join rules
- mtx::events::state::JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb);
- bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb);
- //! Retrieve the topic of the room if any.
- QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
- //! Retrieve the room avatar's url if any.
- QString getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
- //! Retrieve the version of the room if any.
- QString getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb);
- //! Retrieve if the room is a space
- bool getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb);
-
- //! Get a specific state event
- template<typename T>
- std::optional<mtx::events::StateEvent<T>> getStateEvent(const std::string &room_id,
- std::string_view state_key = "")
- {
- auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
- return getStateEvent<T>(txn, room_id, state_key);
- }
-
- //! retrieve a specific event from account data
- //! pass empty room_id for global account data
- std::optional<mtx::events::collections::RoomAccountDataEvents> getAccountData(
- mtx::events::EventType type,
- const std::string &room_id = "");
-
- //! Retrieve member info from a room.
- std::vector<RoomMember> getMembers(const std::string &room_id,
- std::size_t startIndex = 0,
- std::size_t len = 30);
-
- std::vector<RoomMember> getMembersFromInvite(const std::string &room_id,
- std::size_t startIndex = 0,
- std::size_t len = 30);
- size_t memberCount(const std::string &room_id);
-
- void saveState(const mtx::responses::Sync &res);
- bool isInitialized();
- bool isDatabaseReady() { return databaseReady_ && isInitialized(); }
-
- std::string nextBatchToken();
-
- void deleteData();
-
- void removeInvite(lmdb::txn &txn, const std::string &room_id);
- void removeInvite(const std::string &room_id);
- void removeRoom(lmdb::txn &txn, const std::string &roomid);
- void removeRoom(const std::string &roomid);
- void setup();
-
- cache::CacheVersion formatVersion();
- void setCurrentFormat();
- bool runMigrations();
-
- std::vector<QString> roomIds();
- QMap<QString, mtx::responses::Notifications> getTimelineMentions();
-
- //! Retrieve all the user ids from a room.
- std::vector<std::string> roomMembers(const std::string &room_id);
-
- //! Check if the given user has power leve greater than than
- //! lowest power level of the given events.
- bool hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
+ Cache(const QString &userId, QObject *parent = nullptr);
+
+ std::string displayName(const std::string &room_id, const std::string &user_id);
+ QString displayName(const QString &room_id, const QString &user_id);
+ QString avatarUrl(const QString &room_id, const QString &user_id);
+
+ // presence
+ mtx::presence::PresenceState presenceState(const std::string &user_id);
+ std::string statusMessage(const std::string &user_id);
+
+ // user cache stores user keys
+ std::map<std::string, std::optional<UserKeyCache>> getMembersWithKeys(
+ const std::string &room_id,
+ bool verified_only);
+ void updateUserKeys(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery);
+ void markUserKeysOutOfDate(lmdb::txn &txn,
+ lmdb::dbi &db,
+ const std::vector<std::string> &user_ids,
+ const std::string &sync_token);
+ void query_keys(const std::string &user_id,
+ std::function<void(const UserKeyCache &, mtx::http::RequestErr)> cb);
+
+ // device & user verification cache
+ std::optional<UserKeyCache> userKeys(const std::string &user_id);
+ VerificationStatus verificationStatus(const std::string &user_id);
+ void markDeviceVerified(const std::string &user_id, const std::string &device);
+ void markDeviceUnverified(const std::string &user_id, const std::string &device);
+ crypto::Trust roomVerificationStatus(const std::string &room_id);
+
+ std::vector<std::string> joinedRooms();
+
+ QMap<QString, RoomInfo> roomInfo(bool withInvites = true);
+ std::optional<mtx::events::state::CanonicalAlias> getRoomAliases(const std::string &roomid);
+ QHash<QString, RoomInfo> invites();
+ std::optional<RoomInfo> invite(std::string_view roomid);
+ QMap<QString, std::optional<RoomInfo>> spaces();
+
+ //! Calculate & return the name of the room.
+ QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ //! Get room join rules
+ mtx::events::state::JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb);
+ bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb);
+ //! Retrieve the topic of the room if any.
+ QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
+ //! Retrieve the room avatar's url if any.
+ QString getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ //! Retrieve the version of the room if any.
+ QString getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb);
+ //! Retrieve if the room is a space
+ bool getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb);
+
+ //! Get a specific state event
+ template<typename T>
+ std::optional<mtx::events::StateEvent<T>> getStateEvent(const std::string &room_id,
+ std::string_view state_key = "")
+ {
+ auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
+ return getStateEvent<T>(txn, room_id, state_key);
+ }
+
+ //! retrieve a specific event from account data
+ //! pass empty room_id for global account data
+ std::optional<mtx::events::collections::RoomAccountDataEvents> getAccountData(
+ mtx::events::EventType type,
+ const std::string &room_id = "");
+
+ //! Retrieve member info from a room.
+ std::vector<RoomMember> getMembers(const std::string &room_id,
+ std::size_t startIndex = 0,
+ std::size_t len = 30);
+
+ std::vector<RoomMember> getMembersFromInvite(const std::string &room_id,
+ std::size_t startIndex = 0,
+ std::size_t len = 30);
+ size_t memberCount(const std::string &room_id);
+
+ void saveState(const mtx::responses::Sync &res);
+ bool isInitialized();
+ bool isDatabaseReady() { return databaseReady_ && isInitialized(); }
+
+ std::string nextBatchToken();
+
+ void deleteData();
+
+ void removeInvite(lmdb::txn &txn, const std::string &room_id);
+ void removeInvite(const std::string &room_id);
+ void removeRoom(lmdb::txn &txn, const std::string &roomid);
+ void removeRoom(const std::string &roomid);
+ void setup();
+
+ cache::CacheVersion formatVersion();
+ void setCurrentFormat();
+ bool runMigrations();
+
+ std::vector<QString> roomIds();
+ QMap<QString, mtx::responses::Notifications> getTimelineMentions();
+
+ //! Retrieve all the user ids from a room.
+ std::vector<std::string> roomMembers(const std::string &room_id);
+
+ //! Check if the given user has power leve greater than than
+ //! lowest power level of the given events.
+ bool hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
+ const std::string &room_id,
+ const std::string &user_id);
+
+ //! Adds a user to the read list for the given event.
+ //!
+ //! There should be only one user id present in a receipt list per room.
+ //! The user id should be removed from any other lists.
+ using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
+ void updateReadReceipt(lmdb::txn &txn, const std::string &room_id, const Receipts &receipts);
+
+ //! Retrieve all the read receipts for the given event id and room.
+ //!
+ //! Returns a map of user ids and the time of the read receipt in milliseconds.
+ using UserReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
+ UserReceipts readReceipts(const QString &event_id, const QString &room_id);
+
+ RoomInfo singleRoomInfo(const std::string &room_id);
+ std::vector<std::string> roomsWithStateUpdates(const mtx::responses::Sync &res);
+ std::map<QString, RoomInfo> getRoomInfo(const std::vector<std::string> &rooms);
+
+ //! Calculates which the read status of a room.
+ //! Whether all the events in the timeline have been read.
+ bool calculateRoomReadStatus(const std::string &room_id);
+ void calculateRoomReadStatus();
+
+ void markSentNotification(const std::string &event_id);
+ //! Removes an event from the sent notifications.
+ void removeReadNotification(const std::string &event_id);
+ //! Check if we have sent a desktop notification for the given event id.
+ bool isNotificationSent(const std::string &event_id);
+
+ //! Add all notifications containing a user mention to the db.
+ void saveTimelineMentions(const mtx::responses::Notifications &res);
+
+ //! retrieve events in timeline and related functions
+ struct Messages
+ {
+ mtx::responses::Timeline timeline;
+ uint64_t next_index;
+ bool end_of_cache = false;
+ };
+ Messages getTimelineMessages(lmdb::txn &txn,
const std::string &room_id,
- const std::string &user_id);
-
- //! Adds a user to the read list for the given event.
- //!
- //! There should be only one user id present in a receipt list per room.
- //! The user id should be removed from any other lists.
- using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
- void updateReadReceipt(lmdb::txn &txn,
- const std::string &room_id,
- const Receipts &receipts);
-
- //! Retrieve all the read receipts for the given event id and room.
- //!
- //! Returns a map of user ids and the time of the read receipt in milliseconds.
- using UserReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
- UserReceipts readReceipts(const QString &event_id, const QString &room_id);
-
- RoomInfo singleRoomInfo(const std::string &room_id);
- std::vector<std::string> roomsWithStateUpdates(const mtx::responses::Sync &res);
- std::map<QString, RoomInfo> getRoomInfo(const std::vector<std::string> &rooms);
-
- //! Calculates which the read status of a room.
- //! Whether all the events in the timeline have been read.
- bool calculateRoomReadStatus(const std::string &room_id);
- void calculateRoomReadStatus();
-
- void markSentNotification(const std::string &event_id);
- //! Removes an event from the sent notifications.
- void removeReadNotification(const std::string &event_id);
- //! Check if we have sent a desktop notification for the given event id.
- bool isNotificationSent(const std::string &event_id);
-
- //! Add all notifications containing a user mention to the db.
- void saveTimelineMentions(const mtx::responses::Notifications &res);
-
- //! retrieve events in timeline and related functions
- struct Messages
- {
- mtx::responses::Timeline timeline;
- uint64_t next_index;
- bool end_of_cache = false;
- };
- Messages getTimelineMessages(lmdb::txn &txn,
- const std::string &room_id,
- uint64_t index = std::numeric_limits<uint64_t>::max(),
- bool forward = false);
-
- std::optional<mtx::events::collections::TimelineEvent> getEvent(
- const std::string &room_id,
- const std::string &event_id);
- void storeEvent(const std::string &room_id,
- const std::string &event_id,
- const mtx::events::collections::TimelineEvent &event);
- void replaceEvent(const std::string &room_id,
- const std::string &event_id,
- const mtx::events::collections::TimelineEvent &event);
- std::vector<std::string> relatedEvents(const std::string &room_id,
- const std::string &event_id);
-
- struct TimelineRange
- {
- uint64_t first, last;
+ uint64_t index = std::numeric_limits<uint64_t>::max(),
+ bool forward = false);
+
+ std::optional<mtx::events::collections::TimelineEvent> getEvent(const std::string &room_id,
+ const std::string &event_id);
+ void storeEvent(const std::string &room_id,
+ const std::string &event_id,
+ const mtx::events::collections::TimelineEvent &event);
+ void replaceEvent(const std::string &room_id,
+ const std::string &event_id,
+ const mtx::events::collections::TimelineEvent &event);
+ std::vector<std::string> relatedEvents(const std::string &room_id, const std::string &event_id);
+
+ struct TimelineRange
+ {
+ uint64_t first, last;
+ };
+ std::optional<TimelineRange> getTimelineRange(const std::string &room_id);
+ std::optional<uint64_t> getTimelineIndex(const std::string &room_id, std::string_view event_id);
+ std::optional<uint64_t> getEventIndex(const std::string &room_id, std::string_view event_id);
+ std::optional<std::pair<uint64_t, std::string>> lastInvisibleEventAfter(
+ const std::string &room_id,
+ std::string_view event_id);
+ std::optional<std::string> getTimelineEventId(const std::string &room_id, uint64_t index);
+ std::optional<uint64_t> getArrivalIndex(const std::string &room_id, std::string_view event_id);
+
+ std::string previousBatchToken(const std::string &room_id);
+ uint64_t saveOldMessages(const std::string &room_id, const mtx::responses::Messages &res);
+ void savePendingMessage(const std::string &room_id,
+ const mtx::events::collections::TimelineEvent &message);
+ std::optional<mtx::events::collections::TimelineEvent> firstPendingMessage(
+ const std::string &room_id);
+ void removePendingStatus(const std::string &room_id, const std::string &txn_id);
+
+ //! clear timeline keeping only the latest batch
+ void clearTimeline(const std::string &room_id);
+
+ //! Remove old unused data.
+ void deleteOldMessages();
+ void deleteOldData() noexcept;
+ //! Retrieve all saved room ids.
+ std::vector<std::string> getRoomIds(lmdb::txn &txn);
+ std::vector<std::string> getParentRoomIds(const std::string &room_id);
+ std::vector<std::string> getChildRoomIds(const std::string &room_id);
+
+ std::vector<ImagePackInfo> getImagePacks(const std::string &room_id,
+ std::optional<bool> stickers);
+
+ //! Mark a room that uses e2e encryption.
+ void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id);
+ bool isRoomEncrypted(const std::string &room_id);
+ std::optional<mtx::events::state::Encryption> roomEncryptionSettings(
+ const std::string &room_id);
+
+ //! Check if a user is a member of the room.
+ bool isRoomMember(const std::string &user_id, const std::string &room_id);
+
+ //
+ // Outbound Megolm Sessions
+ //
+ void saveOutboundMegolmSession(const std::string &room_id,
+ const GroupSessionData &data,
+ mtx::crypto::OutboundGroupSessionPtr &session);
+ OutboundGroupSessionDataRef getOutboundMegolmSession(const std::string &room_id);
+ bool outboundMegolmSessionExists(const std::string &room_id) noexcept;
+ void updateOutboundMegolmSession(const std::string &room_id,
+ const GroupSessionData &data,
+ mtx::crypto::OutboundGroupSessionPtr &session);
+ void dropOutboundMegolmSession(const std::string &room_id);
+
+ void importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys);
+ mtx::crypto::ExportedSessionKeys exportSessionKeys();
+
+ //
+ // Inbound Megolm Sessions
+ //
+ void saveInboundMegolmSession(const MegolmSessionIndex &index,
+ mtx::crypto::InboundGroupSessionPtr session,
+ const GroupSessionData &data);
+ mtx::crypto::InboundGroupSessionPtr getInboundMegolmSession(const MegolmSessionIndex &index);
+ bool inboundMegolmSessionExists(const MegolmSessionIndex &index);
+ std::optional<GroupSessionData> getMegolmSessionData(const MegolmSessionIndex &index);
+
+ //
+ // Olm Sessions
+ //
+ void saveOlmSession(const std::string &curve25519,
+ mtx::crypto::OlmSessionPtr session,
+ uint64_t timestamp);
+ std::vector<std::string> getOlmSessions(const std::string &curve25519);
+ std::optional<mtx::crypto::OlmSessionPtr> getOlmSession(const std::string &curve25519,
+ const std::string &session_id);
+ std::optional<mtx::crypto::OlmSessionPtr> getLatestOlmSession(const std::string &curve25519);
+
+ void saveOlmAccount(const std::string &pickled);
+ std::string restoreOlmAccount();
+
+ void saveBackupVersion(const OnlineBackupVersion &data);
+ void deleteBackupVersion();
+ std::optional<OnlineBackupVersion> backupVersion();
+
+ void storeSecret(const std::string name, const std::string secret, bool internal = false);
+ void deleteSecret(const std::string name, bool internal = false);
+ std::optional<std::string> secret(const std::string name, bool internal = false);
+
+ std::string pickleSecret();
+
+ template<class T>
+ constexpr static bool isStateEvent_ =
+ std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
+ mtx::events::StateEvent<decltype(std::declval<T>().content)>>;
+
+ static int compare_state_key(const MDB_val *a, const MDB_val *b)
+ {
+ auto get_skey = [](const MDB_val *v) {
+ return nlohmann::json::parse(
+ std::string_view(static_cast<const char *>(v->mv_data), v->mv_size))
+ .value("key", "");
};
- std::optional<TimelineRange> getTimelineRange(const std::string &room_id);
- std::optional<uint64_t> getTimelineIndex(const std::string &room_id,
- std::string_view event_id);
- std::optional<uint64_t> getEventIndex(const std::string &room_id,
- std::string_view event_id);
- std::optional<std::pair<uint64_t, std::string>> lastInvisibleEventAfter(
- const std::string &room_id,
- std::string_view event_id);
- std::optional<std::string> getTimelineEventId(const std::string &room_id, uint64_t index);
- std::optional<uint64_t> getArrivalIndex(const std::string &room_id,
- std::string_view event_id);
-
- std::string previousBatchToken(const std::string &room_id);
- uint64_t saveOldMessages(const std::string &room_id, const mtx::responses::Messages &res);
- void savePendingMessage(const std::string &room_id,
- const mtx::events::collections::TimelineEvent &message);
- std::optional<mtx::events::collections::TimelineEvent> firstPendingMessage(
- const std::string &room_id);
- void removePendingStatus(const std::string &room_id, const std::string &txn_id);
-
- //! clear timeline keeping only the latest batch
- void clearTimeline(const std::string &room_id);
-
- //! Remove old unused data.
- void deleteOldMessages();
- void deleteOldData() noexcept;
- //! Retrieve all saved room ids.
- std::vector<std::string> getRoomIds(lmdb::txn &txn);
- std::vector<std::string> getParentRoomIds(const std::string &room_id);
- std::vector<std::string> getChildRoomIds(const std::string &room_id);
-
- std::vector<ImagePackInfo> getImagePacks(const std::string &room_id,
- std::optional<bool> stickers);
-
- //! Mark a room that uses e2e encryption.
- void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id);
- bool isRoomEncrypted(const std::string &room_id);
- std::optional<mtx::events::state::Encryption> roomEncryptionSettings(
- const std::string &room_id);
-
- //! Check if a user is a member of the room.
- bool isRoomMember(const std::string &user_id, const std::string &room_id);
-
- //
- // Outbound Megolm Sessions
- //
- void saveOutboundMegolmSession(const std::string &room_id,
- const GroupSessionData &data,
- mtx::crypto::OutboundGroupSessionPtr &session);
- OutboundGroupSessionDataRef getOutboundMegolmSession(const std::string &room_id);
- bool outboundMegolmSessionExists(const std::string &room_id) noexcept;
- void updateOutboundMegolmSession(const std::string &room_id,
- const GroupSessionData &data,
- mtx::crypto::OutboundGroupSessionPtr &session);
- void dropOutboundMegolmSession(const std::string &room_id);
-
- void importSessionKeys(const mtx::crypto::ExportedSessionKeys &keys);
- mtx::crypto::ExportedSessionKeys exportSessionKeys();
-
- //
- // Inbound Megolm Sessions
- //
- void saveInboundMegolmSession(const MegolmSessionIndex &index,
- mtx::crypto::InboundGroupSessionPtr session,
- const GroupSessionData &data);
- mtx::crypto::InboundGroupSessionPtr getInboundMegolmSession(
- const MegolmSessionIndex &index);
- bool inboundMegolmSessionExists(const MegolmSessionIndex &index);
- std::optional<GroupSessionData> getMegolmSessionData(const MegolmSessionIndex &index);
-
- //
- // Olm Sessions
- //
- void saveOlmSession(const std::string &curve25519,
- mtx::crypto::OlmSessionPtr session,
- uint64_t timestamp);
- std::vector<std::string> getOlmSessions(const std::string &curve25519);
- std::optional<mtx::crypto::OlmSessionPtr> getOlmSession(const std::string &curve25519,
- const std::string &session_id);
- std::optional<mtx::crypto::OlmSessionPtr> getLatestOlmSession(
- const std::string &curve25519);
-
- void saveOlmAccount(const std::string &pickled);
- std::string restoreOlmAccount();
-
- void saveBackupVersion(const OnlineBackupVersion &data);
- void deleteBackupVersion();
- std::optional<OnlineBackupVersion> backupVersion();
-
- void storeSecret(const std::string name, const std::string secret, bool internal = false);
- void deleteSecret(const std::string name, bool internal = false);
- std::optional<std::string> secret(const std::string name, bool internal = false);
-
- std::string pickleSecret();
-
- template<class T>
- constexpr static bool isStateEvent_ =
- std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
- mtx::events::StateEvent<decltype(std::declval<T>().content)>>;
-
- static int compare_state_key(const MDB_val *a, const MDB_val *b)
- {
- auto get_skey = [](const MDB_val *v) {
- return nlohmann::json::parse(
- std::string_view(static_cast<const char *>(v->mv_data),
- v->mv_size))
- .value("key", "");
- };
-
- return get_skey(a).compare(get_skey(b));
- }
+
+ return get_skey(a).compare(get_skey(b));
+ }
signals:
- void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
- void roomReadStatus(const std::map<QString, bool> &status);
- void removeNotification(const QString &room_id, const QString &event_id);
- void userKeysUpdate(const std::string &sync_token,
- const mtx::responses::QueryKeys &keyQuery);
- void verificationStatusChanged(const std::string &userid);
- void secretChanged(const std::string name);
+ void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
+ void roomReadStatus(const std::map<QString, bool> &status);
+ void removeNotification(const QString &room_id, const QString &event_id);
+ void userKeysUpdate(const std::string &sync_token, const mtx::responses::QueryKeys &keyQuery);
+ void verificationStatusChanged(const std::string &userid);
+ void secretChanged(const std::string name);
private:
- //! Save an invited room.
- void saveInvite(lmdb::txn &txn,
+ //! Save an invited room.
+ void saveInvite(lmdb::txn &txn,
+ lmdb::dbi &statesdb,
+ lmdb::dbi &membersdb,
+ const mtx::responses::InvitedRoom &room);
+
+ //! Add a notification containing a user mention to the db.
+ void saveTimelineMentions(lmdb::txn &txn,
+ const std::string &room_id,
+ const QList<mtx::responses::Notification> &res);
+
+ //! Get timeline items that a user was mentions in for a given room
+ mtx::responses::Notifications getTimelineMentionsForRoom(lmdb::txn &txn,
+ const std::string &room_id);
+
+ QString getInviteRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
+ QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
+ bool getInviteRoomIsSpace(lmdb::txn &txn, lmdb::dbi &db);
+
+ std::optional<MemberInfo> getMember(const std::string &room_id, const std::string &user_id);
+
+ std::string getLastEventId(lmdb::txn &txn, const std::string &room_id);
+ void saveTimelineMessages(lmdb::txn &txn,
+ lmdb::dbi &eventsDb,
+ const std::string &room_id,
+ const mtx::responses::Timeline &res);
+
+ //! retrieve a specific event from account data
+ //! pass empty room_id for global account data
+ std::optional<mtx::events::collections::RoomAccountDataEvents>
+ getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id);
+ bool isHiddenEvent(lmdb::txn &txn,
+ mtx::events::collections::TimelineEvents e,
+ const std::string &room_id);
+
+ //! Remove a room from the cache.
+ // void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
+ template<class T>
+ void saveStateEvents(lmdb::txn &txn,
+ lmdb::dbi &statesdb,
+ lmdb::dbi &stateskeydb,
+ lmdb::dbi &membersdb,
+ lmdb::dbi &eventsDb,
+ const std::string &room_id,
+ const std::vector<T> &events)
+ {
+ for (const auto &e : events)
+ saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e);
+ }
+
+ template<class T>
+ void saveStateEvent(lmdb::txn &txn,
lmdb::dbi &statesdb,
+ lmdb::dbi &stateskeydb,
lmdb::dbi &membersdb,
- const mtx::responses::InvitedRoom &room);
-
- //! Add a notification containing a user mention to the db.
- void saveTimelineMentions(lmdb::txn &txn,
- const std::string &room_id,
- const QList<mtx::responses::Notification> &res);
-
- //! Get timeline items that a user was mentions in for a given room
- mtx::responses::Notifications getTimelineMentionsForRoom(lmdb::txn &txn,
- const std::string &room_id);
-
- QString getInviteRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
- QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
- QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
- bool getInviteRoomIsSpace(lmdb::txn &txn, lmdb::dbi &db);
-
- std::optional<MemberInfo> getMember(const std::string &room_id, const std::string &user_id);
-
- std::string getLastEventId(lmdb::txn &txn, const std::string &room_id);
- void saveTimelineMessages(lmdb::txn &txn,
- lmdb::dbi &eventsDb,
- const std::string &room_id,
- const mtx::responses::Timeline &res);
-
- //! retrieve a specific event from account data
- //! pass empty room_id for global account data
- std::optional<mtx::events::collections::RoomAccountDataEvents>
- getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id);
- bool isHiddenEvent(lmdb::txn &txn,
- mtx::events::collections::TimelineEvents e,
- const std::string &room_id);
-
- //! Remove a room from the cache.
- // void removeLeftRoom(lmdb::txn &txn, const std::string &room_id);
- template<class T>
- void saveStateEvents(lmdb::txn &txn,
- lmdb::dbi &statesdb,
- lmdb::dbi &stateskeydb,
- lmdb::dbi &membersdb,
- lmdb::dbi &eventsDb,
- const std::string &room_id,
- const std::vector<T> &events)
- {
- for (const auto &e : events)
- saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e);
+ lmdb::dbi &eventsDb,
+ const std::string &room_id,
+ const T &event)
+ {
+ using namespace mtx::events;
+ using namespace mtx::events::state;
+
+ if (auto e = std::get_if<StateEvent<Member>>(&event); e != nullptr) {
+ switch (e->content.membership) {
+ //
+ // We only keep users with invite or join membership.
+ //
+ case Membership::Invite:
+ case Membership::Join: {
+ auto display_name =
+ e->content.display_name.empty() ? e->state_key : e->content.display_name;
+
+ // Lightweight representation of a member.
+ MemberInfo tmp{display_name, e->content.avatar_url};
+
+ membersdb.put(txn, e->state_key, json(tmp).dump());
+ break;
+ }
+ default: {
+ membersdb.del(txn, e->state_key, "");
+ break;
+ }
+ }
+
+ return;
+ } else if (std::holds_alternative<StateEvent<Encryption>>(event)) {
+ setEncryptedRoom(txn, room_id);
+ return;
}
- template<class T>
- void saveStateEvent(lmdb::txn &txn,
- lmdb::dbi &statesdb,
- lmdb::dbi &stateskeydb,
- lmdb::dbi &membersdb,
- lmdb::dbi &eventsDb,
- const std::string &room_id,
- const T &event)
- {
- using namespace mtx::events;
- using namespace mtx::events::state;
-
- if (auto e = std::get_if<StateEvent<Member>>(&event); e != nullptr) {
- switch (e->content.membership) {
- //
- // We only keep users with invite or join membership.
- //
- case Membership::Invite:
- case Membership::Join: {
- auto display_name = e->content.display_name.empty()
- ? e->state_key
- : e->content.display_name;
-
- // Lightweight representation of a member.
- MemberInfo tmp{display_name, e->content.avatar_url};
-
- membersdb.put(txn, e->state_key, json(tmp).dump());
- break;
- }
- default: {
- membersdb.del(txn, e->state_key, "");
- break;
- }
- }
-
- return;
- } else if (std::holds_alternative<StateEvent<Encryption>>(event)) {
- setEncryptedRoom(txn, room_id);
- return;
- }
-
- std::visit(
- [&txn, &statesdb, &stateskeydb, &eventsDb, &membersdb](const auto &e) {
- if constexpr (isStateEvent_<decltype(e)>) {
- eventsDb.put(txn, e.event_id, json(e).dump());
-
- if (e.type != EventType::Unsupported) {
- if (std::is_same_v<
- std::remove_cv_t<
- std::remove_reference_t<decltype(e)>>,
- StateEvent<mtx::events::msg::Redacted>>) {
- if (e.type == EventType::RoomMember)
- membersdb.del(txn, e.state_key, "");
- else if (e.state_key.empty())
- statesdb.del(txn, to_string(e.type));
- else
- stateskeydb.del(
- txn,
- to_string(e.type),
- json::object({
- {"key", e.state_key},
- {"id", e.event_id},
- })
- .dump());
- } else if (e.state_key.empty())
- statesdb.put(
- txn, to_string(e.type), json(e).dump());
- else
- stateskeydb.put(
- txn,
- to_string(e.type),
- json::object({
- {"key", e.state_key},
- {"id", e.event_id},
- })
- .dump());
- }
- }
- },
- event);
+ std::visit(
+ [&txn, &statesdb, &stateskeydb, &eventsDb, &membersdb](const auto &e) {
+ if constexpr (isStateEvent_<decltype(e)>) {
+ eventsDb.put(txn, e.event_id, json(e).dump());
+
+ if (e.type != EventType::Unsupported) {
+ if (std::is_same_v<std::remove_cv_t<std::remove_reference_t<decltype(e)>>,
+ StateEvent<mtx::events::msg::Redacted>>) {
+ if (e.type == EventType::RoomMember)
+ membersdb.del(txn, e.state_key, "");
+ else if (e.state_key.empty())
+ statesdb.del(txn, to_string(e.type));
+ else
+ stateskeydb.del(txn,
+ to_string(e.type),
+ json::object({
+ {"key", e.state_key},
+ {"id", e.event_id},
+ })
+ .dump());
+ } else if (e.state_key.empty())
+ statesdb.put(txn, to_string(e.type), json(e).dump());
+ else
+ stateskeydb.put(txn,
+ to_string(e.type),
+ json::object({
+ {"key", e.state_key},
+ {"id", e.event_id},
+ })
+ .dump());
+ }
+ }
+ },
+ event);
+ }
+
+ template<typename T>
+ std::optional<mtx::events::StateEvent<T>> getStateEvent(lmdb::txn &txn,
+ const std::string &room_id,
+ std::string_view state_key = "")
+ {
+ constexpr auto type = mtx::events::state_content_to_type<T>;
+ static_assert(type != mtx::events::EventType::Unsupported,
+ "Not a supported type in state events.");
+
+ if (room_id.empty())
+ return std::nullopt;
+ const auto typeStr = to_string(type);
+
+ std::string_view value;
+ if (state_key.empty()) {
+ auto db = getStatesDb(txn, room_id);
+ if (!db.get(txn, typeStr, value)) {
+ return std::nullopt;
+ }
+ } else {
+ auto db = getStatesKeyDb(txn, room_id);
+ std::string d = json::object({{"key", state_key}}).dump();
+ std::string_view data = d;
+ std::string_view typeStrV = typeStr;
+
+ auto cursor = lmdb::cursor::open(txn, db);
+ if (!cursor.get(typeStrV, data, MDB_GET_BOTH))
+ return std::nullopt;
+
+ try {
+ auto eventsDb = getEventsDb(txn, room_id);
+ if (!eventsDb.get(txn, json::parse(data)["id"].get<std::string>(), value))
+ return std::nullopt;
+ } catch (std::exception &e) {
+ return std::nullopt;
+ }
}
- template<typename T>
- std::optional<mtx::events::StateEvent<T>> getStateEvent(lmdb::txn &txn,
- const std::string &room_id,
- std::string_view state_key = "")
- {
- constexpr auto type = mtx::events::state_content_to_type<T>;
- static_assert(type != mtx::events::EventType::Unsupported,
- "Not a supported type in state events.");
-
- if (room_id.empty())
- return std::nullopt;
- const auto typeStr = to_string(type);
-
- std::string_view value;
- if (state_key.empty()) {
- auto db = getStatesDb(txn, room_id);
- if (!db.get(txn, typeStr, value)) {
- return std::nullopt;
- }
- } else {
- auto db = getStatesKeyDb(txn, room_id);
- std::string d = json::object({{"key", state_key}}).dump();
- std::string_view data = d;
- std::string_view typeStrV = typeStr;
-
- auto cursor = lmdb::cursor::open(txn, db);
- if (!cursor.get(typeStrV, data, MDB_GET_BOTH))
- return std::nullopt;
-
- try {
- auto eventsDb = getEventsDb(txn, room_id);
- if (!eventsDb.get(
- txn, json::parse(data)["id"].get<std::string>(), value))
- return std::nullopt;
- } catch (std::exception &e) {
- return std::nullopt;
- }
- }
-
- try {
- return json::parse(value).get<mtx::events::StateEvent<T>>();
- } catch (std::exception &e) {
- return std::nullopt;
- }
+ try {
+ return json::parse(value).get<mtx::events::StateEvent<T>>();
+ } catch (std::exception &e) {
+ return std::nullopt;
}
+ }
- template<typename T>
- std::vector<mtx::events::StateEvent<T>> getStateEventsWithType(lmdb::txn &txn,
- const std::string &room_id)
+ template<typename T>
+ std::vector<mtx::events::StateEvent<T>> getStateEventsWithType(lmdb::txn &txn,
+ const std::string &room_id)
- {
- constexpr auto type = mtx::events::state_content_to_type<T>;
- static_assert(type != mtx::events::EventType::Unsupported,
- "Not a supported type in state events.");
-
- if (room_id.empty())
- return {};
-
- std::vector<mtx::events::StateEvent<T>> events;
-
- {
- auto db = getStatesKeyDb(txn, room_id);
- auto eventsDb = getEventsDb(txn, room_id);
- const auto typeStr = to_string(type);
- std::string_view typeStrV = typeStr;
- std::string_view data;
- std::string_view value;
-
- auto cursor = lmdb::cursor::open(txn, db);
- bool first = true;
- if (cursor.get(typeStrV, data, MDB_SET)) {
- while (cursor.get(
- typeStrV, data, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) {
- first = false;
-
- if (eventsDb.get(txn,
- json::parse(data)["id"].get<std::string>(),
- value))
- events.push_back(
- json::parse(value)
- .get<mtx::events::StateEvent<T>>());
- }
- }
- }
+ {
+ constexpr auto type = mtx::events::state_content_to_type<T>;
+ static_assert(type != mtx::events::EventType::Unsupported,
+ "Not a supported type in state events.");
- return events;
- }
- void saveInvites(lmdb::txn &txn,
- const std::map<std::string, mtx::responses::InvitedRoom> &rooms);
+ if (room_id.empty())
+ return {};
- void savePresence(
- lmdb::txn &txn,
- const std::vector<mtx::events::Event<mtx::events::presence::Presence>> &presenceUpdates);
+ std::vector<mtx::events::StateEvent<T>> events;
- //! Sends signals for the rooms that are removed.
- void removeLeftRooms(lmdb::txn &txn,
- const std::map<std::string, mtx::responses::LeftRoom> &rooms)
{
- for (const auto &room : rooms) {
- removeRoom(txn, room.first);
-
- // Clean up leftover invites.
- removeInvite(txn, room.first);
+ auto db = getStatesKeyDb(txn, room_id);
+ auto eventsDb = getEventsDb(txn, room_id);
+ const auto typeStr = to_string(type);
+ std::string_view typeStrV = typeStr;
+ std::string_view data;
+ std::string_view value;
+
+ auto cursor = lmdb::cursor::open(txn, db);
+ bool first = true;
+ if (cursor.get(typeStrV, data, MDB_SET)) {
+ while (cursor.get(typeStrV, data, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) {
+ first = false;
+
+ if (eventsDb.get(txn, json::parse(data)["id"].get<std::string>(), value))
+ events.push_back(json::parse(value).get<mtx::events::StateEvent<T>>());
}
+ }
}
- void updateSpaces(lmdb::txn &txn,
- const std::set<std::string> &spaces_with_updates,
- std::set<std::string> rooms_with_updates);
-
- lmdb::dbi getPendingReceiptsDb(lmdb::txn &txn)
- {
- return lmdb::dbi::open(txn, "pending_receipts", MDB_CREATE);
- }
-
- lmdb::dbi getEventsDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(txn, std::string(room_id + "/events").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getEventOrderDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/event_order").c_str(), MDB_CREATE | MDB_INTEGERKEY);
- }
-
- // inverse of EventOrderDb
- lmdb::dbi getEventToOrderDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/event2order").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getMessageToOrderDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/msg2order").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getOrderToMessageDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/order2msg").c_str(), MDB_CREATE | MDB_INTEGERKEY);
- }
-
- lmdb::dbi getPendingMessagesDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/pending").c_str(), MDB_CREATE | MDB_INTEGERKEY);
- }
-
- lmdb::dbi getRelationsDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/related").c_str(), MDB_CREATE | MDB_DUPSORT);
- }
-
- lmdb::dbi getInviteStatesDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/invite_state").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getInviteMembersDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/invite_members").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getStatesDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getStatesKeyDb(lmdb::txn &txn, const std::string &room_id)
- {
- auto db = lmdb::dbi::open(
- txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE | MDB_DUPSORT);
- lmdb::dbi_set_dupsort(txn, db, compare_state_key);
- return db;
- }
-
- lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(
- txn, std::string(room_id + "/account_data").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getMembersDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(txn, std::string(room_id + "/members").c_str(), MDB_CREATE);
- }
-
- lmdb::dbi getMentionsDb(lmdb::txn &txn, const std::string &room_id)
- {
- return lmdb::dbi::open(txn, std::string(room_id + "/mentions").c_str(), MDB_CREATE);
- }
+ return events;
+ }
+ void saveInvites(lmdb::txn &txn,
+ const std::map<std::string, mtx::responses::InvitedRoom> &rooms);
- lmdb::dbi getPresenceDb(lmdb::txn &txn)
- {
- return lmdb::dbi::open(txn, "presence", MDB_CREATE);
- }
+ void savePresence(
+ lmdb::txn &txn,
+ const std::vector<mtx::events::Event<mtx::events::presence::Presence>> &presenceUpdates);
- lmdb::dbi getUserKeysDb(lmdb::txn &txn)
- {
- return lmdb::dbi::open(txn, "user_key", MDB_CREATE);
- }
+ //! Sends signals for the rooms that are removed.
+ void removeLeftRooms(lmdb::txn &txn,
+ const std::map<std::string, mtx::responses::LeftRoom> &rooms)
+ {
+ for (const auto &room : rooms) {
+ removeRoom(txn, room.first);
- lmdb::dbi getVerificationDb(lmdb::txn &txn)
- {
- return lmdb::dbi::open(txn, "verified", MDB_CREATE);
- }
-
- //! Retrieves or creates the database that stores the open OLM sessions between our device
- //! and the given curve25519 key which represents another device.
- //!
- //! Each entry is a map from the session_id to the pickled representation of the session.
- lmdb::dbi getOlmSessionsDb(lmdb::txn &txn, const std::string &curve25519_key)
- {
- return lmdb::dbi::open(
- txn, std::string("olm_sessions.v2/" + curve25519_key).c_str(), MDB_CREATE);
+ // Clean up leftover invites.
+ removeInvite(txn, room.first);
}
-
- QString getDisplayName(const mtx::events::StateEvent<mtx::events::state::Member> &event)
- {
- if (!event.content.display_name.empty())
- return QString::fromStdString(event.content.display_name);
-
- return QString::fromStdString(event.state_key);
- }
-
- std::optional<VerificationCache> verificationCache(const std::string &user_id,
- lmdb::txn &txn);
- VerificationStatus verificationStatus_(const std::string &user_id, lmdb::txn &txn);
- std::optional<UserKeyCache> userKeys_(const std::string &user_id, lmdb::txn &txn);
-
- void setNextBatchToken(lmdb::txn &txn, const std::string &token);
-
- lmdb::env env_;
- lmdb::dbi syncStateDb_;
- lmdb::dbi roomsDb_;
- lmdb::dbi spacesChildrenDb_, spacesParentsDb_;
- lmdb::dbi invitesDb_;
- lmdb::dbi readReceiptsDb_;
- lmdb::dbi notificationsDb_;
-
- lmdb::dbi devicesDb_;
- lmdb::dbi deviceKeysDb_;
-
- lmdb::dbi inboundMegolmSessionDb_;
- lmdb::dbi outboundMegolmSessionDb_;
- lmdb::dbi megolmSessionDataDb_;
-
- lmdb::dbi encryptedRooms_;
-
- QString localUserId_;
- QString cacheDirectory_;
-
- std::string pickle_secret_;
-
- VerificationStorage verification_storage;
-
- bool databaseReady_ = false;
+ }
+
+ void updateSpaces(lmdb::txn &txn,
+ const std::set<std::string> &spaces_with_updates,
+ std::set<std::string> rooms_with_updates);
+
+ lmdb::dbi getPendingReceiptsDb(lmdb::txn &txn)
+ {
+ return lmdb::dbi::open(txn, "pending_receipts", MDB_CREATE);
+ }
+
+ lmdb::dbi getEventsDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/events").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getEventOrderDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(
+ txn, std::string(room_id + "/event_order").c_str(), MDB_CREATE | MDB_INTEGERKEY);
+ }
+
+ // inverse of EventOrderDb
+ lmdb::dbi getEventToOrderDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/event2order").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getMessageToOrderDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/msg2order").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getOrderToMessageDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(
+ txn, std::string(room_id + "/order2msg").c_str(), MDB_CREATE | MDB_INTEGERKEY);
+ }
+
+ lmdb::dbi getPendingMessagesDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(
+ txn, std::string(room_id + "/pending").c_str(), MDB_CREATE | MDB_INTEGERKEY);
+ }
+
+ lmdb::dbi getRelationsDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(
+ txn, std::string(room_id + "/related").c_str(), MDB_CREATE | MDB_DUPSORT);
+ }
+
+ lmdb::dbi getInviteStatesDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/invite_state").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getInviteMembersDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/invite_members").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getStatesDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/state").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getStatesKeyDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ auto db = lmdb::dbi::open(
+ txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE | MDB_DUPSORT);
+ lmdb::dbi_set_dupsort(txn, db, compare_state_key);
+ return db;
+ }
+
+ lmdb::dbi getAccountDataDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/account_data").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getMembersDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/members").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getMentionsDb(lmdb::txn &txn, const std::string &room_id)
+ {
+ return lmdb::dbi::open(txn, std::string(room_id + "/mentions").c_str(), MDB_CREATE);
+ }
+
+ lmdb::dbi getPresenceDb(lmdb::txn &txn) { return lmdb::dbi::open(txn, "presence", MDB_CREATE); }
+
+ lmdb::dbi getUserKeysDb(lmdb::txn &txn) { return lmdb::dbi::open(txn, "user_key", MDB_CREATE); }
+
+ lmdb::dbi getVerificationDb(lmdb::txn &txn)
+ {
+ return lmdb::dbi::open(txn, "verified", MDB_CREATE);
+ }
+
+ //! Retrieves or creates the database that stores the open OLM sessions between our device
+ //! and the given curve25519 key which represents another device.
+ //!
+ //! Each entry is a map from the session_id to the pickled representation of the session.
+ lmdb::dbi getOlmSessionsDb(lmdb::txn &txn, const std::string &curve25519_key)
+ {
+ return lmdb::dbi::open(
+ txn, std::string("olm_sessions.v2/" + curve25519_key).c_str(), MDB_CREATE);
+ }
+
+ QString getDisplayName(const mtx::events::StateEvent<mtx::events::state::Member> &event)
+ {
+ if (!event.content.display_name.empty())
+ return QString::fromStdString(event.content.display_name);
+
+ return QString::fromStdString(event.state_key);
+ }
+
+ std::optional<VerificationCache> verificationCache(const std::string &user_id, lmdb::txn &txn);
+ VerificationStatus verificationStatus_(const std::string &user_id, lmdb::txn &txn);
+ std::optional<UserKeyCache> userKeys_(const std::string &user_id, lmdb::txn &txn);
+
+ void setNextBatchToken(lmdb::txn &txn, const std::string &token);
+
+ lmdb::env env_;
+ lmdb::dbi syncStateDb_;
+ lmdb::dbi roomsDb_;
+ lmdb::dbi spacesChildrenDb_, spacesParentsDb_;
+ lmdb::dbi invitesDb_;
+ lmdb::dbi readReceiptsDb_;
+ lmdb::dbi notificationsDb_;
+
+ lmdb::dbi devicesDb_;
+ lmdb::dbi deviceKeysDb_;
+
+ lmdb::dbi inboundMegolmSessionDb_;
+ lmdb::dbi outboundMegolmSessionDb_;
+ lmdb::dbi megolmSessionDataDb_;
+
+ lmdb::dbi encryptedRooms_;
+
+ QString localUserId_;
+ QString cacheDirectory_;
+
+ std::string pickle_secret_;
+
+ VerificationStorage verification_storage;
+
+ bool databaseReady_ = false;
};
namespace cache {
|