Browse Source

Expose full message data and stable identities in listings

master
evgeny 5 days ago
parent
commit
0af35630d1
  1. 68
      src/chat/chat_core.c

68
src/chat/chat_core.c

@ -378,48 +378,40 @@ int chat_core_get_channels_json(struct UTUN_INSTANCE* inst, char* buf, size_t bu
int chat_core_get_messages_json(struct UTUN_INSTANCE* inst, const char* ch_id, int count, int offset,
char* buf, size_t buf_size, size_t* out_len) {
struct chat_core_ctx* cc = CC(inst);
if (!cc || !cc->initialized || !ch_id || !buf || !out_len) return -1;
char tbl[80]; msg_table_name(ch_id, tbl, sizeof(tbl));
char* w = buf; char* end = buf + buf_size;
*w++ = '['; const char* sep = "";
char sql[256];
struct chat_core_ctx* cc = inst ? CC(inst) : NULL;
if (out_len) *out_len = 0;
if (!cc || !cc->initialized || !ch_id || !buf || !out_len || buf_size < 3 || offset < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: invalid message listing arguments", CC_ID); return -1;
}
char table[80], sql[768]; msg_table_name(ch_id, table, sizeof(table));
snprintf(sql, sizeof(sql),
"SELECT m.id, m.timestamp, m.node_id, CAST(m.data AS TEXT), n.name, m.local_attrs "
"FROM \"%s\" m LEFT JOIN nodes n ON m.node_id=n.node_id "
"ORDER BY m.timestamp DESC LIMIT ? OFFSET ?", tbl);
"SELECT json_object('id',m.id,'message_id',lower(hex(m.message_id)),'ts',m.timestamp,"
"'author_id',printf('0x%%016llx',m.node_id),'author_name',coalesce(n.name,''),"
"'content_type',CASE WHEN json_valid(CAST(m.data AS TEXT)) THEN json_extract(CAST(m.data AS TEXT),'$.ct') ELSE 'text' END,"
"'data',coalesce(CAST(m.data AS TEXT),''),'local_attrs',coalesce(m.local_attrs,''))"
" FROM \"%s\" m LEFT JOIN nodes n ON m.node_id=n.node_id"
" ORDER BY m.timestamp DESC,m.author_signature DESC LIMIT ? OFFSET ?", table);
sqlite3_stmt* st = NULL;
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) != SQLITE_OK) { *out_len = 0; return -1; }
sqlite3_bind_int(st, 1, count > 0 ? count : 100);
sqlite3_bind_int(st, 2, offset);
while (sqlite3_step(st) == SQLITE_ROW) {
int64_t id = sqlite3_column_int64(st, 0);
int64_t ts = sqlite3_column_int64(st, 1);
uint64_t author_id = (uint64_t)sqlite3_column_int64(st, 2);
const char* data = (const char*)sqlite3_column_text(st, 3);
const char* author_name = (const char*)sqlite3_column_text(st, 4);
const char* la = (const char*)sqlite3_column_text(st, 5);
if (!data) data = "";
if (!la) la = "";
const char* ct = "text";
char ctbuf[32] = {0};
const char* ctpos = strstr(data, "\"ct\":\"");
if (ctpos) { ctpos += 6; int ci = 0; while (*ctpos && *ctpos != '"' && ci < 31) ctbuf[ci++] = *ctpos++; ct = ctbuf; }
char esc_data[4096], esc_aname[256], esc_la[256];
json_escape(data, esc_data, sizeof(esc_data));
json_escape(author_name ? author_name : "", esc_aname, sizeof(esc_aname));
json_escape(la, esc_la, sizeof(esc_la));
w += snprintf(w, (size_t)(end - w),
"%s{\"id\":%lld,\"ts\":%lld,\"author_id\":\"0x%016llx\",\"author_name\":\"%s\","
"\"content_type\":\"%s\",\"data\":\"%.2000s\",\"local_attrs\":\"%s\"}",
sep, (long long)id, (long long)ts, (unsigned long long)author_id, esc_aname, ct, esc_data, esc_la);
sep = ",";
if (sqlite3_prepare_v2(cc->db, sql, -1, &st, NULL) != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: messages query ch=%s: %s", CC_ID, ch_id, sqlite3_errmsg(cc->db)); return -1;
}
sqlite3_bind_int(st, 1, count > 0 ? count : 100); sqlite3_bind_int(st, 2, offset);
size_t off = 1; buf[0] = '['; int step, result = 0;
while ((step = sqlite3_step(st)) == SQLITE_ROW) {
const char* row = (const char*)sqlite3_column_text(st, 0); size_t bytes = sqlite3_column_bytes(st, 0);
if (!row || bytes + (off > 1) + 2 > buf_size - off) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: messages exceed output buffer ch=%s capacity=%zu", CC_ID, ch_id, buf_size);
result = -1; break;
}
if (off > 1) buf[off++] = ',';
memcpy(buf + off, row, bytes); off += bytes;
}
if (result == 0 && step != SQLITE_DONE) {
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: messages read ch=%s: %s", CC_ID, ch_id, sqlite3_errmsg(cc->db)); result = -1;
}
sqlite3_finalize(st);
*w++ = ']';
*w = '\0';
*out_len = (size_t)(w - buf);
return 0;
if (result < 0) { buf[0] = 0; return -1; }
buf[off++] = ']'; buf[off] = 0; *out_len = off; return 0;
}
int chat_core_get_members_json(struct UTUN_INSTANCE* inst, const char* ch_id, char* buf, size_t buf_size, size_t* out_len) {

Loading…
Cancel
Save