ssb: Move identity info gathering to db.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 26m52s
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 26m52s
This commit is contained in:
117
src/ssb.db.c
117
src/ssb.db.c
@ -2331,3 +2331,120 @@ bool tf_ssb_db_has_invite(sqlite3* db, const char* id)
|
||||
}
|
||||
return has;
|
||||
}
|
||||
|
||||
static void _tf_ssb_db_get_identity_info_visit(const char* identity, void* user_data)
|
||||
{
|
||||
tf_ssb_identity_info_t* info = user_data;
|
||||
info->identity = tf_resize_vec(info->identity, (info->count + 1) * sizeof(char*));
|
||||
info->name = tf_resize_vec(info->name, (info->count + 1) * sizeof(char*));
|
||||
char buffer[k_id_base64_len];
|
||||
snprintf(buffer, sizeof(buffer), "@%s", identity);
|
||||
info->identity[info->count] = tf_strdup(buffer);
|
||||
info->name[info->count] = NULL;
|
||||
info->count++;
|
||||
}
|
||||
|
||||
tf_ssb_identity_info_t* tf_ssb_db_get_identity_info(tf_ssb_t* ssb, const char* user, const char* package_owner, const char* package_name)
|
||||
{
|
||||
tf_ssb_identity_info_t* info = tf_malloc(sizeof(tf_ssb_identity_info_t));
|
||||
*info = (tf_ssb_identity_info_t) { 0 };
|
||||
|
||||
char id[k_id_base64_len] = "";
|
||||
if (tf_ssb_db_user_has_permission(ssb, NULL, user, "administration"))
|
||||
{
|
||||
if (tf_ssb_whoami(ssb, id, sizeof(id)))
|
||||
{
|
||||
_tf_ssb_db_get_identity_info_visit(*id == '@' ? id + 1 : id, info);
|
||||
}
|
||||
}
|
||||
tf_ssb_db_identity_visit(ssb, user, _tf_ssb_db_get_identity_info_visit, info);
|
||||
|
||||
sqlite3* db = tf_ssb_acquire_db_reader(ssb);
|
||||
sqlite3_stmt* statement = NULL;
|
||||
int result = sqlite3_prepare(db,
|
||||
"SELECT author, name FROM ( "
|
||||
" SELECT "
|
||||
" messages.author, "
|
||||
" RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank, "
|
||||
" messages.content ->> 'name' AS name "
|
||||
" FROM messages "
|
||||
" JOIN identities ON messages.author = ('@' || identities.public_key) "
|
||||
" WHERE "
|
||||
" (identities.user = ? OR identities.public_key = ?) AND "
|
||||
" json_extract(messages.content, '$.type') = 'about' AND "
|
||||
" content ->> 'about' = messages.author AND name IS NOT NULL) "
|
||||
"WHERE author_rank = 1 ",
|
||||
-1, &statement, NULL);
|
||||
if (result == SQLITE_OK)
|
||||
{
|
||||
if (sqlite3_bind_text(statement, 1, user, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, *id == '@' ? id + 1 : id, -1, NULL) == SQLITE_OK)
|
||||
{
|
||||
int r = SQLITE_OK;
|
||||
while ((r = sqlite3_step(statement)) == SQLITE_ROW)
|
||||
{
|
||||
const char* identity = (const char*)sqlite3_column_text(statement, 0);
|
||||
const char* name = (const char*)sqlite3_column_text(statement, 1);
|
||||
for (int i = 0; i < info->count; i++)
|
||||
{
|
||||
if (!info->name[i] && strcmp(info->identity[i], identity) == 0)
|
||||
{
|
||||
info->name[i] = tf_strdup(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_finalize(statement);
|
||||
}
|
||||
else
|
||||
{
|
||||
tf_printf("prepare failed: %s.\n", sqlite3_errmsg(db));
|
||||
}
|
||||
|
||||
tf_ssb_db_identity_get_active(db, user, package_owner, package_name, info->active_identity, sizeof(info->active_identity));
|
||||
if (!*info->active_identity && info->count)
|
||||
{
|
||||
snprintf(info->active_identity, sizeof(info->active_identity), "%s", info->identity[0]);
|
||||
}
|
||||
tf_ssb_release_db_reader(ssb, db);
|
||||
|
||||
size_t size = sizeof(tf_ssb_identity_info_t) + sizeof(char*) * info->count * 2;
|
||||
for (int i = 0; i < info->count; i++)
|
||||
{
|
||||
size += strlen(info->identity[i]) + 1;
|
||||
size += info->name[i] ? strlen(info->name[i]) + 1 : 0;
|
||||
}
|
||||
tf_ssb_identity_info_t* copy = tf_malloc(size);
|
||||
*copy = *info;
|
||||
|
||||
copy->identity = (const char**)(copy + 1);
|
||||
copy->name = (const char**)(copy + 1) + copy->count;
|
||||
|
||||
char* p = (char*)((const char**)(copy + 1) + copy->count * 2);
|
||||
|
||||
for (int i = 0; i < info->count; i++)
|
||||
{
|
||||
size_t length = strlen(info->identity[i]);
|
||||
memcpy(p, info->identity[i], length + 1);
|
||||
copy->identity[i] = p;
|
||||
p += length + 1;
|
||||
tf_free((void*)info->identity[i]);
|
||||
|
||||
if (info->name[i])
|
||||
{
|
||||
length = strlen(info->name[i]);
|
||||
memcpy(p, info->name[i], length + 1);
|
||||
copy->name[i] = p;
|
||||
p += length + 1;
|
||||
tf_free((void*)info->name[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
copy->name[i] = NULL;
|
||||
}
|
||||
}
|
||||
tf_free(info->name);
|
||||
tf_free(info->identity);
|
||||
tf_free(info);
|
||||
return copy;
|
||||
}
|
||||
|
Reference in New Issue
Block a user