Implement database backend for buffer-activity patch
authorJanne Koschinski <janne@kuschku.de>
Fri, 25 Aug 2017 21:09:00 +0000 (23:09 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Tue, 19 Dec 2017 20:08:01 +0000 (21:08 +0100)
17 files changed:
src/core/SQL/PostgreSQL/migrate_write_buffer.sql
src/core/SQL/PostgreSQL/select_buffer_bufferactivities.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/select_buffer_bufferactivity.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/setup_050_buffer.sql
src/core/SQL/PostgreSQL/update_buffer_bufferactivity.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/version/23/upgrade_000_alter_buffer_add_bufferactivity.sql [new file with mode: 0644]
src/core/SQL/SQLite/migrate_read_buffer.sql
src/core/SQL/SQLite/select_buffer_bufferactivity.sql [new file with mode: 0644]
src/core/SQL/SQLite/setup_030_buffer.sql
src/core/SQL/SQLite/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql [new file with mode: 0644]
src/core/abstractsqlstorage.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 35ef61d..8f1e5e9 100644 (file)
@@ -1,2 +1,2 @@
-INSERT INTO buffer (bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, key, joined)
+INSERT INTO buffer (bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, key, joined)
 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
diff --git a/src/core/SQL/PostgreSQL/select_buffer_bufferactivities.sql b/src/core/SQL/PostgreSQL/select_buffer_bufferactivities.sql
new file mode 100644 (file)
index 0000000..e40467c
--- /dev/null
@@ -0,0 +1,3 @@
+SELECT bufferid, bufferactivity
+FROM buffer
+WHERE userid = :userid
\ No newline at end of file
diff --git a/src/core/SQL/PostgreSQL/select_buffer_bufferactivity.sql b/src/core/SQL/PostgreSQL/select_buffer_bufferactivity.sql
new file mode 100644 (file)
index 0000000..294a6cc
--- /dev/null
@@ -0,0 +1,6 @@
+SELECT COALESCE(SUM(t.type),0)
+FROM
+  (SELECT DISTINCT TYPE
+   FROM backlog
+   WHERE bufferid = :bufferid
+     AND messageid > :lastseenmsgid) t;
\ No newline at end of file
index a9206ac..a10265b 100644 (file)
@@ -9,6 +9,7 @@ create TABLE buffer (
        lastmsgid integer NOT NULL DEFAULT 0,
        lastseenmsgid integer NOT NULL DEFAULT 0,
        markerlinemsgid integer NOT NULL DEFAULT 0,
        lastmsgid integer NOT NULL DEFAULT 0,
        lastseenmsgid integer NOT NULL DEFAULT 0,
        markerlinemsgid integer NOT NULL DEFAULT 0,
+       bufferactivity integer NOT NULL DEFAULT 0,
        key varchar(128),
        joined boolean NOT NULL DEFAULT FALSE, -- BOOL
        UNIQUE(userid, networkid, buffercname),
        key varchar(128),
        joined boolean NOT NULL DEFAULT FALSE, -- BOOL
        UNIQUE(userid, networkid, buffercname),
diff --git a/src/core/SQL/PostgreSQL/update_buffer_bufferactivity.sql b/src/core/SQL/PostgreSQL/update_buffer_bufferactivity.sql
new file mode 100644 (file)
index 0000000..29400b9
--- /dev/null
@@ -0,0 +1,3 @@
+UPDATE buffer
+SET bufferactivity = :bufferactivity
+WHERE userid = :userid AND bufferid = :bufferid
\ No newline at end of file
diff --git a/src/core/SQL/PostgreSQL/version/23/upgrade_000_alter_buffer_add_bufferactivity.sql b/src/core/SQL/PostgreSQL/version/23/upgrade_000_alter_buffer_add_bufferactivity.sql
new file mode 100644 (file)
index 0000000..b5cfa6c
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE buffer
+ADD COLUMN bufferactivity integer NOT NULL DEFAULT 0
\ No newline at end of file
index a2cc558..5d20037 100644 (file)
@@ -1,2 +1,2 @@
-SELECT bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, key, joined
+SELECT bufferid, userid, groupid, networkid, buffername, buffercname, buffertype, lastmsgid, lastseenmsgid, markerlinemsgid, bufferactivity, key, joined
 FROM buffer
 FROM buffer
diff --git a/src/core/SQL/SQLite/select_buffer_bufferactivity.sql b/src/core/SQL/SQLite/select_buffer_bufferactivity.sql
new file mode 100644 (file)
index 0000000..294a6cc
--- /dev/null
@@ -0,0 +1,6 @@
+SELECT COALESCE(SUM(t.type),0)
+FROM
+  (SELECT DISTINCT TYPE
+   FROM backlog
+   WHERE bufferid = :bufferid
+     AND messageid > :lastseenmsgid) t;
\ No newline at end of file
index 66f22fa..3e09d06 100644 (file)
@@ -9,6 +9,7 @@ CREATE TABLE buffer (
        lastmsgid INTEGER NOT NULL DEFAULT 0,
        lastseenmsgid INTEGER NOT NULL DEFAULT 0,
        markerlinemsgid INTEGER NOT NULL DEFAULT 0,
        lastmsgid INTEGER NOT NULL DEFAULT 0,
        lastseenmsgid INTEGER NOT NULL DEFAULT 0,
        markerlinemsgid INTEGER NOT NULL DEFAULT 0,
+       bufferactivity INTEGER NOT NULL DEFAULT 0,
        key TEXT,
        joined INTEGER NOT NULL DEFAULT 0, -- BOOL
        CHECK (lastseenmsgid <= lastmsgid)
        key TEXT,
        joined INTEGER NOT NULL DEFAULT 0, -- BOOL
        CHECK (lastseenmsgid <= lastmsgid)
diff --git a/src/core/SQL/SQLite/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql b/src/core/SQL/SQLite/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql
new file mode 100644 (file)
index 0000000..b5cfa6c
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE buffer
+ADD COLUMN bufferactivity integer NOT NULL DEFAULT 0
\ No newline at end of file
index 91950cc..6eb5f8e 100644 (file)
@@ -233,6 +233,7 @@ public:
         int lastmsgid;
         int lastseenmsgid;
         int markerlinemsgid;
         int lastmsgid;
         int lastseenmsgid;
         int markerlinemsgid;
+        int bufferactivity;
         QString key;
         bool joined;
     };
         QString key;
         bool joined;
     };
index db8387f..1adb749 100644 (file)
@@ -1385,6 +1385,61 @@ QHash<BufferId, MsgId> PostgreSqlStorage::bufferMarkerLineMsgIds(UserId user)
     return markerLineHash;
 }
 
     return markerLineHash;
 }
 
+
+void PostgreSqlStorage::setBufferActivity(UserId user, const BufferId &bufferId, const int &bufferActivity)
+{
+    QSqlQuery query(logDb());
+    query.prepare(queryString("update_buffer_bufferactivity"));
+
+    query.bindValue(":userid", user.toInt());
+    query.bindValue(":bufferid", bufferId.toInt());
+    query.bindValue(":bufferactivity", bufferActivity);
+    safeExec(query);
+    watchQuery(query);
+}
+
+QHash<BufferId, int> PostgreSqlStorage::bufferActivities(UserId user)
+{
+    QHash<BufferId, int> bufferActivityHash;
+
+    QSqlDatabase db = logDb();
+    if (!beginReadOnlyTransaction(db)) {
+        qWarning() << "PostgreSqlStorage::bufferActivities(): cannot start read only transaction!";
+        qWarning() << " -" << qPrintable(db.lastError().text());
+        return bufferActivityHash;
+    }
+
+    QSqlQuery query(db);
+    query.prepare(queryString("select_buffer_bufferactivity"));
+    query.bindValue(":userid", user.toInt());
+    safeExec(query);
+    if (!watchQuery(query)) {
+        db.rollback();
+        return bufferActivityHash;
+    }
+
+    while (query.next()) {
+        bufferActivityHash[query.value(0).toInt()] = (Message::Type) query.value(1).toInt();
+    }
+
+    db.commit();
+    return bufferActivityHash;
+}
+
+int PostgreSqlStorage::bufferActivity(BufferId &bufferId, MsgId &lastSeenMsgId)
+{
+    QSqlQuery query(logDb());
+    query.prepare(queryString("select_buffer_bufferactivity"));
+    query.bindValue(":bufferid", bufferId.toInt());
+    query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+    safeExec(query);
+    watchQuery(query);
+    int result = 0;
+    if (query.first())
+        result = query.value(0).toInt();
+    return result;
+}
+
 bool PostgreSqlStorage::logMessage(Message &msg)
 {
     QSqlDatabase db = logDb();
 bool PostgreSqlStorage::logMessage(Message &msg)
 {
     QSqlDatabase db = logDb();
@@ -1978,8 +2033,9 @@ bool PostgreSqlMigrationWriter::writeMo(const BufferMO &buffer)
     bindValue(7, buffer.lastmsgid);
     bindValue(8, buffer.lastseenmsgid);
     bindValue(9, buffer.markerlinemsgid);
     bindValue(7, buffer.lastmsgid);
     bindValue(8, buffer.lastseenmsgid);
     bindValue(9, buffer.markerlinemsgid);
-    bindValue(10, buffer.key);
-    bindValue(11, buffer.joined);
+    bindValue(10, buffer.bufferactivity);
+    bindValue(11, buffer.key);
+    bindValue(12, buffer.joined);
     return exec();
 }
 
     return exec();
 }
 
index c11a819..b248aec 100644 (file)
@@ -96,6 +96,9 @@ public slots:
     virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user);
     virtual void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId);
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user);
     virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user);
     virtual void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId);
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user);
+    virtual void setBufferActivity(UserId id, const BufferId &bufferId, const int &type);
+    virtual QHash<BufferId, int> bufferActivities(UserId id);
+    virtual int bufferActivity(BufferId &bufferId, MsgId &lastSeenMsgId);
 
     /* Message handling */
     virtual bool logMessage(Message &msg);
 
     /* Message handling */
     virtual bool logMessage(Message &msg);
index 63c884a..c5f1c54 100644 (file)
@@ -34,6 +34,8 @@
     <file>./SQL/PostgreSQL/select_authuser.sql</file>
     <file>./SQL/PostgreSQL/select_bufferByName.sql</file>
     <file>./SQL/PostgreSQL/select_bufferExists.sql</file>
     <file>./SQL/PostgreSQL/select_authuser.sql</file>
     <file>./SQL/PostgreSQL/select_bufferByName.sql</file>
     <file>./SQL/PostgreSQL/select_bufferExists.sql</file>
+    <file>./SQL/PostgreSQL/select_buffer_bufferactivities.sql</file>
+    <file>./SQL/PostgreSQL/select_buffer_bufferactivity.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_by_id.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_markerlinemsgids.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_by_id.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/PostgreSQL/select_buffer_markerlinemsgids.sql</file>
@@ -75,6 +77,7 @@
     <file>./SQL/PostgreSQL/setup_120_alter_messageid_seq.sql</file>
     <file>./SQL/PostgreSQL/setup_130_function_lastmsgid.sql</file>
     <file>./SQL/PostgreSQL/update_backlog_bufferid.sql</file>
     <file>./SQL/PostgreSQL/setup_120_alter_messageid_seq.sql</file>
     <file>./SQL/PostgreSQL/setup_130_function_lastmsgid.sql</file>
     <file>./SQL/PostgreSQL/update_backlog_bufferid.sql</file>
+    <file>./SQL/PostgreSQL/update_buffer_bufferactivity.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/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/21/upgrade_000_add_function_backlog_lastmsgid_update.sql</file>
     <file>./SQL/PostgreSQL/version/21/upgrade_001_add_trigger_backlog_lastmsgid_update.sql</file>
     <file>./SQL/PostgreSQL/version/22/upgrade_000_alter_quasseluser_add_authenticator.sql</file>
     <file>./SQL/PostgreSQL/version/21/upgrade_000_add_function_backlog_lastmsgid_update.sql</file>
     <file>./SQL/PostgreSQL/version/21/upgrade_001_add_trigger_backlog_lastmsgid_update.sql</file>
     <file>./SQL/PostgreSQL/version/22/upgrade_000_alter_quasseluser_add_authenticator.sql</file>
+    <file>./SQL/PostgreSQL/version/23/upgrade_000_alter_buffer_add_bufferactivity.sql</file>
     <file>./SQL/PostgreSQL/version/23/upgrade_000_create_senderprefixes.sql</file>
     <file>./SQL/SQLite/delete_backlog_by_uid.sql</file>
     <file>./SQL/SQLite/delete_backlog_for_buffer.sql</file>
     <file>./SQL/PostgreSQL/version/23/upgrade_000_create_senderprefixes.sql</file>
     <file>./SQL/SQLite/delete_backlog_by_uid.sql</file>
     <file>./SQL/SQLite/delete_backlog_for_buffer.sql</file>
     <file>./SQL/SQLite/select_authuser.sql</file>
     <file>./SQL/SQLite/select_bufferByName.sql</file>
     <file>./SQL/SQLite/select_bufferExists.sql</file>
     <file>./SQL/SQLite/select_authuser.sql</file>
     <file>./SQL/SQLite/select_bufferByName.sql</file>
     <file>./SQL/SQLite/select_bufferExists.sql</file>
+    <file>./SQL/SQLite/select_buffer_bufferactivity.sql</file>
     <file>./SQL/SQLite/select_buffer_by_id.sql</file>
     <file>./SQL/SQLite/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/SQLite/select_buffer_markerlinemsgids.sql</file>
     <file>./SQL/SQLite/select_buffer_by_id.sql</file>
     <file>./SQL/SQLite/select_buffer_lastseen_messages.sql</file>
     <file>./SQL/SQLite/select_buffer_markerlinemsgids.sql</file>
     <file>./SQL/SQLite/version/22/upgrade_000_add_trigger_backlog_lastmsgid_update_direct_insert.sql</file>
     <file>./SQL/SQLite/version/22/upgrade_001_add_trigger_backlog_lastmsgid_update_direct_update.sql</file>
     <file>./SQL/SQLite/version/23/upgrade_000_alter_quasseluser_add_authenticator.sql</file>
     <file>./SQL/SQLite/version/22/upgrade_000_add_trigger_backlog_lastmsgid_update_direct_insert.sql</file>
     <file>./SQL/SQLite/version/22/upgrade_001_add_trigger_backlog_lastmsgid_update_direct_update.sql</file>
     <file>./SQL/SQLite/version/23/upgrade_000_alter_quasseluser_add_authenticator.sql</file>
+    <file>./SQL/SQLite/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql</file>
     <file>./SQL/SQLite/version/24/upgrade_000_create_senderprefixes.sql</file>
 </qresource>
 </RCC>
     <file>./SQL/SQLite/version/24/upgrade_000_create_senderprefixes.sql</file>
 </qresource>
 </RCC>
index 9fcd2b9..66c85dc 100644 (file)
@@ -1503,6 +1503,79 @@ QHash<BufferId, MsgId> SqliteStorage::bufferMarkerLineMsgIds(UserId user)
     return markerLineHash;
 }
 
     return markerLineHash;
 }
 
+void SqliteStorage::setBufferActivity(UserId user, const BufferId &bufferId, const int &bufferActivity)
+{
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("update_buffer_bufferactivity"));
+        query.bindValue(":userid", user.toInt());
+        query.bindValue(":bufferid", bufferId.toInt());
+        query.bindValue(":bufferactivity", bufferActivity);
+
+        lockForWrite();
+        safeExec(query);
+        watchQuery(query);
+    }
+    db.commit();
+    unlock();
+}
+
+
+QHash<BufferId, int> SqliteStorage::bufferActivities(UserId user)
+{
+    QHash<BufferId, int> bufferActivityHash;
+
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    bool error = false;
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("select_buffer_bufferactivities"));
+        query.bindValue(":userid", user.toInt());
+
+        lockForRead();
+        safeExec(query);
+        error = !watchQuery(query);
+        if (!error) {
+            while (query.next()) {
+                bufferActivityHash[query.value(0).toInt()] = (Message::Type) query.value(1).toInt();
+            }
+        }
+    }
+
+    db.commit();
+    unlock();
+    return bufferActivityHash;
+}
+
+
+int SqliteStorage::bufferActivity(BufferId &bufferId, MsgId &lastSeenMsgId)
+{
+    QSqlDatabase db = logDb();
+    db.transaction();
+
+    int result = 0;
+    {
+        QSqlQuery query(db);
+        query.prepare(queryString("select_buffer_bufferactivity"));
+        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();
 bool SqliteStorage::logMessage(Message &msg)
 {
     QSqlDatabase db = logDb();
@@ -1953,8 +2026,9 @@ bool SqliteMigrationReader::readMo(BufferMO &buffer)
     buffer.lastmsgid = value(7).toInt();
     buffer.lastseenmsgid = value(8).toInt();
     buffer.markerlinemsgid = value(9).toInt();
     buffer.lastmsgid = value(7).toInt();
     buffer.lastseenmsgid = value(8).toInt();
     buffer.markerlinemsgid = value(9).toInt();
-    buffer.key = value(10).toString();
-    buffer.joined = value(11).toInt() == 1 ? true : false;
+    buffer.bufferactivity = value(10).toInt();
+    buffer.key = value(11).toString();
+    buffer.joined = value(12).toInt() == 1 ? true : false;
     return true;
 }
 
     return true;
 }
 
index 54f1cb4..089f3e7 100644 (file)
@@ -97,6 +97,9 @@ public slots:
     virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user);
     virtual void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId);
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user);
     virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user);
     virtual void setBufferMarkerLineMsg(UserId user, const BufferId &bufferId, const MsgId &msgId);
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user);
+    virtual void setBufferActivity(UserId id, const BufferId &bufferId, const int &type);
+    virtual QHash<BufferId, int> bufferActivities(UserId id);
+    virtual int bufferActivity(BufferId &bufferId, MsgId &lastSeenMsgId);
 
     /* Message handling */
     virtual bool logMessage(Message &msg);
 
     /* Message handling */
     virtual bool logMessage(Message &msg);
index fec8d86..5eed79c 100644 (file)
@@ -384,6 +384,33 @@ public slots:
      */
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user) = 0;
 
      */
     virtual QHash<BufferId, MsgId> bufferMarkerLineMsgIds(UserId user) = 0;
 
+    //! Update the BufferActivity 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 setBufferActivity(UserId id, const BufferId &bufferId, const int &type) = 0;
+
+    //! Get a Hash of all buffer activity states
+    /** This Method is called when the Quassel Core is started to restore the BufferActivities
+     *  \note This method is threadsafe.
+     *
+     * \param user      The Owner of the buffers
+     */
+    virtual QHash<BufferId, int> bufferActivities(UserId id) = 0;
+
+    //! Get the bitset of buffer activity 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 bufferActivity(BufferId &bufferId, MsgId &lastSeenMsgId) = 0;
+
     /* Message handling */
 
     //! Store a Message in the storage backend and set its unique Id.
     /* Message handling */
 
     //! Store a Message in the storage backend and set its unique Id.