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.vala88
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) {