public void buildCapsuleCleanup(long keepId, List<Long> duplicateIds) {
   // Convert the extra IDs into selection arguments
   String[] selectionArgs = CapsuleOperations.convertIdsToArguments(duplicateIds);
   String preparedStatementParams =
       CapsuleOperations.buildPreparedStatementParameters(duplicateIds.size());
   // UPDATE operation to change all Discoveries referencing the extra IDs to instead reference the
   // keep ID
   String discoverySelection =
       CapsuleContract.Discoveries.CAPSULE_ID + " IN (" + preparedStatementParams + ")";
   this.mOperations.add(
       ContentProviderOperation.newUpdate(CapsuleContract.Discoveries.CONTENT_URI)
           .withSelection(discoverySelection, selectionArgs)
           .withValue(CapsuleContract.Discoveries.CAPSULE_ID, keepId)
           .withYieldAllowed(true)
           .build());
   // UPDATE operation to change all Ownerships referencing the extra IDs to instead reference the
   // keep ID
   String ownershipSelection =
       CapsuleContract.Ownerships.CAPSULE_ID + " IN (" + preparedStatementParams + ")";
   this.mOperations.add(
       ContentProviderOperation.newUpdate(CapsuleContract.Ownerships.CONTENT_URI)
           .withSelection(ownershipSelection, selectionArgs)
           .withValue(CapsuleContract.Ownerships.CAPSULE_ID, keepId)
           .withYieldAllowed(false)
           .build());
   // DELETE the duplicate Capsules
   String capsuleSelection =
       CapsuleContract.Capsules._ID + " IN (" + preparedStatementParams + ")";
   this.mOperations.add(
       ContentProviderOperation.newDelete(CapsuleContract.Capsules.CONTENT_URI)
           .withSelection(capsuleSelection, selectionArgs)
           .withYieldAllowed(false)
           .build());
 }
 public void buildOwnershipCleanup(List<Long> duplicateIds) {
   String selection =
       CapsuleContract.Ownerships._ID
           + " IN ("
           + CapsuleOperations.buildPreparedStatementParameters(duplicateIds.size())
           + ")";
   String[] selectionArgs = CapsuleOperations.convertIdsToArguments(duplicateIds);
   this.mOperations.add(
       ContentProviderOperation.newDelete(CapsuleContract.Ownerships.CONTENT_URI)
           .withSelection(selection, selectionArgs)
           .withYieldAllowed(true)
           .build());
 }
    public static long determineBestId(
        ContentResolver resolver, CapsuleOperations operations, CapsuleOwnership capsule) {
      // Build the query URI
      Uri uri =
          CapsuleContract.Ownerships.CONTENT_URI
              .buildUpon()
              .appendQueryParameter(
                  CapsuleContract.Query.Parameters.INNER_JOIN, CapsuleContract.Capsules.TABLE_NAME)
              .build();
      // Query
      Cursor c =
          resolver.query(
              uri,
              CapsuleContract.Ownerships.CAPSULE_JOIN_PROJECTION,
              CapsuleContract.Capsules.TABLE_NAME
                  + "."
                  + CapsuleContract.Capsules.SYNC_ID
                  + " = ?"
                  + " AND "
                  + CapsuleContract.Capsules.TABLE_NAME
                  + "."
                  + CapsuleContract.Capsules.SYNC_ID
                  + " != ?",
              new String[] {String.valueOf(capsule.getSyncId()), "0"},
              null);
      // Check if there is a row
      long id;
      if (c.getCount() < 1) {
        // There is no existing row
        id = 0;
      } else if (c.getCount() > 1) {
        // There is more than one row, so get the first matching one
        c.moveToFirst();
        id = c.getLong(c.getColumnIndex(CapsuleContract.Ownerships.OWNERSHIP_ID_ALIAS));
        // Add any extra IDs to a collection
        List<Long> duplicateIds = new ArrayList<Long>();
        while (c.moveToNext()) {
          duplicateIds.add(
              c.getLong(c.getColumnIndex(CapsuleContract.Ownerships.OWNERSHIP_ID_ALIAS)));
        }
        // Build operations to remove the extra IDs
        operations.buildOwnershipCleanup(duplicateIds);
      } else {
        // There is only one row, so get the ID
        c.moveToFirst();
        id = c.getLong(c.getColumnIndex(CapsuleContract.Ownerships.OWNERSHIP_ID_ALIAS));
      }
      // Close the cursor
      c.close();

      // If a better ID was found (non-zero), re-assign it
      if (id > 0) {
        capsule.setOwnershipId(id);
      }

      return id;
    }
 public void buildOwnershipInsert(
     CapsuleOwnership ownership, boolean withYield, CapsuleContract.SyncStateAction syncAction) {
   // Build the URI
   Uri uri =
       CapsuleOperations.appendDirtyQueryParam(syncAction, CapsuleContract.Ownerships.CONTENT_URI);
   // Build the INSERT operation
   ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
   builder.withValues(Ownerships.buildContentValues(ownership));
   builder.withYieldAllowed(withYield);
   // Add it to the collection
   this.mOperations.add(builder.build());
 }
    public static long determineBestId(
        ContentResolver resolver, CapsuleOperations operations, Capsule capsule) {
      // Query
      Cursor c =
          resolver.query(
              CapsuleContract.Capsules.CONTENT_URI,
              new String[] {CapsuleContract.Capsules._ID},
              CapsuleContract.Capsules.TABLE_NAME
                  + "."
                  + CapsuleContract.Capsules.SYNC_ID
                  + " = ?"
                  + " AND "
                  + CapsuleContract.Capsules.TABLE_NAME
                  + "."
                  + CapsuleContract.Capsules.SYNC_ID
                  + " != ?",
              new String[] {String.valueOf(capsule.getSyncId()), "0"},
              null);
      // Check if there is a row
      long id;
      if (c.getCount() < 1) {
        // There is no existing row
        id = 0;
      } else if (c.getCount() > 1) {
        // Get the first matching row to keep
        c.moveToFirst();
        id = c.getLong(c.getColumnIndex(CapsuleContract.Capsules._ID));
        // Add any extra IDs to a collection
        List<Long> duplicateIds = new ArrayList<Long>();
        while (c.moveToNext()) {
          duplicateIds.add(c.getLong(c.getColumnIndex(CapsuleContract.Capsules._ID)));
        }
        // Build operations to remove the extra IDs
        operations.buildCapsuleCleanup(id, duplicateIds);
      } else {
        // There is only one row, so move to it and get the ID
        c.moveToFirst();
        id = c.getLong(c.getColumnIndex(CapsuleContract.Capsules._ID));
      }
      // Close the cursor
      c.close();

      // If a better ID was found (non-zero), reassign it
      if (id > 0) {
        capsule.setId(id);
      }

      return id;
    }
    public static boolean save(
        ContentResolver resolver, Capsule capsule, CapsuleContract.SyncStateAction syncAction) {
      // Build the ContentProviderOperations for the save
      CapsuleOperations operations = new CapsuleOperations(resolver);
      operations.buildOwnershipSave(capsule, syncAction);

      // Apply the batch operation
      ContentProviderResult[] results = operations.applyBatch();

      // Make sure the rows were properly updated
      boolean success = true;

      // Check the first result (Capsule operation)
      if (results[0].uri != null) {
        // The Capsule operation was an INSERT, so parse the ID from the URI
        capsule.setId(ContentUris.parseId(results[0].uri));
      } else {
        // The Capsule operation was an UPDATE, so make sure a row was updated
        if (results[0].count < 1) {
          success = false;
        }
      }

      // Check the second result (Ownership operation)
      if (results[1].uri != null) {
        // The Ownership operation was an INSERT, so parse the ID from the URI
        ((CapsuleOwnership) capsule).setOwnershipId(ContentUris.parseId(results[1].uri));
      } else {
        // The Ownership operation was an UPDATE, so make sure a row was updated
        if (results[1].count < 1) {
          success = false;
        }
      }

      return success;
    }
 public void buildDiscoveryUpdate(
     CapsuleDiscovery discovery, boolean withYield, CapsuleContract.SyncStateAction syncAction) {
   // Build the URI
   Uri uri =
       CapsuleOperations.appendDirtyQueryParam(
           syncAction,
           ContentUris.withAppendedId(
               CapsuleContract.Discoveries.CONTENT_URI, discovery.getDiscoveryId()));
   // Build the UPDATE operation
   ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(uri);
   builder.withValues(Discoveries.buildContentValues(discovery));
   builder.withYieldAllowed(withYield);
   // Add it to the collection
   this.mOperations.add(builder.build());
 }
 public void buildOwnershipInsert(
     CapsuleOwnership ownership,
     boolean withYield,
     int capsuleIdBackRefIndex,
     CapsuleContract.SyncStateAction syncAction) {
   // Build the URI
   Uri uri =
       CapsuleOperations.appendDirtyQueryParam(syncAction, CapsuleContract.Ownerships.CONTENT_URI);
   // Build the INSERT operation
   ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
   builder.withValues(Ownerships.buildContentValues(ownership));
   builder.withYieldAllowed(withYield);
   // Add the back value reference index for the Capsule ID
   if (capsuleIdBackRefIndex >= 0) {
     builder.withValueBackReference(CapsuleContract.Ownerships.CAPSULE_ID, capsuleIdBackRefIndex);
   }
   // Add it to the collection
   this.mOperations.add(builder.build());
 }
 public void buildDiscoveryUpdate(
     CapsuleDiscovery discovery,
     boolean withYield,
     int capsuleIdBackRefIndex,
     CapsuleContract.SyncStateAction syncAction) {
   // Build the URI
   Uri uri =
       CapsuleOperations.appendDirtyQueryParam(
           syncAction,
           ContentUris.withAppendedId(
               CapsuleContract.Discoveries.CONTENT_URI, discovery.getDiscoveryId()));
   // Build the UPDATE operation
   ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(uri);
   builder.withValues(Discoveries.buildContentValues(discovery));
   builder.withYieldAllowed(withYield);
   // Add the back value reference for the Capsule ID
   if (capsuleIdBackRefIndex >= 0) {
     builder.withValueBackReference(CapsuleContract.Discoveries.CAPSULE_ID, capsuleIdBackRefIndex);
   }
   // Add it to the collection
   this.mOperations.add(builder.build());
 }