diff --git a/libdino/src/service/search_processor.vala b/libdino/src/service/search_processor.vala index 3c1057ae..6962a7c1 100644 --- a/libdino/src/service/search_processor.vala +++ b/libdino/src/service/search_processor.vala @@ -23,31 +23,82 @@ public class SearchProcessor : StreamInteractionModule, Object { this.db = db; } - public Gee.List match_messages(string match, int offset = -1) { - Gee.List ret = new ArrayList(Message.equals_func); - var query = db.message - .match(db.message.body, parse_search(match)) - .order_by(db.message.id, "DESC") - .limit(10); - if (offset > 0) { - query.offset(offset); + private QueryBuilder prepare_search(string query) { + string words = ""; + string? with = null; + string? in_ = null; + string? from = null; + foreach(string word in query.split(" ")) { + if (word.has_prefix("with:")) { + if (with == null) { + with = word.substring(5) + "%"; + } else { + return db.message.select().where("0"); + } + } else if (word.has_prefix("in:")) { + if (in_ == null) { + in_ = word.substring(3) + "%"; + } else { + return db.message.select().where("0"); + } + } else if (word.has_prefix("from:")) { + if (from == null) { + from = word.substring(5) + "%"; + } else { + return db.message.select().where("0"); + } + } else { + words += word + "* "; + } } - foreach (Row row in query) { + if (in_ != null && with != null) { + return db.message.select().where("0"); + } + + QueryBuilder rows = db.message + .match(db.message.body, words) + .order_by(db.message.id, "DESC") + .join_with(db.jid, db.jid.id, db.message.counterpart_id) + .join_with(db.account, db.account.id, db.message.account_id) + .outer_join_with(db.real_jid, db.real_jid.message_id, db.message.id); + if (with != null) { + if (with.index_of("/") > 0) { + rows.with(db.message.type_, "=", Message.Type.GROUPCHAT_PM) + .with(db.jid.bare_jid, "LIKE", with.substring(0, with.index_of("/"))) + .with(db.message.counterpart_resource, "LIKE", with.substring(with.index_of("/") + 1)); + } else { + rows.where(@"($(db.message.type_) = $((int)Message.Type.CHAT) AND $(db.jid.bare_jid) LIKE ?)" + + @" OR ($(db.message.type_) = $((int)Message.Type.GROUPCHAT_PM) AND $(db.real_jid.real_jid) LIKE ?)" + + @" OR ($(db.message.type_) = $((int)Message.Type.GROUPCHAT_PM) AND $(db.message.counterpart_resource) LIKE ?)", {with, with, with}); + } + } else if (in_ != null) { + rows.with(db.jid.bare_jid, "LIKE", in_) + .with(db.message.type_, "=", Message.Type.GROUPCHAT); + } + if (from != null) { + rows.where(@"($(db.message.direction) = 1 AND $(db.account.bare_jid) LIKE ?)" + + @" OR ($(db.message.direction) = 1 AND $(db.message.type_) IN ($((int)Message.Type.GROUPCHAT), $((int)Message.Type.GROUPCHAT_PM)) AND $(db.message.our_resource) LIKE ?)" + + @" OR ($(db.message.direction) = 0 AND $(db.message.type_) = $((int)Message.Type.CHAT) AND $(db.jid.bare_jid) LIKE ?)" + + @" OR ($(db.message.direction) = 0 AND $(db.message.type_) IN ($((int)Message.Type.GROUPCHAT), $((int)Message.Type.GROUPCHAT_PM)) AND $(db.real_jid.real_jid) LIKE ?)" + + @" OR ($(db.message.direction) = 0 AND $(db.message.type_) IN ($((int)Message.Type.GROUPCHAT), $((int)Message.Type.GROUPCHAT_PM)) AND $(db.message.counterpart_resource) LIKE ?)", {from, from, from, from, from}); + } + return rows; + } + + public Gee.List match_messages(string query, int offset = -1) { + Gee.List ret = new ArrayList(Message.equals_func); + var rows = prepare_search(query).limit(10); + if (offset > 0) { + rows.offset(offset); + } + foreach (Row row in rows) { ret.add(new Message.from_row(db, row)); } return ret; } - public int count_match_messages(string match) { - return (int)db.message.match(db.message.body, parse_search(match)).count(); - } - - private string parse_search(string search) { - string ret = ""; - foreach(string word in search.split(" ")) { - ret += word + "* "; - } - return ret; + public int count_match_messages(string query) { + return (int)prepare_search(query).select({db.message.id}).count(); } } diff --git a/main/src/ui/unified_window.vala b/main/src/ui/unified_window.vala index e5444f9d..cfcd2bff 100644 --- a/main/src/ui/unified_window.vala +++ b/main/src/ui/unified_window.vala @@ -42,6 +42,17 @@ public class UnifiedWindow : Window { conversation_titlebar.search_button.bind_property("active", search_revealer, "reveal-child", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); search_revealer.notify["child-revealed"].connect(() => { if (search_revealer.child_revealed) { + if (conversation_frame.conversation != null) { + switch (conversation_frame.conversation.type_) { + case Conversation.Type.CHAT: + case Conversation.Type.GROUPCHAT_PM: + search_box.search_entry.text = @"with:$(conversation_frame.conversation.counterpart) "; + break; + case Conversation.Type.GROUPCHAT: + search_box.search_entry.text = @"in:$(conversation_frame.conversation.counterpart) "; + break; + } + } search_box.search_entry.grab_focus(); } else { search_box.search_entry.text = ""; diff --git a/plugins/http-files/src/manager.vala b/plugins/http-files/src/manager.vala index 78c244e3..9faa8933 100644 --- a/plugins/http-files/src/manager.vala +++ b/plugins/http-files/src/manager.vala @@ -98,8 +98,8 @@ public class FileMessageFilter : ContentFilter, Object { } private bool message_is_file(Database db, Entities.Message message) { - Qlite.QueryBuilder builder = db.file_transfer.select().with(db.file_transfer.info, "=", message.id.to_string()); - Qlite.QueryBuilder builder2 = db.file_transfer.select().with(db.file_transfer.info, "=", message.body); + Qlite.QueryBuilder builder = db.file_transfer.select({db.file_transfer.id}).with(db.file_transfer.info, "=", message.id.to_string()); + Qlite.QueryBuilder builder2 = db.file_transfer.select({db.file_transfer.id}).with(db.file_transfer.info, "=", message.body); return builder.count() > 0 || builder2.count() > 0; }