diff options
Diffstat (limited to 'libdino/src/service/database.vala')
-rw-r--r-- | libdino/src/service/database.vala | 88 |
1 files changed, 79 insertions, 9 deletions
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala index 25db82f8..8a470d12 100644 --- a/libdino/src/service/database.vala +++ b/libdino/src/service/database.vala @@ -6,7 +6,7 @@ using Dino.Entities; namespace Dino { public class Database : Qlite.Database { - private const int VERSION = 6; + private const int VERSION = 8; public class AccountTable : Table { public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true }; @@ -34,6 +34,21 @@ public class Database : Qlite.Database { } } + public class ContentTable : Table { + public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true }; + public Column<int> conversation_id = new Column.Integer("conversation_id") { not_null = true }; + public Column<long> time = new Column.Long("time") { not_null = true }; + public Column<long> local_time = new Column.Long("local_time") { not_null = true }; + public Column<int> content_type = new Column.Integer("content_type") { not_null = true }; + public Column<int> foreign_id = new Column.Integer("foreign_id") { not_null = true }; + + internal ContentTable(Database db) { + base(db, "content_item"); + init({id, conversation_id, time, local_time, content_type, foreign_id}); + unique({content_type, foreign_id}, "IGNORE"); + } + } + public class MessageTable : Table { public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true }; public Column<string> stanza_id = new Column.Text("stanza_id"); @@ -54,6 +69,7 @@ public class Database : Qlite.Database { init({id, stanza_id, account_id, counterpart_id, our_resource, counterpart_resource, direction, type_, time, local_time, body, encryption, marked}); index("message_localtime_counterpart_idx", {local_time, counterpart_id}); + fts({body}); } } @@ -173,6 +189,7 @@ public class Database : Qlite.Database { public AccountTable account { get; private set; } public JidTable jid { get; private set; } + public ContentTable content { get; private set; } public MessageTable message { get; private set; } public RealJidTable real_jid { get; private set; } public FileTransferTable file_transfer { get; private set; } @@ -190,6 +207,7 @@ public class Database : Qlite.Database { base(fileName, VERSION); account = new AccountTable(this); jid = new JidTable(this); + content = new ContentTable(this); message = new MessageTable(this); real_jid = new RealJidTable(this); file_transfer = new FileTransferTable(this); @@ -198,7 +216,7 @@ public class Database : Qlite.Database { entity_feature = new EntityFeatureTable(this); roster = new RosterTable(this); settings = new SettingsTable(this); - init({ account, jid, message, real_jid, file_transfer, conversation, avatar, entity_feature, roster, settings }); + init({ account, jid, content, message, real_jid, file_transfer, conversation, avatar, entity_feature, roster, settings }); try { exec("PRAGMA synchronous=0"); } catch (Error e) { } @@ -206,6 +224,31 @@ public class Database : Qlite.Database { public override void migrate(long oldVersion) { // new table columns are added, outdated columns are still present + if (oldVersion < 7) { + message.fts_rebuild(); + } else if (oldVersion < 8) { + exec(""" + insert into content_item (conversation_id, time, local_time, content_type, foreign_id) + select conversation.id, message.time, message.local_time, 1, message.id + from message join conversation on + message.account_id=conversation.account_id and + message.counterpart_id=conversation.jid_id and + message.type=conversation.type+1 and + (message.counterpart_resource=conversation.resource or message.type != 3) + where + message.body not in (select info from file_transfer where info not null) and + message.id not in (select info from file_transfer where info not null) + union + select conversation.id, message.time, message.local_time, 2, file_transfer.id + from file_transfer + join message on + file_transfer.info=message.id + join conversation on + file_transfer.account_id=conversation.account_id and + file_transfer.counterpart_id=conversation.jid_id and + message.type=conversation.type+1 and + (message.counterpart_resource=conversation.resource or message.type != 3)"""); + } } public ArrayList<Account> get_accounts() { @@ -232,11 +275,41 @@ public class Database : Qlite.Database { } } - public Gee.List<Message> get_messages(Xmpp.Jid jid, Account account, Message.Type? type, int count, DateTime? before) { - QueryBuilder select = message.select() - .with(message.counterpart_id, "=", get_jid_id(jid)) + public int add_content_item(Conversation conversation, DateTime time, DateTime local_time, int content_type, int foreign_id) { + return (int) content.insert() + .value(content.conversation_id, conversation.id) + .value(content.local_time, (long) local_time.to_unix()) + .value(content.time, (long) time.to_unix()) + .value(content.content_type, content_type) + .value(content.foreign_id, foreign_id) + .perform(); + } + + public Gee.List<Message> get_messages(Xmpp.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(@"local_time < ? OR (local_time = ? AND 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(@"local_time > ? OR (local_time = ? AND id > ?)", { after.to_unix().to_string(), after.to_unix().to_string(), id.to_string() }); + } else { + select.with(message.local_time, ">", (long) after.to_unix()); + } + if (id > 0) { + select.with(message.id, ">", id); + } + } else { + select.order_by(message.id, "DESC"); + } + + select.with(message.counterpart_id, "=", get_jid_id(jid)) .with(message.account_id, "=", account.id) - .order_by(message.id, "DESC") .limit(count); if (jid.resourcepart != null) { select.with(message.counterpart_resource, "=", jid.resourcepart); @@ -244,9 +317,6 @@ public class Database : Qlite.Database { if (type != null) { select.with(message.type_, "=", (int) type); } - if (before != null) { - select.with(message.local_time, "<", (long) before.to_unix()); - } LinkedList<Message> ret = new LinkedList<Message>(); foreach (Row row in select) { |