aboutsummaryrefslogtreecommitdiff
path: root/libdino/src/service/occupant_id_store.vala
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2025-09-17 17:47:36 +0200
committerfiaxh <git@lightrise.org>2025-09-17 17:47:36 +0200
commitd625058d76efc9e344dd5e1239a4b040a7d2519a (patch)
tree4b5a6dc6ad05cb96f58014d1f8740f632efa4bdc /libdino/src/service/occupant_id_store.vala
parentfa678bd2cf60ebdcda652794bfb5e06b7bd7917f (diff)
Message correction: Use occupant ids, handle correction-before-message
Diffstat (limited to 'libdino/src/service/occupant_id_store.vala')
-rw-r--r--libdino/src/service/occupant_id_store.vala88
1 files changed, 88 insertions, 0 deletions
diff --git a/libdino/src/service/occupant_id_store.vala b/libdino/src/service/occupant_id_store.vala
new file mode 100644
index 00000000..662b9cbb
--- /dev/null
+++ b/libdino/src/service/occupant_id_store.vala
@@ -0,0 +1,88 @@
+using Xmpp;
+using Gee;
+using Qlite;
+
+using Dino.Entities;
+
+namespace Dino {
+
+ public class OccupantIdStore : StreamInteractionModule, Object {
+ public static ModuleIdentity<OccupantIdStore> IDENTITY = new ModuleIdentity<OccupantIdStore>("occupant_id_cache");
+ public string id { get { return IDENTITY.id; } }
+
+ private Database db;
+
+ // (Account, MUC JID, occupant id) -> occupant db id
+ private HashMap<Account, HashMap<Jid, HashMap<string, int>>> occupant_db_ids = new HashMap<Account, HashMap<Jid, HashMap<string, int>>>(Account.hash_func, Account.equals_func);
+ private HashMap<int, string> occupant_nicks = new HashMap<int, string>();
+
+ public static void start(StreamInteractor stream_interactor, Database db) {
+ OccupantIdStore m = new OccupantIdStore(db);
+ stream_interactor.add_module(m);
+ }
+
+ private OccupantIdStore(Database db) {
+ this.db = db;
+ }
+
+ public int get_occupant_db_id(Account account, string occupant_id, Jid muc_jid) {
+ if (!occupant_db_ids.has_key(account) || !occupant_db_ids[account].has_key(muc_jid) || !occupant_db_ids[account][muc_jid].has_key(occupant_id)) {
+ warning("Requested unknown occupant db id");
+ return -1;
+ }
+
+ return occupant_db_ids[account][muc_jid][occupant_id];
+ }
+
+ public int cache_occupant_id(Account account, string occupant_id, Jid occupant_jid) {
+ string last_nick = occupant_jid.resourcepart;
+ Jid muc_jid = occupant_jid.bare_jid;
+
+ if (occupant_db_ids.has_key(account) && occupant_db_ids[account].has_key(muc_jid) && occupant_db_ids[account][muc_jid].has_key(occupant_id)) {
+ int occupant_db_id = occupant_db_ids[account][muc_jid][occupant_id];
+ if (occupant_nicks[occupant_db_id] == last_nick) {
+ return occupant_db_id;
+ }
+ }
+
+ if (!occupant_db_ids.has_key(account)) occupant_db_ids[account] = new HashMap<Jid, HashMap<string, int>>(Jid.hash_bare_func, Jid.equals_bare_func);
+ if (!occupant_db_ids[account].has_key(muc_jid)) occupant_db_ids[account][muc_jid] = new HashMap<string, int>();
+
+ int muc_jid_id = db.get_jid_id(muc_jid);
+
+ RowOption row = db.occupantid.select()
+ .with(db.occupantid.account_id, "=", account.id)
+ .with(db.occupantid.jid_id, "=", muc_jid_id)
+ .with(db.occupantid.occupant_id, "=", occupant_id)
+ .single().row();
+
+ int occupant_db_id = -1;
+ if (row.is_present()) {
+ occupant_db_id = row[db.occupantid.id];
+
+ if (row[db.occupantid.last_nick] != last_nick) {
+ db.occupantid.upsert()
+ .value(db.occupantid.account_id, account.id, true)
+ .value(db.occupantid.jid_id, muc_jid_id, true)
+ .value(db.occupantid.occupant_id, occupant_id, true)
+ .value(db.occupantid.last_nick, last_nick, false)
+ .perform();
+ }
+ } else {
+ occupant_db_id = (int)db.occupantid.upsert()
+ .value(db.occupantid.account_id, account.id, true)
+ .value(db.occupantid.jid_id, muc_jid_id, true)
+ .value(db.occupantid.occupant_id, occupant_id, true)
+ .value(db.occupantid.last_nick, muc_jid.resourcepart, false)
+ .perform();
+ }
+
+ occupant_db_ids[account][muc_jid][occupant_id] = occupant_db_id;
+ occupant_nicks[occupant_db_id] = last_nick;
+
+ return occupant_db_id;
+ }
+
+
+ }
+} \ No newline at end of file