Bug 1118971 - Lift append* methods into DBUtils r=grisha draft
authorMatt Drill <mddrill@aol.com>
Sun, 20 Nov 2016 00:42:56 -0500
changeset 441630 6ec146a04f2b38cb68514dc83d8c8e5cced3842c
parent 426420 dc89484d4b45abf442162e5ea2dd46f9de40197d
child 537592 85455854dbf5d658687ad31596d020b5db3a323f
push id36469
push userbmo:mddrill@aol.com
push dateSun, 20 Nov 2016 05:52:30 +0000
reviewersgrisha
bugs1118971
milestone52.0a1
Bug 1118971 - Lift append* methods into DBUtils r=grisha MozReview-Commit-ID: K83aB9B7Ctn
mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
mobile/android/base/java/org/mozilla/gecko/db/LocalSearches.java
mobile/android/base/java/org/mozilla/gecko/db/LocalTabsAccessor.java
mobile/android/base/java/org/mozilla/gecko/db/LocalURLMetadata.java
mobile/android/base/java/org/mozilla/gecko/db/LocalUrlAnnotations.java
--- a/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java
@@ -240,27 +240,47 @@ public class DBUtils {
             if (i++ < commaLimit) {
                 builder.append(", ");
             }
         }
         builder.append(")");
         return builder.toString();
     }
 
-    public static Uri appendProfile(final String profile, final Uri uri) {
-        return uri.buildUpon().appendQueryParameter(BrowserContract.PARAM_PROFILE, profile).build();
+    public static Uri appendParameterValue(final Uri uri, final String parameter, final String value) {
+        return uri.buildUpon().appendQueryParameter(parameter, value).build();
+    }
+    public static Uri appendShowDeleted(final Uri uri) {
+        return appendParameterValue(uri, BrowserContract.PARAM_SHOW_DELETED, "true");
+    }
+    public static Uri appendProfile(final Uri uri, final String profile) {
+        return appendParameterValue(uri, BrowserContract.PARAM_PROFILE, profile);
     }
 
-    public static Uri appendProfileWithDefault(final String profile, final Uri uri) {
-        if (profile == null) {
-            return appendProfile(GeckoProfile.DEFAULT_PROFILE, uri);
+    public static Uri appendProfileWithDefault(final Uri uri, final String profile) {
+        if (TextUtils.isEmpty(profile)) {
+            return appendProfile(uri, GeckoProfile.DEFAULT_PROFILE);
         }
-        return appendProfile(profile, uri);
+        return appendProfile(uri, profile);
+    }
+
+    public static Uri appendLimit(final Uri uri, final int limit) {
+        return appendParameterValue(uri, BrowserContract.PARAM_LIMIT, String.valueOf(limit));
     }
 
+    public static Uri appendInsertIfNeeded(final Uri uri) {
+        return appendParameterValue(uri, BrowserContract.PARAM_INSERT_IF_NEEDED, "true");
+    }
+
+    public static Uri appendInsertIfNeededAndWithDeleted(final Uri uri) {
+        return uri.buildUpon()
+                .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true")
+                .appendQueryParameter(BrowserContract.PARAM_SHOW_DELETED, "true")
+                .build();
+    }
     /**
      * Use the following when no conflict action is specified.
      */
     private static final int CONFLICT_NONE = 0;
     private static final String[] CONFLICT_VALUES = new String[] {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
 
     /**
      * Convenience method for updating rows in the database.
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java
@@ -133,26 +133,26 @@ public class LocalBrowserDB extends Brow
                            Bookmarks.TITLE,
                            Bookmarks.TYPE,
                            Bookmarks.PARENT };
 
     public LocalBrowserDB(String profile) {
         mProfile = profile;
         mFolderIdMap = new HashMap<String, Long>();
 
-        mBookmarksUriWithProfile = DBUtils.appendProfile(profile, Bookmarks.CONTENT_URI);
-        mParentsUriWithProfile = DBUtils.appendProfile(profile, Bookmarks.PARENTS_CONTENT_URI);
-        mHistoryUriWithProfile = DBUtils.appendProfile(profile, History.CONTENT_URI);
-        mHistoryExpireUriWithProfile = DBUtils.appendProfile(profile, History.CONTENT_OLD_URI);
-        mCombinedUriWithProfile = DBUtils.appendProfile(profile, Combined.CONTENT_URI);
-        mFaviconsUriWithProfile = DBUtils.appendProfile(profile, Favicons.CONTENT_URI);
-        mTopSitesUriWithProfile = DBUtils.appendProfile(profile, TopSites.CONTENT_URI);
-        mHighlightsUriWithProfile = DBUtils.appendProfile(profile, Highlights.CONTENT_URI);
-        mThumbnailsUriWithProfile = DBUtils.appendProfile(profile, Thumbnails.CONTENT_URI);
-        mActivityStreamBlockedUriWithProfile = DBUtils.appendProfile(profile, ActivityStreamBlocklist.CONTENT_URI);
+        mBookmarksUriWithProfile = DBUtils.appendProfile(Bookmarks.CONTENT_URI, profile);
+        mParentsUriWithProfile = DBUtils.appendProfile(Bookmarks.PARENTS_CONTENT_URI, profile);
+        mHistoryUriWithProfile = DBUtils.appendProfile(History.CONTENT_URI, profile);
+        mHistoryExpireUriWithProfile = DBUtils.appendProfile(History.CONTENT_OLD_URI, profile);
+        mCombinedUriWithProfile = DBUtils.appendProfile(Combined.CONTENT_URI, profile);
+        mFaviconsUriWithProfile = DBUtils.appendProfile(Favicons.CONTENT_URI, profile);
+        mTopSitesUriWithProfile = DBUtils.appendProfile(TopSites.CONTENT_URI, profile);
+        mHighlightsUriWithProfile = DBUtils.appendProfile(Highlights.CONTENT_URI, profile);
+        mThumbnailsUriWithProfile = DBUtils.appendProfile(Thumbnails.CONTENT_URI, profile);
+        mActivityStreamBlockedUriWithProfile = DBUtils.appendProfile(ActivityStreamBlocklist.CONTENT_URI, profile);
 
         mSearchHistoryUri = BrowserContract.SearchHistory.CONTENT_URI;
 
         mUpdateHistoryUriWithProfile =
                 mHistoryUriWithProfile.buildUpon()
                                       .appendQueryParameter(BrowserContract.PARAM_INCREMENT_VISITS, "true")
                                       .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true")
                                       .build();
@@ -538,33 +538,21 @@ public class LocalBrowserDB extends Brow
 
     // Invalidate cached data
     @Override
     public void invalidate() {
         mDesktopBookmarksExist = null;
     }
 
     private Uri bookmarksUriWithLimit(int limit) {
-        return mBookmarksUriWithProfile.buildUpon()
-                                       .appendQueryParameter(BrowserContract.PARAM_LIMIT,
-                                                             String.valueOf(limit))
-                                       .build();
+        return DBUtils.appendLimit(mBookmarksUriWithProfile, limit);
     }
 
     private Uri combinedUriWithLimit(int limit) {
-        return mCombinedUriWithProfile.buildUpon()
-                                      .appendQueryParameter(BrowserContract.PARAM_LIMIT,
-                                                            String.valueOf(limit))
-                                      .build();
-    }
-
-    private static Uri withDeleted(final Uri uri) {
-        return uri.buildUpon()
-                  .appendQueryParameter(BrowserContract.PARAM_SHOW_DELETED, "1")
-                  .build();
+        return DBUtils.appendLimit(mCombinedUriWithProfile, limit);
     }
 
     private Cursor filterAllSites(ContentResolver cr, String[] projection, CharSequence constraint,
                                   int limit, CharSequence urlFilter, String selection, String[] selectionArgs) {
         // The combined history/bookmarks selection queries for sites with a URL or title containing
         // the constraint string(s), treating space-separated words as separate constraints
         if (!TextUtils.isEmpty(constraint)) {
             final String[] constraintWords = constraint.toString().split(" ");
@@ -586,20 +574,20 @@ public class LocalBrowserDB extends Brow
         }
 
         // Order by combined remote+local frecency score.
         // Local visits are preferred, so they will by far outweigh remote visits.
         // Bookmarked history items get extra frecency points.
         final String sortOrder = BrowserContract.getCombinedFrecencySortOrder(true, false);
 
         return cr.query(combinedUriWithLimit(limit),
-                        projection,
-                        selection,
-                        selectionArgs,
-                        sortOrder);
+                projection,
+                selection,
+                selectionArgs,
+                sortOrder);
     }
 
     @Override
     public int getCount(ContentResolver cr, String database) {
         int count = 0;
         String[] columns = null;
         String constraint = null;
         Uri uri = null;
@@ -646,25 +634,25 @@ public class LocalBrowserDB extends Brow
             selection = Combined.URL + " NOT IN (SELECT " +
                                                  Bookmarks.URL + " FROM bookmarks WHERE " +
                                                  DBUtils.qualifyColumn("bookmarks", Bookmarks.PARENT) + " = ? AND " +
                                                  DBUtils.qualifyColumn("bookmarks", Bookmarks.IS_DELETED) + " == 0)";
             selectionArgs = new String[] { String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID) };
         }
 
         return filterAllSites(cr,
-                              new String[] { Combined._ID,
-                                             Combined.URL,
-                                             Combined.TITLE,
-                                             Combined.BOOKMARK_ID,
-                                             Combined.HISTORY_ID },
-                              constraint,
-                              limit,
-                              null,
-                              selection, selectionArgs);
+                new String[]{Combined._ID,
+                        Combined.URL,
+                        Combined.TITLE,
+                        Combined.BOOKMARK_ID,
+                        Combined.HISTORY_ID},
+                constraint,
+                limit,
+                null,
+                selection, selectionArgs);
     }
 
     @Override
     public void updateVisitedHistory(ContentResolver cr, String uri) {
         ContentValues values = new ContentValues();
 
         values.put(History.URL, uri);
         values.put(History.DATE_LAST_VISITED, System.currentTimeMillis());
@@ -712,23 +700,23 @@ public class LocalBrowserDB extends Brow
                         History.DATE_LAST_VISITED + " > 0",
                         null,
                         History.DATE_LAST_VISITED + " DESC");
     }
 
     @Override
     public Cursor getRecentHistoryBetweenTime(ContentResolver cr, int limit, long start, long end) {
         return cr.query(combinedUriWithLimit(limit),
-                new String[] { Combined._ID,
+                new String[]{Combined._ID,
                         Combined.BOOKMARK_ID,
                         Combined.HISTORY_ID,
                         Combined.URL,
                         Combined.TITLE,
                         Combined.DATE_LAST_VISITED,
-                        Combined.VISITS },
+                        Combined.VISITS},
                 History.DATE_LAST_VISITED + " >= " + start + " AND " + History.DATE_LAST_VISITED + " < " + end,
                 null,
                 History.DATE_LAST_VISITED + " DESC");
     }
 
     public Cursor getHistoryForURL(ContentResolver cr, String uri) {
         return cr.query(mHistoryUriWithProfile,
                 new String[] {
@@ -762,17 +750,17 @@ public class LocalBrowserDB extends Brow
         } finally {
             cursor.close();
         }
     }
 
     @Override
     public void expireHistory(ContentResolver cr, ExpirePriority priority) {
         Uri url = mHistoryExpireUriWithProfile;
-        url = url.buildUpon().appendQueryParameter(BrowserContract.PARAM_EXPIRE_PRIORITY, priority.toString()).build();
+        url = DBUtils.appendParameterValue(url, BrowserContract.PARAM_EXPIRE_PRIORITY, priority.toString());
         cr.delete(url, null, null);
     }
 
     @Override
     @RobocopTarget
     public void removeHistoryEntry(ContentResolver cr, String url) {
         cr.delete(mHistoryUriWithProfile,
                   History.URL + " = ?",
@@ -953,24 +941,24 @@ public class LocalBrowserDB extends Brow
     private boolean desktopBookmarksExist(ContentResolver cr) {
         if (mDesktopBookmarksExist != null) {
             return mDesktopBookmarksExist;
         }
 
         // Check to see if there are any bookmarks in one of our three
         // fixed "Desktop Bookmarks" folders.
         final Cursor c = cr.query(bookmarksUriWithLimit(1),
-                                  new String[] { Bookmarks._ID },
-                                  Bookmarks.PARENT + " = ? OR " +
-                                  Bookmarks.PARENT + " = ? OR " +
-                                  Bookmarks.PARENT + " = ?",
-                                  new String[] { String.valueOf(getFolderIdFromGuid(cr, Bookmarks.TOOLBAR_FOLDER_GUID)),
-                                                 String.valueOf(getFolderIdFromGuid(cr, Bookmarks.MENU_FOLDER_GUID)),
-                                                 String.valueOf(getFolderIdFromGuid(cr, Bookmarks.UNFILED_FOLDER_GUID)) },
-                                  null);
+                new String[]{Bookmarks._ID},
+                Bookmarks.PARENT + " = ? OR " +
+                        Bookmarks.PARENT + " = ? OR " +
+                        Bookmarks.PARENT + " = ?",
+                new String[]{String.valueOf(getFolderIdFromGuid(cr, Bookmarks.TOOLBAR_FOLDER_GUID)),
+                        String.valueOf(getFolderIdFromGuid(cr, Bookmarks.MENU_FOLDER_GUID)),
+                        String.valueOf(getFolderIdFromGuid(cr, Bookmarks.UNFILED_FOLDER_GUID))},
+                null);
 
         try {
             // Don't read back out of the cache to avoid races with invalidation.
             final boolean e = c.getCount() > 0;
             mDesktopBookmarksExist = e;
             return e;
         } finally {
             c.close();
@@ -1080,19 +1068,17 @@ public class LocalBrowserDB extends Brow
             }
         } finally {
             c.close();
         }
 
         // Restore deleted record if possible
         values.put(Bookmarks.IS_DELETED, 0);
 
-        final Uri bookmarksWithInsert = mBookmarksUriWithProfile.buildUpon()
-                                          .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true")
-                                          .build();
+        final Uri bookmarksWithInsert = DBUtils.appendInsertIfNeeded(mBookmarksUriWithProfile);
         cr.update(bookmarksWithInsert,
                   values,
                   Bookmarks.URL + " = ? AND " +
                   Bookmarks.PARENT + " = " + folderId,
                   new String[] { uri });
 
         // Bump parent modified time using its ID.
         debug("Bumping parent modified time for addition to: " + folderId);
@@ -1313,18 +1299,18 @@ public class LocalBrowserDB extends Brow
         } else {
             Log.w(LOGTAG, "Favicon compression failed.");
         }
 
         ContentValues values = new ContentValues();
         values.put(Thumbnails.URL, uri);
         values.put(Thumbnails.DATA, data);
 
-        Uri thumbnailsUri = mThumbnailsUriWithProfile.buildUpon().
-                appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
+        final Uri thumbnailsUri = DBUtils.appendInsertIfNeeded(mThumbnailsUriWithProfile);
+
         cr.update(thumbnailsUri,
                   values,
                   Thumbnails.URL + " = ?",
                   new String[] { uri });
     }
 
     @Override
     @RobocopTarget
@@ -1399,21 +1385,21 @@ public class LocalBrowserDB extends Brow
             History._ID,
             History.VISITS,
             History.LOCAL_VISITS,
             History.DATE_LAST_VISITED,
             History.LOCAL_DATE_LAST_VISITED
         };
 
         // We need to get the old visit and date aggregates.
-        final Cursor cursor = cr.query(withDeleted(mHistoryUriWithProfile),
-                                       projection,
-                                       History.URL + " = ?",
-                                       new String[] { url },
-                                       null);
+        final Cursor cursor = cr.query(DBUtils.appendShowDeleted(mHistoryUriWithProfile),
+                               projection,
+                               History.URL + " = ?",
+                               new String[] { url },
+                               null);
         if (cursor == null) {
             Log.w(LOGTAG, "Null cursor while querying for old visit and date aggregates");
             return;
         }
 
         try {
             final ContentValues values = new ContentValues();
 
@@ -1450,18 +1436,17 @@ public class LocalBrowserDB extends Brow
                 values.put(History.DATE_LAST_VISITED, date);
                 values.put(History.LOCAL_DATE_LAST_VISITED, date);
             }
             if (title != null) {
                 values.put(History.TITLE, title);
             }
             values.put(History.URL, url);
 
-            final Uri historyUri = withDeleted(mHistoryUriWithProfile).buildUpon().
-                appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
+            final Uri historyUri = DBUtils.appendInsertIfNeededAndWithDeleted(mHistoryUriWithProfile);
 
             // Update or insert
             final ContentProviderOperation.Builder builder =
                 ContentProviderOperation.newUpdate(historyUri);
             builder.withSelection(History.URL + " = ?", new String[] { url });
             builder.withValues(values);
 
             // Queue the operation
@@ -1573,18 +1558,17 @@ public class LocalBrowserDB extends Brow
         // This assumes no "real" folder has a negative ID. Only
         // things like the reading list folder do.
         if (parent < 0) {
             parent = getFolderIdFromGuid(cr, Bookmarks.MOBILE_FOLDER_GUID);
         }
         values.put(Bookmarks.PARENT, parent);
         values.put(Bookmarks.TYPE, type);
 
-        Uri bookmarkUri = withDeleted(mBookmarksUriWithProfile).buildUpon().
-            appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
+
         // Update or insert
         ContentProviderOperation.Builder builder =
             ContentProviderOperation.newUpdate(bookmarkUri);
         if (url != null) {
             // Bookmarks are defined by their URL and Folder.
             builder.withSelection(Bookmarks.URL + " = ? AND "
                                   + Bookmarks.PARENT + " = ?",
                                   new String[] { url,
@@ -1623,24 +1607,23 @@ public class LocalBrowserDB extends Brow
         values.put(Bookmarks.DATE_MODIFIED, now);
         values.put(Bookmarks.POSITION, position);
         values.put(Bookmarks.IS_DELETED, 0);
 
         // We do an update-and-replace here without deleting any existing pins for the given URL.
         // That means if the user pins a URL, then edits another thumbnail to use the same URL,
         // we'll end up with two pins for that site. This is the intended behavior, which
         // incidentally saves us a delete query.
-        Uri uri = mBookmarksUriWithProfile.buildUpon()
-                .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true").build();
+        final Uri uri = DBUtils.appendInsertIfNeeded(mBookmarksUriWithProfile);
         cr.update(uri,
-                  values,
-                  Bookmarks.POSITION + " = ? AND " +
-                  Bookmarks.PARENT + " = ?",
-                  new String[] { Integer.toString(position),
-                                 String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID) });
+                values,
+                Bookmarks.POSITION + " = ? AND " +
+                        Bookmarks.PARENT + " = ?",
+                new String[]{Integer.toString(position),
+                        String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID)});
     }
 
     @Override
     public void unpinSite(ContentResolver cr, int position) {
         cr.delete(mBookmarksUriWithProfile,
                   Bookmarks.PARENT + " == ? AND " + Bookmarks.POSITION + " = ?",
                   new String[] {
                       String.valueOf(Bookmarks.FIXED_PINNED_LIST_ID),
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalSearches.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalSearches.java
@@ -11,17 +11,17 @@ import android.net.Uri;
 
 /**
  * Helper class for dealing with the search provider inside Fennec.
  */
 public class LocalSearches implements Searches {
     private final Uri uriWithProfile;
 
     public LocalSearches(String mProfile) {
-        uriWithProfile = DBUtils.appendProfileWithDefault(mProfile, BrowserContract.SearchHistory.CONTENT_URI);
+        uriWithProfile = DBUtils.appendProfileWithDefault(BrowserContract.SearchHistory.CONTENT_URI, mProfile);
     }
 
     @Override
     public void insert(ContentResolver cr, String query) {
         final ContentValues values = new ContentValues();
         values.put(BrowserContract.SearchHistory.QUERY, query);
         cr.insert(uriWithProfile, values);
     }
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalTabsAccessor.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalTabsAccessor.java
@@ -64,19 +64,19 @@ public class LocalTabsAccessor implement
 
     private static final Pattern FILTERED_URL_PATTERN = Pattern.compile("^(about|chrome|wyciwyg|file):");
 
     private final Uri clientsRecencyUriWithProfile;
     private final Uri tabsUriWithProfile;
     private final Uri clientsUriWithProfile;
 
     public LocalTabsAccessor(String profileName) {
-        tabsUriWithProfile = DBUtils.appendProfileWithDefault(profileName, BrowserContract.Tabs.CONTENT_URI);
-        clientsUriWithProfile = DBUtils.appendProfileWithDefault(profileName, BrowserContract.Clients.CONTENT_URI);
-        clientsRecencyUriWithProfile = DBUtils.appendProfileWithDefault(profileName, BrowserContract.Clients.CONTENT_RECENCY_URI);
+        tabsUriWithProfile = DBUtils.appendProfileWithDefault(BrowserContract.Tabs.CONTENT_URI, profileName);
+        clientsUriWithProfile = DBUtils.appendProfileWithDefault(BrowserContract.Clients.CONTENT_URI, profileName);
+        clientsRecencyUriWithProfile = DBUtils.appendProfileWithDefault(BrowserContract.Clients.CONTENT_RECENCY_URI, profileName);
     }
 
     /**
      * Extracts a List of just RemoteClients from a cursor.
      * The supplied cursor should be grouped by guid and sorted by most recently used.
      */
     @Override
     public List<RemoteClient> getClientsWithoutTabsByRecencyFromCursor(Cursor cursor) {
@@ -179,19 +179,17 @@ public class LocalTabsAccessor implement
         return getRemoteTabsCursor(context, -1);
     }
 
     @Override
     public Cursor getRemoteTabsCursor(Context context, int limit) {
         Uri uri = tabsUriWithProfile;
 
         if (limit > 0) {
-            uri = uri.buildUpon()
-                     .appendQueryParameter(BrowserContract.PARAM_LIMIT, String.valueOf(limit))
-                     .build();
+            uri = DBUtils.appendLimit(uri, limit);
         }
 
         final String threeWeeksAgoTimestampMillis = Long.valueOf(
                 System.currentTimeMillis() - THREE_WEEKS_IN_MILLISECONDS).toString();
         return context.getContentResolver().query(uri,
                                                             TABS_PROJECTION_COLUMNS,
                                                             REMOTE_TABS_SELECTION_CLIENT_RECENCY,
                                                             new String[] {threeWeeksAgoTimestampMillis},
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalURLMetadata.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalURLMetadata.java
@@ -29,17 +29,17 @@ import android.util.Log;
 import android.util.LruCache;
 
 // Holds metadata info about URLs. Supports some helper functions for getting back a HashMap of key value data.
 public class LocalURLMetadata implements URLMetadata {
     private static final String LOGTAG = "GeckoURLMetadata";
     private final Uri uriWithProfile;
 
     public LocalURLMetadata(String mProfile) {
-        uriWithProfile = DBUtils.appendProfileWithDefault(mProfile, URLMetadataTable.CONTENT_URI);
+        uriWithProfile = DBUtils.appendProfileWithDefault(URLMetadataTable.CONTENT_URI, mProfile);
     }
 
     // A list of columns in the table. It's used to simplify some loops for reading/writing data.
     private static final Set<String> COLUMNS;
     static {
         final HashSet<String> tempModel = new HashSet<>(4);
         tempModel.add(URLMetadataTable.URL_COLUMN);
         tempModel.add(URLMetadataTable.TILE_IMAGE_URL_COLUMN);
@@ -222,19 +222,17 @@ public class LocalURLMetadata implements
                     values.put(key, (String) data.get(key));
                 }
             }
 
             if (values.size() == 0) {
                 return;
             }
 
-            Uri uri = uriWithProfile.buildUpon()
-                                 .appendQueryParameter(BrowserContract.PARAM_INSERT_IF_NEEDED, "true")
-                                 .build();
+            Uri uri = DBUtils.appendInsertIfNeeded(uriWithProfile);
             cr.update(uri, values, URLMetadataTable.URL_COLUMN + "=?", new String[] {
                 (String) data.get(URLMetadataTable.URL_COLUMN)
             });
         } catch (Exception ex) {
             Log.e(LOGTAG, "error saving", ex);
         }
     }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/db/LocalUrlAnnotations.java
+++ b/mobile/android/base/java/org/mozilla/gecko/db/LocalUrlAnnotations.java
@@ -18,17 +18,17 @@ import org.mozilla.gecko.db.BrowserContr
 import org.mozilla.gecko.feeds.subscriptions.FeedSubscription;
 
 public class LocalUrlAnnotations implements UrlAnnotations {
     private static final String LOGTAG = "LocalUrlAnnotations";
 
     private Uri urlAnnotationsTableWithProfile;
 
     public LocalUrlAnnotations(final String profile) {
-        urlAnnotationsTableWithProfile = DBUtils.appendProfile(profile, BrowserContract.UrlAnnotations.CONTENT_URI);
+        urlAnnotationsTableWithProfile = DBUtils.appendProfile(BrowserContract.UrlAnnotations.CONTENT_URI, profile);
     }
 
     /**
      * Get all feed subscriptions.
      */
     @Override
     public Cursor getFeedSubscriptions(ContentResolver cr) {
         return queryByKey(cr,