// SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert // // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL #pragma once #include #include #include #include #include #include #include #include enum MessageState { Unknown = false, Sent = true, Pending, Failed, Received, }; Q_DECLARE_METATYPE(MessageState) inline MessageState parseMessageState(const QString &state) { if (state == SL("pending")) { return MessageState::Pending; } else if (state == SL("sent")) { return MessageState::Sent; } else if (state == SL("failed")) { return MessageState::Failed; } Q_UNREACHABLE(); } struct Message { using ColumnTypes = std::tuple; static Message fromSql(ColumnTypes &&tuple); QString id; PhoneNumberList phoneNumberList; QString text; QDateTime datetime; bool read; MessageState deliveryStatus; bool sentByMe; QString attachments; QString smil; QString fromNumber; QString messageId; int deliveryReport = 0; QString readReport; bool pendingDownload = false; QString contentLocation; QDateTime expires; int size = 0; QString tapbacks; }; Q_DECLARE_METATYPE(Message) struct Chat { PhoneNumberList phoneNumberList; int unreadMessages = 0; QString lastMessage; QDateTime lastDateTime; bool lastSentByMe = false; QString lastAttachment; }; Q_DECLARE_METATYPE(Chat) class Database : public QObject { Q_OBJECT public: explicit Database(QObject *parent = nullptr); // Messages QCoro::Task<> addMessage(const Message &message); QFuture deleteMessage(const QString &id); QFuture> messagesForNumber(const PhoneNumberList &phoneNumberList, const QString &id = QString(), const int limit = 0) const; QFuture updateMessageDeliveryState(const QString &id, const MessageState state); QFuture updateMessageSent(const QString &id, const QString &messageId, const QString &contentLocation); QFuture updateMessageDeliveryReport(const QString &messageId); QFuture updateMessageReadReport(const QString &messageId, const PhoneNumber &fromNumber); QFuture markMessageRead(const int id); QFuture updateMessageTapbacks(const QString &id, const QString tapbacks); QCoro::Task> lastMessageWithText(const PhoneNumberList &phoneNumberList, const QString &text); QCoro::Task> lastMessageWithAttachment(const PhoneNumberList &phoneNumberList); // Chats QCoro::Task> chats(const PhoneNumberList &phoneNumberList) const; QCoro::Task> unreadMessagesForNumber(const PhoneNumberList &phoneNumberList) const; QFuture markChatAsRead(const PhoneNumberList &phoneNumberList); QFuture deleteChat(const PhoneNumberList &phoneNumberList); QCoro::Task<> mergeChats(const QString &fromNumbers, const QString toNumbers); static QString generateRandomId(); static void exec(QSqlQuery &query); QCoro::Task<> migrate(); private: // Ran on the database thread void migrationV1(const QSqlDatabase &db, uint current); void migrationV2(const QSqlDatabase &db, uint current); void migrationV3(const QSqlDatabase &db, uint current); void migrationV4(const QSqlDatabase &db, uint current); void migrationV5(const QSqlDatabase &db, uint current); void migrationV6(const QSqlDatabase &db, uint current); void migrationV7(const QSqlDatabase &db, uint current); void migrationV8(const QSqlDatabase &db, uint current); std::unique_ptr m_database; };