aboutsummaryrefslogtreecommitdiff
path: root/libdino/src/service/database.vala
diff options
context:
space:
mode:
Diffstat (limited to 'libdino/src/service/database.vala')
-rw-r--r--libdino/src/service/database.vala105
1 files changed, 96 insertions, 9 deletions
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala
index 25db82f8..e5ddd0f2 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 = 9;
public class AccountTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
@@ -34,6 +34,23 @@ public class Database : Qlite.Database {
}
}
+ public class ContentItemTable : 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 };
+ public Column<bool> hide = new Column.BoolInt("hide") { default = "0", not_null = true, min_version = 9 };
+
+ internal ContentItemTable(Database db) {
+ base(db, "content_item");
+ init({id, conversation_id, time, local_time, content_type, foreign_id, hide});
+ index("contentitem_localtime_counterpart_idx", {local_time, conversation_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 +71,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 +191,7 @@ public class Database : Qlite.Database {
public AccountTable account { get; private set; }
public JidTable jid { get; private set; }
+ public ContentItemTable content_item { 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 +209,7 @@ public class Database : Qlite.Database {
base(fileName, VERSION);
account = new AccountTable(this);
jid = new JidTable(this);
+ content_item = new ContentItemTable(this);
message = new MessageTable(this);
real_jid = new RealJidTable(this);
file_transfer = new FileTransferTable(this);
@@ -198,7 +218,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_item, message, real_jid, file_transfer, conversation, avatar, entity_feature, roster, settings });
try {
exec("PRAGMA synchronous=0");
} catch (Error e) { }
@@ -206,6 +226,45 @@ 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();
+ }
+ if (oldVersion < 8) {
+ exec("""
+ insert into content_item (conversation_id, time, local_time, content_type, foreign_id, hide)
+ select conversation.id, message.time, message.local_time, 1, message.id, 0
+ 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, 0
+ 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)""");
+ }
+ if (oldVersion < 9) {
+ exec("""
+ insert into content_item (conversation_id, time, local_time, content_type, foreign_id, hide)
+ select conversation.id, message.time, message.local_time, 1, message.id, 1
+ 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 in (select info from file_transfer where info not null) or
+ message.id in (select info from file_transfer where info not null)""");
+ }
}
public ArrayList<Account> get_accounts() {
@@ -232,11 +291,42 @@ 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, bool hide) {
+ return (int) content_item.insert()
+ .value(content_item.conversation_id, conversation.id)
+ .value(content_item.local_time, (long) local_time.to_unix())
+ .value(content_item.time, (long) time.to_unix())
+ .value(content_item.content_type, content_type)
+ .value(content_item.foreign_id, foreign_id)
+ .value(content_item.hide, hide)
+ .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 +334,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) {