|
|
|
@ -8,6 +8,17 @@ |
|
|
|
|
|
|
|
|
|
|
|
/* ── helpers ── */ |
|
|
|
/* ── 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 {}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QString DbManager::sanitizeTableName(const QString& chId) { |
|
|
|
QString DbManager::sanitizeTableName(const QString& chId) { |
|
|
|
QString s; |
|
|
|
QString s; |
|
|
|
s.reserve(chId.size()); |
|
|
|
s.reserve(chId.size()); |
|
|
|
@ -136,17 +147,6 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const { |
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
if (!stmt) return list; |
|
|
|
if (!stmt) return list; |
|
|
|
sqlite3_bind_int(stmt, 1, limit); |
|
|
|
sqlite3_bind_int(stmt, 1, limit); |
|
|
|
/* helper: parse JSON field from data column: {"n":<id>,"ch":"<id>","ct":"<>","d":"<>"} */ |
|
|
|
|
|
|
|
auto parseJsonField = [](const QByteArray& json, const char* key) -> QByteArray { |
|
|
|
|
|
|
|
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 {}; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
uint64_t myId = 0; |
|
|
|
uint64_t myId = 0; |
|
|
|
{ sqlite3_stmt* ms = prepareOrNull("SELECT node_id FROM local_identity WHERE id=1"); |
|
|
|
{ sqlite3_stmt* ms = prepareOrNull("SELECT node_id FROM local_identity WHERE id=1"); |
|
|
|
if (ms) { if (sqlite3_step(ms) == SQLITE_ROW) myId = (uint64_t)sqlite3_column_int64(ms, 0); sqlite3_finalize(ms); } } |
|
|
|
if (ms) { if (sqlite3_step(ms) == SQLITE_ROW) myId = (uint64_t)sqlite3_column_int64(ms, 0); sqlite3_finalize(ms); } } |
|
|
|
@ -170,6 +170,33 @@ QList<MessageRow> DbManager::getMessages(const QString& chId, int limit) const { |
|
|
|
return list; |
|
|
|
return list; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
|
|
" FROM \"%1\" WHERE id > ? ORDER BY id ASC").arg(msgTableName(chId)); |
|
|
|
|
|
|
|
sqlite3_stmt* stmt = prepareOrNull(sql.toUtf8().constData()); |
|
|
|
|
|
|
|
if (!stmt) return list; |
|
|
|
|
|
|
|
sqlite3_bind_int64(stmt, 1, sinceId); |
|
|
|
|
|
|
|
uint64_t myId = m_myNodeId; |
|
|
|
|
|
|
|
while (sqlite3_step(stmt) == SQLITE_ROW) { |
|
|
|
|
|
|
|
MessageRow m; |
|
|
|
|
|
|
|
m.id = sqlite3_column_int64(stmt, 0); |
|
|
|
|
|
|
|
m.authorNodeId = (quint64)sqlite3_column_int64(stmt, 1); |
|
|
|
|
|
|
|
QByteArray jdata = colBlob(stmt, 2); |
|
|
|
|
|
|
|
m.data = parseJsonField(jdata, "d"); |
|
|
|
|
|
|
|
m.timestamp = sqlite3_column_int64(stmt, 3); |
|
|
|
|
|
|
|
m.datahash = 0; |
|
|
|
|
|
|
|
m.chainHash = colBlob(stmt, 4); |
|
|
|
|
|
|
|
m.signature = colBlob(stmt, 5); |
|
|
|
|
|
|
|
m.isOutgoing = (m.authorNodeId == myId); |
|
|
|
|
|
|
|
m.isRead = true; |
|
|
|
|
|
|
|
list.append(m); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
sqlite3_finalize(stmt); |
|
|
|
|
|
|
|
return list; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ── peers (UI) ── */ |
|
|
|
/* ── peers (UI) ── */ |
|
|
|
|
|
|
|
|
|
|
|
int DbManager::getChannelMemberCount(const QString& chId) const { |
|
|
|
int DbManager::getChannelMemberCount(const QString& chId) const { |
|
|
|
|