From 4fdaaeacd9720d4b5b2d48be76c316a6a824c42f Mon Sep 17 00:00:00 2001 From: Chris Heywood <15127-creywood@users.noreply.gitlab.gnome.org> Date: Mon, 24 Aug 2020 19:29:44 +1000 Subject: [PATCH] Fix bug with message retention count during GC plus fix test case --- src/engine/imap-db/imap-db-folder.vala | 33 +++++++++++++++----- test/engine/imap-db/imap-db-folder-test.vala | 25 ++++++++++++++- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/engine/imap-db/imap-db-folder.vala b/src/engine/imap-db/imap-db-folder.vala index 52f3e82f..de015f5a 100644 --- a/src/engine/imap-db/imap-db-folder.vala +++ b/src/engine/imap-db/imap-db-folder.vala @@ -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) { diff --git a/test/engine/imap-db/imap-db-folder-test.vala b/test/engine/imap-db/imap-db-folder-test.vala index be02bcb5..bce1fb43 100644 --- a/test/engine/imap-db/imap-db-folder-test.vala +++ b/test/engine/imap-db/imap-db-folder-test.vala @@ -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(result.int64_at(0), 100); + result.next(); } private Email new_mock_remote_email(int64 uid,