From 3c5b9aac82015a27b82fe8124917a33bfa4e5fca Mon Sep 17 00:00:00 2001 From: LDA Date: Fri, 2 Aug 2024 14:11:23 +0200 Subject: [PATCH] [MOD] Move temporary stanza/event mappings This should increase reliability, as a bad write shouldn't affect the MUC mappings directoy (which I've _seen_ happen.) --- src/MatrixEventHandler.c | 12 ++-- src/Parsee/Data.c | 146 +++++++++++++-------------------------- src/Parsee/User.c | 24 ++----- 3 files changed, 61 insertions(+), 121 deletions(-) diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index f289af8..51c0dc1 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -370,15 +370,17 @@ ParseeEventHandler(ParseeData *data, HashMap *event) { char *event_type, *event_id, *room_id, *sender; char *parsee = ParseeMXID(data); - if (!data || !event) + + event_id = GrabString(event, 1, "event_id"); + event_type = GrabString(event, 1, "type"); + room_id = GrabString(event, 1, "room_id"); + sender = GrabString(event, 1, "sender"); + if (!data || !event || ParseeIsPuppet(data->config, sender)) { + Free(parsee); return; } - event_type = GrabString(event, 1, "type"); - event_id = GrabString(event, 1, "event_id"); - room_id = GrabString(event, 1, "room_id"); - sender = GrabString(event, 1, "sender"); ParseePushHeadTable(room_id, event_id); if (StrEquals(event_type, "m.room.member")) diff --git a/src/Parsee/Data.c b/src/Parsee/Data.c index 1b62540..74b4be0 100644 --- a/src/Parsee/Data.c +++ b/src/Parsee/Data.c @@ -68,45 +68,46 @@ ParseeCleanup(void *datp) uint64_t ts = UtilTsMillis(); Log(LOG_NOTICE, "Cleaning up..."); + chats = DbList(data->db, 1, "chats"); for (i = 0; i < ArraySize(chats); i++) { DbRef *ref; - HashMap *json, *stanzas, *events, *ids; char *stanza, *event, *id; - JsonValue *val; Array *to_delete; size_t j; chat = ArrayGet(chats, i); - ref = DbLock(data->db, 2, "chats", chat); - json = DbJson(ref); #define CleanupField(field, timeout, threshold) do \ { \ + Array *field##_list = DbList(data->db, 3, "chats", chat, #field"s"); \ size_t cleaned = 0; \ - field##s = JsonValueAsObject(HashMapGet(json, #field"s")); \ to_delete = ArrayCreate(); \ - while (HashMapIterate(field##s, &field, (void **) &val)) \ + for (j = 0; j < ArraySize(field##_list); j++) \ { \ - HashMap *obj = JsonValueAsObject(val); \ + char *f = ArrayGet(field##_list, j); \ + ref = DbLock(data->db, 4, "chats", chat, #field"s", f); \ + HashMap *obj = DbJson(ref); \ uint64_t age = JsonValueAsInteger(HashMapGet(obj, "age")); \ uint64_t dur = ts - age; \ \ if ((dur > (timeout))) \ { \ - ArrayAdd(to_delete, StrDuplicate(field)); \ + ArrayAdd(to_delete, StrDuplicate(f)); \ cleaned++; \ } \ + DbUnlock(data->db, ref); \ } \ + DbListFree(field##_list); \ \ for (j = 0; j < ArraySize(to_delete); j++) \ { \ field = ArrayGet(to_delete, j); \ if (cleaned > threshold) \ { \ - JsonValueFree(HashMapDelete(field##s, field)); \ + DbDelete(data->db, 4, "chats", chat, #field"s", field); \ } \ Free(field); \ } \ @@ -117,8 +118,7 @@ ParseeCleanup(void *datp) CleanupField(stanza, 30 MINUTES, 50); CleanupField(event, 30 MINUTES, 50); CleanupField(id, 30 MINUTES, 50); - - DbUnlock(data->db, ref); +#undef CleanupField } DbListFree(chats); /* TODO */ @@ -499,76 +499,56 @@ ParseePushStanza(ParseeData *data, char *chat_id, char *stanza_id, char *id, cha { DbRef *ref; HashMap *j; - HashMap *stanzas, *obj, *events, *ids; - bool new_stanzas = false, new_events = false; - bool new_ids = false; uint64_t age = UtilTsMillis(); if (!data || !chat_id || !stanza_id || !ev || !sender) { return; } - ref = DbLock(data->db, 2, "chats", chat_id); - j = DbJson(ref); - if (!ref) + /* TODO */ { - return; + ref = DbCreate(data->db, 4, "chats", chat_id, "stanzas", stanza_id); + j = DbJson(ref); + if (!ref) + { + return; + } + + HashMapSet(j, "age", JsonValueInteger(age)); + HashMapSet(j, "event", JsonValueString(ev)); + DbUnlock(data->db, ref); } - stanzas = JsonValueAsObject(HashMapGet(j, "stanzas")); - if (!stanzas) { - stanzas = HashMapCreate(); - new_stanzas = true; - } + ref = DbCreate(data->db, 4, "chats", chat_id, "events", ev); + j = DbJson(ref); + if (!ref) + { + return; + } - obj = HashMapCreate(); - HashMapSet(obj, "age", JsonValueInteger(age)); - HashMapSet(obj, "event", JsonValueString(ev)); - JsonValueFree(HashMapSet(stanzas, stanza_id, JsonValueObject(obj))); - - if (new_stanzas) - { - HashMapSet(j, "stanzas", JsonValueObject(stanzas)); - } - - events = JsonValueAsObject(HashMapGet(j, "events")); - if (!events) - { - events = HashMapCreate(); - new_events = true; - } - obj = HashMapCreate(); - HashMapSet(obj, "stanza", JsonValueString(stanza_id)); - HashMapSet(obj, "origin", JsonValueString(id)); - HashMapSet(obj, "sender", JsonValueString(sender)); - HashMapSet(obj, "age", JsonValueInteger(age)); - JsonValueFree(HashMapSet(events, ev, JsonValueObject(obj))); - if (new_events) - { - HashMapSet(j, "events", JsonValueObject(events)); + HashMapSet(j, "event", JsonValueString(ev)); + HashMapSet(j, "stanza", JsonValueString(stanza_id)); + HashMapSet(j, "origin", JsonValueString(id)); + HashMapSet(j, "sender", JsonValueString(sender)); + HashMapSet(j, "age", JsonValueInteger(age)); + DbUnlock(data->db, ref); } if (id) { - ids = JsonValueAsObject(HashMapGet(j, "ids")); - if (!ids) + ref = DbCreate(data->db, 4, "chats", chat_id, "ids", id); + j = DbJson(ref); + if (!ref) { - ids = HashMapCreate(); - new_ids = true; - } - obj = HashMapCreate(); - HashMapSet(obj, "stanza", JsonValueString(stanza_id)); - HashMapSet(obj, "event", JsonValueString(ev)); - HashMapSet(obj, "sender", JsonValueString(sender)); - HashMapSet(obj, "age", JsonValueInteger(age)); - JsonValueFree(HashMapSet(ids, id, JsonValueObject(obj))); - if (new_ids) - { - HashMapSet(j, "ids", JsonValueObject(ids)); + return; } + HashMapSet(j, "stanza", JsonValueString(stanza_id)); + HashMapSet(j, "event", JsonValueString(ev)); + HashMapSet(j, "sender", JsonValueString(sender)); + HashMapSet(j, "age", JsonValueInteger(age)); + DbUnlock(data->db, ref); } - DbUnlock(data->db, ref); } bool @@ -605,29 +585,15 @@ bool ParseeVerifyStanza(ParseeData *data, char *chat_id, char *stanza_id) { DbRef *ref = NULL; - HashMap *j = NULL; - HashMap *stanzas = NULL; bool ret = true; if (!data || !chat_id || !stanza_id) { return true; } - ref = DbLock(data->db, 2, "chats", chat_id); - j = DbJson(ref); - if (!ref) - { - goto end; - } + ref = DbLock(data->db, 4, "chats", chat_id, "stanzas", stanza_id); + ret = !ref; - stanzas = JsonValueAsObject(HashMapGet(j, "stanzas")); - if (!stanzas) - { - goto end; - } - - ret = !HashMapGet(stanzas, stanza_id); -end: DbUnlock(data->db, ref); return ret; } @@ -636,27 +602,20 @@ ParseeEventFromID(ParseeData *data, char *chat_id, char *id) { DbRef *ref = NULL; HashMap *j = NULL; - HashMap *ids = NULL; char *ret = NULL; if (!data || !chat_id || !id) { return NULL; } - ref = DbLock(data->db, 2, "chats", chat_id); + ref = DbLock(data->db, 4, "chats", chat_id, "ids", id); j = DbJson(ref); if (!ref) { goto end; } - ids = JsonValueAsObject(HashMapGet(j, "ids")); - if (!ids) - { - goto end; - } - - ret = JsonValueAsString(JsonGet(ids, 2, id, "event")); + ret = JsonValueAsString(JsonGet(j, 1, "event")); ret = StrDuplicate(ret); end: DbUnlock(data->db, ref); @@ -699,27 +658,20 @@ ParseeEventFromSID(ParseeData *data, char *chat_id, char *id) { DbRef *ref = NULL; HashMap *j = NULL; - HashMap *ids = NULL; char *ret = NULL; if (!data || !chat_id || !id) { return NULL; } - ref = DbLock(data->db, 2, "chats", chat_id); + ref = DbLock(data->db, 4, "chats", chat_id, "stanzas", id); j = DbJson(ref); if (!ref) { goto end; } - ids = JsonValueAsObject(HashMapGet(j, "stanzas")); - if (!ids) - { - goto end; - } - - ret = JsonValueAsString(JsonGet(ids, 2, id, "event")); + ret = JsonValueAsString(JsonGet(j, 1, "event")); ret = StrDuplicate(ret); end: DbUnlock(data->db, ref); diff --git a/src/Parsee/User.c b/src/Parsee/User.c index b11e7d4..0e4d10c 100644 --- a/src/Parsee/User.c +++ b/src/Parsee/User.c @@ -583,28 +583,21 @@ ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char * { DbRef *ref = NULL; HashMap *j = NULL; - HashMap *event = NULL; bool ret = false; if (!data || !chat_id || !ev || !st || !se) { return false; } - ref = DbLock(data->db, 2, "chats", chat_id); + ref = DbLock(data->db, 4, "chats", chat_id, "events", ev); j = DbJson(ref); if (!ref) { goto end; } - - event = JsonValueAsObject(JsonGet(j, 2, "events", ev)); - if (!event) - { - goto end; - } - *st = StrDuplicate(JsonValueAsString(HashMapGet(event, "stanza"))); - *se = StrDuplicate(JsonValueAsString(HashMapGet(event, "sender"))); + *st = StrDuplicate(JsonValueAsString(HashMapGet(j, "stanza"))); + *se = StrDuplicate(JsonValueAsString(HashMapGet(j, "sender"))); ret = true; end: DbUnlock(data->db, ref); @@ -647,27 +640,20 @@ ParseeGetOrigin(ParseeData *data, char *chat_id, char *ev, char **o) { DbRef *ref = NULL; HashMap *j = NULL; - HashMap *event = NULL; bool ret = false; if (!data || !chat_id || !ev || !o) { return false; } - ref = DbLock(data->db, 2, "chats", chat_id); + ref = DbLock(data->db, 4, "chats", chat_id, "events", ev); j = DbJson(ref); if (!ref) { goto end; } - - event = JsonValueAsObject(JsonGet(j, 2, "events", ev)); - if (!event) - { - goto end; - } - *o = StrDuplicate(JsonValueAsString(HashMapGet(event, "origin"))); + *o = StrDuplicate(JsonValueAsString(HashMapGet(j, "origin"))); ret = true; end: DbUnlock(data->db, ref);