diff options
Diffstat (limited to 'libdino')
-rw-r--r-- | libdino/src/entity/account.vala | 64 | ||||
-rw-r--r-- | libdino/src/entity/conversation.vala | 68 | ||||
-rw-r--r-- | libdino/src/entity/message.vala | 99 | ||||
-rw-r--r-- | libdino/src/service/conversation_manager.vala | 5 | ||||
-rw-r--r-- | libdino/src/service/database.vala | 192 | ||||
-rw-r--r-- | libdino/src/service/message_manager.vala | 12 |
6 files changed, 222 insertions, 218 deletions
diff --git a/libdino/src/entity/account.vala b/libdino/src/entity/account.vala index 48be527a..3f1bfdb2 100644 --- a/libdino/src/entity/account.vala +++ b/libdino/src/entity/account.vala @@ -1,6 +1,7 @@ using Gee; namespace Dino.Entities { + public class Account : Object { public int id { get; set; } @@ -10,19 +11,51 @@ public class Account : Object { public Jid bare_jid { get; private set; } public string? password { get; set; } public string display_name { - owned get { - if (alias != null) { - return alias; - } else { - return bare_jid.to_string(); - } - } + owned get { return alias ?? bare_jid.to_string(); } } public string? alias { get; set; } - public bool enabled { get; set; } + public bool enabled { get; set; default = false; } + + private Database? db; - public Account.from_bare_jid(string bare_jid) { - this.bare_jid = new Jid(bare_jid); + public Account(Jid bare_jid, string? resourcepart, string? password, string? alias) { + this.id = -1; + this.resourcepart = resourcepart ?? "dino." + Random.next_int().to_string("%x"); + this.bare_jid = bare_jid; + this.password = password; + this.alias = alias; + } + + public Account.from_row(Database db, Qlite.Row row) { + this.db = db; + id = row[db.account.id]; + resourcepart = row[db.account.resourcepart]; + bare_jid = new Jid(row[db.account.bare_jid]); + password = row[db.account.password]; + alias = row[db.account.alias]; + enabled = row[db.account.enabled]; + + notify.connect(on_update); + } + + public void persist(Database db) { + this.db = db; + id = (int) db.account.insert() + .value(db.account.bare_jid, bare_jid.to_string()) + .value(db.account.resourcepart, resourcepart) + .value(db.account.password, password) + .value(db.account.alias, alias) + .value(db.account.enabled, enabled) + .perform(); + + notify.connect(on_update); + } + + public void remove() { + db.account.delete().with(db.account.bare_jid, "=", bare_jid.to_string()).perform(); + notify.disconnect(on_update); + id = -1; + db = null; } public bool equals(Account acc) { @@ -36,5 +69,16 @@ public class Account : Object { public static uint hash_func(Account acc) { return acc.bare_jid.to_string().hash(); } + + private void on_update(Object o, ParamSpec sp) { + db.account.update().with(db.account.id, "=", id) + .set(db.account.bare_jid, bare_jid.to_string()) + .set(db.account.resourcepart, resourcepart) + .set(db.account.password, password) + .set(db.account.alias, alias) + .set(db.account.enabled, enabled) + .perform(); + } } + }
\ No newline at end of file diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala index 5a83e02b..fd226b3e 100644 --- a/libdino/src/entity/conversation.vala +++ b/libdino/src/entity/conversation.vala @@ -1,4 +1,5 @@ namespace Dino.Entities { + public class Conversation : Object { public signal void object_updated(Conversation conversation); @@ -11,24 +12,51 @@ public class Conversation : Object { public int id { get; set; } public Account account { get; private set; } public Jid counterpart { get; private set; } - public bool active { get; set; } - public DateTime last_active { get; set; } - public Encryption encryption { get; set; } - public Type? type_ { get; set; } + public bool active { get; set; default = false; } + public DateTime? last_active { get; set; } + public Encryption encryption { get; set; default = Encryption.NONE; } + public Type type_ { get; set; } public Message read_up_to { get; set; } - public Conversation(Jid jid, Account account) { + private Database? db; + + public Conversation(Jid jid, Account account, Type type) { this.counterpart = jid; this.account = account; - this.active = false; - this.last_active = new DateTime.from_unix_utc(0); - this.encryption = Encryption.NONE; + this.type_ = type; } - public Conversation.with_id(Jid jid, Account account, int id) { - this.counterpart = jid; - this.account = account; - this.id = id; + public Conversation.from_row(Database db, Qlite.Row row) { + this.db = db; + + id = row[db.conversation.id]; + counterpart = new Jid(db.get_jid_by_id(row[db.conversation.jid_id])); + account = db.get_account_by_id(row[db.conversation.account_id]); + active = row[db.conversation.active]; + int64? last_active = row[db.conversation.last_active]; + if (last_active != null) this.last_active = new DateTime.from_unix_utc(last_active); + type_ = (Conversation.Type) row[db.conversation.type_]; + encryption = (Encryption) row[db.conversation.encryption]; + int? read_up_to = row[db.conversation.read_up_to]; + if (read_up_to != null) this.read_up_to = db.get_message_by_id(read_up_to); + + notify.connect(on_update); + } + + public void persist(Database db) { + this.db = db; + var insert = db.conversation.insert() + .value(db.conversation.jid_id, db.get_jid_id(counterpart)) + .value(db.conversation.account_id, account.id) + .value(db.conversation.type_, type_) + .value(db.conversation.encryption, encryption) + //.value(conversation.read_up_to, new_conversation.read_up_to) + .value(db.conversation.active, active); + if (last_active != null) { + insert.value(db.conversation.last_active, (long) last_active.to_unix()); + } + id = (int) insert.perform(); + notify.connect(on_update); } public bool equals(Conversation? conversation) { @@ -43,5 +71,21 @@ public class Conversation : Object { public static uint hash_func(Conversation conversation) { return conversation.counterpart.to_string().hash() ^ conversation.account.bare_jid.to_string().hash(); } + + private void on_update(Object o, ParamSpec sp) { + var update = db.conversation.update().with(db.conversation.jid_id, "=", db.get_jid_id(counterpart)) + .with(db.conversation.account_id, "=", account.id) + .set(db.conversation.type_, type_) + .set(db.conversation.encryption, encryption) + //.set(conversation.read_up_to, changed_conversation.read_up_to) + .set(db.conversation.active, active); + if (last_active != null) { + update.set(db.conversation.last_active, (long) last_active.to_unix()); + } else { + update.set_null(db.conversation.last_active); + } + update.perform(); + } } + }
\ No newline at end of file diff --git a/libdino/src/entity/message.vala b/libdino/src/entity/message.vala index 16562561..602c74b6 100644 --- a/libdino/src/entity/message.vala +++ b/libdino/src/entity/message.vala @@ -1,8 +1,8 @@ using Gee; -using Xmpp; +namespace Dino.Entities { -public class Dino.Entities.Message : Object { +public class Message : Object { public const bool DIRECTION_SENT = true; public const bool DIRECTION_RECEIVED = false; @@ -45,8 +45,62 @@ public class Dino.Entities.Message : Object { public Marked marked { get; set; default = Marked.NONE; } public Xmpp.Message.Stanza stanza { get; set; } + private Database? db; + + public Message(string? body, Type type) { + this.id = -1; + this.body = body; + this.type_ = type; + } + + public Message.from_row(Database db, Qlite.Row row) { + this.db = db; + + id = row[db.message.id]; + stanza_id = row[db.message.stanza_id]; + string from = db.get_jid_by_id(row[db.message.counterpart_id]); + string from_resource = row[db.message.counterpart_resource]; + counterpart = from_resource != null ? new Jid(from + "/" + from_resource) : new Jid(from); + direction = row[db.message.direction]; + type_ = (Message.Type) row[db.message.type_]; + time = new DateTime.from_unix_utc(row[db.message.time]); + body = row[db.message.body]; + account = db.get_account_by_id(row[db.message.account_id]); // TODO dont have to generate acc new + marked = (Message.Marked) row[db.message.marked]; + encryption = (Encryption) row[db.message.encryption]; + real_jid = db.real_jid.select({db.real_jid.real_jid}).with(db.real_jid.message_id, "=", id)[db.real_jid.real_jid]; + + notify.connect(on_update); + } + + public void persist(Database db) { + this.db = db; + Qlite.InsertBuilder builder = db.message.insert() + .value(db.message.account_id, account.id) + .value(db.message.counterpart_id, db.get_jid_id(counterpart)) + .value(db.message.counterpart_resource, counterpart.resourcepart) + .value(db.message.our_resource, ourpart.resourcepart) + .value(db.message.direction, direction) + .value(db.message.type_, type_) + .value(db.message.time, (long) time.to_unix()) + .value(db.message.local_time, (long) local_time.to_unix()) + .value(db.message.body, body) + .value(db.message.encryption, encryption) + .value(db.message.marked, marked); + if (stanza_id != null) builder.value(db.message.stanza_id, stanza_id); + id = (int) builder.perform(); + + if (real_jid != null) { + db.real_jid.insert() + .value(db.real_jid.message_id, id) + .value(db.real_jid.real_jid, real_jid) + .perform(); + } + notify.connect(on_update); + } + public void set_type_string(string type) { - switch (type) { + switch (type) { case Xmpp.Message.Stanza.TYPE_CHAT: type_ = Type.CHAT; break; case Xmpp.Message.Stanza.TYPE_GROUPCHAT: @@ -57,7 +111,7 @@ public class Dino.Entities.Message : Object { } public new string get_type_string() { - switch (type_) { + switch (type_) { case Type.CHAT: return Xmpp.Message.Stanza.TYPE_CHAT; case Type.GROUPCHAT: @@ -83,4 +137,41 @@ public class Dino.Entities.Message : Object { public static uint hash_func(Message message) { return message.body.hash(); } + + private void on_update(Object o, ParamSpec sp) { + Qlite.UpdateBuilder update_builder = db.message.update().with(db.message.id, "=", id); + switch (sp.get_name()) { + case "stanza_id": + update_builder.set(db.message.stanza_id, stanza_id); break; + case "counterpart": + update_builder.set(db.message.counterpart_id, db.get_jid_id(counterpart)); + update_builder.set(db.message.counterpart_resource, counterpart.resourcepart); break; + case "ourpart": + update_builder.set(db.message.our_resource, ourpart.resourcepart); break; + case "direction": + update_builder.set(db.message.direction, direction); break; + case "type_": + update_builder.set(db.message.type_, type_); break; + case "time": + update_builder.set(db.message.time, (long) time.to_unix()); break; + case "local_time": + update_builder.set(db.message.local_time, (long) local_time.to_unix()); break; + case "body": + update_builder.set(db.message.body, body); break; + case "encryption": + update_builder.set(db.message.encryption, encryption); break; + case "marked": + update_builder.set(db.message.marked, marked); break; + } + update_builder.perform(); + + if (sp.get_name() == "real_jid") { + db.real_jid.insert() + .value(db.real_jid.message_id, id) + .value(db.real_jid.real_jid, real_jid) + .perform(); + } + } } + +}
\ No newline at end of file diff --git a/libdino/src/service/conversation_manager.vala b/libdino/src/service/conversation_manager.vala index 10c6ac51..2d046e83 100644 --- a/libdino/src/service/conversation_manager.vala +++ b/libdino/src/service/conversation_manager.vala @@ -92,10 +92,9 @@ public class ConversationManager : StreamInteractionModule, Object { private void ensure_add_conversation(Jid jid, Account account, Conversation.Type type) { if (conversations.has_key(account) && !conversations[account].has_key(jid)) { - Conversation conversation = new Conversation(jid, account); - conversation.type_ = type; + Conversation conversation = new Conversation(jid, account, type); add_conversation(conversation); - db.add_conversation(conversation); + conversation.persist(db); } } diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index 29c6f3ee..f631ff1f 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -137,122 +137,23 @@ public class Database : Qlite.Database { // new table columns are added, outdated columns are still present } - public void add_account(Account new_account) { - new_account.id = (int) account.insert() - .value(account.bare_jid, new_account.bare_jid.to_string()) - .value(account.resourcepart, new_account.resourcepart) - .value(account.password, new_account.password) - .value(account.alias, new_account.alias) - .value(account.enabled, new_account.enabled) - .perform(); - new_account.notify.connect(on_account_update); - } - - private void on_account_update(Object o, ParamSpec sp) { - Account changed_account = (Account) o; - account.update().with(account.id, "=", changed_account.id) - .set(account.bare_jid, changed_account.bare_jid.to_string()) - .set(account.resourcepart, changed_account.resourcepart) - .set(account.password, changed_account.password) - .set(account.alias, changed_account.alias) - .set(account.enabled, changed_account.enabled) - .perform(); - } - - public void remove_account(Account to_delete) { - account.delete().with(account.bare_jid, "=", to_delete.bare_jid.to_string()).perform(); - } - public ArrayList<Account> get_accounts() { ArrayList<Account> ret = new ArrayList<Account>(); foreach(Row row in account.select()) { - Account account = get_account_from_row(row); - account.notify.connect(on_account_update); + Account account = new Account.from_row(this, row); ret.add(account); } return ret; } - private Account? get_account_by_id(int id) { + public Account? get_account_by_id(int id) { Row? row = account.row_with(account.id, id).inner; if (row != null) { - return get_account_from_row(row); + return new Account.from_row(this, row); } return null; } - private Account get_account_from_row(Row row) { - Account new_account = new Account.from_bare_jid(row[account.bare_jid]); - - new_account.id = row[account.id]; - new_account.resourcepart = row[account.resourcepart]; - new_account.password = row[account.password]; - new_account.alias = row[account.alias]; - new_account.enabled = row[account.enabled]; - return new_account; - } - - public void add_message(Message new_message, Account account) { - InsertBuilder builder = message.insert() - .value(message.account_id, new_message.account.id) - .value(message.counterpart_id, get_jid_id(new_message.counterpart)) - .value(message.counterpart_resource, new_message.counterpart.resourcepart) - .value(message.our_resource, new_message.ourpart.resourcepart) - .value(message.direction, new_message.direction) - .value(message.type_, new_message.type_) - .value(message.time, (long) new_message.time.to_unix()) - .value(message.local_time, (long) new_message.local_time.to_unix()) - .value(message.body, new_message.body) - .value(message.encryption, new_message.encryption) - .value(message.marked, new_message.marked); - if (new_message.stanza_id != null) builder.value(message.stanza_id, new_message.stanza_id); - new_message.id = (int) builder.perform(); - - if (new_message.real_jid != null) { - real_jid.insert() - .value(real_jid.message_id, new_message.id) - .value(real_jid.real_jid, new_message.real_jid) - .perform(); - } - new_message.notify.connect(on_message_update); - } - - private void on_message_update(Object o, ParamSpec sp) { - Message changed_message = (Message) o; - UpdateBuilder update_builder = message.update().with(message.id, "=", changed_message.id); - switch (sp.get_name()) { - case "stanza_id": - update_builder.set(message.stanza_id, changed_message.stanza_id); break; - case "counterpart": - update_builder.set(message.counterpart_id, get_jid_id(changed_message.counterpart)); - update_builder.set(message.counterpart_resource, changed_message.counterpart.resourcepart); break; - case "ourpart": - update_builder.set(message.our_resource, changed_message.ourpart.resourcepart); break; - case "direction": - update_builder.set(message.direction, changed_message.direction); break; - case "type_": - update_builder.set(message.type_, changed_message.type_); break; - case "time": - update_builder.set(message.time, (long) changed_message.time.to_unix()); break; - case "local_time": - update_builder.set(message.local_time, (long) changed_message.local_time.to_unix()); break; - case "body": - update_builder.set(message.body, changed_message.body); break; - case "encryption": - update_builder.set(message.encryption, changed_message.encryption); break; - case "marked": - update_builder.set(message.marked, changed_message.marked); break; - } - update_builder.perform(); - - if (sp.get_name() == "real_jid") { - real_jid.insert() - .value(real_jid.message_id, changed_message.id) - .value(real_jid.real_jid, changed_message.real_jid) - .perform(); - } - } - public Gee.List<Message> get_messages(Jid jid, Account account, int count, Message? before) { string jid_id = get_jid_id(jid).to_string(); @@ -267,7 +168,7 @@ public class Database : Qlite.Database { LinkedList<Message> ret = new LinkedList<Message>(); foreach (Row row in select) { - ret.insert(0, get_message_from_row(row)); + ret.insert(0, new Message.from_row(this, row)); } return ret; } @@ -275,7 +176,7 @@ public class Database : Qlite.Database { public Gee.List<Message> get_unsend_messages(Account account) { Gee.List<Message> ret = new ArrayList<Message>(); foreach (Row row in message.select().with(message.marked, "=", (int) Message.Marked.UNSENT)) { - ret.add(get_message_from_row(row)); + ret.add(new Message.from_row(this, row)); } return ret; } @@ -307,94 +208,19 @@ public class Database : Qlite.Database { public Message? get_message_by_id(int id) { Row? row = message.row_with(message.id, id).inner; if (row != null) { - return get_message_from_row(row); + return new Message.from_row(this, row); } return null; } - public Message get_message_from_row(Row row) { - Message new_message = new Message(); - - new_message.id = row[message.id]; - new_message.stanza_id = row[message.stanza_id]; - string from = get_jid_by_id(row[message.counterpart_id]); - string from_resource = row[message.counterpart_resource]; - if (from_resource != null) { - new_message.counterpart = new Jid(from + "/" + from_resource); - } else { - new_message.counterpart = new Jid(from); - } - new_message.direction = row[message.direction]; - new_message.type_ = (Message.Type) row[message.type_]; - new_message.time = new DateTime.from_unix_utc(row[message.time]); - new_message.body = row[message.body]; - new_message.account = get_account_by_id(row[message.account_id]); // TODO dont have to generate acc new - new_message.marked = (Message.Marked) row[message.marked]; - new_message.encryption = (Encryption) row[message.encryption]; - new_message.real_jid = get_real_jid_for_message(new_message); - - new_message.notify.connect(on_message_update); - return new_message; - } - - public string? get_real_jid_for_message(Message message) { - return real_jid.select({real_jid.real_jid}).with(real_jid.message_id, "=", message.id)[real_jid.real_jid]; - } - - public void add_conversation(Conversation new_conversation) { - var insert = conversation.insert() - .value(conversation.jid_id, get_jid_id(new_conversation.counterpart)) - .value(conversation.account_id, new_conversation.account.id) - .value(conversation.type_, new_conversation.type_) - .value(conversation.encryption, new_conversation.encryption) - //.value(conversation.read_up_to, new_conversation.read_up_to) - .value(conversation.active, new_conversation.active); - if (new_conversation.last_active != null) { - insert.value(conversation.last_active, (long) new_conversation.last_active.to_unix()); - } - new_conversation.id = (int) insert.perform(); - new_conversation.notify.connect(on_conversation_update); - } - 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)) { - ret.add(get_conversation_from_row(row)); + ret.add(new Conversation.from_row(this, row)); } return ret; } - private void on_conversation_update(Object o, ParamSpec sp) { - Conversation changed_conversation = (Conversation) o; - var update = conversation.update().with(conversation.jid_id, "=", get_jid_id(changed_conversation.counterpart)).with(conversation.account_id, "=", changed_conversation.account.id) - .set(conversation.type_, changed_conversation.type_) - .set(conversation.encryption, changed_conversation.encryption) - //.set(conversation.read_up_to, changed_conversation.read_up_to) - .set(conversation.active, changed_conversation.active); - if (changed_conversation.last_active != null) { - update.set(conversation.last_active, (long) changed_conversation.last_active.to_unix()); - } else { - update.set_null(conversation.last_active); - } - update.perform(); - } - - private Conversation get_conversation_from_row(Row row) { - Conversation new_conversation = new Conversation(new Jid(get_jid_by_id(row[conversation.jid_id])), get_account_by_id(row[conversation.account_id])); - - new_conversation.id = row[conversation.id]; - new_conversation.active = row[conversation.active]; - int64? last_active = row[conversation.last_active]; - if (last_active != null) new_conversation.last_active = new DateTime.from_unix_utc(last_active); - new_conversation.type_ = (Conversation.Type) row[conversation.type_]; - new_conversation.encryption = (Encryption) row[conversation.encryption]; - int? read_up_to = row[conversation.read_up_to]; - if (read_up_to != null) new_conversation.read_up_to = get_message_by_id(read_up_to); - - new_conversation.notify.connect(on_conversation_update); - return new_conversation; - } - public void set_avatar_hash(Jid jid, string hash, int type) { avatar.insert().or("REPLACE") .value(avatar.jid, jid.to_string()) @@ -429,12 +255,12 @@ public class Database : Qlite.Database { } - private int get_jid_id(Jid jid_obj) { + public int get_jid_id(Jid jid_obj) { Row? row = jid.row_with(jid.bare_jid, jid_obj.bare_jid.to_string()).inner; return row != null ? row[jid.id] : add_jid(jid_obj); } - private string? get_jid_by_id(int id) { + public string? get_jid_by_id(int id) { return jid.select({jid.bare_jid}).with(jid.id, "=", id)[jid.bare_jid]; } diff --git a/libdino/src/service/message_manager.vala b/libdino/src/service/message_manager.vala index e83e82b1..c2d1021e 100644 --- a/libdino/src/service/message_manager.vala +++ b/libdino/src/service/message_manager.vala @@ -36,7 +36,7 @@ public class MessageManager : StreamInteractionModule, Object { public void send_message(string text, Conversation conversation) { Entities.Message message = create_out_message(text, conversation); add_message(message, conversation); - db.add_message(message, conversation.account); + message.persist(db); send_xmpp_message(message, conversation); message_sent(message, conversation); } @@ -88,7 +88,8 @@ public class MessageManager : StreamInteractionModule, Object { private void on_message_received(Account account, Xmpp.Message.Stanza message) { if (message.body == null) return; - Entities.Message new_message = new Entities.Message(); + Entities.Message.Type type_ = message.type_ == Xmpp.Message.Stanza.TYPE_GROUPCHAT ? Entities.Message.Type.GROUPCHAT : Entities.Message.Type.CHAT; + Entities.Message new_message = new Entities.Message(message.body, type_); new_message.account = account; new_message.stanza_id = message.id; Jid from_jid = new Jid(message.from); @@ -100,9 +101,7 @@ public class MessageManager : StreamInteractionModule, Object { } new_message.counterpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.to) : new Jid(message.from); new_message.ourpart = new_message.direction == Entities.Message.DIRECTION_SENT ? new Jid(message.from) : new Jid(message.to); - new_message.body = message.body; new_message.stanza = message; - new_message.set_type_string(message.type_); Xep.DelayedDelivery.MessageFlag? deleyed_delivery_flag = Xep.DelayedDelivery.MessageFlag.get_flag(message); new_message.time = deleyed_delivery_flag != null ? deleyed_delivery_flag.datetime : new DateTime.now_utc(); new_message.local_time = new DateTime.now_utc(); @@ -112,7 +111,7 @@ public class MessageManager : StreamInteractionModule, Object { bool is_uuid = new_message.stanza_id != null && Regex.match_simple("""[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}""", new_message.stanza_id); if ((is_uuid && !db.contains_message_by_stanza_id(new_message.stanza_id, conversation.account)) || (!is_uuid && !db.contains_message(new_message, conversation.account))) { - db.add_message(new_message, conversation.account); + new_message.persist(db); add_message(new_message, conversation); if (new_message.time.difference(conversation.last_active) > 0) { conversation.last_active = new_message.time; @@ -133,7 +132,8 @@ public class MessageManager : StreamInteractionModule, Object { } private Entities.Message create_out_message(string text, Conversation conversation) { - Entities.Message message = new Entities.Message(); + Entities.Message.Type type_ = conversation.type_ == Conversation.Type.GROUPCHAT ? Entities.Message.Type.GROUPCHAT : Entities.Message.Type.CHAT; + Entities.Message message = new Entities.Message(text, type_); message.stanza_id = random_uuid(); message.account = conversation.account; message.body = text; |