From b134e777b822b929a78455fd92146bf7443e9aa1 Mon Sep 17 00:00:00 2001 From: Janne Koschinski Date: Thu, 30 May 2019 08:39:06 +0200 Subject: [PATCH] Sync last message id per buffer --- src/common/buffersyncer.cpp | 34 ++++++++++++++++++- src/common/buffersyncer.h | 17 +++++++++- .../select_buffer_last_messages.sql | 3 ++ .../SQLite/select_buffer_last_messages.sql | 3 ++ src/core/core.h | 8 +++++ src/core/corebuffersyncer.cpp | 3 +- src/core/postgresqlstorage.cpp | 28 +++++++++++++++ src/core/postgresqlstorage.h | 1 + src/core/sqlitestorage.cpp | 28 +++++++++++++++ src/core/sqlitestorage.h | 1 + src/core/storage.h | 6 ++++ 11 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 src/core/SQL/PostgreSQL/select_buffer_last_messages.sql create mode 100644 src/core/SQL/SQLite/select_buffer_last_messages.sql diff --git a/src/common/buffersyncer.cpp b/src/common/buffersyncer.cpp index cbebd03a..74126a14 100644 --- a/src/common/buffersyncer.cpp +++ b/src/common/buffersyncer.cpp @@ -26,18 +26,25 @@ BufferSyncer::BufferSyncer(QObject* parent) : SyncableObject(parent) {} -BufferSyncer::BufferSyncer(QHash lastSeenMsg, +BufferSyncer::BufferSyncer(QHash lastMsg, + QHash lastSeenMsg, QHash markerLines, QHash activities, QHash highlightCounts, QObject* parent) : SyncableObject(parent) + , _lastMsg(std::move(lastMsg)) , _lastSeenMsg(std::move(lastSeenMsg)) , _markerLines(std::move(markerLines)) , _bufferActivities(std::move(activities)) , _highlightCounts(std::move(highlightCounts)) {} +MsgId BufferSyncer::lastMsg(BufferId buffer) const +{ + return _lastMsg.value(buffer, MsgId()); +} + MsgId BufferSyncer::lastSeenMsg(BufferId buffer) const { return _lastSeenMsg.value(buffer, MsgId()); @@ -77,6 +84,26 @@ bool BufferSyncer::setMarkerLine(BufferId buffer, const MsgId& msgId) return true; } +QVariantList BufferSyncer::initLastMsg() const +{ + QVariantList list; + QHash::const_iterator iter = _lastMsg.constBegin(); + while (iter != _lastMsg.constEnd()) { + list << QVariant::fromValue(iter.key()) << QVariant::fromValue(iter.value()); + ++iter; + } + return list; +} + +void BufferSyncer::initSetLastMsg(const QVariantList& list) +{ + _lastMsg.clear(); + Q_ASSERT(list.count() % 2 == 0); + for (int i = 0; i < list.count(); i += 2) { + setLastMsg(list.at(i).value(), list.at(i + 1).value()); + } +} + QVariantList BufferSyncer::initLastSeenMsg() const { QVariantList list; @@ -144,6 +171,8 @@ Message::Types BufferSyncer::activity(BufferId buffer) const void BufferSyncer::removeBuffer(BufferId buffer) { + if (_lastMsg.contains(buffer)) + _lastMsg.remove(buffer); if (_lastSeenMsg.contains(buffer)) _lastSeenMsg.remove(buffer); if (_markerLines.contains(buffer)) @@ -158,9 +187,12 @@ void BufferSyncer::removeBuffer(BufferId buffer) void BufferSyncer::mergeBuffersPermanently(BufferId buffer1, BufferId buffer2) { + setLastMsg(buffer1, std::max(_lastMsg[buffer1], _lastMsg[buffer2])); setBufferActivity(buffer1, _bufferActivities[buffer1] | _bufferActivities[buffer2]); setHighlightCount(buffer1, _highlightCounts[buffer1] + _highlightCounts[buffer2]); + if (_lastMsg.contains(buffer2)) + _lastMsg.remove(buffer2); if (_lastSeenMsg.contains(buffer2)) _lastSeenMsg.remove(buffer2); if (_markerLines.contains(buffer2)) diff --git a/src/common/buffersyncer.h b/src/common/buffersyncer.h index 4bca34e5..d6535e29 100644 --- a/src/common/buffersyncer.h +++ b/src/common/buffersyncer.h @@ -33,13 +33,15 @@ class COMMON_EXPORT BufferSyncer : public SyncableObject public: explicit BufferSyncer(QObject* parent); - explicit BufferSyncer(QHash lastSeenMsg, + explicit BufferSyncer(QHash lastMsg, + QHash lastSeenMsg, QHash markerLines, QHash activities, QHash highlightCounts, QObject* parent); MsgId lastSeenMsg(BufferId buffer) const; + MsgId lastMsg(BufferId buffer) const; MsgId markerLine(BufferId buffer) const; Message::Types activity(BufferId buffer) const; int highlightCount(BufferId buffer) const; @@ -59,6 +61,9 @@ public: } public slots: + QVariantList initLastMsg() const; + void initSetLastMsg(const QVariantList&); + QVariantList initLastSeenMsg() const; void initSetLastSeenMsg(const QVariantList&); @@ -71,6 +76,13 @@ public slots: QVariantList initHighlightCounts() const; void initSetHighlightCounts(const QVariantList&); + virtual inline void setLastMsg(BufferId buffer, const MsgId& msgId) + { + SYNC(ARG(buffer), ARG(msgId)); + _lastMsg[buffer] = msgId; + emit lastMsgSet(buffer, msgId); + } + virtual inline void requestSetLastSeenMsg(BufferId buffer, const MsgId& msgId) { REQUEST(ARG(buffer), ARG(msgId)) } virtual inline void requestSetMarkerLine(BufferId buffer, const MsgId& msgId) { @@ -110,6 +122,7 @@ public slots: virtual inline void markBufferAsRead(BufferId buffer) { SYNC(ARG(buffer)) emit bufferMarkedAsRead(buffer); } signals: + void lastMsgSet(BufferId buffer, const MsgId& msgId); void lastSeenMsgSet(BufferId buffer, const MsgId& msgId); void markerLineSet(BufferId buffer, const MsgId& msgId); void bufferRemoved(BufferId buffer); @@ -124,11 +137,13 @@ protected slots: bool setMarkerLine(BufferId buffer, const MsgId& msgId); protected: + inline QList lastBufferIds() const { return _lastMsg.keys(); } inline QList lastSeenBufferIds() const { return _lastSeenMsg.keys(); } inline QList markerLineBufferIds() const { return _markerLines.keys(); } inline QHash markerLines() const { return _markerLines; } private: + QHash _lastMsg; QHash _lastSeenMsg; QHash _markerLines; QHash _bufferActivities; diff --git a/src/core/SQL/PostgreSQL/select_buffer_last_messages.sql b/src/core/SQL/PostgreSQL/select_buffer_last_messages.sql new file mode 100644 index 00000000..784635aa --- /dev/null +++ b/src/core/SQL/PostgreSQL/select_buffer_last_messages.sql @@ -0,0 +1,3 @@ +SELECT bufferid, lastmsgid +FROM buffer +WHERE userid = :userid diff --git a/src/core/SQL/SQLite/select_buffer_last_messages.sql b/src/core/SQL/SQLite/select_buffer_last_messages.sql new file mode 100644 index 00000000..784635aa --- /dev/null +++ b/src/core/SQL/SQLite/select_buffer_last_messages.sql @@ -0,0 +1,3 @@ +SELECT bufferid, lastmsgid +FROM buffer +WHERE userid = :userid diff --git a/src/core/core.h b/src/core/core.h index ce8693ab..d2b8092c 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -536,6 +536,14 @@ public: */ QString strictSysIdent(UserId user) const; + //! Get a Hash of all last message ids + /** This Method is called when the Quassel Core is started to restore the lastMsgIds + * \note This method is threadsafe. + * + * \param user The Owner of the buffers + */ + static inline QHash bufferLastMsgIds(UserId user) { return instance()->_storage->bufferLastMsgIds(user); } + //! Get a Hash of all last seen message ids /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds * \note This method is threadsafe. diff --git a/src/core/corebuffersyncer.cpp b/src/core/corebuffersyncer.cpp index 8fdb3915..2829f5d4 100644 --- a/src/core/corebuffersyncer.cpp +++ b/src/core/corebuffersyncer.cpp @@ -39,7 +39,8 @@ public: }; CoreBufferSyncer::CoreBufferSyncer(CoreSession* parent) - : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), + : BufferSyncer(Core::bufferLastMsgIds(parent->user()), + Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), Core::bufferActivities(parent->user()), Core::highlightCounts(parent->user()), diff --git a/src/core/postgresqlstorage.cpp b/src/core/postgresqlstorage.cpp index 9374a48f..90b0fdbb 100644 --- a/src/core/postgresqlstorage.cpp +++ b/src/core/postgresqlstorage.cpp @@ -1385,6 +1385,34 @@ bool PostgreSqlStorage::mergeBuffersPermanently(const UserId& user, const Buffer return true; } +QHash PostgreSqlStorage::bufferLastMsgIds(UserId user) +{ + QHash lastMsgHash; + + QSqlDatabase db = logDb(); + if (!beginReadOnlyTransaction(db)) { + qWarning() << "PostgreSqlStorage::bufferLastMsgIds(): cannot start read only transaction!"; + qWarning() << " -" << qPrintable(db.lastError().text()); + return lastMsgHash; + } + + QSqlQuery query(db); + query.prepare(queryString("select_buffer_last_messages")); + query.bindValue(":userid", user.toInt()); + safeExec(query); + if (!watchQuery(query)) { + db.rollback(); + return lastMsgHash; + } + + while (query.next()) { + lastMsgHash[query.value(0).toInt()] = query.value(1).toLongLong(); + } + + db.commit(); + return lastMsgHash; +} + void PostgreSqlStorage::setBufferLastSeenMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) { QSqlQuery query(logDb()); diff --git a/src/core/postgresqlstorage.h b/src/core/postgresqlstorage.h index 86fa204e..78ddc9da 100644 --- a/src/core/postgresqlstorage.h +++ b/src/core/postgresqlstorage.h @@ -92,6 +92,7 @@ public slots: bool removeBuffer(const UserId& user, const BufferId& bufferId) override; bool renameBuffer(const UserId& user, const BufferId& bufferId, const QString& newName) override; bool mergeBuffersPermanently(const UserId& user, const BufferId& bufferId1, const BufferId& bufferId2) override; + QHash bufferLastMsgIds(UserId user) override; void setBufferLastSeenMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) override; QHash bufferLastSeenMsgIds(UserId user) override; void setBufferMarkerLineMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) override; diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index 026b4dc6..dc5b5467 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -1485,6 +1485,34 @@ bool SqliteStorage::mergeBuffersPermanently(const UserId& user, const BufferId& return !error; } +QHash SqliteStorage::bufferLastMsgIds(UserId user) +{ + QHash lastMsgHash; + + QSqlDatabase db = logDb(); + db.transaction(); + + bool error = false; + { + QSqlQuery query(db); + query.prepare(queryString("select_buffer_last_messages")); + query.bindValue(":userid", user.toInt()); + + lockForRead(); + safeExec(query); + error = !watchQuery(query); + if (!error) { + while (query.next()) { + lastMsgHash[query.value(0).toInt()] = query.value(1).toLongLong(); + } + } + } + + db.commit(); + unlock(); + return lastMsgHash; +} + void SqliteStorage::setBufferLastSeenMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) { QSqlDatabase db = logDb(); diff --git a/src/core/sqlitestorage.h b/src/core/sqlitestorage.h index 7c579b07..3e9de416 100644 --- a/src/core/sqlitestorage.h +++ b/src/core/sqlitestorage.h @@ -96,6 +96,7 @@ public slots: bool removeBuffer(const UserId& user, const BufferId& bufferId) override; bool renameBuffer(const UserId& user, const BufferId& bufferId, const QString& newName) override; bool mergeBuffersPermanently(const UserId& user, const BufferId& bufferId1, const BufferId& bufferId2) override; + QHash bufferLastMsgIds(UserId user) override; void setBufferLastSeenMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) override; QHash bufferLastSeenMsgIds(UserId user) override; void setBufferMarkerLineMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) override; diff --git a/src/core/storage.h b/src/core/storage.h index b49aee0a..5d47c097 100644 --- a/src/core/storage.h +++ b/src/core/storage.h @@ -386,6 +386,12 @@ public slots: */ virtual void setBufferLastSeenMsg(UserId user, const BufferId& bufferId, const MsgId& msgId) = 0; + //! Get a Hash of all last message ids + /** This Method is called when the Quassel Core is started to restore the lastMsgIds + * \param user The Owner of the buffers + */ + virtual QHash bufferLastMsgIds(UserId user) = 0; + //! Get a Hash of all last seen message ids /** This Method is called when the Quassel Core is started to restore the lastSeenMsgIds * \param user The Owner of the buffers -- 2.20.1