Fix bug with message retention count during GC plus fix test case

This commit is contained in:
Chris Heywood 2020-08-24 19:29:44 +10:00
parent 497d9906bd
commit 4fdaaeacd9
2 changed files with 50 additions and 8 deletions

View file

@ -947,23 +947,42 @@ private class Geary.ImapDB.Folder : BaseObject, Geary.ReferenceSemantics {
// UIDs not guaranteed to be in order.
StringBuilder sql = new StringBuilder();
sql.append("""
SELECT ml.id, ml.message_id, ml.ordering
SELECT COUNT(*)
FROM MessageLocationTable ml
INNER JOIN MessageTable m
INDEXED BY MessageTableInternalDateTimeTIndex
ON ml.message_id = m.id
WHERE folder_id = ?
AND m.internaldate_time_t < ?
ORDER BY m.internaldate_time_t DESC
LIMIT -1 OFFSET ?;
WHERE ml.folder_id = ?
AND m.internaldate_time_t >= ?
""");
Db.Statement stmt = cx.prepare(sql.str);
stmt.bind_rowid(0, folder_id);
stmt.bind_int64(1, cutoff.to_unix());
stmt.bind_int64(2, MINIMUM_MESSAGES_TO_RETAIN_DURING_GC);
Db.Result results = stmt.exec(cancellable);
int64 found_within_threshold = results.int64_at(0);
int64 extra_to_retain =
(MINIMUM_MESSAGES_TO_RETAIN_DURING_GC - found_within_threshold).clamp(0, int64.MAX);
sql = new StringBuilder();
sql.append("""
SELECT ml.id, ml.message_id, ml.ordering
FROM MessageLocationTable ml
INNER JOIN MessageTable m
INDEXED BY MessageTableInternalDateTimeTIndex
ON ml.message_id = m.id
WHERE ml.folder_id = ?
AND m.internaldate_time_t < ?
ORDER BY m.internaldate_time_t DESC
LIMIT -1 OFFSET ?;
""");
stmt = cx.prepare(sql.str);
stmt.bind_rowid(0, folder_id);
stmt.bind_int64(1, cutoff.to_unix());
stmt.bind_int64(2, extra_to_retain);
results = stmt.exec(cancellable);
while (!results.finished) {
if (deleted_email_ids == null) {

View file

@ -366,6 +366,22 @@ class Geary.ImapDB.FolderTest : TestCase {
(3, 3, 1, 2, 1);
""");
for (int i = 4; i <= 200; i++) {
this.account.db.exec(
"INSERT INTO MessageTable (id, fields, to_field, internaldate_time_t) " +
"VALUES (%d, %d, '%s', %s);".printf(i,
fixture_fields,
fixture_to,
beyond_threshold.to_unix().to_string())
);
this.account.db.exec(
"INSERT INTO MessageLocationTable " +
" (id, message_id, folder_id, ordering, remove_marker) " +
"VALUES (%d, %d, 1, %d, 1);".printf(i, i, i)
);
}
this.folder.detach_emails_before_timestamp.begin(
threshold,
null,
@ -375,7 +391,7 @@ class Geary.ImapDB.FolderTest : TestCase {
int64[] expected = { 1, 2 };
Db.Result result = this.account.db.query(
"SELECT id FROM MessageLocationTable"
"SELECT id FROM MessageLocationTable WHERE id IN (1, 2);"
);
int i = 0;
@ -386,6 +402,13 @@ class Geary.ImapDB.FolderTest : TestCase {
result.next();
}
assert_true(i == expected.length, "Not enough rows");
result = this.account.db.query(
"SELECT COUNT(id) FROM MessageLocationTable WHERE folder_id = 1;"
);
assert_false(result.finished);
assert_equal<int64?>(result.int64_at(0), 100);
result.next();
}
private Email new_mock_remote_email(int64 uid,