Store highlight status per buffer coreside
authorJanne Koschinski <janne@kuschku.de>
Tue, 8 May 2018 18:36:25 +0000 (13:36 -0500)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 23 May 2018 22:33:28 +0000 (00:33 +0200)
- Add highlightCount to buffersyncer, same as with buffer activities
- If this value is increased, it is synced with clients, and they add
  it to the buffer status, showing it in orange
- This allows you to see highlights even if they are not loaded in
  initial backlog, but only core-side highlights.

Closes GH-333.

27 files changed:
src/client/client.cpp
src/client/networkmodel.cpp
src/client/networkmodel.h
src/common/buffersyncer.cpp
src/common/buffersyncer.h
src/core/SQL/PostgreSQL/migrate_write_buffer.sql
src/core/SQL/PostgreSQL/select_buffer_highlightcount.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/select_buffer_highlightcounts.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/setup_050_buffer.sql
src/core/SQL/PostgreSQL/update_buffer_highlightcount.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/version/26/upgrade_000_alter_buffer_add_highlightcount.sql [new file with mode: 0644]
src/core/SQL/SQLite/migrate_read_buffer.sql
src/core/SQL/SQLite/select_buffer_highlightcount.sql [new file with mode: 0644]
src/core/SQL/SQLite/select_buffer_highlightcounts.sql [new file with mode: 0644]
src/core/SQL/SQLite/setup_030_buffer.sql
src/core/SQL/SQLite/update_buffer_highlightcount.sql [new file with mode: 0644]
src/core/SQL/SQLite/version/28/upgrade_000_alter_buffer_add_highlightcount.sql [new file with mode: 0644]
src/core/abstractsqlstorage.h
src/core/core.h
src/core/corebuffersyncer.cpp
src/core/corebuffersyncer.h
src/core/postgresqlstorage.cpp
src/core/postgresqlstorage.h
src/core/sql.qrc
src/core/sqlitestorage.cpp
src/core/sqlitestorage.h
src/core/storage.h

index 5805887..f8627d0 100644 (file)
@@ -394,6 +394,7 @@ void Client::setSyncedToCore()
     connect(bufferSyncer(), SIGNAL(buffersPermanentlyMerged(BufferId, BufferId)), _messageModel, SLOT(buffersPermanentlyMerged(BufferId, BufferId)));
     connect(bufferSyncer(), SIGNAL(bufferMarkedAsRead(BufferId)), SIGNAL(bufferMarkedAsRead(BufferId)));
     connect(bufferSyncer(), SIGNAL(bufferActivityChanged(BufferId, const Message::Types)), _networkModel, SLOT(bufferActivityChanged(BufferId, const Message::Types)));
+    connect(bufferSyncer(), SIGNAL(highlightCountChanged(BufferId, int)), _networkModel, SLOT(highlightCountChanged(BufferId, int)));
     connect(networkModel(), SIGNAL(requestSetLastSeenMsg(BufferId, MsgId)), bufferSyncer(), SLOT(requestSetLastSeenMsg(BufferId, const MsgId &)));
 
     SignalProxy *p = signalProxy();
@@ -460,8 +461,10 @@ void Client::finishConnectionInitialization()
     disconnect(bufferSyncer(), SIGNAL(initDone()), this, SLOT(finishConnectionInitialization()));
 
     requestInitialBacklog();
-    if (isCoreFeatureEnabled(Quassel::Feature::BufferActivitySync))
+    if (isCoreFeatureEnabled(Quassel::Feature::BufferActivitySync)) {
         bufferSyncer()->markActivitiesChanged();
+        bufferSyncer()->markHighlightCountsChanged();
+    }
 }
 
 
index 77aeccc..8214966 100644 (file)
@@ -147,8 +147,12 @@ BufferItem *NetworkItem::bufferItem(const BufferInfo &bufferInfo)
     }
 
     BufferSyncer *bufferSyncer = Client::bufferSyncer();
-    if (bufferSyncer)
-        bufferItem->addActivity(bufferSyncer->activity(bufferItem->bufferId()), false);
+    if (bufferSyncer) {
+        bufferItem->addActivity(
+                bufferSyncer->activity(bufferItem->bufferId()),
+                bufferSyncer->highlightCount(bufferItem->bufferId()) > 0
+        );
+    }
 
     return bufferItem;
 }
@@ -1757,3 +1761,12 @@ void NetworkModel::bufferActivityChanged(BufferId bufferId, const Message::Types
     auto activityVisibleTypesIntersection = activity & visibleTypes;
     _bufferItem->setActivity(activityVisibleTypesIntersection, false);
 }
+
+void NetworkModel::highlightCountChanged(BufferId bufferId, int count) {
+    auto _bufferItem = findBufferItem(bufferId);
+    if (!_bufferItem) {
+        qDebug() << "NetworkModel::highlightCountChanged(): buffer is unknown:" << bufferId;
+        return;
+    }
+    _bufferItem->addActivity(Message::Types{}, count > 0);
+}
index cc06938..6b68191 100644 (file)
@@ -386,6 +386,7 @@ public slots:
     void updateBufferActivity(Message &msg);
     void networkRemoved(const NetworkId &networkId);
     void bufferActivityChanged(BufferId, Message::Types);
+    void highlightCountChanged(BufferId, int);
 
 signals:
     void requestSetLastSeenMsg(BufferId buffer, MsgId msg);
index 7198a46..3f437d9 100644 (file)
@@ -27,11 +27,17 @@ BufferSyncer::BufferSyncer(QObject *parent)
 }
 
 
-BufferSyncer::BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, const QHash<BufferId, MsgId> &markerLines, const QHash<BufferId, Message::Types> &activities, QObject *parent)
-    : SyncableObject(parent),
+BufferSyncer::BufferSyncer(
+        const QHash<BufferId, MsgId> &lastSeenMsg,
+        const QHash<BufferId, MsgId> &markerLines,
+        const QHash<BufferId, Message::Types> &activities,
+        const QHash<BufferId, int> &highlightCounts,
+        QObject *parent
+) : SyncableObject(parent),
     _lastSeenMsg(lastSeenMsg),
     _markerLines(markerLines),
-    _bufferActivities(activities)
+    _bufferActivities(activities),
+    _highlightCounts(highlightCounts)
 {
 }
 
@@ -162,6 +168,8 @@ void BufferSyncer::removeBuffer(BufferId buffer)
         _markerLines.remove(buffer);
     if (_bufferActivities.contains(buffer))
         _bufferActivities.remove(buffer);
+    if (_highlightCounts.contains(buffer))
+        _highlightCounts.remove(buffer);
     SYNC(ARG(buffer))
     emit bufferRemoved(buffer);
 }
@@ -175,6 +183,31 @@ void BufferSyncer::mergeBuffersPermanently(BufferId buffer1, BufferId buffer2)
         _markerLines.remove(buffer2);
     if (_bufferActivities.contains(buffer2))
         _bufferActivities.remove(buffer2);
+    if (_highlightCounts.contains(buffer2))
+        _highlightCounts.remove(buffer2);
     SYNC(ARG(buffer1), ARG(buffer2))
     emit buffersPermanentlyMerged(buffer1, buffer2);
 }
+
+int BufferSyncer::highlightCount(BufferId buffer) const {
+    return _highlightCounts.value(buffer, 0);
+}
+
+QVariantList BufferSyncer::initHighlightCounts() const {
+    QVariantList list;
+    auto iter = _highlightCounts.constBegin();
+    while (iter != _highlightCounts.constEnd()) {
+        list << QVariant::fromValue<BufferId>(iter.key())
+             << QVariant::fromValue<int>((int) iter.value());
+        ++iter;
+    }
+    return list;
+}
+
+void BufferSyncer::initSetHighlightCounts(const QVariantList &list) {
+    _highlightCounts.clear();
+    Q_ASSERT(list.count() % 2 == 0);
+    for (int i = 0; i < list.count(); i += 2) {
+        setHighlightCount(list.at(i).value<BufferId>(), list.at(i+1).value<int>());
+    }
+}
index 3dc706e..9ca0c01 100644 (file)
@@ -32,13 +32,14 @@ class BufferSyncer : public SyncableObject
 
 public:
     explicit BufferSyncer(QObject *parent);
-    explicit BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, const QHash<BufferId, MsgId> &markerLines, const QHash<BufferId, Message::Types> &activities, QObject *parent);
+    explicit BufferSyncer(const QHash<BufferId, MsgId> &lastSeenMsg, const QHash<BufferId, MsgId> &markerLines, const QHash<BufferId, Message::Types> &activities, const QHash<BufferId, int> &highlightCounts, QObject *parent);
 
     inline virtual const QMetaObject *syncMetaObject() const { return &staticMetaObject; }
 
     MsgId lastSeenMsg(BufferId buffer) const;
     MsgId markerLine(BufferId buffer) const;
     Message::Types activity(BufferId buffer) const;
+    int highlightCount(BufferId buffer) const;
 
     void markActivitiesChanged() {
         for (auto buffer : _bufferActivities.keys()) {
@@ -46,6 +47,12 @@ public:
         }
     }
 
+    void markHighlightCountsChanged() {
+        for (auto buffer : _highlightCounts.keys()) {
+            emit highlightCountChanged(buffer, highlightCount(buffer));
+        }
+    }
+
 public slots:
     QVariantList initLastSeenMsg() const;
     void initSetLastSeenMsg(const QVariantList &);
@@ -56,6 +63,9 @@ public slots:
     QVariantList initActivities() const;
     void initSetActivities(const QVariantList &);
 
+    QVariantList initHighlightCounts() const;
+    void initSetHighlightCounts(const QVariantList &);
+
     virtual inline void requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId) { REQUEST(ARG(buffer), ARG(msgId)) }
     virtual inline void requestSetMarkerLine(BufferId buffer, const MsgId &msgId) { REQUEST(ARG(buffer), ARG(msgId)) setMarkerLine(buffer, msgId); }
 
@@ -66,6 +76,12 @@ public slots:
         emit bufferActivityChanged(buffer, flags);
     }
 
+    virtual inline void setHighlightCount(BufferId buffer, int count) {
+        SYNC(ARG(buffer), ARG(count));
+        _highlightCounts[buffer] = count;
+        emit highlightCountChanged(buffer, count);
+    }
+
     virtual inline void requestRemoveBuffer(BufferId buffer) { REQUEST(ARG(buffer)) }
     virtual void removeBuffer(BufferId buffer);
 
@@ -88,6 +104,7 @@ signals:
     void buffersPermanentlyMerged(BufferId buffer1, BufferId buffer2);
     void bufferMarkedAsRead(BufferId buffer);
     void bufferActivityChanged(BufferId, Message::Types);
+    void highlightCountChanged(BufferId, int);
 
 protected slots:
     bool setLastSeenMsg(BufferId buffer, const MsgId &msgId);
@@ -102,6 +119,7 @@ private:
     QHash<BufferId, MsgId> _lastSeenMsg;
     QHash<BufferId, MsgId> _markerLines;
     QHash<BufferId, Message::Types> _bufferActivities;
+    QHash<BufferId, int> _highlightCounts;
 };
 
 
index 3ae6cf4..e87a736 100644 (file)
@@ -1,2 +1,2 @@
-INSERT INTO buffer (bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, key, joined, cipher)
-VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+INSERT INTO buffer (bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, highlightcount, key, joined, cipher)
+VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
diff --git a/src/core/SQL/PostgreSQL/select_buffer_highlightcount.sql b/src/core/SQL/PostgreSQL/select_buffer_highlightcount.sql
new file mode 100644 (file)
index 0000000..33058f8
--- /dev/null
@@ -0,0 +1,7 @@
+SELECT COALESCE(t.sum,0)
+FROM
+  (SELECT COUNT(*) AS sum FROM backlog
+   WHERE bufferid = :bufferid
+     AND flags & 2 != 0
+     AND flags & 1 = 0
+     AND messageid > :lastseenmsgid) t;
diff --git a/src/core/SQL/PostgreSQL/select_buffer_highlightcounts.sql b/src/core/SQL/PostgreSQL/select_buffer_highlightcounts.sql
new file mode 100644 (file)
index 0000000..b5b7688
--- /dev/null
@@ -0,0 +1,3 @@
+SELECT bufferid, highlightcount
+FROM buffer
+WHERE userid = :userid
index 0d92f43..5b73c88 100644 (file)
@@ -10,6 +10,7 @@ create TABLE buffer (
        lastseenmsgid integer NOT NULL DEFAULT 0,
        markerlinemsgid integer NOT NULL DEFAULT 0,
        bufferactivity integer NOT NULL DEFAULT 0,
+       highlightcount integer NOT NULL DEFAULT 0,
        key varchar(128),
        joined boolean NOT NULL DEFAULT FALSE, -- BOOL
        cipher TEXT,
diff --git a/src/core/SQL/PostgreSQL/update_buffer_highlightcount.sql b/src/core/SQL/PostgreSQL/update_buffer_highlightcount.sql
new file mode 100644 (file)
index 0000000..9619fd3
--- /dev/null
@@ -0,0 +1,3 @@
+UPDATE buffer
+SET highlightcount = :highlightcount
+WHERE userid = :userid AND bufferid = :bufferid
diff --git a/src/core/SQL/PostgreSQL/version/26/upgrade_000_alter_buffer_add_highlightcount.sql b/src/core/SQL/PostgreSQL/version/26/upgrade_000_alter_buffer_add_highlightcount.sql
new file mode 100644 (file)
index 0000000..4ea3d99
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE buffer
+ADD COLUMN highlightcount integer NOT NULL DEFAULT 0
index da20e39..515e2c8 100644 (file)
@@ -1,2 +1,2 @@
-SELECT bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, key, joined, cipher
+SELECT bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, highlightcount, key, joined, cipher
 FROM buffer
diff --git a/src/core/SQL/SQLite/select_buffer_highlightcount.sql b/src/core/SQL/SQLite/select_buffer_highlightcount.sql
new file mode 100644 (file)
index 0000000..33058f8
--- /dev/null
@@ -0,0 +1,7 @@
+SELECT COALESCE(t.sum,0)
+FROM
+  (SELECT COUNT(*) AS sum FROM backlog
+   WHERE bufferid = :bufferid
+     AND flags & 2 != 0
+     AND flags & 1 = 0
+     AND messageid > :lastseenmsgid) t;
diff --git a/src/core/SQL/SQLite/select_buffer_highlightcounts.sql b/src/core/SQL/SQLite/select_buffer_highlightcounts.sql
new file mode 100644 (file)
index 0000000..b5b7688
--- /dev/null
@@ -0,0 +1,3 @@
+SELECT bufferid, highlightcount
+FROM buffer
+WHERE userid = :userid
index 5781c24..7e29531 100644 (file)
@@ -10,6 +10,7 @@ CREATE TABLE buffer (
        lastseenmsgid INTEGER NOT NULL DEFAULT 0,
        markerlinemsgid INTEGER NOT NULL DEFAULT 0,
        bufferactivity INTEGER NOT NULL DEFAULT 0,
+       highlightcount INTEGER NOT NULL DEFAULT 0,
        key TEXT,
        joined INTEGER NOT NULL DEFAULT 0, -- BOOL
        cipher TEXT,
diff --git a/src/core/SQL/SQLite/update_buffer_highlightcount.sql b/src/core/SQL/SQLite/update_buffer_highlightcount.sql
new file mode 100644 (file)
index 0000000..9619fd3
--- /dev/null
@@ -0,0 +1,3 @@
+UPDATE buffer
+SET highlightcount = :highlightcount
+WHERE userid = :userid AND bufferid = :bufferid
diff --git a/src/core/SQL/SQLite/version/28/upgrade_000_alter_buffer_add_highlightcount.sql b/src/core/SQL/SQLite/version/28/upgrade_000_alter_buffer_add_highlightcount.sql
new file mode 100644 (file)
index 0000000..4ea3d99
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE buffer
+ADD COLUMN highlightcount integer NOT NULL DEFAULT 0
index c554d9a..2a59fbf 100644 (file)
@@ -234,6 +234,7 @@ public:
         int lastseenmsgid;
         int markerlinemsgid;
         int bufferactivity;
+        int highlightcount;
         QString key;
         bool joined;
         QString cipher;
index 98e2612..640ba18 100644 (file)
@@ -606,6 +606,39 @@ public:
         return instance()->_storage->bufferActivity(bufferId, lastSeenMsgId);
     }
 
+    //! Update the highlight count for a Buffer
+    /** This Method is used to make the highlight count state of a Buffer persistent
+     *  \note This method is threadsafe.
+     *
+     * \param user      The Owner of that Buffer
+     * \param bufferId  The buffer id
+     * \param MsgId     The Message id where the marker line should be placed
+     */
+    static inline void setHighlightCount(UserId user, BufferId bufferId, int highlightCount) {
+        return instance()->_storage->setHighlightCount(user, bufferId, highlightCount);
+    }
+
+
+    //! Get a Hash of all highlight count states
+    /** This Method is called when the Quassel Core is started to restore the highlight count
+     *  \note This method is threadsafe.
+     *
+     * \param user      The Owner of the buffers
+     */
+    static inline QHash<BufferId, int> highlightCounts(UserId user) {
+        return instance()->_storage->highlightCounts(user);
+    }
+    //! Get the highlight count states for a buffer
+    /** This method is used to load the highlight count of a buffer when its last seen message changes.
+     *  \note This method is threadsafe.
+     *
+     * \param bufferId The buffer
+     * \param lastSeenMsgId     The last seen message
+     */
+    static inline int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) {
+        return instance()->_storage->highlightCount(bufferId, lastSeenMsgId);
+    }
+
     static inline QDateTime startTime() { return instance()->_startTime; }
     static inline bool isConfigured() { return instance()->_configured; }
     static bool sslSupported();
index 175606b..0548326 100644 (file)
@@ -34,11 +34,12 @@ public:
 
 INIT_SYNCABLE_OBJECT(CoreBufferSyncer)
 CoreBufferSyncer::CoreBufferSyncer(CoreSession *parent)
-    : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), Core::bufferActivities(parent->user()), parent),
+    : BufferSyncer(Core::bufferLastSeenMsgIds(parent->user()), Core::bufferMarkerLineMsgIds(parent->user()), Core::bufferActivities(parent->user()), Core::highlightCounts(parent->user()), parent),
     _coreSession(parent),
     _purgeBuffers(false)
 {
     connect(parent, SIGNAL(displayMsg(Message)), SLOT(addBufferActivity(Message)));
+    connect(parent, SIGNAL(displayMsg(Message)), SLOT(addCoreHighlight(Message)));
 }
 
 
@@ -46,7 +47,11 @@ void CoreBufferSyncer::requestSetLastSeenMsg(BufferId buffer, const MsgId &msgId
 {
     if (setLastSeenMsg(buffer, msgId)) {
         int activity = Core::bufferActivity(buffer, msgId);
+        int highlightCount = Core::highlightCount(buffer, msgId);
+
         setBufferActivity(buffer, activity);
+        setHighlightCount(buffer, highlightCount);
+
         dirtyLastSeenBuffers << buffer;
     }
 }
@@ -79,9 +84,14 @@ void CoreBufferSyncer::storeDirtyIds()
         Core::setBufferActivity(userId, bufferId, activity(bufferId));
     }
 
+    foreach(BufferId bufferId, dirtyHighlights) {
+        Core::setHighlightCount(userId, bufferId, highlightCount(bufferId));
+    }
+
     dirtyLastSeenBuffers.clear();
     dirtyMarkerLineBuffers.clear();
     dirtyActivities.clear();
+    dirtyHighlights.clear();
 }
 
 
@@ -195,3 +205,8 @@ void CoreBufferSyncer::setBufferActivity(BufferId buffer, int activity) {
     BufferSyncer::setBufferActivity(buffer, activity);
     dirtyActivities << buffer;
 }
+
+void CoreBufferSyncer::setHighlightCount(BufferId buffer, int highlightCount) {
+    BufferSyncer::setHighlightCount(buffer, highlightCount);
+    dirtyHighlights << buffer;
+}
index 6aeaa6d..dd33f06 100644 (file)
@@ -47,8 +47,17 @@ public slots:
         }
     }
 
+    void addCoreHighlight(const Message &message) {
+        auto oldHighlightCount = highlightCount(message.bufferId());
+        if (message.flags().testFlag(Message::Flag::Highlight) && !message.flags().testFlag(Message::Flag::Self)) {
+            setHighlightCount(message.bufferId(), oldHighlightCount + 1);
+        }
+    }
+
     void setBufferActivity(BufferId buffer, int activity) override;
 
+    void setHighlightCount(BufferId buffer, int highlightCount) override;
+
     inline void requestRenameBuffer(BufferId buffer, QString newName) override { renameBuffer(buffer, newName); }
     void renameBuffer(BufferId buffer, QString newName) override;
 
@@ -60,6 +69,7 @@ public slots:
     inline void requestMarkBufferAsRead(BufferId buffer) override {
         int activity = Message::Types();
         setBufferActivity(buffer, activity);
+        setHighlightCount(buffer, 0);
         markBufferAsRead(buffer);
     }
 
@@ -75,6 +85,7 @@ private:
     QSet<BufferId> dirtyLastSeenBuffers;
     QSet<BufferId> dirtyMarkerLineBuffers;
     QSet<BufferId> dirtyActivities;
+    QSet<BufferId> dirtyHighlights;
 
     void purgeBufferIds();
 };
index b64592d..7377149 100644 (file)
@@ -1478,6 +1478,61 @@ void PostgreSqlStorage::setBufferCipher(UserId user, const NetworkId &networkId,
     watchQuery(query);
 }
 
+
+void PostgreSqlStorage::setHighlightCount(UserId user, BufferId bufferId, int highlightcount)
+{
+    QSqlQuery query(logDb());
+    query.prepare(queryString("update_buffer_highlightcount"));
+
+    query.bindValue(":userid", user.toInt());
+    query.bindValue(":bufferid", bufferId.toInt());
+    query.bindValue(":highlightcount", highlightcount);
+    safeExec(query);
+    watchQuery(query);
+}
+
+QHash<BufferId, int> PostgreSqlStorage::highlightCounts(UserId user)
+{
+    QHash<BufferId, int> highlightCountHash;
+
+    QSqlDatabase db = logDb();
+    if (!beginReadOnlyTransaction(db)) {
+        qWarning() << "PostgreSqlStorage::highlightCounts(): cannot start read only transaction!";
+        qWarning() << " -" << qPrintable(db.lastError().text());
+        return highlightCountHash;
+    }
+
+    QSqlQuery query(db);
+    query.prepare(queryString("select_buffer_highlightcounts"));
+    query.bindValue(":userid", user.toInt());
+    safeExec(query);
+    if (!watchQuery(query)) {
+        db.rollback();
+        return highlightCountHash;
+    }
+
+    while (query.next()) {
+        highlightCountHash[query.value(0).toInt()] = query.value(1).toInt();
+    }
+
+    db.commit();
+    return highlightCountHash;
+}
+
+int PostgreSqlStorage::highlightCount(BufferId bufferId, MsgId lastSeenMsgId)
+{
+    QSqlQuery query(logDb());
+    query.prepare(queryString("select_buffer_highlightcount"));
+    query.bindValue(":bufferid", bufferId.toInt());
+    query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+    safeExec(query);
+    watchQuery(query);
+    int result = int(0);
+    if (query.first())
+        result = query.value(0).toInt();
+    return result;
+}
+
 bool PostgreSqlStorage::logMessage(Message &msg)
 {
     QSqlDatabase db = logDb();
@@ -2102,9 +2157,10 @@ bool PostgreSqlMigrationWriter::writeMo(const BufferMO &buffer)
     bindValue(8, buffer.lastseenmsgid);
     bindValue(9, buffer.markerlinemsgid);
     bindValue(10, buffer.bufferactivity);
-    bindValue(11, buffer.key);
-    bindValue(12, buffer.joined);
-    bindValue(13, buffer.cipher);
+    bindValue(11, buffer.highlightcount);
+    bindValue(12, buffer.key);
+    bindValue(13, buffer.joined);
+    bindValue(14, buffer.cipher);
     return exec();
 }
 
index 3146581..5322a09 100644 (file)
@@ -98,6 +98,9 @@ public slots:
     void setBufferActivity(UserId id, BufferId bufferId, Message::Types type) override;
     QHash<BufferId, Message::Types> bufferActivities(UserId id) override;
     Message::Types bufferActivity(BufferId bufferId, MsgId lastSeenMsgId) override;
+    void setHighlightCount(UserId id, BufferId bufferId, int count) override;
+    QHash<BufferId, int> highlightCounts(UserId id) override;
+    int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) override;
     QHash<QString, QByteArray> bufferCiphers(UserId user, const NetworkId &networkId) override;
     void setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher) override;
 
index 60ef637..b8fc95e 100644 (file)
@@ -40,6 +40,8 @@
     <file>./SQL/PostgreSQL/select_buffer_bufferactivity.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_by_id.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_ciphers.sql</file>
+    <file>./SQL/PostgreSQL/select_buffer_highlightcount.sql</file>
+    <file>./SQL/PostgreSQL/select_buffer_highlightcounts.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_markerlinemsgids.sql</file>
     <file>./SQL/PostgreSQL/select_buffers.sql</file>
@@ -82,6 +84,7 @@
     <file>./SQL/PostgreSQL/update_backlog_bufferid.sql</file>
     <file>./SQL/PostgreSQL/update_buffer_bufferactivity.sql</file>
     <file>./SQL/PostgreSQL/update_buffer_cipher.sql</file>
+    <file>./SQL/PostgreSQL/update_buffer_highlightcount.sql</file>
     <file>./SQL/PostgreSQL/update_buffer_lastseen.sql</file>
     <file>./SQL/PostgreSQL/update_buffer_markerlinemsgid.sql</file>
     <file>./SQL/PostgreSQL/update_buffer_name.sql</file>
     <file>./SQL/PostgreSQL/version/23/upgrade_000_create_senderprefixes.sql</file>
     <file>./SQL/PostgreSQL/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql</file>
     <file>./SQL/PostgreSQL/version/25/upgrade_000_alter_buffer_add_cipher.sql</file>
+    <file>./SQL/PostgreSQL/version/26/upgrade_000_alter_buffer_add_highlightcount.sql</file>
     <file>./SQL/SQLite/delete_backlog_by_uid.sql</file>
     <file>./SQL/SQLite/delete_backlog_for_buffer.sql</file>
     <file>./SQL/SQLite/delete_backlog_for_network.sql</file>
     <file>./SQL/SQLite/select_buffer_bufferactivity.sql</file>
     <file>./SQL/SQLite/select_buffer_by_id.sql</file>
     <file>./SQL/SQLite/select_buffer_ciphers.sql</file>
+    <file>./SQL/SQLite/select_buffer_highlightcount.sql</file>
+    <file>./SQL/SQLite/select_buffer_highlightcounts.sql</file>
     <file>./SQL/SQLite/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/SQLite/select_buffer_markerlinemsgids.sql</file>
     <file>./SQL/SQLite/select_buffers.sql</file>
     <file>./SQL/SQLite/update_backlog_bufferid.sql</file>
     <file>./SQL/SQLite/update_buffer_bufferactivity.sql</file>
     <file>./SQL/SQLite/update_buffer_cipher.sql</file>
+    <file>./SQL/SQLite/update_buffer_highlightcount.sql</file>
     <file>./SQL/SQLite/update_buffer_lastseen.sql</file>
     <file>./SQL/SQLite/update_buffer_markerlinemsgid.sql</file>
     <file>./SQL/SQLite/update_buffer_name.sql</file>
     <file>./SQL/SQLite/version/25/upgrade_000_alter_buffer_add_bufferactivity.sql</file>
     <file>./SQL/SQLite/version/26/upgrade_000_create_buffer_idx.sql</file>
     <file>./SQL/SQLite/version/27/upgrade_000_alter_buffer_add_cipher.sql</file>
+    <file>./SQL/SQLite/version/28/upgrade_000_alter_buffer_add_highlightcount.sql</file>
 </qresource>
 </RCC>
index 6333882..d71dd3c 100644 (file)
@@ -1620,6 +1620,79 @@ void SqliteStorage::setBufferCipher(UserId user, const NetworkId &networkId, con
     unlock();
 }
 
+void SqliteStorage::setHighlightCount(UserId user, BufferId bufferId, int count)
+{
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("update_buffer_highlightcount"));
+        query.bindValue(":userid", user.toInt());
+        query.bindValue(":bufferid", bufferId.toInt());
+        query.bindValue(":highlightcount", count);
+
+        lockForWrite();
+        safeExec(query);
+        watchQuery(query);
+    }
+    db.commit();
+    unlock();
+}
+
+
+QHash<BufferId, int> SqliteStorage::highlightCounts(UserId user)
+{
+    QHash<BufferId, int> highlightCountHash;
+
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    bool error = false;
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("select_buffer_highlightcounts"));
+        query.bindValue(":userid", user.toInt());
+
+        lockForRead();
+        safeExec(query);
+        error = !watchQuery(query);
+        if (!error) {
+            while (query.next()) {
+                highlightCountHash[query.value(0).toInt()] = query.value(1).toInt();
+            }
+        }
+    }
+
+    db.commit();
+    unlock();
+    return highlightCountHash;
+}
+
+
+int SqliteStorage::highlightCount(BufferId bufferId, MsgId lastSeenMsgId)
+{
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    int result = 0;
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("select_buffer_highlightcount"));
+        query.bindValue(":bufferid", bufferId.toInt());
+        query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+
+        lockForRead();
+        safeExec(query);
+        if (query.first())
+            result = query.value(0).toInt();
+    }
+
+    db.commit();
+    unlock();
+    return result;
+}
+
 bool SqliteStorage::logMessage(Message &msg)
 {
     QSqlDatabase db = logDb();
@@ -2116,9 +2189,10 @@ bool SqliteMigrationReader::readMo(BufferMO &buffer)
     buffer.lastseenmsgid = value(8).toInt();
     buffer.markerlinemsgid = value(9).toInt();
     buffer.bufferactivity = value(10).toInt();
-    buffer.key = value(11).toString();
-    buffer.joined = value(12).toInt() == 1 ? true : false;
-    buffer.cipher = value(13).toString();
+    buffer.highlightcount = value(11).toInt();
+    buffer.key = value(12).toString();
+    buffer.joined = value(13).toInt() == 1 ? true : false;
+    buffer.cipher = value(14).toString();
     return true;
 }
 
index aa0dad1..367c644 100644 (file)
@@ -99,6 +99,9 @@ public slots:
     void setBufferActivity(UserId id, BufferId bufferId, Message::Types type) override;
     QHash<BufferId, Message::Types> bufferActivities(UserId id) override;
     Message::Types bufferActivity(BufferId bufferId, MsgId lastSeenMsgId) override;
+    void setHighlightCount(UserId id, BufferId bufferId, int count) override;
+    QHash<BufferId, int> highlightCounts(UserId id) override;
+    int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) override;
     QHash<QString, QByteArray> bufferCiphers(UserId user, const NetworkId &networkId) override;
     void setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher) override;
 
index 49f2df8..d22372e 100644 (file)
@@ -430,6 +430,33 @@ public slots:
      */
     virtual void setBufferCipher(UserId user, const NetworkId &networkId, const QString &bufferName, const QByteArray &cipher) = 0;
 
+    //! Update the highlight count for a Buffer
+    /** This Method is used to make the activity state of a Buffer persistent
+     *  \note This method is threadsafe.
+     *
+     * \param user      The Owner of that Buffer
+     * \param bufferId  The buffer id
+     * \param MsgId     The Message id where the marker line should be placed
+     */
+    virtual void setHighlightCount(UserId id, BufferId bufferId, int count) = 0;
+
+    //! Get a Hash of all highlight count states
+    /** This Method is called when the Quassel Core is started to restore the HighlightCounts
+     *  \note This method is threadsafe.
+     *
+     * \param user      The Owner of the buffers
+     */
+    virtual QHash<BufferId, int> highlightCounts(UserId id) = 0;
+
+    //! Get the highlight count states for a buffer
+    /** This method is used to load the activity state of a buffer when its last seen message changes.
+     *  \note This method is threadsafe.
+     *
+     * \param bufferId The buffer
+     * \param lastSeenMsgId     The last seen message
+     */
+    virtual int highlightCount(BufferId bufferId, MsgId lastSeenMsgId) = 0;
+
     /* Message handling */
 
     //! Store a Message in the storage backend and set its unique Id.