File indexing completed on 2024-05-05 17:32:28
0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im> 0002 // 0003 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #pragma once 0006 0007 #include <QDateTime> 0008 #include <QObject> 0009 #include <QSqlDatabase> 0010 #include <QSqlQuery> 0011 0012 #include <ThreadedDatabase> 0013 0014 #include <QCoroTask> 0015 0016 #include <global.h> 0017 #include <phonenumberlist.h> 0018 0019 enum MessageState { 0020 Unknown = false, 0021 Sent = true, 0022 Pending, 0023 Failed, 0024 Received, 0025 }; 0026 Q_DECLARE_METATYPE(MessageState) 0027 0028 inline MessageState parseMessageState(const QString &state) 0029 { 0030 if (state == SL("pending")) { 0031 return MessageState::Pending; 0032 } else if (state == SL("sent")) { 0033 return MessageState::Sent; 0034 } else if (state == SL("failed")) { 0035 return MessageState::Failed; 0036 } 0037 0038 Q_UNREACHABLE(); 0039 } 0040 0041 struct Message { 0042 using ColumnTypes = 0043 std::tuple<QString, QString, QString, qint64, bool, int, bool, QString, QString, QString, QString, int, QString, bool, QString, qint64, int, QString>; 0044 0045 static Message fromSql(ColumnTypes &&tuple); 0046 0047 QString id; 0048 PhoneNumberList phoneNumberList; 0049 QString text; 0050 QDateTime datetime; 0051 bool read; 0052 MessageState deliveryStatus; 0053 bool sentByMe; 0054 QString attachments; 0055 QString smil; 0056 QString fromNumber; 0057 QString messageId; 0058 int deliveryReport = 0; 0059 QString readReport; 0060 bool pendingDownload = false; 0061 QString contentLocation; 0062 QDateTime expires; 0063 int size = 0; 0064 QString tapbacks; 0065 }; 0066 Q_DECLARE_METATYPE(Message) 0067 0068 struct Chat { 0069 PhoneNumberList phoneNumberList; 0070 int unreadMessages = 0; 0071 QString lastMessage; 0072 QDateTime lastDateTime; 0073 bool lastSentByMe = false; 0074 QString lastAttachment; 0075 }; 0076 Q_DECLARE_METATYPE(Chat) 0077 0078 class Database : public QObject 0079 { 0080 Q_OBJECT 0081 0082 public: 0083 explicit Database(QObject *parent = nullptr); 0084 0085 // Messages 0086 QCoro::Task<> addMessage(const Message &message); 0087 QFuture<void> deleteMessage(const QString &id); 0088 QFuture<std::vector<Message>> messagesForNumber(const PhoneNumberList &phoneNumberList, const QString &id = QString(), const int limit = 0) const; 0089 QFuture<void> updateMessageDeliveryState(const QString &id, const MessageState state); 0090 QFuture<void> updateMessageSent(const QString &id, const QString &messageId, const QString &contentLocation); 0091 QFuture<void> updateMessageDeliveryReport(const QString &messageId); 0092 QFuture<void> updateMessageReadReport(const QString &messageId, const PhoneNumber &fromNumber); 0093 QFuture<void> markMessageRead(const int id); 0094 QFuture<void> updateMessageTapbacks(const QString &id, const QString tapbacks); 0095 QCoro::Task<std::optional<QString>> lastMessageWithText(const PhoneNumberList &phoneNumberList, const QString &text); 0096 QCoro::Task<std::optional<QString>> lastMessageWithAttachment(const PhoneNumberList &phoneNumberList); 0097 0098 // Chats 0099 QCoro::Task<QVector<Chat>> chats(const PhoneNumberList &phoneNumberList) const; 0100 QCoro::Task<std::optional<int>> unreadMessagesForNumber(const PhoneNumberList &phoneNumberList) const; 0101 QFuture<void> markChatAsRead(const PhoneNumberList &phoneNumberList); 0102 QFuture<void> deleteChat(const PhoneNumberList &phoneNumberList); 0103 QCoro::Task<> mergeChats(const QString &fromNumbers, const QString toNumbers); 0104 0105 static QString generateRandomId(); 0106 0107 static void exec(QSqlQuery &query); 0108 0109 QCoro::Task<> migrate(); 0110 0111 private: 0112 // Ran on the database thread 0113 void migrationV1(const QSqlDatabase &db, uint current); 0114 void migrationV2(const QSqlDatabase &db, uint current); 0115 void migrationV3(const QSqlDatabase &db, uint current); 0116 void migrationV4(const QSqlDatabase &db, uint current); 0117 void migrationV5(const QSqlDatabase &db, uint current); 0118 void migrationV6(const QSqlDatabase &db, uint current); 0119 void migrationV7(const QSqlDatabase &db, uint current); 0120 void migrationV8(const QSqlDatabase &db, uint current); 0121 0122 std::unique_ptr<ThreadedDatabase> m_database; 0123 };