Use 64-bit IDs for messages
authorMichael Marley <michael@michaelmarley.com>
Fri, 9 Mar 2018 17:17:05 +0000 (12:17 -0500)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 23 May 2018 22:33:28 +0000 (00:33 +0200)
Increase the length of message IDs from 32 to 64 bits, allowing for
many more total messages be stored.  Because messages are synced to
the client, this requires a protocol change.  The protocol change is
guarded behind a new feature flag that will retain backwards
compatibility with existing clients, at least until the IDs go above
the maximum for a 32-bit number.  At this point, legacy clients will
behave incorrectly or perhaps crash, but this is an acceptable risk
because in the current implementation, this event would cause the
core to behave incorrectly or crash.  The client is also still
limited to 32 bits worth of backlog per buffer displayed at once
(due to Qt limitations), but it would be highly unlikely to hit
this limit because the client becomes unusably slow with a small
fraction of that amount of backlog loaded in a single buffer.

For SQLite, no schema change was necessary as SQLite makes no
differentiation between the bitnesses of integers.

For PostgreSQL, this patch also changes senderId to 64-bit, but
this has no effect outside the PostgreSQL database driver.

This patch only changes the message ID to 64-bit.  All other IDs
are left at 32 bits because it is either exceedingly unlikely or
technically infeasible to have more than 32 bits worth of entries
in any of the other tables.  If, at some point, it is decided that
other IDs should also be 64-bit, the way in which the feature flag
affects (de)serialization will need to be changed.  This is because
the flag LongMessageId currently acts upon all IDs inheriting from
SignedId64 and it would be necessary to independently control the
(de)serialization of each ID if other IDs became 64-bit in order to
continue to maintain backwards compatibility.  One possible method
of doing this would be to subclass the SignedId64 class for each
ID that inherits from it to allow for separately controlling
(de)serialization for each of the types.  I have not implemented
this, however, because of the unlikelihood of any of the other IDs
ever being made 64-bit.

Closes GH-343.

18 files changed:
src/common/CMakeLists.txt
src/common/quassel.h
src/common/types.cpp [new file with mode: 0644]
src/common/types.h
src/core/SQL/PostgreSQL/setup_010_sender.sql
src/core/SQL/PostgreSQL/setup_050_buffer.sql
src/core/SQL/PostgreSQL/setup_060_backlog.sql
src/core/SQL/PostgreSQL/version/29/upgrade_010_alter_sender_64bit_ids.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/version/29/upgrade_050_alter_buffer_64bit_ids.sql [new file with mode: 0644]
src/core/SQL/PostgreSQL/version/29/upgrade_060_alter_backlog_64bit_ids.sql [new file with mode: 0644]
src/core/abstractsqlstorage.h
src/core/coresession.cpp
src/core/postgresqlstorage.cpp
src/core/sql.qrc
src/core/sqlitestorage.cpp
src/core/sqlitestorage.h
src/qtui/chatitem.cpp
src/qtui/debugmessagemodelfilter.cpp

index b5efb4a..8ec2bed 100644 (file)
@@ -38,6 +38,7 @@ set(SOURCES
     syncableobject.cpp
     transfer.cpp
     transfermanager.cpp
+    types.cpp
     util.cpp
 
     serializers/serializers.cpp
index dc697fc..8908365 100644 (file)
@@ -137,6 +137,7 @@ public:
 #if QT_VERSION >= 0x050500
         EcdsaCertfpKeys,          ///< ECDSA keys for CertFP in identities
 #endif
+        LongMessageId,            ///< 64-bit IDs for messages
     };
     Q_ENUMS(Feature)
 
diff --git a/src/common/types.cpp b/src/common/types.cpp
new file mode 100644 (file)
index 0000000..1974c58
--- /dev/null
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2018 by the Quassel Project                        *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
+ ***************************************************************************/
+
+#include "peer.h"
+#include "types.h"
+
+QDataStream &operator<<(QDataStream &out, const SignedId64 &signedId) {
+    Q_ASSERT(SignalProxy::current());
+    Q_ASSERT(SignalProxy::current()->targetPeer());
+
+    if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::LongMessageId)) {
+        out << signedId.toQint64();
+    } else {
+        out << (qint32) signedId.toQint64();
+    }
+    return out;
+}
+
+QDataStream &operator>>(QDataStream &in, SignedId64 &signedId) {
+    Q_ASSERT(SignalProxy::current());
+    Q_ASSERT(SignalProxy::current()->sourcePeer());
+
+    if (SignalProxy::current()->sourcePeer()->hasFeature(Quassel::Feature::LongMessageId)) {
+        in >> signedId.id;
+    } else {
+        qint32 id;
+        in >> id;
+        signedId.id = id;
+    }
+    return in;
+}
index 5e63f93..d7b4404 100644 (file)
@@ -58,20 +58,53 @@ public:
     friend QDataStream &operator>>(QDataStream &in, SignedId &signedId);
 };
 
-
 inline QDataStream &operator<<(QDataStream &out, const SignedId &signedId) { out << signedId.toInt(); return out; }
 inline QDataStream &operator>>(QDataStream &in, SignedId &signedId) { in >> signedId.id; return in; }
 inline QTextStream &operator<<(QTextStream &out, const SignedId &signedId) { out << QString::number(signedId.toInt()); return out; }
 inline QDebug operator<<(QDebug dbg, const SignedId &signedId) { dbg.space() << signedId.toInt(); return dbg; }
 inline uint qHash(const SignedId &id) { return qHash(id.toInt()); }
 
+class SignedId64
+{
+protected:
+    qint64 id;
+
+public:
+    inline SignedId64(qint64 _id = 0) { id = _id; }
+    inline qint64 toQint64() const { return id; }
+    inline bool isValid() const { return id > 0; }
+
+    inline bool operator==(const SignedId64 &other) const { return id == other.id; }
+    inline bool operator!=(const SignedId64 &other) const { return id != other.id; }
+    inline bool operator<(const SignedId64 &other) const { return id < other.id; }
+    inline bool operator<=(const SignedId64 &other) const { return id <= other.id; }
+    inline bool operator>(const SignedId64 &other) const { return id > other.id; }
+    inline bool operator>=(const SignedId64 &other) const { return id >= other.id; }
+    inline bool operator==(qint64 i) const { return id == i; }
+    inline bool operator!=(qint64 i) const { return id != i; }
+    inline bool operator<(qint64 i) const { return id < i; }
+    inline bool operator>(qint64 i) const { return id > i; }
+    inline bool operator<=(qint64 i) const { return id <= i; }
+
+    inline SignedId64 operator++(int) { id++; return *this; }
+    //inline operator int() const { return toQint64(); } // no automatic conversion!
+
+    friend QDataStream &operator>>(QDataStream &in, SignedId64 &signedId);
+};
+
+QDataStream &operator<<(QDataStream &out, const SignedId64 &signedId);
+QDataStream &operator>>(QDataStream &in, SignedId64 &signedId);
+inline QTextStream &operator<<(QTextStream &out, const SignedId64 &signedId) { out << QString::number(signedId.toQint64()); return out; }
+inline QDebug operator<<(QDebug dbg, const SignedId64 &signedId) { dbg.space() << signedId.toQint64(); return dbg; }
+inline uint qHash(const SignedId64 &id) { return qHash(id.toQint64()); }
+
 struct UserId : public SignedId {
     inline UserId(int _id = 0) : SignedId(_id) {}
     //inline operator QVariant() const { return QVariant::fromValue<UserId>(*this); }  // no automatic conversion!
 };
 
-struct MsgId : public SignedId {
-    inline MsgId(int _id = 0) : SignedId(_id) {}
+struct MsgId : public SignedId64 {
+    inline MsgId(qint64 _id = 0) : SignedId64(_id) {}
     //inline operator QVariant() const { return QVariant::fromValue<MsgId>(*this); }
 };
 
index 0854291..87c8366 100644 (file)
@@ -1,5 +1,5 @@
 CREATE TABLE sender ( -- THE SENDER OF IRC MESSAGES
-       senderid serial NOT NULL PRIMARY KEY,
+       senderid bigserial NOT NULL PRIMARY KEY,
        sender varchar(128) NOT NULL,
        realname TEXT,
        avatarurl TEXT
index 5b73c88..0487dd3 100644 (file)
@@ -6,9 +6,9 @@ create TABLE buffer (
        buffername varchar(128) NOT NULL,
        buffercname varchar(128) NOT NULL, -- CANONICAL BUFFER NAME (lowercase version)
        buffertype integer NOT NULL DEFAULT 0,
-       lastmsgid integer NOT NULL DEFAULT 0,
-       lastseenmsgid integer NOT NULL DEFAULT 0,
-       markerlinemsgid integer NOT NULL DEFAULT 0,
+       lastmsgid bigint NOT NULL DEFAULT 0,
+       lastseenmsgid bigint NOT NULL DEFAULT 0,
+       markerlinemsgid bigint NOT NULL DEFAULT 0,
        bufferactivity integer NOT NULL DEFAULT 0,
        highlightcount integer NOT NULL DEFAULT 0,
        key varchar(128),
index 4c75e09..4352f2e 100644 (file)
@@ -1,10 +1,10 @@
 CREATE TABLE backlog (
-       messageid serial PRIMARY KEY,
+       messageid bigserial PRIMARY KEY,
        time timestamp NOT NULL,
        bufferid integer NOT NULL REFERENCES buffer (bufferid) ON DELETE CASCADE,
        type integer NOT NULL,
        flags integer NOT NULL,
-       senderid integer NOT NULL REFERENCES sender (senderid) ON DELETE SET NULL,
+       senderid bigint NOT NULL REFERENCES sender (senderid) ON DELETE SET NULL,
        senderprefixes TEXT,
        message TEXT
 )
diff --git a/src/core/SQL/PostgreSQL/version/29/upgrade_010_alter_sender_64bit_ids.sql b/src/core/SQL/PostgreSQL/version/29/upgrade_010_alter_sender_64bit_ids.sql
new file mode 100644 (file)
index 0000000..ff0b2e2
--- /dev/null
@@ -0,0 +1,2 @@
+ALTER TABLE sender
+ALTER COLUMN senderid TYPE bigint
diff --git a/src/core/SQL/PostgreSQL/version/29/upgrade_050_alter_buffer_64bit_ids.sql b/src/core/SQL/PostgreSQL/version/29/upgrade_050_alter_buffer_64bit_ids.sql
new file mode 100644 (file)
index 0000000..e938d7e
--- /dev/null
@@ -0,0 +1,4 @@
+ALTER TABLE buffer
+ALTER COLUMN lastmsgid TYPE bigint,
+ALTER COLUMN lastseenmsgid TYPE bigint,
+ALTER COLUMN markerlinemsgid TYPE bigint
diff --git a/src/core/SQL/PostgreSQL/version/29/upgrade_060_alter_backlog_64bit_ids.sql b/src/core/SQL/PostgreSQL/version/29/upgrade_060_alter_backlog_64bit_ids.sql
new file mode 100644 (file)
index 0000000..73921c8
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE backlog
+ALTER COLUMN messageid TYPE bigint,
+ALTER COLUMN senderid TYPE bigint
index 5e4c360..5d77cf3 100644 (file)
@@ -167,7 +167,7 @@ public:
     };
 
     struct SenderMO {
-        int senderId;
+        qint64 senderId;
         QString sender;
         QString realname;
         QString avatarurl;
@@ -189,7 +189,7 @@ public:
         bool autoAwayReasonEnabled;
         bool detachAwayEnabled;
         QString detachAwayReason;
-        bool detchAwayReasonEnabled;
+        bool detachAwayReasonEnabled;
         QString ident;
         QString kickReason;
         QString partReason;
@@ -246,9 +246,9 @@ public:
         QString buffername;
         QString buffercname;
         int buffertype;
-        int lastmsgid;
-        int lastseenmsgid;
-        int markerlinemsgid;
+        qint64 lastmsgid;
+        qint64 lastseenmsgid;
+        qint64 markerlinemsgid;
         int bufferactivity;
         int highlightcount;
         QString key;
@@ -262,7 +262,7 @@ public:
         BufferId bufferid;
         int type;
         int flags;
-        int senderid;
+        qint64 senderid;
         QString senderprefixes;
         QString message;
     };
index df9061d..64f4608 100644 (file)
@@ -262,8 +262,12 @@ void CoreSession::restoreSessionState()
 
 void CoreSession::addClient(RemotePeer *peer)
 {
+    signalProxy()->setTargetPeer(peer);
+
     peer->dispatch(sessionState());
     signalProxy()->addPeer(peer);
+
+    signalProxy()->setTargetPeer(nullptr);
 }
 
 
index 5bad758..48236bc 100644 (file)
@@ -1371,7 +1371,7 @@ void PostgreSqlStorage::setBufferLastSeenMsg(UserId user, const BufferId &buffer
 
     query.bindValue(":userid", user.toInt());
     query.bindValue(":bufferid", bufferId.toInt());
-    query.bindValue(":lastseenmsgid", msgId.toInt());
+    query.bindValue(":lastseenmsgid", msgId.toQint64());
     safeExec(query);
     watchQuery(query);
 }
@@ -1398,7 +1398,7 @@ QHash<BufferId, MsgId> PostgreSqlStorage::bufferLastSeenMsgIds(UserId user)
     }
 
     while (query.next()) {
-        lastSeenHash[query.value(0).toInt()] = query.value(1).toInt();
+        lastSeenHash[query.value(0).toInt()] = query.value(1).toLongLong();
     }
 
     db.commit();
@@ -1413,7 +1413,7 @@ void PostgreSqlStorage::setBufferMarkerLineMsg(UserId user, const BufferId &buff
 
     query.bindValue(":userid", user.toInt());
     query.bindValue(":bufferid", bufferId.toInt());
-    query.bindValue(":markerlinemsgid", msgId.toInt());
+    query.bindValue(":markerlinemsgid", msgId.toQint64());
     safeExec(query);
     watchQuery(query);
 }
@@ -1440,7 +1440,7 @@ QHash<BufferId, MsgId> PostgreSqlStorage::bufferMarkerLineMsgIds(UserId user)
     }
 
     while (query.next()) {
-        markerLineHash[query.value(0).toInt()] = query.value(1).toInt();
+        markerLineHash[query.value(0).toInt()] = query.value(1).toLongLong();
     }
 
     db.commit();
@@ -1493,7 +1493,7 @@ Message::Types PostgreSqlStorage::bufferActivity(BufferId bufferId, MsgId lastSe
     QSqlQuery query(logDb());
     query.prepare(queryString("select_buffer_bufferactivity"));
     query.bindValue(":bufferid", bufferId.toInt());
-    query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+    query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64());
     safeExec(query);
     watchQuery(query);
     Message::Types result = Message::Types(0);
@@ -1586,7 +1586,7 @@ 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());
+    query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64());
     safeExec(query);
     watchQuery(query);
     int result = int(0);
@@ -1609,9 +1609,9 @@ bool PostgreSqlStorage::logMessage(Message &msg)
                  << msg.realName()
                  << msg.avatarUrl();
     QSqlQuery getSenderIdQuery = executePreparedQuery("select_senderid", senderParams, db);
-    int senderId;
+    qint64 senderId;
     if (getSenderIdQuery.first()) {
-        senderId = getSenderIdQuery.value(0).toInt();
+        senderId = getSenderIdQuery.value(0).toLongLong();
     }
     else {
         // it's possible that the sender was already added by another thread
@@ -1624,12 +1624,12 @@ bool PostgreSqlStorage::logMessage(Message &msg)
             getSenderIdQuery = executePreparedQuery("select_senderid", senderParams, db);
             watchQuery(getSenderIdQuery);
             getSenderIdQuery.first();
-            senderId = getSenderIdQuery.value(0).toInt();
+            senderId = getSenderIdQuery.value(0).toLongLong();
         }
         else {
             releaseSavePoint("sender_sp1", db);
             addSenderQuery.first();
-            senderId = addSenderQuery.value(0).toInt();
+            senderId = addSenderQuery.value(0).toLongLong();
         }
     }
 
@@ -1649,7 +1649,7 @@ bool PostgreSqlStorage::logMessage(Message &msg)
     }
 
     logMessageQuery.first();
-    MsgId msgId = logMessageQuery.value(0).toInt();
+    MsgId msgId = logMessageQuery.value(0).toLongLong();
     db.commit();
     if (msgId.isValid()) {
         msg.setMsgId(msgId);
@@ -1671,7 +1671,7 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
     }
 
     QList<int> senderIdList;
-    QHash<SenderData, int> senderIds;
+    QHash<SenderData, qint64> senderIds;
     QSqlQuery addSenderQuery;
     QSqlQuery selectSenderQuery;;
     for (int i = 0; i < msgs.count(); i++) {
@@ -1689,8 +1689,8 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
 
         selectSenderQuery = executePreparedQuery("select_senderid", senderParams, db);
         if (selectSenderQuery.first()) {
-            senderIdList << selectSenderQuery.value(0).toInt();
-            senderIds[sender] = selectSenderQuery.value(0).toInt();
+            senderIdList << selectSenderQuery.value(0).toLongLong();
+            senderIds[sender] = selectSenderQuery.value(0).toLongLong();
         }
         else {
             savePoint("sender_sp", db);
@@ -1701,14 +1701,14 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
                 selectSenderQuery = executePreparedQuery("select_senderid", senderParams, db);
                 watchQuery(selectSenderQuery);
                 selectSenderQuery.first();
-                senderIdList << selectSenderQuery.value(0).toInt();
-                senderIds[sender] = selectSenderQuery.value(0).toInt();
+                senderIdList << selectSenderQuery.value(0).toLongLong();
+                senderIds[sender] = selectSenderQuery.value(0).toLongLong();
             }
             else {
                 releaseSavePoint("sender_sp", db);
                 addSenderQuery.first();
-                senderIdList << addSenderQuery.value(0).toInt();
-                senderIds[sender] = addSenderQuery.value(0).toInt();
+                senderIdList << addSenderQuery.value(0).toLongLong();
+                senderIds[sender] = addSenderQuery.value(0).toLongLong();
             }
         }
     }
@@ -1733,7 +1733,7 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
         }
         else {
             logMessageQuery.first();
-            msg.setMsgId(logMessageQuery.value(0).toInt());
+            msg.setMsgId(logMessageQuery.value(0).toLongLong());
         }
     }
 
@@ -1774,12 +1774,12 @@ QList<Message> PostgreSqlStorage::requestMsgs(UserId user, BufferId bufferId, Ms
     }
     else if (last == -1) {
         queryName = "select_messagesNewerThan";
-        params << first.toInt();
+        params << first.toQint64();
     }
     else {
         queryName = "select_messagesRange";
-        params << first.toInt();
-        params << last.toInt();
+        params << first.toQint64();
+        params << last.toQint64();
     }
     params << bufferId.toInt();
     if (limit != -1)
@@ -1808,7 +1808,7 @@ QList<Message> PostgreSqlStorage::requestMsgs(UserId user, BufferId bufferId, Ms
             query.value(6).toString(),
             query.value(7).toString(),
             (Message::Flags)query.value(3).toUInt());
-        msg.setMsgId(query.value(0).toInt());
+        msg.setMsgId(query.value(0).toLongLong());
         messagelist << msg;
     }
 
@@ -1839,11 +1839,11 @@ QList<Message> PostgreSqlStorage::requestMsgsFiltered(UserId user, BufferId buff
         query.prepare(queryString("select_messagesNewestK_filtered"));
     } else if (last == -1) {
         query.prepare(queryString("select_messagesNewerThan_filtered"));
-        query.bindValue(":first", first.toInt());
+        query.bindValue(":first", first.toQint64());
     } else {
         query.prepare(queryString("select_messagesRange_filtered"));
-        query.bindValue(":last", last.toInt());
-        query.bindValue(":first", first.toInt());
+        query.bindValue(":last", last.toQint64());
+        query.bindValue(":first", first.toQint64());
     }
     query.bindValue(":buffer", bufferId.toInt());
     query.bindValue(":limit", limit);
@@ -1872,7 +1872,7 @@ QList<Message> PostgreSqlStorage::requestMsgsFiltered(UserId user, BufferId buff
                     query.value(6).toString(),
                     query.value(7).toString(),
                     Message::Flags{query.value(3).toInt()});
-        msg.setMsgId(query.value(0).toInt());
+        msg.setMsgId(query.value(0).toLongLong());
         messagelist << msg;
     }
 
@@ -1904,10 +1904,10 @@ QList<Message> PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId
     }
     else {
         query.prepare(queryString("select_messagesAll"));
-        query.bindValue(":lastmsg", last.toInt());
+        query.bindValue(":lastmsg", last.toQint64());
     }
     query.bindValue(":userid", user.toInt());
-    query.bindValue(":firstmsg", first.toInt());
+    query.bindValue(":firstmsg", first.toQint64());
     safeExec(query);
     if (!watchQuery(query)) {
         db.rollback();
@@ -1927,7 +1927,7 @@ QList<Message> PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId
             query.value(7).toString(),
             query.value(8).toString(),
             (Message::Flags)query.value(4).toUInt());
-        msg.setMsgId(query.value(0).toInt());
+        msg.setMsgId(query.value(0).toLongLong());
         messagelist << msg;
     }
 
@@ -1959,10 +1959,10 @@ QList<Message> PostgreSqlStorage::requestAllMsgsFiltered(UserId user, MsgId firs
     }
     else {
         query.prepare(queryString("select_messagesAll_filtered"));
-        query.bindValue(":lastmsg", last.toInt());
+        query.bindValue(":lastmsg", last.toQint64());
     }
     query.bindValue(":userid", user.toInt());
-    query.bindValue(":firstmsg", first.toInt());
+    query.bindValue(":firstmsg", first.toQint64());
 
     int typeRaw = type;
     query.bindValue(":type", typeRaw);
@@ -1989,7 +1989,7 @@ QList<Message> PostgreSqlStorage::requestAllMsgsFiltered(UserId user, MsgId firs
                     query.value(7).toString(),
                     query.value(8).toString(),
                     Message::Flags{query.value(4).toInt()});
-        msg.setMsgId(query.value(0).toInt());
+        msg.setMsgId(query.value(0).toLongLong());
         messagelist << msg;
     }
 
@@ -2288,7 +2288,7 @@ bool PostgreSqlMigrationWriter::writeMo(const IdentityMO &identity)
     bindValue(11, identity.autoAwayReasonEnabled);
     bindValue(12, identity.detachAwayEnabled);
     bindValue(13, identity.detachAwayReason);
-    bindValue(14, identity.detchAwayReasonEnabled);
+    bindValue(14, identity.detachAwayReasonEnabled);
     bindValue(15, identity.ident);
     bindValue(16, identity.kickReason);
     bindValue(17, identity.partReason);
@@ -2374,7 +2374,7 @@ bool PostgreSqlMigrationWriter::writeMo(const BufferMO &buffer)
 //bool PostgreSqlMigrationWriter::writeBacklog(const BacklogMO &backlog) {
 bool PostgreSqlMigrationWriter::writeMo(const BacklogMO &backlog)
 {
-    bindValue(0, backlog.messageid.toInt());
+    bindValue(0, backlog.messageid.toQint64());
     bindValue(1, backlog.time);
     bindValue(2, backlog.bufferid.toInt());
     bindValue(3, backlog.type);
index d9578c0..fa20173 100644 (file)
     <file>./SQL/PostgreSQL/version/27/upgrade_020_update_sender_add_new_constraint.sql</file>
     <file>./SQL/PostgreSQL/version/27/upgrade_030_upgrade_sender_drop_old_constraint.sql</file>
     <file>./SQL/PostgreSQL/version/28/upgrade_000_create_corestate.sql</file>
+    <file>./SQL/PostgreSQL/version/29/upgrade_010_alter_sender_64bit_ids.sql</file>
+    <file>./SQL/PostgreSQL/version/29/upgrade_050_alter_buffer_64bit_ids.sql</file>
+    <file>./SQL/PostgreSQL/version/29/upgrade_060_alter_backlog_64bit_ids.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>
index 7694021..6fe8ffd 100644 (file)
@@ -1468,7 +1468,7 @@ void SqliteStorage::setBufferLastSeenMsg(UserId user, const BufferId &bufferId,
         query.prepare(queryString("update_buffer_lastseen"));
         query.bindValue(":userid", user.toInt());
         query.bindValue(":bufferid", bufferId.toInt());
-        query.bindValue(":lastseenmsgid", msgId.toInt());
+        query.bindValue(":lastseenmsgid", msgId.toQint64());
 
         lockForWrite();
         safeExec(query);
@@ -1497,7 +1497,7 @@ QHash<BufferId, MsgId> SqliteStorage::bufferLastSeenMsgIds(UserId user)
         error = !watchQuery(query);
         if (!error) {
             while (query.next()) {
-                lastSeenHash[query.value(0).toInt()] = query.value(1).toInt();
+                lastSeenHash[query.value(0).toInt()] = query.value(1).toLongLong();
             }
         }
     }
@@ -1518,7 +1518,7 @@ void SqliteStorage::setBufferMarkerLineMsg(UserId user, const BufferId &bufferId
         query.prepare(queryString("update_buffer_markerlinemsgid"));
         query.bindValue(":userid", user.toInt());
         query.bindValue(":bufferid", bufferId.toInt());
-        query.bindValue(":markerlinemsgid", msgId.toInt());
+        query.bindValue(":markerlinemsgid", msgId.toQint64());
 
         lockForWrite();
         safeExec(query);
@@ -1547,7 +1547,7 @@ QHash<BufferId, MsgId> SqliteStorage::bufferMarkerLineMsgIds(UserId user)
         error = !watchQuery(query);
         if (!error) {
             while (query.next()) {
-                markerLineHash[query.value(0).toInt()] = query.value(1).toInt();
+                markerLineHash[query.value(0).toInt()] = query.value(1).toLongLong();
             }
         }
     }
@@ -1617,7 +1617,7 @@ Message::Types SqliteStorage::bufferActivity(BufferId bufferId, MsgId lastSeenMs
         QSqlQuery query(db);
         query.prepare(queryString("select_buffer_bufferactivity"));
         query.bindValue(":bufferid", bufferId.toInt());
-        query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+        query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64());
 
         lockForRead();
         safeExec(query);
@@ -1734,7 +1734,7 @@ int SqliteStorage::highlightCount(BufferId bufferId, MsgId lastSeenMsgId)
         QSqlQuery query(db);
         query.prepare(queryString("select_buffer_highlightcount"));
         query.bindValue(":bufferid", bufferId.toInt());
-        query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+        query.bindValue(":lastseenmsgid", lastSeenMsgId.toQint64());
 
         lockForRead();
         safeExec(query);
@@ -1787,7 +1787,7 @@ bool SqliteStorage::logMessage(Message &msg)
             }
         }
         if (!error) {
-            MsgId msgId = logMessageQuery.lastInsertId().toInt();
+            MsgId msgId = logMessageQuery.lastInsertId().toLongLong();
             if (msgId.isValid()) {
                 msg.setMsgId(msgId);
             }
@@ -1856,7 +1856,7 @@ bool SqliteStorage::logMessages(MessageList &msgs)
                 break;
             }
             else {
-                msg.setMsgId(logMessageQuery.lastInsertId().toInt());
+                msg.setMsgId(logMessageQuery.lastInsertId().toLongLong());
             }
         }
     }
@@ -1887,7 +1887,7 @@ QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId
     bool error = false;
     BufferInfo bufferInfo;
     {
-        // code dupication from getBufferInfo:
+        // code duplication from getBufferInfo:
         // this is due to the impossibility of nesting transactions and recursive locking
         QSqlQuery bufferInfoQuery(db);
         bufferInfoQuery.prepare(queryString("select_buffer_by_id"));
@@ -1915,12 +1915,12 @@ QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId
         }
         else if (last == -1) {
             query.prepare(queryString("select_messagesNewerThan"));
-            query.bindValue(":firstmsg", first.toInt());
+            query.bindValue(":firstmsg", first.toQint64());
         }
         else {
             query.prepare(queryString("select_messagesRange"));
-            query.bindValue(":lastmsg", last.toInt());
-            query.bindValue(":firstmsg", first.toInt());
+            query.bindValue(":lastmsg", last.toQint64());
+            query.bindValue(":firstmsg", first.toQint64());
         }
         query.bindValue(":bufferid", bufferId.toInt());
         query.bindValue(":limit", limit);
@@ -1938,7 +1938,7 @@ QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId
                 query.value(6).toString(),
                 query.value(7).toString(),
                 (Message::Flags)query.value(3).toUInt());
-            msg.setMsgId(query.value(0).toInt());
+            msg.setMsgId(query.value(0).toLongLong());
             messagelist << msg;
         }
     }
@@ -1987,12 +1987,12 @@ QList<Message> SqliteStorage::requestMsgsFiltered(UserId user, BufferId bufferId
         }
         else if (last == -1) {
             query.prepare(queryString("select_messagesNewerThan_filtered"));
-            query.bindValue(":firstmsg", first.toInt());
+            query.bindValue(":firstmsg", first.toQint64());
         }
         else {
             query.prepare(queryString("select_messagesRange_filtered"));
-            query.bindValue(":lastmsg", last.toInt());
-            query.bindValue(":firstmsg", first.toInt());
+            query.bindValue(":lastmsg", last.toQint64());
+            query.bindValue(":firstmsg", first.toQint64());
         }
         query.bindValue(":bufferid", bufferId.toInt());
         query.bindValue(":limit", limit);
@@ -2014,7 +2014,7 @@ QList<Message> SqliteStorage::requestMsgsFiltered(UserId user, BufferId bufferId
                         query.value(6).toString(),
                         query.value(7).toString(),
                         Message::Flags{query.value(3).toInt()});
-            msg.setMsgId(query.value(0).toInt());
+            msg.setMsgId(query.value(0).toLongLong());
             messagelist << msg;
         }
     }
@@ -2052,10 +2052,10 @@ QList<Message> SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las
         }
         else {
             query.prepare(queryString("select_messagesAll"));
-            query.bindValue(":lastmsg", last.toInt());
+            query.bindValue(":lastmsg", last.toQint64());
         }
         query.bindValue(":userid", user.toInt());
-        query.bindValue(":firstmsg", first.toInt());
+        query.bindValue(":firstmsg", first.toQint64());
         query.bindValue(":limit", limit);
         safeExec(query);
 
@@ -2071,7 +2071,7 @@ QList<Message> SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las
                 query.value(7).toString(),
                 query.value(8).toString(),
                 (Message::Flags)query.value(4).toUInt());
-            msg.setMsgId(query.value(0).toInt());
+            msg.setMsgId(query.value(0).toLongLong());
             messagelist << msg;
         }
     }
@@ -2107,10 +2107,10 @@ QList<Message> SqliteStorage::requestAllMsgsFiltered(UserId user, MsgId first, M
         }
         else {
             query.prepare(queryString("select_messagesAll_filtered"));
-            query.bindValue(":lastmsg", last.toInt());
+            query.bindValue(":lastmsg", last.toQint64());
         }
         query.bindValue(":userid", user.toInt());
-        query.bindValue(":firstmsg", first.toInt());
+        query.bindValue(":firstmsg", first.toQint64());
         query.bindValue(":limit", limit);
         int typeRaw = type;
         query.bindValue(":type", typeRaw);
@@ -2130,7 +2130,7 @@ QList<Message> SqliteStorage::requestAllMsgsFiltered(UserId user, MsgId first, M
                         query.value(7).toString(),
                         query.value(8).toString(),
                         Message::Flags{query.value(4).toInt()});
-            msg.setMsgId(query.value(0).toInt());
+            msg.setMsgId(query.value(0).toLongLong());
             messagelist << msg;
         }
     }
@@ -2234,7 +2234,7 @@ void SqliteMigrationReader::setMaxId(MigrationObject mo)
     }
     QSqlQuery query = logDb().exec(queryString);
     query.first();
-    _maxId = query.value(0).toInt();
+    _maxId = query.value(0).toLongLong();
 }
 
 
@@ -2315,7 +2315,7 @@ bool SqliteMigrationReader::readMo(IdentityMO &identity)
     identity.autoAwayReasonEnabled = value(11).toInt() == 1 ? true : false;
     identity.detachAwayEnabled = value(12).toInt() == 1 ? true : false;
     identity.detachAwayReason = value(13).toString();
-    identity.detchAwayReasonEnabled = value(14).toInt() == 1 ? true : false;
+    identity.detachAwayReasonEnabled = value(14).toInt() == 1 ? true : false;
     identity.ident = value(15).toString();
     identity.kickReason = value(16).toString();
     identity.partReason = value(17).toString();
@@ -2389,9 +2389,9 @@ bool SqliteMigrationReader::readMo(BufferMO &buffer)
     buffer.buffername = value(4).toString();
     buffer.buffercname = value(5).toString();
     buffer.buffertype = value(6).toInt();
-    buffer.lastmsgid = value(7).toInt();
-    buffer.lastseenmsgid = value(8).toInt();
-    buffer.markerlinemsgid = value(9).toInt();
+    buffer.lastmsgid = value(7).toLongLong();
+    buffer.lastseenmsgid = value(8).toLongLong();
+    buffer.markerlinemsgid = value(9).toLongLong();
     buffer.bufferactivity = value(10).toInt();
     buffer.highlightcount = value(11).toInt();
     buffer.key = value(12).toString();
@@ -2417,7 +2417,7 @@ bool SqliteMigrationReader::readMo(SenderMO &sender)
         }
     }
 
-    sender.senderId = value(0).toInt();
+    sender.senderId = value(0).toLongLong();
     sender.sender = value(1).toString();
     sender.realname = value(2).toString();
     sender.avatarurl = value(3).toString();
@@ -2430,8 +2430,8 @@ bool SqliteMigrationReader::readMo(BacklogMO &backlog)
     int skipSteps = 0;
     while (!next()) {
         if (backlog.messageid < _maxId) {
-            bindValue(0, backlog.messageid.toInt() + (skipSteps * stepSize()));
-            bindValue(1, backlog.messageid.toInt() + ((skipSteps + 1) * stepSize()));
+            bindValue(0, backlog.messageid.toQint64() + (skipSteps * stepSize()));
+            bindValue(1, backlog.messageid.toQint64() + ((skipSteps + 1) * stepSize()));
             skipSteps++;
             if (!exec())
                 return false;
@@ -2441,12 +2441,12 @@ bool SqliteMigrationReader::readMo(BacklogMO &backlog)
         }
     }
 
-    backlog.messageid = value(0).toInt();
+    backlog.messageid = value(0).toLongLong();
     backlog.time = QDateTime::fromTime_t(value(1).toInt()).toUTC();
     backlog.bufferid = value(2).toInt();
     backlog.type = value(3).toInt();
     backlog.flags = value(4).toInt();
-    backlog.senderid = value(5).toInt();
+    backlog.senderid = value(5).toLongLong();
     backlog.senderprefixes = value(6).toString();
     backlog.message = value(7).toString();
     return true;
index 9a37160..f72a839 100644 (file)
@@ -184,7 +184,7 @@ protected:
 
 private:
     void setMaxId(MigrationObject mo);
-    int _maxId;
+    qint64 _maxId;
 };
 
 
index 1fc8f60..fb5d6fa 100644 (file)
@@ -245,7 +245,7 @@ void ChatItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
 //   }
 // 2) draw MsgId over the time column
 //   if(column() == 0) {
-//     QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value<MsgId>().toInt());
+//     QString msgIdString = QString::number(data(MessageModel::MsgIdRole).value<MsgId>().toLongLong());
 //     QPointF bottomPoint = boundingRect().bottomLeft();
 //     bottomPoint.ry() -= 2;
 //     painter->drawText(bottomPoint, msgIdString);
index ba33c46..292ab48 100644 (file)
@@ -55,5 +55,5 @@ QVariant DebugMessageModelFilter::data(const QModelIndex &index, int role) const
         return QVariant();
 
     QModelIndex source_index = mapToSource(index);
-    return sourceModel()->data(source_index, MessageModel::MsgIdRole).value<MsgId>().toInt();
+    return sourceModel()->data(source_index, MessageModel::MsgIdRole).value<MsgId>().toQint64();
 }