1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

feat(history): Save/load system messages to history

This commit is contained in:
Mick Sayson 2021-02-28 11:19:24 -08:00
parent 916834fb9c
commit 18109b2f7f
5 changed files with 99 additions and 7 deletions

View File

@ -214,7 +214,10 @@ std::vector<IChatLog::DateChatLogIdxPair> ChatHistory::getDateIdxs(const QDate&
void ChatHistory::addSystemMessage(const SystemMessage& message)
{
// FIXME: #6221 Insert into history
if (canUseHistory()) {
history->addNewSystemMessage(f.getPublicKey(), message);
}
sessionChatLog.addSystemMessage(message);
}
@ -410,6 +413,11 @@ void ChatHistory::loadHistoryIntoSessionChatLog(ChatLogIdx start) const
}
break;
}
case HistMessageContentType::system: {
const auto& systemMessage = message.content.asSystemMessage();
sessionChatLog.insertSystemMessageAtIdx(currentIdx, systemMessage);
break;
}
}
}

View File

@ -65,6 +65,7 @@ public slots:
void onFileTransferRemotePausedUnpaused(const ToxPk& sender, const ToxFile& file, bool paused);
void onFileTransferBrokenUnbroken(const ToxPk& sender, const ToxFile& file, bool broken);
private:
QString resolveSenderNameFromSender(const ToxPk &sender);

View File

@ -27,7 +27,7 @@
#include "src/core/toxpk.h"
namespace {
static constexpr int SCHEMA_VERSION = 7;
static constexpr int SCHEMA_VERSION = 8;
bool createCurrentSchema(RawDatabase& db)
{
@ -395,6 +395,19 @@ bool dbSchema6to7(RawDatabase& db)
return db.execNow(upgradeQueries);
}
bool dbSchema7to8(RawDatabase& db)
{
// Dummy upgrade. This upgrade does not change the schema, however on
// version 7 if qtox saw a system message it would assert and crash. This
// upgrade ensures that old versions of qtox do not try to load the new
// database
QVector<RawDatabase::Query> upgradeQueries;
upgradeQueries += RawDatabase::Query(QStringLiteral("PRAGMA user_version = 8;"));
return db.execNow(upgradeQueries);
}
/**
* @brief Upgrade the db schema
* @note On future alterations of the database all you have to do is bump the SCHEMA_VERSION
@ -444,7 +457,7 @@ bool dbSchemaUpgrade(std::shared_ptr<RawDatabase>& db)
using DbSchemaUpgradeFn = bool (*)(RawDatabase&);
std::vector<DbSchemaUpgradeFn> upgradeFns = {dbSchema0to1, dbSchema1to2, dbSchema2to3,
dbSchema3to4, dbSchema4to5, dbSchema5to6,
dbSchema6to7};
dbSchema6to7, dbSchema7to8};
assert(databaseSchemaVersion < static_cast<int>(upgradeFns.size()));
assert(upgradeFns.size() == SCHEMA_VERSION);
@ -550,7 +563,26 @@ generateNewTextMessageQueries(const ToxPk& friendPk, const QString& message, con
return queries;
}
QVector<RawDatabase::Query> generateNewSystemMessageQueries(const ToxPk& friendPk,
const SystemMessage& systemMessage)
{
QVector<RawDatabase::Query> queries;
queries += generateEnsurePkInPeers(friendPk);
queries += generateHistoryTableInsertion('S', systemMessage.timestamp, friendPk);
QVector<QByteArray> blobs;
std::transform(systemMessage.args.begin(), systemMessage.args.end(), std::back_inserter(blobs),
[](const QString& s) { return s.toUtf8(); });
queries += RawDatabase::Query(QString("INSERT INTO system_messages (id, message_type, "
"system_message_type, arg1, arg2, arg3, arg4)"
"VALUES (last_insert_rowid(), 'S', %1, ?, ?, ?, ?)")
.arg(static_cast<int>(systemMessage.messageType)),
blobs);
return queries;
}
} // namespace
/**
@ -756,6 +788,7 @@ History::generateNewFileTransferQueries(const ToxPk& friendPk, const ToxPk& send
return queries;
}
RawDatabase::Query History::generateFileFinished(RowId id, bool success, const QString& filePath,
const QByteArray& fileHash)
{
@ -818,6 +851,16 @@ void History::addNewFileMessage(const ToxPk& friendPk, const QString& fileId,
db->execLater(queries);
}
void History::addNewSystemMessage(const ToxPk& friendPk, const SystemMessage& systemMessage)
{
if (historyAccessBlocked())
return;
const auto queries = generateNewSystemMessageQueries(friendPk, systemMessage);
db->execLater(queries);
}
/**
* @brief Saves a chat message in the database.
* @param friendPk Friend publick key to save.
@ -983,8 +1026,18 @@ QList<History::HistMessage> History::getMessagesForFriend(const ToxPk& friendPk,
}
default:
case 'S':
// System messages not yet supported
assert(false);
it = std::next(row.begin(), systemOffset);
assert(!it->isNull());
SystemMessage systemMessage;
systemMessage.messageType = static_cast<SystemMessageType>((*it++).toLongLong());
auto argEnd = std::next(it, systemMessage.args.size());
std::transform(it, argEnd, systemMessage.args.begin(), [](const QVariant& arg) {
return QString::fromUtf8(arg.toByteArray().replace('\0', ""));
});
it = argEnd;
messages += HistMessage(id, timestamp, friendPk.toString(), systemMessage);
break;
}
};

View File

@ -28,10 +28,11 @@
#include <cstdint>
#include <tox/toxencryptsave.h>
#include "src/core/extension.h"
#include "src/core/toxfile.h"
#include "src/core/toxpk.h"
#include "src/core/extension.h"
#include "src/model/brokenmessagereason.h"
#include "src/model/systemmessage.h"
#include "src/persistence/db/rawdatabase.h"
#include "src/widget/searchtypes.h"
@ -41,7 +42,8 @@ class HistoryKeeper;
enum class HistMessageContentType
{
message,
file
file,
system,
};
class HistMessageContent
@ -57,6 +59,11 @@ public:
, type(HistMessageContentType::file)
{}
HistMessageContent(SystemMessage systemMessage)
: data(std::make_shared<SystemMessage>(std::move(systemMessage)))
, type(HistMessageContentType::system)
{}
HistMessageContentType getType() const
{
return type;
@ -74,6 +81,12 @@ public:
return *static_cast<ToxFile*>(data.get());
}
SystemMessage& asSystemMessage()
{
assert(type == HistMessageContentType::system);
return *static_cast<SystemMessage*>(data.get());
}
const QString& asMessage() const
{
assert(type == HistMessageContentType::message);
@ -86,6 +99,12 @@ public:
return *static_cast<ToxFile*>(data.get());
}
const SystemMessage& asSystemMessage() const
{
assert(type == HistMessageContentType::system);
return *static_cast<SystemMessage*>(data.get());
}
private:
// Not really shared but shared_ptr has support for shared_ptr<void>
std::shared_ptr<void> data;
@ -142,6 +161,13 @@ public:
, content(std::move(file))
{}
HistMessage(RowId id, QDateTime timestamp, QString chat, SystemMessage systemMessage)
: chat{chat}
, timestamp{timestamp}
, id{id}
, state(MessageState::complete)
, content(std::move(systemMessage))
{}
QString chat;
QString sender;
@ -177,6 +203,8 @@ public:
const QString& fileName, const QString& filePath, int64_t size,
const ToxPk& sender, const QDateTime& time, QString const& dispName);
void addNewSystemMessage(const ToxPk& friendPk, const SystemMessage& systemMessage);
void setFileFinished(const QString& fileId, bool success, const QString& filePath, const QByteArray& fileHash);
size_t getNumMessagesForFriend(const ToxPk& friendPk);
size_t getNumMessagesForFriendBeforeDate(const ToxPk& friendPk, const QDateTime& date);

View File

@ -53,6 +53,8 @@ private slots:
void test4to5();
void test5to6();
void test6to7();
// test7to8 omitted, version only upgrade, versions are not verified in this
// test suite
void cleanupTestCase() const;
private: