From fa78573b052693b29350bdd0f7eaf74dc6571e4a Mon Sep 17 00:00:00 2001 From: fiaxh Date: Wed, 22 Mar 2017 17:15:06 +0100 Subject: Move some database interaction into entities fixes #2 --- libdino/src/entity/account.vala | 64 +++++++++++++++++++---- libdino/src/entity/conversation.vala | 68 ++++++++++++++++++++----- libdino/src/entity/message.vala | 99 ++++++++++++++++++++++++++++++++++-- 3 files changed, 205 insertions(+), 26 deletions(-) (limited to 'libdino/src/entity') 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 -- cgit v1.2.3-70-g09d2