Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite IMAP expunge #2927

Merged
merged 1 commit into from Nov 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions k9mail-library/src/main/java/com/fsck/k9/mail/Folder.java
Expand Up @@ -116,6 +116,9 @@ public abstract void setFlags(List<? extends Message> messages, Set<Flag> flags,
public void expunge() throws MessagingException
{}

public void expungeUids(List<String> uids) throws MessagingException {
}

/**
* Populate a list of messages based upon a FetchProfile. See {@link FetchProfile} for the things that can
* be fetched.
Expand Down
Expand Up @@ -14,4 +14,5 @@ class Capabilities {
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
public static final String STARTTLS = "STARTTLS";
public static final String SPECIAL_USE = "SPECIAL-USE";
public static final String UID_PLUS = "UIDPLUS";
}
Expand Up @@ -18,4 +18,5 @@ class Commands {
public static final String UID_STORE = "UID STORE";
public static final String UID_FETCH = "UID FETCH";
public static final String UID_COPY = "UID COPY";
public static final String UID_EXPUNGE = "UID EXPUNGE";
}
Expand Up @@ -710,6 +710,10 @@ protected boolean isIdleCapable() {
return capabilities.contains(Capabilities.IDLE);
}

boolean isUidPlusCapable() {
return capabilities.contains(Capabilities.UID_PLUS);
}

public void close() {
open = false;
stacktraceForClose = new Exception();
Expand Down
Expand Up @@ -1259,6 +1259,30 @@ public void expunge() throws MessagingException {
}
}

@Override
public void expungeUids(List<String> uids) throws MessagingException {
if (uids == null || uids.isEmpty()) {
throw new IllegalArgumentException("expungeUids() must be called with a non-empty set of UIDs");
}

open(OPEN_MODE_RW);
checkOpen();

try {
if (connection.isUidPlusCapable()) {
Set<Long> longUids = new HashSet<>(uids.size());
for (String uid : uids) {
longUids.add(Long.parseLong(uid));
}
connection.executeCommandWithIdSet(Commands.UID_EXPUNGE, "", longUids);
} else {
executeSimpleCommand("EXPUNGE");
}
} catch (IOException ioe) {
throw ioExceptionHandler(connection, ioe);
}
}

@Override
public void setFlags(Set<Flag> flags, boolean value) throws MessagingException {
open(OPEN_MODE_RW);
Expand Down
Expand Up @@ -1005,6 +1005,28 @@ public void expunge_shouldIssueExpungeCommand() throws Exception {
verify(imapConnection).executeSimpleCommand("EXPUNGE");
}

@Test
public void expungeUids_withUidPlus_shouldIssueUidExpungeCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
prepareImapFolderForOpen(OPEN_MODE_RW);
when(imapConnection.isUidPlusCapable()).thenReturn(true);

folder.expungeUids(singletonList("1"));

assertCommandWithIdsIssued("UID EXPUNGE 1");
}

@Test
public void expungeUids_withoutUidPlus_shouldIssueExpungeCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
prepareImapFolderForOpen(OPEN_MODE_RW);
when(imapConnection.isUidPlusCapable()).thenReturn(false);

folder.expungeUids(singletonList("1"));

verify(imapConnection).executeSimpleCommand("EXPUNGE");
}

@Test
public void setFlags_shouldIssueUidStoreCommand() throws Exception {
ImapFolder folder = createFolder("Folder");
Expand Down Expand Up @@ -1226,8 +1248,8 @@ private void assertCommandWithIdsIssued(String expectedCommand) throws Messaging

for (int i = 0, end = commandPrefixes.size(); i < end; i++) {
String command = commandPrefixes.get(i) +
" " + ImapUtility.join(",", commandUids.get(i)) + " " +
commandSuffixes.get(i);
" " + ImapUtility.join(",", commandUids.get(i)) +
((commandSuffixes.get(i).length() == 0) ? "" : " " + commandSuffixes.get(i));
if (command.equals(expectedCommand)) {
return;
}
Expand Down
Expand Up @@ -1830,7 +1830,7 @@ void processPendingAppend(PendingAppend command, Account account) throws Messagi
if (remoteDate != null) {
remoteMessage.setFlag(Flag.DELETED, true);
if (Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
remoteFolder.expunge();
remoteFolder.expungeUids(Collections.singletonList(remoteMessage.getUid()));
}
}
}
Expand Down Expand Up @@ -1914,7 +1914,11 @@ void processPendingMoveOrCopy(PendingMoveOrCopy command, Account account) throws
}
if (!isCopy && Expunge.EXPUNGE_IMMEDIATELY == account.getExpungePolicy()) {
Timber.i("processingPendingMoveOrCopy expunging folder %s:%s", account.getDescription(), srcFolder);
remoteSrcFolder.expunge();
List<String> movedUids = new ArrayList<>(messages.size());
for (Message message : messages) {
movedUids.add(message.getUid());
}
remoteSrcFolder.expungeUids(movedUids);
}

/*
Expand Down