2011-06-16 16:27:08 -07:00
|
|
|
/* Copyright 2011 Yorba Foundation
|
|
|
|
|
*
|
|
|
|
|
* This software is licensed under the GNU Lesser General Public License
|
|
|
|
|
* (version 2.1 or later). See the COPYING file in this distribution.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
public class Geary.Sqlite.MessageTable : Geary.Sqlite.Table {
|
|
|
|
|
// This *must* match the column order in the database
|
|
|
|
|
public enum Column {
|
|
|
|
|
ID,
|
2011-06-23 19:07:04 -07:00
|
|
|
FIELDS,
|
2011-06-16 16:27:08 -07:00
|
|
|
|
|
|
|
|
DATE_FIELD,
|
2011-07-15 13:39:02 -07:00
|
|
|
DATE_TIME_T,
|
2011-06-16 16:27:08 -07:00
|
|
|
|
|
|
|
|
FROM_FIELD,
|
|
|
|
|
SENDER,
|
|
|
|
|
REPLY_TO,
|
|
|
|
|
|
|
|
|
|
TO_FIELD,
|
|
|
|
|
CC,
|
|
|
|
|
BCC,
|
|
|
|
|
|
|
|
|
|
MESSAGE_ID,
|
|
|
|
|
IN_REPLY_TO,
|
|
|
|
|
|
|
|
|
|
SUBJECT,
|
|
|
|
|
|
|
|
|
|
HEADER,
|
|
|
|
|
|
|
|
|
|
BODY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal MessageTable(Geary.Sqlite.Database gdb, SQLHeavy.Table table) {
|
|
|
|
|
base (gdb, table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async int64 create_async(MessageRow row, Cancellable? cancellable) throws Error {
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
|
|
|
|
"INSERT INTO MessageTable "
|
2011-06-23 19:07:04 -07:00
|
|
|
+ "(fields, date_field, date_time_t, from_field, sender, reply_to, to_field, cc, bcc, "
|
|
|
|
|
+ "message_id, in_reply_to, subject, header, body) "
|
|
|
|
|
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
|
|
|
query.bind_int(0, row.fields);
|
|
|
|
|
query.bind_string(1, row.date);
|
|
|
|
|
query.bind_int64(2, row.date_time_t);
|
|
|
|
|
query.bind_string(3, row.from);
|
|
|
|
|
query.bind_string(4, row.sender);
|
|
|
|
|
query.bind_string(5, row.reply_to);
|
|
|
|
|
query.bind_string(6, row.to);
|
|
|
|
|
query.bind_string(7, row.cc);
|
|
|
|
|
query.bind_string(8, row.bcc);
|
|
|
|
|
query.bind_string(9, row.message_id);
|
|
|
|
|
query.bind_string(10, row.in_reply_to);
|
|
|
|
|
query.bind_string(11, row.subject);
|
|
|
|
|
query.bind_string(12, row.header);
|
|
|
|
|
query.bind_string(13, row.body);
|
2011-06-16 16:27:08 -07:00
|
|
|
|
|
|
|
|
return yield query.execute_insert_async(cancellable);
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 19:07:04 -07:00
|
|
|
public async void merge_async(MessageRow row, Cancellable? cancellable = null) throws Error {
|
|
|
|
|
SQLHeavy.Transaction transaction = db.begin_transaction();
|
|
|
|
|
|
|
|
|
|
// merge the valid fields in the row
|
|
|
|
|
SQLHeavy.Query query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET fields = fields | ? WHERE id=?");
|
|
|
|
|
query.bind_int(0, row.fields);
|
|
|
|
|
query.bind_int64(1, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.DATE)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET date_field=?, date_time_t=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.date);
|
|
|
|
|
query.bind_int64(1, row.date_time_t);
|
|
|
|
|
query.bind_int64(2, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.ORIGINATORS)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET from_field=?, sender=?, reply_to=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.from);
|
|
|
|
|
query.bind_string(1, row.sender);
|
|
|
|
|
query.bind_string(2, row.reply_to);
|
|
|
|
|
query.bind_int64(3, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.RECEIVERS)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET to_field=?, cc=?, bcc=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.to);
|
|
|
|
|
query.bind_string(1, row.cc);
|
|
|
|
|
query.bind_string(2, row.bcc);
|
|
|
|
|
query.bind_int64(3, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.REFERENCES)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET message_id=?, in_reply_to=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.message_id);
|
|
|
|
|
query.bind_string(1, row.in_reply_to);
|
|
|
|
|
query.bind_int64(2, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.SUBJECT)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET subject=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.subject);
|
|
|
|
|
query.bind_int64(1, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.HEADER)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET header=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.header);
|
|
|
|
|
query.bind_int64(1, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-15 13:39:02 -07:00
|
|
|
if (row.fields.is_any_set(Geary.Email.Field.BODY)) {
|
2011-06-23 19:07:04 -07:00
|
|
|
query = transaction.prepare(
|
|
|
|
|
"UPDATE MessageTable SET body=? WHERE id=?");
|
|
|
|
|
query.bind_string(0, row.body);
|
|
|
|
|
query.bind_int64(1, row.id);
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield query.execute_async(cancellable);
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-07-18 12:26:43 -07:00
|
|
|
yield transaction.commit_async();
|
2011-06-23 19:07:04 -07:00
|
|
|
}
|
|
|
|
|
|
2011-06-16 16:27:08 -07:00
|
|
|
public async Gee.List<MessageRow>? list_by_message_id_async(Geary.RFC822.MessageID message_id,
|
|
|
|
|
Geary.Email.Field fields, Cancellable? cancellable) throws Error {
|
|
|
|
|
assert(fields != Geary.Email.Field.NONE);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
2011-06-23 19:07:04 -07:00
|
|
|
"SELECT %s FROM MessageTable WHERE message_id=?".printf(fields_to_columns(fields)));
|
2011-06-16 16:27:08 -07:00
|
|
|
query.bind_string(0, message_id.value);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.QueryResult results = yield query.execute_async(cancellable);
|
|
|
|
|
if (results.finished)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
Gee.List<MessageRow> list = new Gee.ArrayList<MessageRow>();
|
|
|
|
|
do {
|
|
|
|
|
list.add(new MessageRow.from_query_result(this, fields, results));
|
|
|
|
|
yield results.next_async(cancellable);
|
|
|
|
|
} while (!results.finished);
|
|
|
|
|
|
|
|
|
|
return (list.size > 0) ? list : null;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 19:07:04 -07:00
|
|
|
public async MessageRow? fetch_async(int64 id, Geary.Email.Field requested_fields,
|
2011-06-16 16:27:08 -07:00
|
|
|
Cancellable? cancellable = null) throws Error {
|
2011-06-23 19:07:04 -07:00
|
|
|
assert(requested_fields != Geary.Email.Field.NONE);
|
2011-06-16 16:27:08 -07:00
|
|
|
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
2011-06-23 19:07:04 -07:00
|
|
|
"SELECT %s FROM MessageTable WHERE id=?".printf(fields_to_columns(requested_fields)));
|
2011-06-16 16:27:08 -07:00
|
|
|
query.bind_int64(0, id);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.QueryResult results = yield query.execute_async(cancellable);
|
|
|
|
|
if (results.finished)
|
|
|
|
|
return null;
|
|
|
|
|
|
2011-06-23 19:07:04 -07:00
|
|
|
MessageRow row = new MessageRow.from_query_result(this, requested_fields, results);
|
2011-06-16 16:27:08 -07:00
|
|
|
|
|
|
|
|
return row;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-23 19:07:04 -07:00
|
|
|
public async bool fetch_fields_async(int64 id, out Geary.Email.Field available_fields,
|
|
|
|
|
Cancellable? cancellable = null) throws Error {
|
|
|
|
|
available_fields = Geary.Email.Field.NONE;
|
|
|
|
|
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
|
|
|
|
"SELECT fields FROM MessageTable WHERE id=?");
|
|
|
|
|
query.bind_int64(0, id);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.QueryResult result = yield query.execute_async(cancellable);
|
|
|
|
|
if (result.finished)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
available_fields = (Geary.Email.Field) result.fetch_int(0);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2011-06-16 16:27:08 -07:00
|
|
|
private static string fields_to_columns(Geary.Email.Field fields) {
|
2011-06-23 19:07:04 -07:00
|
|
|
StringBuilder builder = new StringBuilder("id, fields");
|
2011-06-16 16:27:08 -07:00
|
|
|
foreach (Geary.Email.Field field in Geary.Email.Field.all()) {
|
|
|
|
|
string? append = null;
|
2011-06-21 17:48:40 -07:00
|
|
|
if ((fields & field) != 0) {
|
|
|
|
|
switch (field) {
|
|
|
|
|
case Geary.Email.Field.DATE:
|
|
|
|
|
append = "date_field, date_time_t";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.ORIGINATORS:
|
|
|
|
|
append = "from_field, sender, reply_to";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.RECEIVERS:
|
|
|
|
|
append = "to_field, cc, bcc";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.REFERENCES:
|
|
|
|
|
append = "message_id, in_reply_to";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.SUBJECT:
|
|
|
|
|
append = "subject";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.HEADER:
|
|
|
|
|
append = "header";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Geary.Email.Field.BODY:
|
|
|
|
|
append = "body";
|
|
|
|
|
break;
|
|
|
|
|
}
|
2011-06-16 16:27:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (append != null) {
|
|
|
|
|
if (!String.is_empty(builder.str))
|
|
|
|
|
builder.append(", ");
|
|
|
|
|
|
|
|
|
|
builder.append(append);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return builder.str;
|
|
|
|
|
}
|
2011-06-23 19:07:04 -07:00
|
|
|
|
|
|
|
|
public async int search_message_id_count_async(Geary.RFC822.MessageID message_id,
|
|
|
|
|
Cancellable? cancellable = null) throws Error {
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
|
|
|
|
"SELECT COUNT(*) FROM MessageTable WHERE message_id=?");
|
|
|
|
|
query.bind_string(0, message_id.value);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.QueryResult result = yield query.execute_async(cancellable);
|
|
|
|
|
|
|
|
|
|
return (result.finished) ? 0 : result.fetch_int(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Gee.List<int64?>? search_message_id_async(Geary.RFC822.MessageID message_id,
|
|
|
|
|
Cancellable? cancellable = null) throws Error {
|
|
|
|
|
SQLHeavy.Query query = db.prepare(
|
|
|
|
|
"SELECT id FROM MessageTable WHERE message_id=?");
|
|
|
|
|
query.bind_string(0, message_id.value);
|
|
|
|
|
|
|
|
|
|
SQLHeavy.QueryResult result = yield query.execute_async(cancellable);
|
|
|
|
|
if (result.finished)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
Gee.List<int64?> list = new Gee.ArrayList<int64?>();
|
|
|
|
|
do {
|
|
|
|
|
list.add(result.fetch_int64(0));
|
|
|
|
|
yield result.next_async(cancellable);
|
|
|
|
|
} while (!result.finished);
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
2011-06-16 16:27:08 -07:00
|
|
|
}
|
|
|
|
|
|