|
|
|
|
@ -6,18 +6,13 @@
|
|
|
|
|
#include <cstring> |
|
|
|
|
#include <QSet> |
|
|
|
|
#include <QElapsedTimer> |
|
|
|
|
#include <QJsonDocument> |
|
|
|
|
#include <QJsonObject> |
|
|
|
|
|
|
|
|
|
/* ── helpers ── */ |
|
|
|
|
|
|
|
|
|
static QByteArray parseJsonField(const QByteArray& json, const char* key) { |
|
|
|
|
QByteArray pat = "\"" + QByteArray(key) + "\":\""; |
|
|
|
|
int idx = json.indexOf(pat); |
|
|
|
|
if (idx < 0) return {}; |
|
|
|
|
idx += pat.size(); |
|
|
|
|
int end = idx; |
|
|
|
|
while (end < json.size() && !(json[end] == '"' && (end == idx || json[end - 1] != '\\'))) end++; |
|
|
|
|
if (end > idx) return QByteArray(json.constData() + idx, end - idx); |
|
|
|
|
return {}; |
|
|
|
|
return QJsonDocument::fromJson(json).object().value(QString::fromLatin1(key)).toString().toUtf8(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
QString DbManager::sanitizeTableName(const QString& chId) { |
|
|
|
|
@ -239,7 +234,7 @@ QString DbManager::getChannelLastMessage(const QString& channelId) const {
|
|
|
|
|
QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const { |
|
|
|
|
QList<MessageRow> list; |
|
|
|
|
QString sql = QStringLiteral( |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs" |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id" |
|
|
|
|
" FROM \"%1\" ORDER BY timestamp DESC, author_signature DESC LIMIT ?").arg(msgTableName(chId)); |
|
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
|
if (!stmt) return list; |
|
|
|
|
@ -259,6 +254,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const {
|
|
|
|
|
m.datahash = 0; |
|
|
|
|
m.chainHash = colBlob(stmt, 4); |
|
|
|
|
m.signature = colBlob(stmt, 5); |
|
|
|
|
m.messageId = colBlob(stmt, 7); |
|
|
|
|
m.localAttrs = QByteArray((const char*)sqlite3_column_text(stmt, 6)); |
|
|
|
|
m.isOutgoing = (m.authorNodeId == myId); |
|
|
|
|
m.isRead = true; |
|
|
|
|
@ -271,7 +267,7 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const {
|
|
|
|
|
QList<MessageRow> DbManager::getMessagesSince(const QString& chId, qint64 sinceId) const { |
|
|
|
|
QList<MessageRow> list; |
|
|
|
|
QString sql = QStringLiteral( |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs" |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id" |
|
|
|
|
" FROM \"%1\" WHERE id > ? ORDER BY id ASC").arg(msgTableName(chId)); |
|
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
|
if (!stmt) return list; |
|
|
|
|
@ -289,6 +285,7 @@ QList<MessageRow> DbManager::getMessagesSince(const QString& chId, qint64 sinceI
|
|
|
|
|
m.datahash = 0; |
|
|
|
|
m.chainHash = colBlob(stmt, 4); |
|
|
|
|
m.signature = colBlob(stmt, 5); |
|
|
|
|
m.messageId = colBlob(stmt, 7); |
|
|
|
|
m.localAttrs = QByteArray((const char*)sqlite3_column_text(stmt, 6)); |
|
|
|
|
m.isOutgoing = (m.authorNodeId == myId); |
|
|
|
|
m.isRead = true; |
|
|
|
|
@ -301,7 +298,7 @@ QList<MessageRow> DbManager::getMessagesSince(const QString& chId, qint64 sinceI
|
|
|
|
|
MessageRow DbManager::getMessageById(const QString& chId, qint64 msgId) const { |
|
|
|
|
MessageRow m; |
|
|
|
|
QString sql = QStringLiteral( |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs" |
|
|
|
|
"SELECT id, node_id, data, timestamp, chain_hash, author_signature, local_attrs, message_id" |
|
|
|
|
" FROM \"%1\" WHERE id = ?").arg(msgTableName(chId)); |
|
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
|
if (!stmt) return m; |
|
|
|
|
@ -317,6 +314,7 @@ MessageRow DbManager::getMessageById(const QString& chId, qint64 msgId) const {
|
|
|
|
|
m.datahash = 0; |
|
|
|
|
m.chainHash = colBlob(stmt, 4); |
|
|
|
|
m.signature = colBlob(stmt, 5); |
|
|
|
|
m.messageId = colBlob(stmt, 7); |
|
|
|
|
m.localAttrs = QByteArray((const char*)sqlite3_column_text(stmt, 6)); |
|
|
|
|
m.isOutgoing = (m.authorNodeId == m_myNodeId); |
|
|
|
|
m.isRead = true; |
|
|
|
|
|