public void testTrimInsertInsert() { final ContactsSource source = getSource(); final Sources sources = getSources(source); final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); // Try creating a contact with single empty entry final EntityDelta state = getEntity(null); final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome); final EntitySet set = EntitySet.fromSingle(state); // Build diff, expecting two insert operations final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); state.buildDiff(diff); assertEquals("Unexpected operations", 3, diff.size()); { final ContentProviderOperation oper = diff.get(0); assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } { final ContentProviderOperation oper = diff.get(1); assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); } // Trim empty rows and try again, expecting silence EntityModifier.trimEmpty(set, sources); diff.clear(); state.buildDiff(diff); assertEquals("Unexpected operations", 0, diff.size()); }
public void testTrimUpdateUpdate() { final ContactsSource source = getSource(); final Sources sources = getSources(source); final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); // Build "before" with two phone numbers final ContentValues first = new ContentValues(); first.put(Data._ID, TEST_ID); first.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE); first.put(kindPhone.typeColumn, typeHome.rawValue); first.put(Phone.NUMBER, TEST_PHONE); final EntityDelta state = getEntity(TEST_ID, first); final EntitySet set = EntitySet.fromSingle(state); // Build diff, expecting no changes final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); state.buildDiff(diff); assertEquals("Unexpected operations", 0, diff.size()); // Now update row by changing number to empty string, expecting single update final ValuesDelta child = state.getEntry(TEST_ID); child.put(Phone.NUMBER, ""); diff.clear(); state.buildDiff(diff); assertEquals("Unexpected operations", 3, diff.size()); { final ContentProviderOperation oper = diff.get(0); assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } { final ContentProviderOperation oper = diff.get(1); assertEquals("Incorrect type", TYPE_UPDATE, oper.getType()); assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); } { final ContentProviderOperation oper = diff.get(2); assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } // Now run trim, which should turn into deleting the whole contact EntityModifier.trimEmpty(set, sources); diff.clear(); state.buildDiff(diff); assertEquals("Unexpected operations", 1, diff.size()); { final ContentProviderOperation oper = diff.get(0); assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } }
@Override public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException { HashSet<Uri> urisToNotify = new HashSet<Uri>(operations.size()); for (ContentProviderOperation operation : operations) { urisToNotify.add(operation.getUri()); } SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase(); db.beginTransaction(); try { int numOperations = operations.size(); ContentProviderResult[] results = new ContentProviderResult[numOperations]; int i = 0; for (ContentProviderOperation operation : operations) { results[i] = operation.apply(this, results, i); if (operation.isYieldAllowed()) { db.yieldIfContendedSafely(); } i++; } db.setTransactionSuccessful(); for (Uri uri : urisToNotify) { getContext().getContentResolver().notifyChange(uri, null); } return results; } finally { db.endTransaction(); } }
public void testTrimEmptySingle() { final ContactsSource source = getSource(); final DataKind kindPhone = source.getKindForMimetype(Phone.CONTENT_ITEM_TYPE); final EditType typeHome = EntityModifier.getType(kindPhone, Phone.TYPE_HOME); // Test row that has type values, but core fields are empty final EntityDelta state = getEntity(TEST_ID); final ValuesDelta values = EntityModifier.insertChild(state, kindPhone, typeHome); // Build diff, expecting insert for data row and update enforcement final ArrayList<ContentProviderOperation> diff = Lists.newArrayList(); state.buildDiff(diff); assertEquals("Unexpected operations", 3, diff.size()); { final ContentProviderOperation oper = diff.get(0); assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } { final ContentProviderOperation oper = diff.get(1); assertEquals("Incorrect type", TYPE_INSERT, oper.getType()); assertEquals("Incorrect target", Data.CONTENT_URI, oper.getUri()); } { final ContentProviderOperation oper = diff.get(2); assertEquals("Expected aggregation mode change", TYPE_UPDATE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } // Trim empty rows and try again, expecting delete of overall contact EntityModifier.trimEmpty(state, source); diff.clear(); state.buildDiff(diff); assertEquals("Unexpected operations", 1, diff.size()); { final ContentProviderOperation oper = diff.get(0); assertEquals("Incorrect type", TYPE_DELETE, oper.getType()); assertEquals("Incorrect target", RawContacts.CONTENT_URI, oper.getUri()); } }