Changeset View
Changeset View
Standalone View
Standalone View
src/db-store.hpp
| /* | /* | ||||
| * This file is part of kazv. | * This file is part of kazv. | ||||
| * SPDX-FileCopyrightText: 2026 tusooa <tusooa@kazv.moe> | * SPDX-FileCopyrightText: 2026 tusooa <tusooa@kazv.moe> | ||||
| * SPDX-License-Identifier: AGPL-3.0-or-later | * SPDX-License-Identifier: AGPL-3.0-or-later | ||||
| */ | */ | ||||
| #include <kazv-defs.hpp> | #include <kazv-defs.hpp> | ||||
| #include <tuple> | #include <tuple> | ||||
| #include <functional> | #include <functional> | ||||
| #include <QString> | #include <QString> | ||||
| #include <QThread> | #include <QThread> | ||||
| #include <QFuture> | #include <QFuture> | ||||
| #include <QSqlDatabase> | #include <QSqlDatabase> | ||||
| #include <QCoroTask> | #include <QCoroTask> | ||||
| #include <sdk-model.hpp> | #include <sdk-model.hpp> | ||||
| #include <kazvevents.hpp> | |||||
| /** | /** | ||||
| * This implements the event storage system using a relational database. | * This implements the event storage system using a relational database. | ||||
| * | * | ||||
| * The functions in this class are implemented as async because we do not | * The functions in this class are implemented as async because we do not | ||||
| * want to block the calling thread. Just like in MatrixSdk, we create a | * want to block the calling thread. Just like in MatrixSdk, we create a | ||||
| * dedicated thread for the database, and perform all work there. | * dedicated thread for the database, and perform all work there. | ||||
| * Results are sent back using coroutines as they are easier to use than QFuture. | * Results are sent back using coroutines as they are easier to use than QFuture. | ||||
| */ | */ | ||||
| class DbStore | class DbStore | ||||
| { | { | ||||
| public: | public: | ||||
| static inline constexpr std::string dbDirName{"database"}; | static inline constexpr std::string dbDirName{"database"}; | ||||
| static inline constexpr std::string dbBaseName{"db.sqlite3"}; | static inline constexpr std::string dbBaseName{"db.sqlite3"}; | ||||
| static QString getHandleFor(std::string userId, std::string deviceId); | static QString getHandleFor(std::string userId, std::string deviceId); | ||||
| static std::optional<Kazv::Event> resultToEvent(bool encrypted, bool decrypted, QString originalJson, QString decryptedJson); | |||||
| DbStore(); | DbStore(); | ||||
| ~DbStore(); | ~DbStore(); | ||||
| /** | /** | ||||
| * Open the database for a specific session. | * Open the database for a specific session. | ||||
| * @param userDataDir The user data dir from MatrixSdk. | * @param userDataDir The user data dir from MatrixSdk. | ||||
| * @param userId The user id. | * @param userId The user id. | ||||
| * @param deviceId The device id. | * @param deviceId The device id. | ||||
| * @return A pair of (status, error text). status is true iff the setup is successful. error text contains the error text reported by the database. | * @return A pair of (status, error text). status is true iff the setup is successful. error text contains the error text reported by the database. | ||||
| */ | */ | ||||
| QCoro::Task<std::pair<bool, QString>> setup(std::string userDataDir, std::string userId, std::string deviceId); | QCoro::Task<std::pair<bool, QString>> setup(std::string userDataDir, std::string userId, std::string deviceId); | ||||
| /// @return Whether the DbStore is valid | /// @return Whether the DbStore is valid | ||||
| bool valid() const; | bool valid() const; | ||||
| public Q_SLOTS: | public Q_SLOTS: | ||||
| /** | /** | ||||
| * Import all events from a model. | * Import all events from a model. | ||||
| * @param model The model. | * @param model The model. | ||||
| */ | */ | ||||
| QCoro::Task<std::pair<bool, QString>> importAllFrom(const Kazv::SdkModel &model); | QCoro::Task<std::pair<bool, QString>> importAllFrom(const Kazv::SdkModel &model); | ||||
| /** | |||||
| * Save events from a SaveEventsRequested trigger. | |||||
| * | |||||
| * @param s The SaveEventsRequested trigger. | |||||
| */ | |||||
| QCoro::Task<std::pair<bool, QString>> saveEvents(Kazv::SaveEventsRequested s); | |||||
| /** | |||||
| * Get one event from the database. | |||||
| * | |||||
| * @param roomId The room id of the event. | |||||
| * @param eventId The id of the event. | |||||
| * @return A pair of (Event, isInTimeline) associated with the ids or std::nullopt if it is not found. | |||||
| */ | |||||
| QCoro::Task<std::optional<std::pair<Kazv::Event, bool>>> getEventById(const QString &roomId, const QString &eventId); | |||||
| private: | private: | ||||
| void cleanup(); | void cleanup(); | ||||
| QCoro::Task<std::pair<bool, QString>> migrate(); | QCoro::Task<std::pair<bool, QString>> migrate(); | ||||
| QCoro::Task<std::pair<bool, QString>> importOne(const QString &roomId, const Kazv::Event &event, bool isInTimeline); | QCoro::Task<std::pair<bool, QString>> importOne(const QString &roomId, const Kazv::Event &event, bool isInTimeline); | ||||
| QCoro::Task<std::pair<bool, QString>> asyncQuery(const QString &qs, std::function<void(QSqlQuery &)> tf = [](auto &) {}); | QCoro::Task<std::pair<bool, QString>> asyncQuery(const QString &qs, std::function<void(QSqlQuery &)> tf = [](auto &) {}); | ||||
| QThread *m_thread; | QThread *m_thread; | ||||
| QObject *m_obj; | QObject *m_obj; | ||||
| std::optional<QSqlDatabase> m_d; | std::optional<QSqlDatabase> m_d; | ||||
| QString m_handle; | QString m_handle; | ||||
| }; | }; | ||||