diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index 3f04dc538..8e6d513fe 100755 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -128,6 +128,34 @@ public abstract class EmailContent { public static Uri MAILBOX_NOTIFICATION_URI; public static Uri MAILBOX_MOST_RECENT_MESSAGE_URI; public static Uri ACCOUNT_CHECK_URI; + + /** The path for the query to get the moved message info for an account. */ + public static final String MOVED_MESSAGES_PATH = "movedMessages"; + /** + * The URI to query for information regarding messages that have been moved on the client + * where this move has not yet been synced to the server. + * This query will return the columns in {@link MovedMessagesColumns}. + */ + public static Uri MOVED_MESSAGES_URI; + + /** + * Columns returned by the moved messages query. + */ + public static final class MovedMessagesColumns { + /** The server side message id for the message that is moving. */ + public static final String MESSAGE_ID = "messageId"; + /** The local message id for the message that is moving. */ + public static final String LOCAL_MESSAGE_ID = "localMessageId"; + /** The server side folder id for the folder the message was in. */ + public static final String SOURCE_FOLDER_ID = "sourceFolderId"; + /** The local folder id for the folder the message was in. */ + public static final String LOCAL_SOURCE_FOLDER_ID = "localSourceFolderId"; + /** The server side folder id for the folder the message is moving to. */ + public static final String DEST_FOLDER_ID = "destFolderId"; + /** The local folder id for the folder the message is moving to. */ + public static final String LOCAL_DEST_FOLDER_ID = "localDestFolderId"; + } + public static String PROVIDER_PERMISSION; public static synchronized void init(Context context) { @@ -145,6 +173,8 @@ public abstract class EmailContent { MAILBOX_MOST_RECENT_MESSAGE_URI = Uri.parse("content://" + AUTHORITY + "/mailboxMostRecentMessage"); ACCOUNT_CHECK_URI = Uri.parse("content://" + AUTHORITY + "/accountCheck"); + MOVED_MESSAGES_URI = + CONTENT_URI.buildUpon().appendEncodedPath("/" + MOVED_MESSAGES_PATH).build(); PROVIDER_PERMISSION = EMAIL_PACKAGE_NAME + ".permission.ACCESS_PROVIDER"; // Initialize subclasses Account.initAccount(); @@ -681,7 +711,7 @@ public abstract class EmailContent { public static final String[] ID_COLUMN_PROJECTION = new String[] { RECORD_ID }; - private static final String ACCOUNT_KEY_SELECTION = + public static final String ACCOUNT_KEY_SELECTION = MessageColumns.ACCOUNT_KEY + "=?"; /** diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java index 06f238ac3..15da396a2 100644 --- a/src/com/android/email/provider/EmailProvider.java +++ b/src/com/android/email/provider/EmailProvider.java @@ -71,6 +71,7 @@ import com.android.emailcommon.provider.EmailContent.BodyColumns; import com.android.emailcommon.provider.EmailContent.MailboxColumns; import com.android.emailcommon.provider.EmailContent.Message; import com.android.emailcommon.provider.EmailContent.MessageColumns; +import com.android.emailcommon.provider.EmailContent.MovedMessagesColumns; import com.android.emailcommon.provider.EmailContent.PolicyColumns; import com.android.emailcommon.provider.EmailContent.SyncColumns; import com.android.emailcommon.provider.HostAuth; @@ -183,6 +184,7 @@ public class EmailProvider extends ContentProvider { private static final int MESSAGE_ID = MESSAGE_BASE + 1; private static final int SYNCED_MESSAGE_ID = MESSAGE_BASE + 2; private static final int MESSAGE_SELECTION = MESSAGE_BASE + 3; + private static final int MOVED_MESSAGES = MESSAGE_BASE + 4; private static final int ATTACHMENT_BASE = 0x3000; private static final int ATTACHMENT = ATTACHMENT_BASE; @@ -301,6 +303,43 @@ public class EmailProvider extends ContentProvider { private static final String SYNC_STATUS_CALLBACK_METHOD = "sync_status"; + /** FROM clause for a SQL query to get info about updated messages. */ + private static final String GET_CHANGED_MESSAGES_FROM_CLAUSE = "from " + + Message.UPDATED_TABLE_NAME + " as u inner join " + Message.TABLE_NAME + + " as m using (" + MessageColumns.ID + ")"; + + /** FROM clause for a SQL query to get moved messages info. */ + private static final String GET_MOVED_MESSAGES_FROM_CLAUSE = GET_CHANGED_MESSAGES_FROM_CLAUSE + + " inner join " + Mailbox.TABLE_NAME + " as src on u." + MessageColumns.MAILBOX_KEY + + "=src." + MailboxColumns.ID + + " inner join " + Mailbox.TABLE_NAME + " as dst on m." + MessageColumns.MAILBOX_KEY + + "=dst." + MailboxColumns.ID; + + /** WHERE clause for a SQL query to get info about updated messages. */ + private static final String GET_CHANGED_MESSAGES_WHERE_CLAUSE = + "where u." + MessageColumns.ACCOUNT_KEY + "=?"; + + /** WHERE clause for a SQL query to get moved messages info. */ + private static final String GET_MOVED_MESSAGES_WHERE_CLAUSE = GET_CHANGED_MESSAGES_WHERE_CLAUSE + + " and src." + MailboxColumns.ID + "!=dst." + MailboxColumns.ID; + + /** SELECT clause for a SQL query to get moved messages info. */ + private static final String GET_MOVED_MESSAGES_SELECTION = "select " + + "u." + SyncColumns.SERVER_ID + " as " + MovedMessagesColumns.MESSAGE_ID + + ",u." + MessageColumns.ID + " as " + MovedMessagesColumns.LOCAL_MESSAGE_ID + + ",src." + MailboxColumns.SERVER_ID + " as " + MovedMessagesColumns.SOURCE_FOLDER_ID + + ",src." + MailboxColumns.ID + " as " + MovedMessagesColumns.LOCAL_SOURCE_FOLDER_ID + + ",dst." + MailboxColumns.SERVER_ID + " as " + MovedMessagesColumns.DEST_FOLDER_ID + + ",dst." + MailboxColumns.ID + " as " + MovedMessagesColumns.LOCAL_DEST_FOLDER_ID; + + /** + * A raw SQL query for getting the moved messages info. + * See {@link EmailContent#MOVED_MESSAGES_URI} for details on this query. + */ + private static final String GET_MOVED_MESSAGES_QUERY = GET_MOVED_MESSAGES_SELECTION + " " + + GET_MOVED_MESSAGES_FROM_CLAUSE + " " + GET_MOVED_MESSAGES_WHERE_CLAUSE; + + /** * Wrap the UriMatcher call so we can throw a runtime exception if an unknown Uri is passed in * @param uri the Uri to match @@ -928,6 +967,9 @@ public class EmailProvider extends ContentProvider { sURIMatcher.addURI(EmailContent.AUTHORITY, "syncedMessage/#", SYNCED_MESSAGE_ID); sURIMatcher.addURI(EmailContent.AUTHORITY, "messageBySelection", MESSAGE_SELECTION); + sURIMatcher.addURI(EmailContent.AUTHORITY, EmailContent.MOVED_MESSAGES_PATH + "/#", + MOVED_MESSAGES); + /** * THE URIs BELOW THIS POINT ARE INTENDED TO BE USED BY SYNC ADAPTERS ONLY * THEY REFER TO DATA CREATED AND MAINTAINED BY CALLS TO THE SYNCED_MESSAGE_ID URI @@ -1111,6 +1153,8 @@ public class EmailProvider extends ContentProvider { case MAILBOX_MESSAGE_COUNT: c = getMailboxMessageCount(uri); return c; + case MOVED_MESSAGES: + return getMovedMessages(uri.getPathSegments().get(1)); case BODY: case MESSAGE: case UPDATED_MESSAGE: @@ -1182,6 +1226,18 @@ public class EmailProvider extends ContentProvider { return c; } + /** + * Queries the DB for the moved messages info for an account. See the comments for + * {@link EmailContent#MOVED_MESSAGES_URI} for details on what this should return. + * TODO: May be convenient to eventually allow a projection, or selection args, etc. + * @param accountId The account to query. + * @return The moved messages info cursor. + */ + private Cursor getMovedMessages(final String accountId) { + return getDatabase(getContext()).rawQuery(GET_MOVED_MESSAGES_QUERY, + new String[] { accountId }); + } + private static String whereWithId(String id, String selection) { StringBuilder sb = new StringBuilder(256); sb.append("_id=");