Implement sender prefix storage in the database
authorJanne Koschinski <janne@kuschku.de>
Thu, 31 Aug 2017 23:11:50 +0000 (01:11 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Mon, 4 Sep 2017 20:40:50 +0000 (22:40 +0200)
* When processing a new message, find the mode the user that
  sent this message has in a channel (for example o or hv)
* Convert it to a prefix (for example @ or +%)
* Store this in a new sendermode column in the backlog table

Schema for both SQLite and PostgreSQL is updated.

27 files changed:
src/common/message.cpp
src/common/message.h
src/common/network.h
src/core/SQL/PostgreSQL/insert_message.sql
src/core/SQL/PostgreSQL/migrate_write_backlog.sql
src/core/SQL/PostgreSQL/select_messagesAll.sql
src/core/SQL/PostgreSQL/select_messagesAllNew.sql
src/core/SQL/PostgreSQL/select_messagesNewerThan.sql
src/core/SQL/PostgreSQL/select_messagesNewestK.sql
src/core/SQL/PostgreSQL/select_messagesRange.sql
src/core/SQL/PostgreSQL/setup_060_backlog.sql
src/core/SQL/PostgreSQL/version/23/upgrade_000_create_mode.sql [new file with mode: 0644]
src/core/SQL/SQLite/insert_message.sql
src/core/SQL/SQLite/migrate_read_backlog.sql
src/core/SQL/SQLite/select_messagesAll.sql
src/core/SQL/SQLite/select_messagesAllNew.sql
src/core/SQL/SQLite/select_messagesNewerThan.sql
src/core/SQL/SQLite/select_messagesNewestK.sql
src/core/SQL/SQLite/select_messagesRange.sql
src/core/SQL/SQLite/setup_060_backlog.sql
src/core/SQL/SQLite/version/24/upgrade_000_create_mode.sql [new file with mode: 0644]
src/core/abstractsqlstorage.h
src/core/coresession.cpp
src/core/coresession.h
src/core/postgresqlstorage.cpp
src/core/sql.qrc
src/core/sqlitestorage.cpp

index dfa6bff..cd50158 100644 (file)
 
 #include <QDataStream>
 
-Message::Message(const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, Flags flags)
+Message::Message(const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, const QString &senderPrefixes, Flags flags)
     : _timestamp(QDateTime::currentDateTime().toUTC()),
     _bufferInfo(bufferInfo),
     _contents(contents),
     _sender(sender),
+    _senderPrefixes(senderPrefixes),
     _type(type),
     _flags(flags)
 {
 }
 
 
-Message::Message(const QDateTime &ts, const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, Flags flags)
+Message::Message(const QDateTime &ts, const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, const QString &senderPrefixes, Flags flags)
     : _timestamp(ts),
     _bufferInfo(bufferInfo),
     _contents(contents),
     _sender(sender),
+    _senderPrefixes(senderPrefixes),
     _type(type),
     _flags(flags)
 {
@@ -67,6 +69,7 @@ QDataStream &operator>>(QDataStream &in, Message &msg)
     msg._bufferInfo = buf;
     msg._timestamp = QDateTime::fromTime_t(ts);
     msg._sender = QString::fromUtf8(s);
+    msg._senderPrefixes = QString("");
     msg._contents = QString::fromUtf8(m);
     return in;
 }
index c20ce97..d61a8a7 100644 (file)
@@ -66,9 +66,9 @@ public:
     };
     Q_DECLARE_FLAGS(Flags, Flag)
 
-    Message(const BufferInfo &bufferInfo = BufferInfo(), Type type = Plain, const QString &contents = "", const QString &sender = "", Flags flags = None);
+    Message(const BufferInfo &bufferInfo = BufferInfo(), Type type = Plain, const QString &contents = "", const QString &sender = "", const QString &senderPrefixes = "", Flags flags = None);
     Message(const QDateTime &ts, const BufferInfo &buffer = BufferInfo(), Type type = Plain,
-        const QString &contents = "", const QString &sender = "", Flags flags = None);
+        const QString &contents = "", const QString &sender = "", const QString &senderPrefixes = "", Flags flags = None);
 
     inline static Message ChangeOfDay(const QDateTime &day) { return Message(day, BufferInfo(), DayChange); }
     inline const MsgId &msgId() const { return _msgId; }
@@ -79,6 +79,7 @@ public:
     inline void setBufferId(BufferId id) { _bufferInfo.setBufferId(id); }
     inline const QString &contents() const { return _contents; }
     inline const QString &sender() const { return _sender; }
+    inline const QString &senderPrefixes() const { return _senderPrefixes; }
     inline Type type() const { return _type; }
     inline Flags flags() const { return _flags; }
     inline void setFlags(Flags flags) { _flags = flags; }
@@ -94,6 +95,7 @@ private:
     BufferInfo _bufferInfo;
     QString _contents;
     QString _sender;
+    QString _senderPrefixes;
     Type _type;
     Flags _flags;
 
index 5ad42e9..addb1d5 100644 (file)
@@ -172,10 +172,37 @@ public :
     //Network::ConnectionState connectionState() const;
     inline int connectionState() const { return _connectionState; }
 
+    /**@{*/
+    /**
+     * Translates a user’s prefix to the channelmode associated with it.
+     * @param prefix Prefix to be translated.
+     */
     QString prefixToMode(const QString &prefix) const;
     inline QString prefixToMode(const QCharRef &prefix) const { return prefixToMode(QString(prefix)); }
+    inline QString prefixesToModes(const QString &prefix) const {
+        QString mode = "";
+        for (QChar c : prefix) {
+            mode += prefixToMode(c);
+        }
+        return mode;
+    }
+    /**@}*/
+
+    /**@{*/
+    /**
+     * Translates a user’s prefix to the channelmode associated with it.
+     * @param prefix Prefix to be translated.
+     */
     QString modeToPrefix(const QString &mode) const;
     inline QString modeToPrefix(const QCharRef &mode) const { return modeToPrefix(QString(mode)); }
+    inline QString modesToPrefixes(const QString &mode) const {
+        QString prefix = "";
+        for (QChar c : mode) {
+            prefix += modeToPrefix(c);
+        }
+        return prefix;
+    }
+    /**@}*/
 
     ChannelModeType channelModeType(const QString &mode);
     inline ChannelModeType channelModeType(const QCharRef &mode) { return channelModeType(QString(mode)); }
index 2013acb..867942c 100644 (file)
@@ -1,3 +1,3 @@
-INSERT INTO backlog (time, bufferid, type, flags, senderid, message)
-VALUES ($1, $2, $3, $4, $5, $6)
+INSERT INTO backlog (time, bufferid, type, flags, senderid, senderprefixes, message)
+VALUES ($1, $2, $3, $4, $5, $6, $7)
 RETURNING messageid
index a603522..c2d2a75 100644 (file)
@@ -1,2 +1,2 @@
-INSERT INTO backlog (messageid, time, bufferid, type, flags, senderid, message)
-VALUES (?, ?, ?, ?, ?, ?, ?)
+INSERT INTO backlog (messageid, time, bufferid, type, flags, senderid, senderprefixes, message)
+VALUES (?, ?, ?, ?, ?, ?, ?, ?)
index 10009c3..0ee372a 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, bufferid, time,  type, flags, sender, message
+SELECT messageid, bufferid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid)
index b810f0d..9f81545 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, bufferid, time,  type, flags, sender, message
+SELECT messageid, bufferid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid)
index 571f538..621fd0a 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.messageid >= $1
index 50be2e3..e705928 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE bufferid = $1
index b7af909..a95c23c 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.messageid >= $1
index 0523fcd..1711b23 100644 (file)
@@ -5,5 +5,6 @@ CREATE TABLE backlog (
        type integer NOT NULL,
        flags integer NOT NULL,
        senderid integer NOT NULL REFERENCES sender (senderid) ON DELETE SET NULL,
+    senderprefixes TEXT,
        message TEXT
 )
diff --git a/src/core/SQL/PostgreSQL/version/23/upgrade_000_create_mode.sql b/src/core/SQL/PostgreSQL/version/23/upgrade_000_create_mode.sql
new file mode 100644 (file)
index 0000000..ad507cc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE backlog
+ADD COLUMN senderprefixes TEXT;
index 20facb8..0a91299 100644 (file)
@@ -1,2 +1,2 @@
-INSERT INTO backlog (time, bufferid, type, flags, senderid, message)
-VALUES (:time, :bufferid, :type, :flags, (SELECT senderid FROM sender WHERE sender = :sender), :message)
+INSERT INTO backlog (time, bufferid, type, flags, senderid, senderprefixes, message)
+VALUES (:time, :bufferid, :type, :flags, (SELECT senderid FROM sender WHERE sender = :sender), :senderprefixes, :message)
index 6c0f299..8d53b17 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time, bufferid, type, flags, senderid, message
+SELECT messageid, time, bufferid, type, flags, senderid, senderprefixes, message
 FROM backlog
 WHERE messageid > ? AND messageid <= ?
 ORDER BY messageid ASC
index 52285af..2fb1cdb 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, bufferid, time,  type, flags, sender, message
+SELECT messageid, bufferid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid)
index a29f094..f6a5471 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, bufferid, time,  type, flags, sender, message
+SELECT messageid, bufferid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid)
index bac2a04..8129c44 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE backlog.messageid >= :firstmsg
index 6f86e70..18105db 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE bufferid = :bufferid
index 641179f..dc6e617 100644 (file)
@@ -1,4 +1,4 @@
-SELECT messageid, time,  type, flags, sender, message
+SELECT messageid, time,  type, flags, sender, senderprefixes, message
 FROM backlog
 JOIN sender ON backlog.senderid = sender.senderid
 WHERE bufferid = :bufferid
index d3e191d..59329e1 100644 (file)
@@ -5,4 +5,5 @@ CREATE TABLE backlog (
        type INTEGER NOT NULL,
        flags INTEGER NOT NULL,
        senderid INTEGER NOT NULL,
+    senderprefixes TEXT,
        message TEXT)
diff --git a/src/core/SQL/SQLite/version/24/upgrade_000_create_mode.sql b/src/core/SQL/SQLite/version/24/upgrade_000_create_mode.sql
new file mode 100644 (file)
index 0000000..ad507cc
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE backlog
+ADD COLUMN senderprefixes TEXT;
index 8a58be9..91950cc 100644 (file)
@@ -244,6 +244,7 @@ public:
         int type;
         int flags;
         int senderid;
+        QString senderprefixes;
         QString message;
     };
 
index 2ca9627..8c012ac 100644 (file)
@@ -366,7 +366,8 @@ void CoreSession::processMessages()
             Q_ASSERT(!createBuffer);
             bufferInfo = Core::bufferInfo(user(), rawMsg.networkId, BufferInfo::StatusBuffer, "");
         }
-        Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags);
+        Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender,
+                    senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags);
         if(Core::storeMessage(msg))
             emit displayMsg(msg);
     }
@@ -390,7 +391,8 @@ void CoreSession::processMessages()
                 }
                 bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo;
             }
-            Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags);
+            Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender,
+                        senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags);
             messages << msg;
         }
 
@@ -406,7 +408,8 @@ void CoreSession::processMessages()
                 // add the StatusBuffer to the Cache in case there are more Messages for the original target
                 bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo;
             }
-            Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, rawMsg.flags);
+            Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender,
+                        senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags);
             messages << msg;
         }
 
@@ -421,6 +424,25 @@ void CoreSession::processMessages()
     _messageQueue.clear();
 }
 
+QString CoreSession::senderPrefixes(const QString &sender, const BufferInfo &bufferInfo) const
+{
+    CoreNetwork *currentNetwork = network(bufferInfo.networkId());
+    if (!currentNetwork) {
+        return "";
+    }
+
+    if (bufferInfo.type() != BufferInfo::ChannelBuffer) {
+        return "";
+    }
+
+    IrcChannel *currentChannel = currentNetwork->ircChannel(bufferInfo.bufferName());
+    if (!currentChannel) {
+        return "";
+    }
+
+    const QString modes = currentChannel->userModes(nickFromMask(sender).toLower());
+    return currentNetwork->modesToPrefixes(modes);
+}
 
 Protocol::SessionState CoreSession::sessionState() const
 {
index 849575f..d7b2ceb 100644 (file)
@@ -224,6 +224,13 @@ private:
 
     QScriptEngine *scriptEngine;
 
+    /**
+     * This method obtains the prefixes of the message's sender within a channel, by looking up their channelmodes, and
+     * processing them to prefixes based on the network's settings.
+     * @param sender The hostmask of the sender
+     * @param bufferInfo The BufferInfo object of the buffer
+     */
+    QString senderPrefixes(const QString &sender, const BufferInfo &bufferInfo) const;
     QList<RawMessage> _messageQueue;
     bool _processMessages;
     CoreIgnoreListManager _ignoreListManager;
index ac6dec9..db8387f 100644 (file)
@@ -1425,6 +1425,7 @@ bool PostgreSqlStorage::logMessage(Message &msg)
            << msg.type()
            << (int)msg.flags()
            << senderId
+           << msg.senderPrefixes()
            << msg.contents();
     QSqlQuery logMessageQuery = executePreparedQuery("insert_message", params, db);
 
@@ -1502,6 +1503,7 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
                << msg.type()
                << (int)msg.flags()
                << senderIdList.at(i)
+               << msg.senderPrefixes()
                << msg.contents();
         QSqlQuery logMessageQuery = executePreparedQuery("insert_message", params, db);
         if (!watchQuery(logMessageQuery)) {
@@ -1580,8 +1582,9 @@ QList<Message> PostgreSqlStorage::requestMsgs(UserId user, BufferId bufferId, Ms
         Message msg(timestamp,
             bufferInfo,
             (Message::Type)query.value(2).toUInt(),
-            query.value(5).toString(),
+            query.value(6).toString(),
             query.value(4).toString(),
+            query.value(5).toString(),
             (Message::Flags)query.value(3).toUInt());
         msg.setMsgId(query.value(0).toInt());
         messagelist << msg;
@@ -1632,8 +1635,9 @@ QList<Message> PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId
         Message msg(timestamp,
             bufferInfoHash[query.value(1).toInt()],
             (Message::Type)query.value(3).toUInt(),
-            query.value(6).toString(),
+            query.value(7).toString(),
             query.value(5).toString(),
+            query.value(6).toString(),
             (Message::Flags)query.value(4).toUInt());
         msg.setMsgId(query.value(0).toInt());
         messagelist << msg;
@@ -1989,7 +1993,8 @@ bool PostgreSqlMigrationWriter::writeMo(const BacklogMO &backlog)
     bindValue(3, backlog.type);
     bindValue(4, (int)backlog.flags);
     bindValue(5, backlog.senderid);
-    bindValue(6, backlog.message);
+    bindValue(6, backlog.senderprefixes);
+    bindValue(7, backlog.message);
     return exec();
 }
 
index f945690..1eee7d0 100644 (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_create_mode.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/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_create_mode.sql</file>
 </qresource>
 </RCC>
index c14d7cb..9fcd2b9 100644 (file)
@@ -1518,6 +1518,7 @@ bool SqliteStorage::logMessage(Message &msg)
         logMessageQuery.bindValue(":type", msg.type());
         logMessageQuery.bindValue(":flags", (int)msg.flags());
         logMessageQuery.bindValue(":sender", msg.sender());
+        logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes());
         logMessageQuery.bindValue(":message", msg.contents());
 
         lockForWrite();
@@ -1593,6 +1594,7 @@ bool SqliteStorage::logMessages(MessageList &msgs)
             logMessageQuery.bindValue(":type", msg.type());
             logMessageQuery.bindValue(":flags", (int)msg.flags());
             logMessageQuery.bindValue(":sender", msg.sender());
+            logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes());
             logMessageQuery.bindValue(":message", msg.contents());
 
             safeExec(logMessageQuery);
@@ -1677,8 +1679,9 @@ QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId
             Message msg(QDateTime::fromTime_t(query.value(1).toInt()),
                 bufferInfo,
                 (Message::Type)query.value(2).toUInt(),
-                query.value(5).toString(),
+                query.value(6).toString(),
                 query.value(4).toString(),
+                query.value(5).toString(),
                 (Message::Flags)query.value(3).toUInt());
             msg.setMsgId(query.value(0).toInt());
             messagelist << msg;
@@ -1731,8 +1734,9 @@ QList<Message> SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las
             Message msg(QDateTime::fromTime_t(query.value(2).toInt()),
                 bufferInfoHash[query.value(1).toInt()],
                 (Message::Type)query.value(3).toUInt(),
-                query.value(6).toString(),
+                query.value(7).toString(),
                 query.value(5).toString(),
+                query.value(6).toString(),
                 (Message::Flags)query.value(4).toUInt());
             msg.setMsgId(query.value(0).toInt());
             messagelist << msg;
@@ -1999,7 +2003,8 @@ bool SqliteMigrationReader::readMo(BacklogMO &backlog)
     backlog.type = value(3).toInt();
     backlog.flags = value(4).toInt();
     backlog.senderid = value(5).toInt();
-    backlog.message = value(6).toString();
+    backlog.senderprefixes = value(6).toString();
+    backlog.message = value(7).toString();
     return true;
 }