am f095e9df
: Merge change Ib53e4411 into eclair-mr2
Merge commit 'f095e9df5a8dbd97dcefecb479fbcce05ddb4d87' into eclair-mr2-plus-aosp * commit 'f095e9df5a8dbd97dcefecb479fbcce05ddb4d87': Clear out orphaned messages in updates/deletes tables
This commit is contained in:
commit
bdaf801ea2
@ -54,15 +54,25 @@ public class EmailProvider extends ContentProvider {
|
|||||||
|
|
||||||
private static final String TAG = "EmailProvider";
|
private static final String TAG = "EmailProvider";
|
||||||
|
|
||||||
static final String DATABASE_NAME = "EmailProvider.db";
|
private static final String DATABASE_NAME = "EmailProvider.db";
|
||||||
static final String BODY_DATABASE_NAME = "EmailProviderBody.db";
|
private static final String BODY_DATABASE_NAME = "EmailProviderBody.db";
|
||||||
|
|
||||||
|
// Definitions for our queries looking for orphaned messages
|
||||||
|
private static final String[] ORPHANS_PROJECTION
|
||||||
|
= new String[] {MessageColumns.ID, MessageColumns.MAILBOX_KEY};
|
||||||
|
private static final int ORPHANS_ID = 0;
|
||||||
|
private static final int ORPHANS_MAILBOX_KEY = 1;
|
||||||
|
|
||||||
|
private static final String WHERE_ID = EmailContent.RECORD_ID + "=?";
|
||||||
|
|
||||||
// Any changes to the database format *must* include update-in-place code.
|
// Any changes to the database format *must* include update-in-place code.
|
||||||
// Original version: 3
|
// Original version: 3
|
||||||
// Version 4: Database wipe required; changing AccountManager interface w/Exchange
|
// Version 4: Database wipe required; changing AccountManager interface w/Exchange
|
||||||
// Version 5: Database wipe required; changing AccountManager interface w/Exchange
|
// Version 5: Database wipe required; changing AccountManager interface w/Exchange
|
||||||
// Version 6: Adding Message.mServerTimeStamp column
|
// Version 6: Adding Message.mServerTimeStamp column
|
||||||
public static final int DATABASE_VERSION = 6;
|
// Version 7: Replace the mailbox_delete trigger with a version that removes orphaned messages
|
||||||
|
// from the Message_Deletes and Message_Updates tables
|
||||||
|
public static final int DATABASE_VERSION = 7;
|
||||||
|
|
||||||
// Any changes to the database format *must* include update-in-place code.
|
// Any changes to the database format *must* include update-in-place code.
|
||||||
// Original version: 2
|
// Original version: 2
|
||||||
@ -162,6 +172,17 @@ public class EmailProvider extends ContentProvider {
|
|||||||
|
|
||||||
private static final String ID_EQUALS = EmailContent.RECORD_ID + "=?";
|
private static final String ID_EQUALS = EmailContent.RECORD_ID + "=?";
|
||||||
|
|
||||||
|
private static final String TRIGGER_MAILBOX_DELETE =
|
||||||
|
"create trigger mailbox_delete before delete on " + Mailbox.TABLE_NAME +
|
||||||
|
" begin" +
|
||||||
|
" delete from " + Message.TABLE_NAME +
|
||||||
|
" where " + MessageColumns.MAILBOX_KEY + "=old." + EmailContent.RECORD_ID +
|
||||||
|
"; delete from " + Message.UPDATED_TABLE_NAME +
|
||||||
|
" where " + MessageColumns.MAILBOX_KEY + "=old." + EmailContent.RECORD_ID +
|
||||||
|
"; delete from " + Message.DELETED_TABLE_NAME +
|
||||||
|
" where " + MessageColumns.MAILBOX_KEY + "=old." + EmailContent.RECORD_ID +
|
||||||
|
"; end";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Email URI matching table
|
// Email URI matching table
|
||||||
UriMatcher matcher = sURIMatcher;
|
UriMatcher matcher = sURIMatcher;
|
||||||
@ -450,11 +471,8 @@ public class EmailProvider extends ContentProvider {
|
|||||||
+ " on " + Mailbox.TABLE_NAME + " (" + MailboxColumns.SERVER_ID + ")");
|
+ " on " + Mailbox.TABLE_NAME + " (" + MailboxColumns.SERVER_ID + ")");
|
||||||
db.execSQL("create index mailbox_" + MailboxColumns.ACCOUNT_KEY
|
db.execSQL("create index mailbox_" + MailboxColumns.ACCOUNT_KEY
|
||||||
+ " on " + Mailbox.TABLE_NAME + " (" + MailboxColumns.ACCOUNT_KEY + ")");
|
+ " on " + Mailbox.TABLE_NAME + " (" + MailboxColumns.ACCOUNT_KEY + ")");
|
||||||
// Deleting a Mailbox deletes associated Messages
|
// Deleting a Mailbox deletes associated Messages in all three tables
|
||||||
db.execSQL("create trigger mailbox_delete before delete on " + Mailbox.TABLE_NAME +
|
db.execSQL(TRIGGER_MAILBOX_DELETE);
|
||||||
" begin delete from " + Message.TABLE_NAME +
|
|
||||||
" where " + MessageColumns.MAILBOX_KEY + "=old." + EmailContent.RECORD_ID +
|
|
||||||
"; end");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resetMailboxTable(SQLiteDatabase db, int oldVersion, int newVersion) {
|
static void resetMailboxTable(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
@ -540,9 +558,67 @@ public class EmailProvider extends ContentProvider {
|
|||||||
mDatabase.execSQL("attach \"" + bodyFileName + "\" as BodyDatabase");
|
mDatabase.execSQL("attach \"" + bodyFileName + "\" as BodyDatabase");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for any orphaned Messages in the updated/deleted tables
|
||||||
|
deleteOrphans(mDatabase, Message.UPDATED_TABLE_NAME);
|
||||||
|
deleteOrphans(mDatabase, Message.DELETED_TABLE_NAME);
|
||||||
|
|
||||||
return mDatabase;
|
return mDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*package*/ static SQLiteDatabase getReadableDatabase(Context context) {
|
||||||
|
DatabaseHelper helper = new EmailProvider().new DatabaseHelper(context, DATABASE_NAME);
|
||||||
|
return helper.getReadableDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*package*/ static void deleteOrphans(SQLiteDatabase database, String tableName) {
|
||||||
|
if (database != null) {
|
||||||
|
// We'll look at all of the items in the table; there won't be many typically
|
||||||
|
Cursor c = database.query(tableName, ORPHANS_PROJECTION, null, null, null, null, null);
|
||||||
|
// Usually, there will be nothing in these tables, so make a quick check
|
||||||
|
try {
|
||||||
|
if (c.getCount() == 0) return;
|
||||||
|
ArrayList<Long> foundMailboxes = new ArrayList<Long>();
|
||||||
|
ArrayList<Long> notFoundMailboxes = new ArrayList<Long>();
|
||||||
|
ArrayList<Long> deleteList = new ArrayList<Long>();
|
||||||
|
String[] bindArray = new String[1];
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
// Get the mailbox key and see if we've already found this mailbox
|
||||||
|
// If so, we're fine
|
||||||
|
long mailboxId = c.getLong(ORPHANS_MAILBOX_KEY);
|
||||||
|
// If we already know this mailbox doesn't exist, mark the message for deletion
|
||||||
|
if (notFoundMailboxes.contains(mailboxId)) {
|
||||||
|
deleteList.add(c.getLong(ORPHANS_ID));
|
||||||
|
// If we don't know about this mailbox, we'll try to find it
|
||||||
|
} else if (!foundMailboxes.contains(mailboxId)) {
|
||||||
|
bindArray[0] = Long.toString(mailboxId);
|
||||||
|
Cursor boxCursor = database.query(Mailbox.TABLE_NAME,
|
||||||
|
Mailbox.ID_PROJECTION, WHERE_ID, bindArray, null, null, null);
|
||||||
|
try {
|
||||||
|
// If it exists, we'll add it to the "found" mailboxes
|
||||||
|
if (boxCursor.moveToFirst()) {
|
||||||
|
foundMailboxes.add(mailboxId);
|
||||||
|
// Otherwise, we'll add to "not found" and mark the message for deletion
|
||||||
|
} else {
|
||||||
|
notFoundMailboxes.add(mailboxId);
|
||||||
|
deleteList.add(c.getLong(ORPHANS_ID));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
boxCursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now, delete the orphan messages
|
||||||
|
for (long messageId: deleteList) {
|
||||||
|
bindArray[0] = Long.toString(messageId);
|
||||||
|
database.delete(tableName, WHERE_ID, bindArray);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
c.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class BodyDatabaseHelper extends SQLiteOpenHelper {
|
private class BodyDatabaseHelper extends SQLiteOpenHelper {
|
||||||
BodyDatabaseHelper(Context context, String name) {
|
BodyDatabaseHelper(Context context, String name) {
|
||||||
super(context, name, null, BODY_DATABASE_VERSION);
|
super(context, name, null, BODY_DATABASE_VERSION);
|
||||||
@ -614,6 +690,12 @@ public class EmailProvider extends ContentProvider {
|
|||||||
}
|
}
|
||||||
oldVersion = 6;
|
oldVersion = 6;
|
||||||
}
|
}
|
||||||
|
if (oldVersion == 6) {
|
||||||
|
// Use the newer mailbox_delete trigger
|
||||||
|
db.execSQL("delete trigger mailbox_delete;");
|
||||||
|
db.execSQL(TRIGGER_MAILBOX_DELETE);
|
||||||
|
oldVersion = 7;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -779,6 +861,8 @@ public class EmailProvider extends ContentProvider {
|
|||||||
Uri resultUri = null;
|
Uri resultUri = null;
|
||||||
|
|
||||||
switch (match) {
|
switch (match) {
|
||||||
|
case UPDATED_MESSAGE:
|
||||||
|
case DELETED_MESSAGE:
|
||||||
case BODY:
|
case BODY:
|
||||||
case MESSAGE:
|
case MESSAGE:
|
||||||
case ATTACHMENT:
|
case ATTACHMENT:
|
||||||
@ -787,6 +871,13 @@ public class EmailProvider extends ContentProvider {
|
|||||||
case HOSTAUTH:
|
case HOSTAUTH:
|
||||||
id = db.insert(TABLE_NAMES[table], "foo", values);
|
id = db.insert(TABLE_NAMES[table], "foo", values);
|
||||||
resultUri = ContentUris.withAppendedId(uri, id);
|
resultUri = ContentUris.withAppendedId(uri, id);
|
||||||
|
// Clients shouldn't normally be adding rows to these tables, as they are
|
||||||
|
// maintained by triggers. However, we need to be able to do this for unit
|
||||||
|
// testing, so we allow the insert and then throw the same exception that we
|
||||||
|
// would if this weren't allowed.
|
||||||
|
if (match == UPDATED_MESSAGE || match == DELETED_MESSAGE) {
|
||||||
|
throw new IllegalArgumentException("Unknown URL " + uri);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MAILBOX_ID:
|
case MAILBOX_ID:
|
||||||
// This implies adding a message to a mailbox
|
// This implies adding a message to a mailbox
|
||||||
|
@ -142,7 +142,7 @@ public class SyncManager extends Service implements Runnable {
|
|||||||
protected static final String WHERE_IN_ACCOUNT_AND_PUSHABLE =
|
protected static final String WHERE_IN_ACCOUNT_AND_PUSHABLE =
|
||||||
MailboxColumns.ACCOUNT_KEY + "=? and type in (" + Mailbox.TYPE_INBOX + ','
|
MailboxColumns.ACCOUNT_KEY + "=? and type in (" + Mailbox.TYPE_INBOX + ','
|
||||||
+ Mailbox.TYPE_EAS_ACCOUNT_MAILBOX + ',' + Mailbox.TYPE_CONTACTS + ')';
|
+ Mailbox.TYPE_EAS_ACCOUNT_MAILBOX + ',' + Mailbox.TYPE_CONTACTS + ')';
|
||||||
private static final String WHERE_MAILBOX_KEY = EmailContent.RECORD_ID + "=?";
|
private static final String WHERE_MAILBOX_KEY = Message.MAILBOX_KEY + "=?";
|
||||||
private static final String WHERE_PROTOCOL_EAS = HostAuthColumns.PROTOCOL + "=\"" +
|
private static final String WHERE_PROTOCOL_EAS = HostAuthColumns.PROTOCOL + "=\"" +
|
||||||
AbstractSyncService.EAS_PROTOCOL + "\"";
|
AbstractSyncService.EAS_PROTOCOL + "\"";
|
||||||
private static final String WHERE_NOT_INTERVAL_NEVER_AND_ACCOUNT_KEY_IN =
|
private static final String WHERE_NOT_INTERVAL_NEVER_AND_ACCOUNT_KEY_IN =
|
||||||
@ -1147,6 +1147,10 @@ public class SyncManager extends Service implements Runnable {
|
|||||||
// We ignore drafts completely (doesn't sync). Changes in Outbox are handled
|
// We ignore drafts completely (doesn't sync). Changes in Outbox are handled
|
||||||
// in the checkMailboxes loop, so we can ignore these pings.
|
// in the checkMailboxes loop, so we can ignore these pings.
|
||||||
if (m.mType == Mailbox.TYPE_DRAFTS || m.mType == Mailbox.TYPE_OUTBOX) {
|
if (m.mType == Mailbox.TYPE_DRAFTS || m.mType == Mailbox.TYPE_OUTBOX) {
|
||||||
|
String[] args = new String[] {Long.toString(m.mId)};
|
||||||
|
ContentResolver resolver = INSTANCE.mResolver;
|
||||||
|
resolver.delete(Message.DELETED_CONTENT_URI, WHERE_MAILBOX_KEY, args);
|
||||||
|
resolver.delete(Message.UPDATED_CONTENT_URI, WHERE_MAILBOX_KEY, args);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
service.mAccount = Account.restoreAccountWithId(INSTANCE, m.mAccountKey);
|
service.mAccount = Account.restoreAccountWithId(INSTANCE, m.mAccountKey);
|
||||||
|
@ -169,6 +169,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
/**
|
/**
|
||||||
* Test the various combinations of SSL, TLS, and trust-certificates encoded as Uris
|
* Test the various combinations of SSL, TLS, and trust-certificates encoded as Uris
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void testHostAuthSecurityUri() {
|
public void testHostAuthSecurityUri() {
|
||||||
HostAuth ha = ProviderTestUtils.setupHostAuth("uri-security", 1, false, mMockContext);
|
HostAuth ha = ProviderTestUtils.setupHostAuth("uri-security", 1, false, mMockContext);
|
||||||
|
|
||||||
@ -209,6 +210,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
/**
|
/**
|
||||||
* Test port assignments made from Uris
|
* Test port assignments made from Uris
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public void testHostAuthPortAssignments() {
|
public void testHostAuthPortAssignments() {
|
||||||
HostAuth ha = ProviderTestUtils.setupHostAuth("uri-port", 1, false, mMockContext);
|
HostAuth ha = ProviderTestUtils.setupHostAuth("uri-port", 1, false, mMockContext);
|
||||||
|
|
||||||
@ -656,7 +658,7 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
public void testDeleteOrphanBodies() {
|
public void testDeleteOrphanBodies() {
|
||||||
final ContentResolver resolver = mMockContext.getContentResolver();
|
final ContentResolver resolver = mMockContext.getContentResolver();
|
||||||
|
|
||||||
// Create account and twa mailboxes
|
// Create account and two mailboxes
|
||||||
Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
|
Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
|
||||||
long account1Id = account1.mId;
|
long account1Id = account1.mId;
|
||||||
Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
|
Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
|
||||||
@ -686,6 +688,130 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
assertNotNull(loadBodyForMessageId(message2Id));
|
assertNotNull(loadBodyForMessageId(message2Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test delete orphan messages
|
||||||
|
* 1. create message without body (message id 1)
|
||||||
|
* 2. create message with body (message id 2. Body has _id 1 and messageKey 2).
|
||||||
|
* 3. delete first message.
|
||||||
|
* 4. delete some other mailbox -- this triggers delete orphan bodies.
|
||||||
|
* 5. verify that body for message 2 has not been deleted.
|
||||||
|
*/
|
||||||
|
public void testDeleteOrphanMessages() {
|
||||||
|
final ContentResolver resolver = mMockContext.getContentResolver();
|
||||||
|
final Context context = mMockContext;
|
||||||
|
|
||||||
|
// Create account and two mailboxes
|
||||||
|
Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context);
|
||||||
|
Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
|
||||||
|
Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context);
|
||||||
|
|
||||||
|
// Create 4 messages in box1
|
||||||
|
Message msg1_1 =
|
||||||
|
ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context);
|
||||||
|
Message msg1_2 =
|
||||||
|
ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context);
|
||||||
|
Message msg1_3 =
|
||||||
|
ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context);
|
||||||
|
Message msg1_4 =
|
||||||
|
ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context);
|
||||||
|
|
||||||
|
// Create 4 messages in box2
|
||||||
|
Message msg2_1 =
|
||||||
|
ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context);
|
||||||
|
Message msg2_2 =
|
||||||
|
ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context);
|
||||||
|
Message msg2_3 =
|
||||||
|
ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context);
|
||||||
|
Message msg2_4 =
|
||||||
|
ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context);
|
||||||
|
|
||||||
|
// Delete 2 from each mailbox
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_1.mId),
|
||||||
|
null, null);
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_2.mId),
|
||||||
|
null, null);
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_1.mId),
|
||||||
|
null, null);
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_2.mId),
|
||||||
|
null, null);
|
||||||
|
|
||||||
|
// There should be 4 items in the deleted item table
|
||||||
|
assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
|
||||||
|
|
||||||
|
// Update 2 from each mailbox
|
||||||
|
ContentValues v = new ContentValues();
|
||||||
|
v.put(MessageColumns.DISPLAY_NAME, "--updated--");
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_3.mId),
|
||||||
|
v, null, null);
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_4.mId),
|
||||||
|
v, null, null);
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_3.mId),
|
||||||
|
v, null, null);
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_4.mId),
|
||||||
|
v, null, null);
|
||||||
|
|
||||||
|
// There should be 4 items in the updated item table
|
||||||
|
assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
|
||||||
|
|
||||||
|
// Manually add 2 messages from a "deleted" mailbox to deleted and updated tables
|
||||||
|
// Use a value > 2 for the deleted box id
|
||||||
|
long delBoxId = 10;
|
||||||
|
// Create 4 messages in the "deleted" mailbox
|
||||||
|
Message msgX_A =
|
||||||
|
ProviderTestUtils.setupMessage("messageA", acct.mId, delBoxId, false, false, context);
|
||||||
|
Message msgX_B =
|
||||||
|
ProviderTestUtils.setupMessage("messageB", acct.mId, delBoxId, false, false, context);
|
||||||
|
Message msgX_C =
|
||||||
|
ProviderTestUtils.setupMessage("messageC", acct.mId, delBoxId, false, false, context);
|
||||||
|
Message msgX_D =
|
||||||
|
ProviderTestUtils.setupMessage("messageD", acct.mId, delBoxId, false, false, context);
|
||||||
|
|
||||||
|
ContentValues cv;
|
||||||
|
// We have to assign id's manually because there are no autoincrement id's for these tables
|
||||||
|
// Start with an id that won't exist, since id's in these tables must be unique
|
||||||
|
long msgId = 10;
|
||||||
|
// It's illegal to manually insert these, so we need to catch the exception
|
||||||
|
// NOTE: The insert succeeds, and then throws the exception
|
||||||
|
try {
|
||||||
|
cv = msgX_A.toContentValues();
|
||||||
|
cv.put(EmailContent.RECORD_ID, msgId++);
|
||||||
|
resolver.insert(Message.DELETED_CONTENT_URI, cv);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cv = msgX_B.toContentValues();
|
||||||
|
cv.put(EmailContent.RECORD_ID, msgId++);
|
||||||
|
resolver.insert(Message.DELETED_CONTENT_URI, cv);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cv = msgX_C.toContentValues();
|
||||||
|
cv.put(EmailContent.RECORD_ID, msgId++);
|
||||||
|
resolver.insert(Message.UPDATED_CONTENT_URI, cv);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cv = msgX_D.toContentValues();
|
||||||
|
cv.put(EmailContent.RECORD_ID, msgId++);
|
||||||
|
resolver.insert(Message.UPDATED_CONTENT_URI, cv);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// There should be 6 items in the deleted and updated tables
|
||||||
|
assertEquals(6, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
|
||||||
|
assertEquals(6, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
|
||||||
|
|
||||||
|
// Delete the orphans
|
||||||
|
EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context),
|
||||||
|
Message.DELETED_TABLE_NAME);
|
||||||
|
EmailProvider.deleteOrphans(EmailProvider.getReadableDatabase(context),
|
||||||
|
Message.UPDATED_TABLE_NAME);
|
||||||
|
|
||||||
|
// There should now be 4 messages in each of the deleted and updated tables again
|
||||||
|
assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
|
||||||
|
assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test delete mailbox
|
* Test delete mailbox
|
||||||
*/
|
*/
|
||||||
@ -961,10 +1087,16 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
long account1Id = account1.mId;
|
long account1Id = account1.mId;
|
||||||
Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
|
Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
|
||||||
long box1Id = box1.mId;
|
long box1Id = box1.mId;
|
||||||
/* Message message1 = */ ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
|
Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
|
||||||
false, true, mMockContext);
|
false, true, mMockContext);
|
||||||
/* Message message2 = */ ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
|
Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
|
||||||
false, true, mMockContext);
|
false, true, mMockContext);
|
||||||
|
Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id,
|
||||||
|
false, true, mMockContext);
|
||||||
|
Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id,
|
||||||
|
false, true, mMockContext);
|
||||||
|
ProviderTestUtils.setupMessage("message5", account1Id, box1Id, false, true, mMockContext);
|
||||||
|
ProviderTestUtils.setupMessage("message6", account1Id, box1Id, false, true, mMockContext);
|
||||||
|
|
||||||
String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
|
String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
|
||||||
EmailContent.MessageColumns.MAILBOX_KEY + "=?";
|
EmailContent.MessageColumns.MAILBOX_KEY + "=?";
|
||||||
@ -972,15 +1104,46 @@ public class ProviderTests extends ProviderTestCase2<EmailProvider> {
|
|||||||
|
|
||||||
// make sure there are two messages
|
// make sure there are two messages
|
||||||
int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
|
int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
|
||||||
|
assertEquals(6, numMessages);
|
||||||
|
|
||||||
|
ContentValues cv = new ContentValues();
|
||||||
|
cv.put(Message.SERVER_ID, "SERVER_ID");
|
||||||
|
ContentResolver resolver = mMockContext.getContentResolver();
|
||||||
|
|
||||||
|
// Update two messages
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1.mId),
|
||||||
|
cv, null, null);
|
||||||
|
resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2.mId),
|
||||||
|
cv, null, null);
|
||||||
|
// Delete two messages
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message3.mId),
|
||||||
|
null, null);
|
||||||
|
resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message4.mId),
|
||||||
|
null, null);
|
||||||
|
|
||||||
|
// There should now be two messages in updated/deleted, and 4 in messages
|
||||||
|
numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
|
||||||
|
assertEquals(4, numMessages);
|
||||||
|
numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
|
||||||
|
selArgs);
|
||||||
|
assertEquals(2, numMessages);
|
||||||
|
numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
|
||||||
|
selArgs);
|
||||||
assertEquals(2, numMessages);
|
assertEquals(2, numMessages);
|
||||||
|
|
||||||
// now delete the mailbox
|
// now delete the mailbox
|
||||||
Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id);
|
Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id);
|
||||||
mMockContext.getContentResolver().delete(uri, null, null);
|
resolver.delete(uri, null, null);
|
||||||
|
|
||||||
// there should now be zero messages
|
// there should now be zero messages in all three tables
|
||||||
numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
|
numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
|
||||||
assertEquals(0, numMessages);
|
assertEquals(0, numMessages);
|
||||||
|
numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
|
||||||
|
selArgs);
|
||||||
|
assertEquals(0, numMessages);
|
||||||
|
numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
|
||||||
|
selArgs);
|
||||||
|
assertEquals(0, numMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user