Clean up the method to build message list selection.

- Moved the method to EmailCommon.
- Use *_SELECTION for magic mailboxes
  (meaning we now use subqueries for magic mailbox selections, rather than
   building the mailbox ID list by ourselves)

Change-Id: I3ebf6af62fd912fea6faea0f75e05fc61c87af3b
This commit is contained in:
Makoto Onuki 2011-05-13 14:09:22 -07:00
parent e0bb7e7909
commit 4c4e4c3515
8 changed files with 104 additions and 140 deletions

View File

@ -586,7 +586,14 @@ public abstract class EmailContent {
private static final String ACCOUNT_KEY_SELECTION =
MessageColumns.ACCOUNT_KEY + "=?";
/** Selection for messages that are loaded */
/**
* Selection for messages that are loaded
*
* POP messages at the initial stage have very little information. (Server UID only)
* Use this to make sure they're not visible on any UI.
* This means unread counts on the mailbox list can be different from the
* number of messages in the message list, but it should be transient...
*/
public static final String FLAG_LOADED_SELECTION =
MessageColumns.FLAG_LOADED + " IN ("
+ Message.FLAG_LOADED_PARTIAL + "," + Message.FLAG_LOADED_COMPLETE
@ -599,19 +606,37 @@ public abstract class EmailContent {
+ " WHERE " + MailboxColumns.TYPE + " = " + Mailbox.TYPE_TRASH
+ ")"
+ " AND " + FLAG_LOADED_SELECTION;
/** Selection to retrieve all messages in "inbox" for any account */
public static final String INBOX_SELECTION =
public static final String ALL_INBOX_SELECTION =
MessageColumns.MAILBOX_KEY + " IN ("
+ "SELECT " + MailboxColumns.ID + " FROM " + Mailbox.TABLE_NAME
+ " WHERE " + MailboxColumns.TYPE + " = " + Mailbox.TYPE_INBOX
+ ")"
+ " AND " + FLAG_LOADED_SELECTION;
/** Selection to retrieve all messages in "drafts" for any account */
public static final String ALL_DRAFT_SELECTION =
MessageColumns.MAILBOX_KEY + " IN ("
+ "SELECT " + MailboxColumns.ID + " FROM " + Mailbox.TABLE_NAME
+ " WHERE " + MailboxColumns.TYPE + " = " + Mailbox.TYPE_DRAFTS
+ ")"
+ " AND " + FLAG_LOADED_SELECTION;
/** Selection to retrieve all messages in "outbox" for any account */
public static final String ALL_OUTBOX_SELECTION =
MessageColumns.MAILBOX_KEY + " IN ("
+ "SELECT " + MailboxColumns.ID + " FROM " + Mailbox.TABLE_NAME
+ " WHERE " + MailboxColumns.TYPE + " = " + Mailbox.TYPE_OUTBOX
+ ")"; // NOTE No flag_loaded test for outboxes.
/** Selection to retrieve unread messages in "inbox" for any account */
public static final String UNREAD_SELECTION =
MessageColumns.FLAG_READ + "=0 AND " + INBOX_SELECTION;
public static final String ALL_UNREAD_SELECTION =
MessageColumns.FLAG_READ + "=0 AND " + ALL_INBOX_SELECTION;
/** Selection to retrieve all messages in "inbox" for one account */
public static final String PER_ACCOUNT_INBOX_SELECTION =
ACCOUNT_KEY_SELECTION + " AND " + INBOX_SELECTION;
ACCOUNT_KEY_SELECTION + " AND " + ALL_INBOX_SELECTION;
private static final String ACCOUNT_FAVORITE_SELECTION =
ACCOUNT_KEY_SELECTION + " AND " + ALL_FAVORITE_SELECTION;
@ -906,6 +931,40 @@ public abstract class EmailContent {
}
return -1;
}
/**
* Returns the where clause for a message list selection.
*
* Accesses the detabase to determine the mailbox type. DO NOT CALL FROM UI THREAD.
*/
public static String buildMessageListSelection(Context context, long mailboxId) {
if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
return Message.ALL_INBOX_SELECTION;
}
if (mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
return Message.ALL_DRAFT_SELECTION;
}
if (mailboxId == Mailbox.QUERY_ALL_OUTBOX) {
return Message.ALL_OUTBOX_SELECTION;
}
if (mailboxId == Mailbox.QUERY_ALL_UNREAD) {
return Message.ALL_UNREAD_SELECTION;
}
if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) {
return Message.ALL_FAVORITE_SELECTION;
}
// Now it's a regular mailbox.
final StringBuilder selection = new StringBuilder();
selection.append(MessageColumns.MAILBOX_KEY).append('=').append(mailboxId);
if (Mailbox.getMailboxType(context, mailboxId) != Mailbox.TYPE_OUTBOX) {
selection.append(" AND ").append(Message.FLAG_LOADED_SELECTION);
}
return selection.toString();
}
}
public interface AccountColumns {
@ -1983,7 +2042,7 @@ public abstract class EmailContent {
public static final String PRECACHE_INBOX_SELECTION =
PRECACHE_SELECTION + " AND " + AttachmentColumns.MESSAGE_KEY + " IN ("
+ "SELECT " + MessageColumns.ID + " FROM " + Message.TABLE_NAME
+ " WHERE " + Message.INBOX_SELECTION
+ " WHERE " + Message.ALL_INBOX_SELECTION
+ ")";
// Bits used in mFlags

View File

@ -239,71 +239,6 @@ public class Utility {
return null;
}
}
/**
* Returns the where clause for a message list selection.
*
* TODO This method needs to be rewritten to use the _SELECTION constants defined in
* EmailContent.Message.
*
* MUST NOT be called on the UI thread.
*/
public static String buildMailboxIdSelection(Context context, long mailboxId) {
final ContentResolver resolver = context.getContentResolver();
final StringBuilder selection = new StringBuilder();
// We don't check "flagLoaded" for messages in Outbox.
boolean testFlagLoaded = true;
if (mailboxId == Mailbox.QUERY_ALL_INBOXES
|| mailboxId == Mailbox.QUERY_ALL_DRAFTS
|| mailboxId == Mailbox.QUERY_ALL_OUTBOX) {
// query for all mailboxes of type INBOX, DRAFTS, or OUTBOX
int type;
if (mailboxId == Mailbox.QUERY_ALL_INBOXES) {
type = Mailbox.TYPE_INBOX;
} else if (mailboxId == Mailbox.QUERY_ALL_DRAFTS) {
type = Mailbox.TYPE_DRAFTS;
} else {
type = Mailbox.TYPE_OUTBOX;
testFlagLoaded = false;
}
StringBuilder inboxes = new StringBuilder();
Cursor c = resolver.query(Mailbox.CONTENT_URI,
EmailContent.ID_PROJECTION,
MailboxColumns.TYPE + "=? AND " + MailboxColumns.FLAG_VISIBLE + "=1",
new String[] { Integer.toString(type) }, null);
// build an IN (mailboxId, ...) list
while (c.moveToNext()) {
if (inboxes.length() != 0) {
inboxes.append(",");
}
inboxes.append(c.getLong(EmailContent.ID_PROJECTION_COLUMN));
}
c.close();
selection.append(MessageColumns.MAILBOX_KEY + " IN ");
selection.append("(").append(inboxes).append(")");
} else if (mailboxId == Mailbox.QUERY_ALL_UNREAD) {
selection.append(Message.FLAG_READ + "=0");
} else if (mailboxId == Mailbox.QUERY_ALL_FAVORITES) {
selection.append(Message.ALL_FAVORITE_SELECTION);
} else {
selection.append(MessageColumns.MAILBOX_KEY + "=" + mailboxId);
if (Mailbox.getMailboxType(context, mailboxId) == Mailbox.TYPE_OUTBOX) {
testFlagLoaded = false;
}
}
if (testFlagLoaded) {
// POP messages at the initial stage have very little information. (Server UID only)
// This makes sure they're not visible in the message list.
// This means unread counts on the mailbox list can be different from the
// number of messages in the message list, but it should be transient...
selection.append(" AND ").append(Message.FLAG_LOADED_SELECTION);
}
return selection.toString();
}
private final static String HOSTAUTH_WHERE_CREDENTIALS = HostAuthColumns.ADDRESS + " like ?"
+ " and " + HostAuthColumns.LOGIN + " like ?"
+ " and " + HostAuthColumns.PROTOCOL + " not like \"smtp\"";

View File

@ -17,6 +17,7 @@
package com.android.email.activity;
import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.utility.Utility;
import android.content.ContentResolver;
@ -292,10 +293,6 @@ public class MessageOrderManager {
}
}
/* package */ String getQuerySelection() { // Extracted for testing
return Utility.buildMailboxIdSelection(mContext, mMailboxId);
}
/**
* Open a new cursor for a message list.
*
@ -303,8 +300,8 @@ public class MessageOrderManager {
*/
private Cursor openNewCursor() {
final Cursor cursor = mContentResolver.query(EmailContent.Message.CONTENT_URI,
EmailContent.ID_PROJECTION, getQuerySelection(), null,
EmailContent.MessageColumns.TIMESTAMP + " DESC");
EmailContent.ID_PROJECTION, Message.buildMessageListSelection(mContext, mMailboxId),
null, EmailContent.MessageColumns.TIMESTAMP + " DESC");
return cursor;
}

View File

@ -251,8 +251,8 @@ import java.util.Set;
canHaveMessages = (box != null) && (box.mFlags & Mailbox.FLAG_HOLDS_MAIL) != 0;
}
if (canHaveMessages) {
// Determine the where clause. (Can't do this on the UI thread.)
setSelection(Utility.buildMailboxIdSelection(mContext, mMailboxId));
// Build the where cause (which can't be done on the UI thread.)
setSelection(Message.buildMessageListSelection(mContext, mMailboxId));
// Then do a query to get the cursor
returnCursor = super.loadInBackground();
} else {

View File

@ -41,9 +41,9 @@ import android.net.Uri;
private static final int ID_NAME_COLUMN_NAME = 1;
private static enum ViewType {
TYPE_ALL_UNREAD(false, Message.UNREAD_SELECTION, R.string.widget_unread, false),
TYPE_ALL_UNREAD(false, Message.ALL_UNREAD_SELECTION, R.string.widget_unread, false),
TYPE_ALL_STARRED(false, Message.ALL_FAVORITE_SELECTION, R.string.widget_starred, false),
TYPE_ALL_INBOX(false, Message.INBOX_SELECTION, R.string.widget_all_mail, true),
TYPE_ALL_INBOX(false, Message.ALL_INBOX_SELECTION, R.string.widget_all_mail, true),
TYPE_ACCOUNT_INBOX(true, Message.PER_ACCOUNT_INBOX_SELECTION, 0, true) {
@Override public String getTitle(Context context, String accountName) {
return accountName;

View File

@ -76,11 +76,6 @@ public class MessageOrderManagerTest extends ProviderTestCase2<EmailProvider> {
assertEquals(0, mom.getTotalMessageCount());
}
public void testSelection() {
MessageOrderManagerForTest mom = new MessageOrderManagerForTest(getContext(), 5, mCallback);
assertEquals("mailboxKey=5 AND flagLoaded IN (2,1)", mom.getQuerySelection());
}
/**
* Test with actual message list.
*

View File

@ -2197,4 +2197,36 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
testMailbox = Mailbox.restoreMailboxWithId(c, b34.mId);
assertEquals(b34, testMailbox);
}
public void testBuildMessageListSelection() {
final Context c = mMockContext;
assertEquals(Message.ALL_INBOX_SELECTION, Message.buildMessageListSelection(c,
Mailbox.QUERY_ALL_INBOXES));
assertEquals(Message.ALL_DRAFT_SELECTION, Message.buildMessageListSelection(c,
Mailbox.QUERY_ALL_DRAFTS));
assertEquals(Message.ALL_OUTBOX_SELECTION, Message.buildMessageListSelection(c,
Mailbox.QUERY_ALL_OUTBOX));
assertEquals(Message.ALL_UNREAD_SELECTION, Message.buildMessageListSelection(c,
Mailbox.QUERY_ALL_UNREAD));
assertEquals(Message.ALL_FAVORITE_SELECTION, Message.buildMessageListSelection(c,
Mailbox.QUERY_ALL_FAVORITES));
final Account account = ProviderTestUtils.setupAccount("1", true, mMockContext);
final Mailbox in = ProviderTestUtils.setupMailbox("i", account.mId, true, c,
Mailbox.TYPE_INBOX);
final Mailbox out = ProviderTestUtils.setupMailbox("o", account.mId, true, c,
Mailbox.TYPE_OUTBOX);
assertEquals(Message.MAILBOX_KEY + "=" + in.mId + " AND " + Message.FLAG_LOADED_SELECTION,
Message.buildMessageListSelection(c, in.mId));
// No LOADED check for outboxes.
assertEquals(Message.MAILBOX_KEY + "=" + out.mId,
Message.buildMessageListSelection(c, out.mId));
}
}

View File

@ -233,58 +233,4 @@ public class UtilityMediumTests extends ProviderTestCase2<EmailProvider> {
Account.DISPLAY_NAME + " like :1", new String[] {"NO SUCH ACCOUNT"},
null, 0, "-"));
}
public void testBuildMailboxIdSelection() {
// Create dummy data...
Context c = mMockContext;
Account account1 = ProviderTestUtils.setupAccount("1", true, mMockContext);
Account account2 = ProviderTestUtils.setupAccount("X1", true, mMockContext);
Mailbox box1in = ProviderTestUtils.setupMailbox("m", account1.mId, true, c,
Mailbox.TYPE_INBOX);
Mailbox box1out = ProviderTestUtils.setupMailbox("m", account1.mId, true, c,
Mailbox.TYPE_OUTBOX);
Mailbox box1d = ProviderTestUtils.setupMailbox("m", account1.mId, true, c,
Mailbox.TYPE_DRAFTS);
Mailbox box2in = ProviderTestUtils.setupMailbox("m", account2.mId, true, c,
Mailbox.TYPE_INBOX);
Mailbox box2out = ProviderTestUtils.setupMailbox("m", account2.mId, true, c,
Mailbox.TYPE_OUTBOX);
Mailbox box2d = ProviderTestUtils.setupMailbox("m", account2.mId, true, c,
Mailbox.TYPE_DRAFTS);
final String FLAG_LOADED_TEST =
" AND "
+ MessageColumns.FLAG_LOADED + " IN ("
+ Message.FLAG_LOADED_PARTIAL + "," + Message.FLAG_LOADED_COMPLETE
+ ")";
// Test!
// Normal mailbox
assertEquals(MessageColumns.MAILBOX_KEY + "=" + box1in.mId + FLAG_LOADED_TEST,
Utility.buildMailboxIdSelection(mMockContext, box1in.mId));
// Outbox query doesn't have FLAG_LOADED_TEST
assertEquals(MessageColumns.MAILBOX_KEY + "=" + box1out.mId,
Utility.buildMailboxIdSelection(mMockContext, box1out.mId));
// Combined mailboxes
assertEquals(Message.FLAG_READ + "=0" + FLAG_LOADED_TEST,
Utility.buildMailboxIdSelection(mMockContext, Mailbox.QUERY_ALL_UNREAD));
assertEquals(Message.ALL_FAVORITE_SELECTION + FLAG_LOADED_TEST,
Utility.buildMailboxIdSelection(mMockContext, Mailbox.QUERY_ALL_FAVORITES));
assertEquals(MessageColumns.MAILBOX_KEY + " IN (" + box1in.mId + "," + box2in.mId + ")"
+ FLAG_LOADED_TEST,
Utility.buildMailboxIdSelection(mMockContext, Mailbox.QUERY_ALL_INBOXES));
assertEquals(MessageColumns.MAILBOX_KEY + " IN (" + box1d.mId + "," + box2d.mId + ")"
+ FLAG_LOADED_TEST,
Utility.buildMailboxIdSelection(mMockContext, Mailbox.QUERY_ALL_DRAFTS));
assertEquals(MessageColumns.MAILBOX_KEY + " IN (" + box1out.mId + "," + box2out.mId + ")",
Utility.buildMailboxIdSelection(mMockContext, Mailbox.QUERY_ALL_OUTBOX));
}
}