[PR-540] Allow loading backlog in reverse direction
[quassel.git] / src / core / postgresqlstorage.cpp
index 88bc86c..36301c6 100644 (file)
@@ -49,7 +49,7 @@ bool PostgreSqlStorage::isAvailable() const
 {
     if (!QSqlDatabase::isDriverAvailable("QPSQL")) {
         qWarning() << qPrintable(tr("PostgreSQL driver plugin not available for Qt. Installed drivers:"))
-                    << qPrintable(QSqlDatabase::drivers().join(", "));
+                   << qPrintable(QSqlDatabase::drivers().join(", "));
         return false;
     }
     return true;
@@ -115,7 +115,8 @@ bool PostgreSqlStorage::initDbSession(QSqlDatabase& db)
         break;
     default:
         // The slash got replaced with 0 or more than 2 slashes! o_O
-        qCritical() << "Your version of Qt does something _VERY_ strange to slashes in QSqlQueries! You should consult your trusted doctor!";
+        qCritical()
+            << "Your version of Qt does something _VERY_ strange to slashes in QSqlQueries! You should consult your trusted doctor!";
         return false;
         break;
     }
@@ -1907,6 +1908,82 @@ std::vector<Message> PostgreSqlStorage::requestMsgsFiltered(
     return messagelist;
 }
 
+std::vector<Message> PostgreSqlStorage::requestMsgsForward(
+    UserId user, BufferId bufferId, MsgId first, MsgId last, int limit, Message::Types type, Message::Flags flags)
+{
+    std::vector<Message> messagelist;
+
+    QSqlDatabase db = logDb();
+    if (!beginReadOnlyTransaction(db)) {
+        qWarning() << "PostgreSqlStorage::requestMsgsForward(): cannot start read only transaction!";
+        qWarning() << " -" << qPrintable(db.lastError().text());
+        return messagelist;
+    }
+
+    BufferInfo bufferInfo = getBufferInfo(user, bufferId);
+    if (!bufferInfo.isValid()) {
+        db.rollback();
+        return messagelist;
+    }
+
+    QString queryName;
+    QVariantList params;
+
+    if (first == -1) {
+        params << std::numeric_limits<qint64>::min();
+    } else {
+        params << first.toQint64();
+    }
+
+    if (last == -1) {
+        params << std::numeric_limits<qint64>::max();
+    } else {
+        params << last.toQint64();
+    }
+
+    params << bufferId.toInt();
+
+    int typeRaw = type;
+    int flagsRaw = flags;
+    params << typeRaw;
+    params << flagsRaw;
+
+    if (limit != -1)
+        params << limit;
+    else
+        params << QVariant(QVariant::Int);
+
+    QSqlQuery query = executePreparedQuery("select_messagesForward", params, db);
+
+    if (!watchQuery(query)) {
+        qDebug() << "select_messages failed";
+        db.rollback();
+        return messagelist;
+    }
+
+    QDateTime timestamp;
+    while (query.next()) {
+        // PostgreSQL returns date/time in ISO 8601 format, no 64-bit handling needed
+        // See https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-DATETIME-OUTPUT
+        timestamp = query.value(1).toDateTime();
+        timestamp.setTimeSpec(Qt::UTC);
+        Message msg(timestamp,
+                    bufferInfo,
+                    (Message::Type)query.value(2).toInt(),
+                    query.value(8).toString(),
+                    query.value(4).toString(),
+                    query.value(5).toString(),
+                    query.value(6).toString(),
+                    query.value(7).toString(),
+                    (Message::Flags)query.value(3).toInt());
+        msg.setMsgId(query.value(0).toLongLong());
+        messagelist.push_back(std::move(msg));
+    }
+
+    db.commit();
+    return messagelist;
+}
+
 std::vector<Message> PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId last, int limit)
 {
     std::vector<Message> messagelist;