Improve performance of PostgreSQL for large databases.
[quassel.git] / src / core / postgresqlstorage.cpp
index 68cf254..05da7a1 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-2015 by the Quassel Project                        *
+ *   Copyright (C) 2005-2016 by the Quassel Project                        *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -697,6 +697,11 @@ void PostgreSqlStorage::bindNetworkInfo(QSqlQuery &query, const NetworkInfo &inf
     query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
     query.bindValue(":unlimitedconnectretries", info.unlimitedReconnectRetries);
     query.bindValue(":rejoinchannels", info.rejoinChannels);
+    // Custom rate limiting
+    query.bindValue(":usecustomessagerate", info.useCustomMessageRate);
+    query.bindValue(":messagerateburstsize", info.messageRateBurstSize);
+    query.bindValue(":messageratedelay", info.messageRateDelay);
+    query.bindValue(":unlimitedmessagerate", info.unlimitedMessageRate);
     if (info.networkId.isValid())
         query.bindValue(":networkid", info.networkId.toInt());
 }
@@ -715,6 +720,7 @@ void PostgreSqlStorage::bindServerInfo(QSqlQuery &query, const Network::Server &
     query.bindValue(":proxyport", server.proxyPort);
     query.bindValue(":proxyuser", server.proxyUser);
     query.bindValue(":proxypass", server.proxyPass);
+    query.bindValue(":sslverify", server.sslVerify);
 }
 
 
@@ -842,6 +848,11 @@ QList<NetworkInfo> PostgreSqlStorage::networks(UserId user)
         net.useSasl = networksQuery.value(16).toBool();
         net.saslAccount = networksQuery.value(17).toString();
         net.saslPassword = networksQuery.value(18).toString();
+        // Custom rate limiting
+        net.useCustomMessageRate = networksQuery.value(19).toBool();
+        net.messageRateBurstSize = networksQuery.value(20).toUInt();
+        net.messageRateDelay = networksQuery.value(21).toUInt();
+        net.unlimitedMessageRate = networksQuery.value(22).toBool();
 
         serversQuery.bindValue(":networkid", net.networkId.toInt());
         safeExec(serversQuery);
@@ -864,6 +875,7 @@ QList<NetworkInfo> PostgreSqlStorage::networks(UserId user)
             server.proxyPort = serversQuery.value(8).toUInt();
             server.proxyUser = serversQuery.value(9).toString();
             server.proxyPass = serversQuery.value(10).toString();
+            server.sslVerify = serversQuery.value(11).toBool();
             servers << server;
         }
         net.serverList = servers;
@@ -944,7 +956,7 @@ void PostgreSqlStorage::setChannelPersistent(UserId user, const NetworkId &netwo
     QSqlQuery query(logDb());
     query.prepare(queryString("update_buffer_persistent_channel"));
     query.bindValue(":userid", user.toInt());
-    query.bindValue(":networkId", networkId.toInt());
+    query.bindValue(":networkid", networkId.toInt());
     query.bindValue(":buffercname", channel.toLower());
     query.bindValue(":joined", isJoined);
     safeExec(query);
@@ -957,7 +969,7 @@ void PostgreSqlStorage::setPersistentChannelKey(UserId user, const NetworkId &ne
     QSqlQuery query(logDb());
     query.prepare(queryString("update_buffer_set_channel_key"));
     query.bindValue(":userid", user.toInt());
-    query.bindValue(":networkId", networkId.toInt());
+    query.bindValue(":networkid", networkId.toInt());
     query.bindValue(":buffercname", channel.toLower());
     query.bindValue(":key", key);
     safeExec(query);
@@ -1358,6 +1370,16 @@ QHash<BufferId, MsgId> PostgreSqlStorage::bufferMarkerLineMsgIds(UserId user)
     return markerLineHash;
 }
 
+void PostgreSqlStorage::setBufferLastMsg(const BufferId &bufferId, const MsgId &msgId)
+{
+    QSqlQuery query(logDb());
+    query.prepare(queryString("update_buffer_lastmsgid"));
+
+    query.bindValue(":bufferid", bufferId.toInt());
+    query.bindValue(":lastmsgid", msgId.toInt());
+    safeExec(query);
+    watchQuery(query);
+}
 
 bool PostgreSqlStorage::logMessage(Message &msg)
 {
@@ -1381,8 +1403,7 @@ bool PostgreSqlStorage::logMessage(Message &msg)
 
         if (addSenderQuery.lastError().isValid()) {
             rollbackSavePoint("sender_sp1", db);
-            getSenderIdQuery.prepare(getSenderIdQuery.lastQuery());
-            safeExec(getSenderIdQuery);
+            getSenderIdQuery = executePreparedQuery("select_senderid", msg.sender(), db);
             watchQuery(getSenderIdQuery);
             getSenderIdQuery.first();
             senderId = getSenderIdQuery.value(0).toInt();
@@ -1413,6 +1434,9 @@ bool PostgreSqlStorage::logMessage(Message &msg)
     db.commit();
     if (msgId.isValid()) {
         msg.setMsgId(msgId);
+
+        setBufferLastMsg(msg.bufferInfo().bufferId(), msgId);
+
         return true;
     }
     else {
@@ -1452,8 +1476,7 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs)
             if (addSenderQuery.lastError().isValid()) {
                 // seems it was inserted meanwhile... by a different thread
                 rollbackSavePoint("sender_sp", db);
-                selectSenderQuery.prepare(selectSenderQuery.lastQuery());
-                safeExec(selectSenderQuery);
+                selectSenderQuery = executePreparedQuery("select_senderid", sender, db);
                 watchQuery(selectSenderQuery);
                 selectSenderQuery.first();
                 senderIdList << selectSenderQuery.value(0).toInt();
@@ -1843,6 +1866,7 @@ bool PostgreSqlMigrationWriter::writeMo(const QuasselUserMO &user)
     bindValue(0, user.id.toInt());
     bindValue(1, user.username);
     bindValue(2, user.password);
+    bindValue(3, user.hashversion);
     return exec();
 }
 
@@ -1926,6 +1950,11 @@ bool PostgreSqlMigrationWriter::writeMo(const NetworkMO &network)
     bindValue(22, network.usesasl);
     bindValue(23, network.saslaccount);
     bindValue(24, network.saslpassword);
+    // Custom rate limiting
+    bindValue(25, network.usecustommessagerate);
+    bindValue(26, network.messagerateburstsize);
+    bindValue(27, network.messageratedelay);
+    bindValue(28, network.unlimitedmessagerate);
     return exec();
 }
 
@@ -1979,6 +2008,7 @@ bool PostgreSqlMigrationWriter::writeMo(const IrcServerMO &ircserver)
     bindValue(11, ircserver.proxyport);
     bindValue(12, ircserver.proxyuser);
     bindValue(13, ircserver.proxypass);
+    bindValue(14, ircserver.sslverify);
     return exec();
 }
 
@@ -2006,11 +2036,15 @@ bool PostgreSqlMigrationWriter::postProcess()
               << Sequence("quasseluser", "userid")
               << Sequence("sender", "senderid");
     QList<Sequence>::const_iterator iter;
-    for (iter = sequences.constBegin(); iter != sequences.constEnd(); iter++) {
+    for (iter = sequences.constBegin(); iter != sequences.constEnd(); ++iter) {
         resetQuery();
         newQuery(QString("SELECT setval('%1_%2_seq', max(%2)) FROM %1").arg(iter->table, iter->field), db);
         if (!exec())
             return false;
     }
+
+    newQuery(QString("SELECT populate_lastmsgid()"), db);
+    if (!exec())
+        return false;
     return true;
 }