diff options
| -rw-r--r-- | libdino/src/service/database.vala | 59 | ||||
| -rw-r--r-- | libdino/src/service/message_correction.vala | 32 | ||||
| -rw-r--r-- | libdino/src/service/message_storage.vala | 118 | ||||
| -rw-r--r-- | libdino/src/service/reactions.vala | 9 |
4 files changed, 87 insertions, 131 deletions
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index 4319e027..fba6f7a2 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -767,65 +767,6 @@ public class Database : Qlite.Database { .perform(); } - public Gee.List<Message> get_messages(Jid jid, Account account, Message.Type? type, int count, DateTime? before, DateTime? after, int id) { - QueryBuilder select = message.select(); - - if (before != null) { - if (id > 0) { - select.where(@"time < ? OR (time = ? AND message.id < ?)", { before.to_unix().to_string(), before.to_unix().to_string(), id.to_string() }); - } else { - select.with(message.id, "<", id); - } - } - if (after != null) { - if (id > 0) { - select.where(@"time > ? OR (time = ? AND message.id > ?)", { after.to_unix().to_string(), after.to_unix().to_string(), id.to_string() }); - } else { - select.with(message.time, ">", (long) after.to_unix()); - } - if (id > 0) { - select.with(message.id, ">", id); - } - } else { - select.order_by(message.time, "DESC"); - } - - select.with(message.counterpart_id, "=", get_jid_id(jid)) - .with(message.account_id, "=", account.id) - .limit(count); - if (jid.resourcepart != null) { - select.with(message.counterpart_resource, "=", jid.resourcepart); - } - if (type != null) { - select.with(message.type_, "=", (int) type); - } - - select.outer_join_with(real_jid, real_jid.message_id, message.id); - select.outer_join_with(message_correction, message_correction.message_id, message.id); - - LinkedList<Message> ret = new LinkedList<Message>(); - foreach (Row row in select) { - try { - ret.insert(0, new Message.from_row(this, row)); - } catch (InvalidJidError e) { - warning("Ignoring message with invalid Jid: %s", e.message); - } - } - return ret; - } - - public Message? get_message_by_id(int id) { - Row? row = message.row_with(message.id, id).inner; - if (row != null) { - try { - return new Message.from_row(this, row); - } catch (InvalidJidError e) { - warning("Ignoring message with invalid Jid: %s", e.message); - } - } - return null; - } - public ArrayList<Conversation> get_conversations(Account account) { ArrayList<Conversation> ret = new ArrayList<Conversation>(); foreach (Row row in conversation.select().with(conversation.account_id, "=", account.id)) { diff --git a/libdino/src/service/message_correction.vala b/libdino/src/service/message_correction.vala index 02151ac8..55d121e2 100644 --- a/libdino/src/service/message_correction.vala +++ b/libdino/src/service/message_correction.vala @@ -29,7 +29,6 @@ public class MessageCorrection : StreamInteractionModule, MessageListener { public MessageCorrection(StreamInteractor stream_interactor, Database db) { this.stream_interactor = stream_interactor; this.db = db; - stream_interactor.account_added.connect(on_account_added); stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(this); stream_interactor.get_module(MessageProcessor.IDENTITY).build_message_stanza.connect(check_add_correction_node); stream_interactor.get_module(PresenceManager.IDENTITY).received_offline_presence.connect((jid, account) => { @@ -65,15 +64,17 @@ public class MessageCorrection : StreamInteractionModule, MessageListener { Jid? own_jid = null; if (conversation.type_ == Conversation.Type.CHAT) { own_jid = stream_interactor.get_account_full_jid(conversation.account); + if (own_jid == null) return false; + Message other = stream_interactor.get_module(MessageStorage.IDENTITY).get_last_message_by_sent_resource(conversation, own_jid.resourcepart); + return other != null && other.id == message.id; } else if (conversation.type_ == Conversation.Type.GROUPCHAT) { own_jid = stream_interactor.get_module(MucManager.IDENTITY).get_own_jid(conversation.counterpart, conversation.account); + if (own_jid == null) return false; + return last_messages.has_key(conversation) && + last_messages[conversation].has_key(own_jid) && + last_messages[conversation][own_jid].stanza_id == stanza_id; } - - if (own_jid == null) return false; - - return last_messages.has_key(conversation) && - last_messages[conversation].has_key(own_jid) && - last_messages[conversation][own_jid].stanza_id == stanza_id; + return false; } private void check_add_correction_node(Entities.Message message, Xmpp.MessageStanza message_stanza, Conversation conversation) { @@ -245,23 +246,6 @@ public class MessageCorrection : StreamInteractionModule, MessageListener { return -1; } - private void on_account_added(Account account) { - Gee.List<Conversation> conversations = stream_interactor.get_module(ConversationManager.IDENTITY).get_active_conversations(account); - foreach (Conversation conversation in conversations) { - if (conversation.type_ != Conversation.Type.CHAT) continue; - - HashMap<Jid, Message> last_conversation_messages = new HashMap<Jid, Message>(Jid.hash_func, Jid.equals_func); - Gee.List<Message> messages = stream_interactor.get_module(MessageStorage.IDENTITY).get_messages(conversation); - for (int i = messages.size - 1; i > 0; i--) { - Message message = messages[i]; - if (!last_conversation_messages.has_key(message.from) && message.edit_to == null) { - last_conversation_messages[message.from] = message; - } - } - last_messages[conversation] = last_conversation_messages; - } - } - private void cache_unmatched_correction(ContentItem content_item, Conversation conversation) { MessageItem message_item = content_item as MessageItem; if (message_item == null || message_item.message.edit_to == null) return; diff --git a/libdino/src/service/message_storage.vala b/libdino/src/service/message_storage.vala index 2567738c..0bcbe533 100644 --- a/libdino/src/service/message_storage.vala +++ b/libdino/src/service/message_storage.vala @@ -35,41 +35,82 @@ public class MessageStorage : StreamInteractionModule, Object { cache_message(message, conversation); } - public Gee.List<Message> get_messages(Conversation conversation, int count = 50) { - var query = db.message.select() + public Message? get_last_message(Conversation conversation) { + Gee.List<Message> messages = get_messages(conversation, 1); + + if (messages.size > 0) { + return messages[0]; + } + + return null; + } + + public Message? get_last_message_by_sent_resource(Conversation conversation, string resource) { + RowOption row = db.message.select({db.message.id}) .with(db.message.account_id, "=", conversation.account.id) .with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart)) .with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation)) + .with(db.message.our_resource, "=", resource) + .with(db.message.direction, "=", Message.DIRECTION_SENT) .order_by(db.message.time, "DESC") - .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id) - .outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id) - .outer_join_with(db.reply, db.reply.message_id, db.message.id) - .limit(count); + .single().row(); + return get_message_by_id_row_opt(row, conversation); + } - Gee.List<Message> ret = new LinkedList<Message>(Message.equals_func); - foreach (Row row in query) { - Message? message = messages_by_db_id[row[db.message.id]]; - if (message == null) { - message = create_message_from_row(row, conversation); + public Gee.List<Message> get_messages(Conversation conversation, int count = 50, Message.Type? type = null, DateTime? before = null, DateTime? after = null, int id = 0) { + QueryBuilder select = db.message.select(); + + if (before != null) { + if (id > 0) { + select.where(@"time < ? OR (time = ? AND message.id < ?)", { before.to_unix().to_string(), before.to_unix().to_string(), id.to_string() }); + } else { + select.with(db.message.id, "<", id); } - ret.insert(0, message); + } + if (after != null) { + if (id > 0) { + select.where(@"time > ? OR (time = ? AND message.id > ?)", { after.to_unix().to_string(), after.to_unix().to_string(), id.to_string() }); + } else { + select.with(db.message.time, ">", (long) after.to_unix()); + } + if (id > 0) { + select.with(db.message.id, ">", id); + } + } else { + select.order_by(db.message.time, "DESC"); } - return ret; - } + select.with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart)) + .with(db.message.account_id, "=", conversation.account.id) + .limit(count); + if (conversation.counterpart.resourcepart != null) { + select.with(db.message.counterpart_resource, "=", conversation.counterpart.resourcepart); + } + if (type != null) { + select.with(db.message.type_, "=", (int) type); + } - public Message? get_last_message(Conversation conversation) { - Gee.List<Message> messages = get_messages(conversation, 1); + select.outer_join_with(db.real_jid, db.real_jid.message_id, db.message.id); + select.outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id); + select.outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id); + select.outer_join_with(db.reply, db.reply.message_id, db.message.id); - if (messages.size > 0) { - return messages[0]; + LinkedList<Message> ret = new LinkedList<Message>(); + foreach (Row row in select) { + try { + Message? message = messages_by_db_id[row[db.message.id]]; + if (message == null) { + message = create_message_from_row(row, conversation); + } + } catch (InvalidJidError e) { + warning("Ignoring message with invalid Jid: %s", e.message); + } } - - return null; + return ret; } public Gee.List<MessageItem> get_messages_before_message(Conversation? conversation, DateTime before, int id, int count = 20) { - Gee.List<Message> db_messages = db.get_messages(conversation.counterpart, conversation.account, Util.get_message_type_for_conversation(conversation), count, before, null, id); + Gee.List<Message> db_messages = get_messages(conversation, count, Util.get_message_type_for_conversation(conversation), before, null, id); Gee.List<MessageItem> ret = new ArrayList<MessageItem>(); foreach (Message message in db_messages) { ret.add(new MessageItem(message, conversation, -1)); @@ -78,7 +119,7 @@ public class MessageStorage : StreamInteractionModule, Object { } public Gee.List<MessageItem> get_messages_after_message(Conversation? conversation, DateTime after, int id, int count = 20) { - Gee.List<Message> db_messages = db.get_messages(conversation.counterpart, conversation.account, Util.get_message_type_for_conversation(conversation), count, null, after, id); + Gee.List<Message> db_messages = get_messages(conversation, count, Util.get_message_type_for_conversation(conversation), null, after, id); Gee.List<MessageItem> ret = new ArrayList<MessageItem>(); foreach (Message message in db_messages) { ret.add(new MessageItem(message, conversation, -1)); @@ -86,6 +127,11 @@ public class MessageStorage : StreamInteractionModule, Object { return ret; } + private Message? get_message_by_id_row_opt(RowOption row_option, Conversation conversation) { + if (!row_option.is_present()) return null; + return get_message_by_id(row_option[db.message.id], conversation); + } + public Message? get_message_by_id(int id, Conversation conversation) { Message? message = messages_by_db_id[id]; if (message != null) { @@ -93,9 +139,11 @@ public class MessageStorage : StreamInteractionModule, Object { } RowOption row_option = db.message.select().with(db.message.id, "=", id) + .outer_join_with(db.real_jid, db.real_jid.message_id, db.message.id) .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id) .outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id) .outer_join_with(db.reply, db.reply.message_id, db.message.id) + .single() .row(); return create_message_from_row_opt(row_option, conversation); @@ -103,9 +151,9 @@ public class MessageStorage : StreamInteractionModule, Object { public Message? get_message_by_referencing_id(string id, Conversation conversation) { if (conversation.type_ == Conversation.Type.CHAT) { - return stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(id, conversation); + return get_message_by_stanza_id(id, conversation); } else { - return stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(id, conversation); + return get_message_by_server_id(id, conversation); } } @@ -117,15 +165,12 @@ public class MessageStorage : StreamInteractionModule, Object { } } - var query = db.message.select() + var query = db.message.select({db.message.id}) .with(db.message.account_id, "=", conversation.account.id) .with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart)) .with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation)) .with(db.message.stanza_id, "=", stanza_id) - .order_by(db.message.time, "DESC") - .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id) - .outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id) - .outer_join_with(db.reply, db.reply.message_id, db.message.id); + .order_by(db.message.time, "DESC"); if (conversation.counterpart.resourcepart != null) { query.with(db.message.counterpart_resource, "=", conversation.counterpart.resourcepart); @@ -133,7 +178,7 @@ public class MessageStorage : StreamInteractionModule, Object { RowOption row_option = query.single().row(); - return create_message_from_row_opt(row_option, conversation); + return get_message_by_id_row_opt(row_option, conversation); } public Message? get_message_by_server_id(string server_id, Conversation conversation) { @@ -144,25 +189,20 @@ public class MessageStorage : StreamInteractionModule, Object { } } - var query = db.message.select() + var query = db.message.select({db.message.id}) .with(db.message.account_id, "=", conversation.account.id) .with(db.message.counterpart_id, "=", db.get_jid_id(conversation.counterpart)) .with(db.message.type_, "=", (int) Util.get_message_type_for_conversation(conversation)) .with(db.message.server_id, "=", server_id) - .order_by(db.message.time, "DESC") - .outer_join_with(db.message_occupant_id, db.message_occupant_id.message_id, db.message.id) - .outer_join_with(db.message_correction, db.message_correction.message_id, db.message.id) - .outer_join_with(db.reply, db.reply.message_id, db.message.id); + .order_by(db.message.time, "DESC"); - if (conversation.counterpart.resourcepart == null) { - query.with_null(db.message.counterpart_resource); - } else { + if (conversation.counterpart.resourcepart != null) { query.with(db.message.counterpart_resource, "=", conversation.counterpart.resourcepart); } RowOption row_option = query.single().row(); - return create_message_from_row_opt(row_option, conversation); + return get_message_by_id_row_opt(row_option, conversation); } private Message? create_message_from_row_opt(RowOption row_option, Conversation conversation) { diff --git a/libdino/src/service/reactions.vala b/libdino/src/service/reactions.vala index 8f3aa4fa..a8df614e 100644 --- a/libdino/src/service/reactions.vala +++ b/libdino/src/service/reactions.vala @@ -296,15 +296,6 @@ public class Dino.Reactions : StreamInteractionModule, Object { } } - private Message? get_message_for_reaction(Conversation conversation, string message_id) { - // Query message from a specific account and counterpart. This also makes sure it's a valid reaction for the message. - if (conversation.type_ == Conversation.Type.CHAT) { - return stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_stanza_id(message_id, conversation); - } else { - return stream_interactor.get_module(MessageStorage.IDENTITY).get_message_by_server_id(message_id, conversation); - } - } - private void process_reaction_for_message(int content_item_id, ReactionInfo reaction_info) { Account account = reaction_info.conversation.account; MessageStanza stanza = reaction_info.stanza; |
