Loading k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +11 −13 Original line number Diff line number Diff line Loading @@ -796,11 +796,7 @@ public class MessagingController { final LocalFolder localFolder = tLocalFolder; localFolder.open(Folder.OPEN_MODE_RW); localFolder.updateLastUid(); List<? extends Message> localMessages = localFolder.getMessages(null); Map<String, Message> localUidMap = new HashMap<>(); for (Message message : localMessages) { localUidMap.put(message.getUid(), message); } Map<String, Long> localUidMap = localFolder.getAllMessagesAndEffectiveDates(); if (providedRemoteFolder != null) { if (K9.DEBUG) Loading Loading @@ -899,8 +895,9 @@ public class MessagingController { for (MessagingListener l : getListeners(listener)) { l.synchronizeMailboxHeadersProgress(account, folder, headerProgress.get(), messageCount); } Message localMessage = localUidMap.get(thisMess.getUid()); if (localMessage == null || !localMessage.olderThan(earliestDate)) { Long localMessageDateRaw = localUidMap.get(thisMess.getUid()); Date localMessageDate = localMessageDateRaw != null ? new Date(localMessageDateRaw) : null; if (localMessageDate == null || !localMessageDate.before(earliestDate)) { remoteMessages.add(thisMess); remoteUidMap.put(thisMess.getUid(), thisMess); } Loading @@ -921,14 +918,15 @@ public class MessagingController { */ MoreMessages moreMessages = localFolder.getMoreMessages(); if (account.syncRemoteDeletions()) { List<Message> destroyMessages = new ArrayList<>(); for (Message localMessage : localMessages) { if (remoteUidMap.get(localMessage.getUid()) == null) { destroyMessages.add(localMessage); List<String> destroyMessageUids = new ArrayList<>(); for (String localMessageUid : localUidMap.keySet()) { if (remoteUidMap.get(localMessageUid) == null) { destroyMessageUids.add(localMessageUid); } } if (!destroyMessages.isEmpty()) { List<LocalMessage> destroyMessages = localFolder.getMessagesByUids(destroyMessageUids); if (!destroyMessageUids.isEmpty()) { moreMessages = MoreMessages.UNKNOWN; localFolder.destroyMessages(destroyMessages); Loading @@ -941,7 +939,7 @@ public class MessagingController { } } // noinspection UnusedAssignment, free memory early? (better break up the method!) localMessages = null; localUidMap = null; if (moreMessages == MoreMessages.UNKNOWN) { updateMoreMessages(remoteFolder, localFolder, earliestDate, remoteStart); Loading k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +37 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,43 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable { } } public Map<String,Long> getAllMessagesAndEffectiveDates() throws MessagingException { try { return localStore.database.execute(false, new DbCallback<Map<String, Long>>() { @Override public Map<String, Long> doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException { Cursor cursor = null; HashMap<String, Long> result = new HashMap<>(); try { open(OPEN_MODE_RO); cursor = db.rawQuery( "SELECT uid, date " + "FROM messages " + "WHERE empty = 0 AND deleted = 0 AND " + "folder_id = ? ORDER BY date DESC", new String[] { Long.toString(mFolderId) }); while (cursor.moveToNext()) { String uid = cursor.getString(0); Long date = cursor.isNull(1) ? null : cursor.getLong(1); result.put(uid, date); } } catch (MessagingException e) { throw new WrappedException(e); } finally { Utility.closeQuietly(cursor); } return result; } }); } catch (WrappedException e) { throw(MessagingException) e.getCause(); } } public List<LocalMessage> getMessages(MessageRetrievalListener<LocalMessage> listener) throws MessagingException { return getMessages(listener, true); } Loading k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java +8 −4 Original line number Diff line number Diff line package com.fsck.k9.controller; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; Loading @@ -26,7 +27,6 @@ import com.fsck.k9.mailstore.LocalMessage; import com.fsck.k9.mailstore.LocalStore; import com.fsck.k9.notification.NotificationController; import com.fsck.k9.search.LocalSearch; import org.junit.After; import org.junit.Before; import org.junit.Test; Loading Loading @@ -65,6 +65,7 @@ import static org.mockito.Mockito.when; public class MessagingControllerTest { private static final String FOLDER_NAME = "Folder"; private static final int MAXIMUM_SMALL_MESSAGE_SIZE = 1000; private static final String MESSAGE_UID1 = "message-uid1"; private MessagingController controller; Loading Loading @@ -573,7 +574,9 @@ public class MessagingControllerTest { messageCountInRemoteFolder(0); LocalMessage localCopyOfRemoteDeletedMessage = mock(LocalMessage.class); when(account.syncRemoteDeletions()).thenReturn(true); when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localCopyOfRemoteDeletedMessage)); when(localFolder.getAllMessagesAndEffectiveDates()).thenReturn(Collections.singletonMap(MESSAGE_UID1, 0L)); when(localFolder.getMessagesByUids(any(List.class))) .thenReturn(Collections.singletonList(localCopyOfRemoteDeletedMessage)); controller.synchronizeMailboxSynchronous(account, FOLDER_NAME, listener, remoteFolder); Loading Loading @@ -606,7 +609,8 @@ public class MessagingControllerTest { when(account.syncRemoteDeletions()).thenReturn(true); when(account.getEarliestPollDate()).thenReturn(dateOfEarliestPoll); when(localMessage.olderThan(dateOfEarliestPoll)).thenReturn(true); when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localMessage)); when(localFolder.getAllMessagesAndEffectiveDates()).thenReturn(Collections.singletonMap(MESSAGE_UID1, 0L)); when(localFolder.getMessagesByUids(any(List.class))).thenReturn(Collections.singletonList(localMessage)); controller.synchronizeMailboxSynchronous(account, FOLDER_NAME, listener, remoteFolder); Loading Loading @@ -638,9 +642,9 @@ public class MessagingControllerTest { verify(remoteFolder, atLeastOnce()).fetch(any(List.class), fetchProfileCaptor.capture(), any(MessageRetrievalListener.class)); assertEquals(2, fetchProfileCaptor.getAllValues().get(0).size()); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.FLAGS)); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.ENVELOPE)); assertEquals(2, fetchProfileCaptor.getAllValues().get(0).size()); } @Test Loading Loading
k9mail/src/main/java/com/fsck/k9/controller/MessagingController.java +11 −13 Original line number Diff line number Diff line Loading @@ -796,11 +796,7 @@ public class MessagingController { final LocalFolder localFolder = tLocalFolder; localFolder.open(Folder.OPEN_MODE_RW); localFolder.updateLastUid(); List<? extends Message> localMessages = localFolder.getMessages(null); Map<String, Message> localUidMap = new HashMap<>(); for (Message message : localMessages) { localUidMap.put(message.getUid(), message); } Map<String, Long> localUidMap = localFolder.getAllMessagesAndEffectiveDates(); if (providedRemoteFolder != null) { if (K9.DEBUG) Loading Loading @@ -899,8 +895,9 @@ public class MessagingController { for (MessagingListener l : getListeners(listener)) { l.synchronizeMailboxHeadersProgress(account, folder, headerProgress.get(), messageCount); } Message localMessage = localUidMap.get(thisMess.getUid()); if (localMessage == null || !localMessage.olderThan(earliestDate)) { Long localMessageDateRaw = localUidMap.get(thisMess.getUid()); Date localMessageDate = localMessageDateRaw != null ? new Date(localMessageDateRaw) : null; if (localMessageDate == null || !localMessageDate.before(earliestDate)) { remoteMessages.add(thisMess); remoteUidMap.put(thisMess.getUid(), thisMess); } Loading @@ -921,14 +918,15 @@ public class MessagingController { */ MoreMessages moreMessages = localFolder.getMoreMessages(); if (account.syncRemoteDeletions()) { List<Message> destroyMessages = new ArrayList<>(); for (Message localMessage : localMessages) { if (remoteUidMap.get(localMessage.getUid()) == null) { destroyMessages.add(localMessage); List<String> destroyMessageUids = new ArrayList<>(); for (String localMessageUid : localUidMap.keySet()) { if (remoteUidMap.get(localMessageUid) == null) { destroyMessageUids.add(localMessageUid); } } if (!destroyMessages.isEmpty()) { List<LocalMessage> destroyMessages = localFolder.getMessagesByUids(destroyMessageUids); if (!destroyMessageUids.isEmpty()) { moreMessages = MoreMessages.UNKNOWN; localFolder.destroyMessages(destroyMessages); Loading @@ -941,7 +939,7 @@ public class MessagingController { } } // noinspection UnusedAssignment, free memory early? (better break up the method!) localMessages = null; localUidMap = null; if (moreMessages == MoreMessages.UNKNOWN) { updateMoreMessages(remoteFolder, localFolder, earliestDate, remoteStart); Loading
k9mail/src/main/java/com/fsck/k9/mailstore/LocalFolder.java +37 −0 Original line number Diff line number Diff line Loading @@ -865,6 +865,43 @@ public class LocalFolder extends Folder<LocalMessage> implements Serializable { } } public Map<String,Long> getAllMessagesAndEffectiveDates() throws MessagingException { try { return localStore.database.execute(false, new DbCallback<Map<String, Long>>() { @Override public Map<String, Long> doDbWork(final SQLiteDatabase db) throws WrappedException, UnavailableStorageException { Cursor cursor = null; HashMap<String, Long> result = new HashMap<>(); try { open(OPEN_MODE_RO); cursor = db.rawQuery( "SELECT uid, date " + "FROM messages " + "WHERE empty = 0 AND deleted = 0 AND " + "folder_id = ? ORDER BY date DESC", new String[] { Long.toString(mFolderId) }); while (cursor.moveToNext()) { String uid = cursor.getString(0); Long date = cursor.isNull(1) ? null : cursor.getLong(1); result.put(uid, date); } } catch (MessagingException e) { throw new WrappedException(e); } finally { Utility.closeQuietly(cursor); } return result; } }); } catch (WrappedException e) { throw(MessagingException) e.getCause(); } } public List<LocalMessage> getMessages(MessageRetrievalListener<LocalMessage> listener) throws MessagingException { return getMessages(listener, true); } Loading
k9mail/src/test/java/com/fsck/k9/controller/MessagingControllerTest.java +8 −4 Original line number Diff line number Diff line package com.fsck.k9.controller; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; Loading @@ -26,7 +27,6 @@ import com.fsck.k9.mailstore.LocalMessage; import com.fsck.k9.mailstore.LocalStore; import com.fsck.k9.notification.NotificationController; import com.fsck.k9.search.LocalSearch; import org.junit.After; import org.junit.Before; import org.junit.Test; Loading Loading @@ -65,6 +65,7 @@ import static org.mockito.Mockito.when; public class MessagingControllerTest { private static final String FOLDER_NAME = "Folder"; private static final int MAXIMUM_SMALL_MESSAGE_SIZE = 1000; private static final String MESSAGE_UID1 = "message-uid1"; private MessagingController controller; Loading Loading @@ -573,7 +574,9 @@ public class MessagingControllerTest { messageCountInRemoteFolder(0); LocalMessage localCopyOfRemoteDeletedMessage = mock(LocalMessage.class); when(account.syncRemoteDeletions()).thenReturn(true); when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localCopyOfRemoteDeletedMessage)); when(localFolder.getAllMessagesAndEffectiveDates()).thenReturn(Collections.singletonMap(MESSAGE_UID1, 0L)); when(localFolder.getMessagesByUids(any(List.class))) .thenReturn(Collections.singletonList(localCopyOfRemoteDeletedMessage)); controller.synchronizeMailboxSynchronous(account, FOLDER_NAME, listener, remoteFolder); Loading Loading @@ -606,7 +609,8 @@ public class MessagingControllerTest { when(account.syncRemoteDeletions()).thenReturn(true); when(account.getEarliestPollDate()).thenReturn(dateOfEarliestPoll); when(localMessage.olderThan(dateOfEarliestPoll)).thenReturn(true); when(localFolder.getMessages(null)).thenReturn(Collections.singletonList(localMessage)); when(localFolder.getAllMessagesAndEffectiveDates()).thenReturn(Collections.singletonMap(MESSAGE_UID1, 0L)); when(localFolder.getMessagesByUids(any(List.class))).thenReturn(Collections.singletonList(localMessage)); controller.synchronizeMailboxSynchronous(account, FOLDER_NAME, listener, remoteFolder); Loading Loading @@ -638,9 +642,9 @@ public class MessagingControllerTest { verify(remoteFolder, atLeastOnce()).fetch(any(List.class), fetchProfileCaptor.capture(), any(MessageRetrievalListener.class)); assertEquals(2, fetchProfileCaptor.getAllValues().get(0).size()); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.FLAGS)); assertTrue(fetchProfileCaptor.getAllValues().get(0).contains(FetchProfile.Item.ENVELOPE)); assertEquals(2, fetchProfileCaptor.getAllValues().get(0).size()); } @Test Loading