Distinguish failed avatar reads from committed empty blobs

This commit is contained in:
evgeny committed 2026-10-27 11:57:30 +01:00
1 parent 95e88ac66f
commit 905d30ceaf
2 files changed
+35 -8

No files matched your search

+31 -7
View File
@@ -10,6 +10,7 @@
#include <QJsonObject>
#include <QCoreApplication>
#include "chat/chat_poll.h"
#include "chat/group_avatar.h"
/* ── helpers ── */
@@ -119,14 +120,37 @@ QList<ChannelRow> DbManager::getChannels(ChannelSortMode sort) const {
return list;
}
QByteArray DbManager::getChannelAvatar(const QString& channelId) const {
sqlite3_stmt* st = prepareOrNull("SELECT avatar_data FROM channels WHERE channel_id=?"); if (!st) return {};
const QByteArray id = channelId.toLatin1(); sqlite3_bind_text(st, 1, id.constData(), id.size(), SQLITE_TRANSIENT);
QByteArray DbManager::getChannelAvatar(const QString& channelId, bool* ok) const {
if (ok) *ok = false;
if (!m_db) { GUI_WARN("group avatar: database unavailable channel=%s", qPrintable(channelId)); return {}; }
sqlite3_stmt* st = nullptr;
const char* stage = "prepare";
int rc = sqlite3_prepare_v2(m_db, "SELECT avatar_data FROM channels WHERE channel_id=?", -1, &st, nullptr);
const QByteArray id = channelId.toLatin1();
if (rc == SQLITE_OK) { stage = "bind"; rc = sqlite3_bind_text(st, 1, id.constData(), id.size(), SQLITE_TRANSIENT); }
if (rc == SQLITE_OK) { stage = "step"; rc = sqlite3_step(st); }
QByteArray bytes;
int rc = sqlite3_step(st);
if (rc == SQLITE_ROW) bytes = colBlob(st, 0);
else if (rc != SQLITE_DONE) GUI_ERROR("group avatar: database read failed channel=%s rc=%d", qPrintable(channelId), rc);
sqlite3_finalize(st); return bytes;
int type = -1, length = 0;
if (rc == SQLITE_ROW) {
stage = "blob"; type = sqlite3_column_type(st, 0); length = sqlite3_column_bytes(st, 0);
if (type != SQLITE_BLOB) rc = SQLITE_CORRUPT;
else if (length > GROUP_AVATAR_MAX) rc = SQLITE_TOOBIG;
else {
const char* blob = static_cast<const char*>(sqlite3_column_blob(st, 0));
if (length && !blob) rc = SQLITE_NOMEM;
else bytes = QByteArray(blob, length);
}
}
const int final = sqlite3_finalize(st);
if ((rc != SQLITE_ROW && rc != SQLITE_DONE) || final != SQLITE_OK) {
GUI_ERROR("group avatar: read channel=%s stage=%s rc=%d finalize=%d type=%d bytes=%d: %s",
qPrintable(channelId), stage, rc, final, type, length, sqlite3_errmsg(m_db)); return {};
}
if (rc == SQLITE_DONE) {
GUI_DEBUG("group avatar: channel disappeared during read channel=%s", qPrintable(channelId)); return {};
}
if (ok) *ok = true;
return bytes;
}
bool DbManager::isChannelMember(const QString& chId, quint64 nodeId) const {