From 47fa5a94b34cdf755aa968a8dd10c2fc5b110dfd Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Thu, 30 Jun 2016 15:35:12 +1000 Subject: [PATCH 1/7] Ensure constants always used for fields in ApkProvider. --- .../main/java/org/fdroid/fdroid/data/ApkProvider.java | 10 +++++----- .../main/java/org/fdroid/fdroid/data/RepoProvider.java | 2 +- app/src/main/java/org/fdroid/fdroid/data/Schema.java | 2 +- .../java/org/fdroid/fdroid/data/TempApkProvider.java | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java index 66b9e6f1d..dbc667ffa 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java @@ -350,8 +350,8 @@ public class ApkProvider extends FDroidProvider { appendField("rowid", "apk", "_id"); } else if (field.equals(Cols._COUNT)) { appendField("COUNT(*) AS " + Cols._COUNT); - } else if (field.equals(Cols._COUNT_DISTINCT_ID)) { - appendField("COUNT(DISTINCT apk.id) AS " + Cols._COUNT_DISTINCT_ID); + } else if (field.equals(Cols._COUNT_DISTINCT)) { + appendField("COUNT(DISTINCT apk." + Cols.PACKAGE_NAME + ") AS " + Cols._COUNT_DISTINCT); } else { appendField(field, "apk"); } @@ -360,7 +360,7 @@ public class ApkProvider extends FDroidProvider { private void addRepoField(String field, String alias) { if (!repoTableRequired) { repoTableRequired = true; - leftJoin(RepoTable.NAME, "repo", "apk.repo = repo._id"); + leftJoin(RepoTable.NAME, "repo", "apk." + Cols.REPO_ID + " = repo." + RepoTable.Cols._ID); } appendField(field, "repo", alias); } @@ -374,7 +374,7 @@ public class ApkProvider extends FDroidProvider { } private QuerySelection querySingle(Uri uri) { - final String selection = " vercode = ? and id = ? "; + final String selection = Cols.VERSION_CODE + " = ? and " + Cols.PACKAGE_NAME + " = ? "; final String[] args = { // First (0th) path segment is the word "apk", // and we are not interested in it. @@ -412,7 +412,7 @@ public class ApkProvider extends FDroidProvider { if (i != 0) { sb.append(" OR "); } - sb.append(" ( id = ? AND vercode = ? ) "); + sb.append(" ( " + Cols.PACKAGE_NAME + " = ? AND " + Cols.VERSION_CODE + " = ? ) "); } return new QuerySelection(sb.toString(), args); } diff --git a/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java b/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java index bc7d9c8fa..702d69ca6 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java @@ -195,7 +195,7 @@ public class RepoProvider extends FDroidProvider { public static int countAppsForRepo(Context context, long repoId) { ContentResolver resolver = context.getContentResolver(); - final String[] projection = {Schema.ApkTable.Cols._COUNT_DISTINCT_ID}; + final String[] projection = {Schema.ApkTable.Cols._COUNT_DISTINCT}; Uri apkUri = ApkProvider.getRepoUri(repoId); Cursor cursor = resolver.query(apkUri, projection, null, null, null); int count = 0; diff --git a/app/src/main/java/org/fdroid/fdroid/data/Schema.java b/app/src/main/java/org/fdroid/fdroid/data/Schema.java index 2a8cbbc91..0d6571794 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/Schema.java +++ b/app/src/main/java/org/fdroid/fdroid/data/Schema.java @@ -80,7 +80,7 @@ public interface Schema { String NAME = "fdroid_apk"; interface Cols extends BaseColumns { - String _COUNT_DISTINCT_ID = "countDistinct"; + String _COUNT_DISTINCT = "countDistinct"; String PACKAGE_NAME = "id"; String VERSION_NAME = "version"; diff --git a/app/src/main/java/org/fdroid/fdroid/data/TempApkProvider.java b/app/src/main/java/org/fdroid/fdroid/data/TempApkProvider.java index 55f90fe11..0033c353e 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/TempApkProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/TempApkProvider.java @@ -131,9 +131,9 @@ public class TempApkProvider extends ApkProvider { final SQLiteDatabase db = db(); final String memoryDbName = TempAppProvider.DB; db.execSQL("CREATE TABLE " + memoryDbName + "." + getTableName() + " AS SELECT * FROM main." + ApkTable.NAME); - db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_vercode on " + getTableName() + " (vercode);"); - db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_id on " + getTableName() + " (id);"); - db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_compatible ON " + getTableName() + " (compatible);"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_vercode on " + getTableName() + " (" + ApkTable.Cols.VERSION_CODE + ");"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_id on " + getTableName() + " (" + ApkTable.Cols.PACKAGE_NAME + ");"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + memoryDbName + ".apk_compatible ON " + getTableName() + " (" + ApkTable.Cols.IS_COMPATIBLE + ");"); } } From a8d2b2aff3d2614240459bddabc71c8cd13352f2 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Thu, 30 Jun 2016 16:01:18 +1000 Subject: [PATCH 2/7] Ensure constants always used for fields in AppProvider. --- .../org/fdroid/fdroid/data/AppProvider.java | 167 +++++++----------- .../fdroid/fdroid/data/TempAppProvider.java | 6 +- 2 files changed, 70 insertions(+), 103 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java index f1d5e0b8d..3dedab94f 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java @@ -247,8 +247,8 @@ public class AppProvider extends FDroidProvider { final String repo = RepoTable.NAME; return app + - " LEFT JOIN " + apk + " ON ( " + apk + ".id = " + app + ".id ) " + - " LEFT JOIN " + repo + " ON ( " + apk + ".repo = " + repo + "._id )"; + " LEFT JOIN " + apk + " ON (" + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + ") " + + " LEFT JOIN " + repo + " ON (" + apk + "." + ApkTable.Cols.REPO_ID + " = " + repo + "." + RepoTable.Cols._ID + ") "; } @Override @@ -259,7 +259,7 @@ public class AppProvider extends FDroidProvider { @Override protected String groupBy() { // If the count field has been requested, then we want to group all rows together. - return countFieldAppended ? null : getTableName() + ".id"; + return countFieldAppended ? null : getTableName() + "." + Cols.PACKAGE_NAME; } public void addSelection(AppQuerySelection selection) { @@ -276,7 +276,7 @@ public class AppProvider extends FDroidProvider { join( InstalledAppTable.NAME, "installed", - "installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + ".id"); + "installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + "." + Cols.PACKAGE_NAME); requiresInstalledTable = true; } } @@ -286,7 +286,7 @@ public class AppProvider extends FDroidProvider { leftJoin( InstalledAppTable.NAME, "installed", - "installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + ".id"); + "installed." + InstalledAppTable.Cols.PACKAGE_NAME + " = " + getTableName() + "." + Cols.PACKAGE_NAME); requiresInstalledTable = true; } } @@ -320,7 +320,7 @@ public class AppProvider extends FDroidProvider { private void appendCountField() { countFieldAppended = true; - appendField("COUNT( DISTINCT " + getTableName() + ".id ) AS " + Cols._COUNT); + appendField("COUNT( DISTINCT " + getTableName() + "." + Cols.PACKAGE_NAME + " ) AS " + Cols._COUNT); } private void addSuggestedApkVersionField() { @@ -335,7 +335,7 @@ public class AppProvider extends FDroidProvider { leftJoin( getApkTableName(), "suggestedApk", - getTableName() + ".suggestedVercode = suggestedApk.vercode AND " + getTableName() + ".id = suggestedApk.id"); + getTableName() + "." + Cols.SUGGESTED_VERSION_CODE + " = suggestedApk." + ApkTable.Cols.VERSION_CODE + " AND " + getTableName() + "." + Cols.PACKAGE_NAME + " = suggestedApk." + ApkTable.Cols.PACKAGE_NAME); } appendField(fieldName, "suggestedApk", alias); } @@ -547,15 +547,16 @@ public class AppProvider extends FDroidProvider { } private AppQuerySelection queryCanUpdate() { - final String ignoreCurrent = getTableName() + ".ignoreThisUpdate != " + getTableName() + ".suggestedVercode "; - final String ignoreAll = getTableName() + ".ignoreAllUpdates != 1 "; - final String ignore = " ( " + ignoreCurrent + " AND " + ignoreAll + " ) "; - final String where = ignore + " AND " + getTableName() + "." + Cols.SUGGESTED_VERSION_CODE + " > installed.versionCode"; + final String app = getTableName(); + final String ignoreCurrent = app + "." + Cols.IGNORE_THISUPDATE + "!= " + app + "." + Cols.SUGGESTED_VERSION_CODE; + final String ignoreAll = app + "." + Cols.IGNORE_ALLUPDATES + " != 1"; + final String ignore = " (" + ignoreCurrent + " AND " + ignoreAll + ") "; + final String where = ignore + " AND " + app + "." + Cols.SUGGESTED_VERSION_CODE + " > installed." + InstalledAppTable.Cols.VERSION_CODE; return new AppQuerySelection(where).requireNaturalInstalledTable(); } private AppQuerySelection queryRepo(long repoId) { - final String selection = getApkTableName() + ".repo = ? "; + final String selection = getApkTableName() + "." + ApkTable.Cols.REPO_ID + " = ? "; final String[] args = {String.valueOf(repoId)}; return new AppQuerySelection(selection, args); } @@ -580,11 +581,12 @@ public class AppProvider extends FDroidProvider { iKeyword++; } + final String app = getTableName(); final String[] columns = { - getTableName() + ".id", - getTableName() + ".name", - getTableName() + ".summary", - getTableName() + ".description", + app + "." + Cols.PACKAGE_NAME, + app + "." + Cols.NAME, + app + "." + Cols.SUMMARY, + app + "." + Cols.DESCRIPTION, }; // Build selection string and fill out keyword arguments @@ -596,7 +598,7 @@ public class AppProvider extends FDroidProvider { if (firstColumn) { firstColumn = false; } else { - selection.append("OR "); + selection.append(" OR "); } selection.append('('); boolean firstKeyword = true; @@ -606,7 +608,7 @@ public class AppProvider extends FDroidProvider { } else { selection.append(" AND "); } - selection.append(column).append(" like ?"); + selection.append(column).append(" LIKE ?"); selectionKeywords[iKeyword] = keyword; iKeyword++; } @@ -616,15 +618,15 @@ public class AppProvider extends FDroidProvider { } protected AppQuerySelection querySingle(String packageName) { - final String selection = getTableName() + ".id = ?"; + final String selection = getTableName() + "." + Cols.PACKAGE_NAME + " = ?"; final String[] args = {packageName}; return new AppQuerySelection(selection, args); } private AppQuerySelection queryIgnored() { final String table = getTableName(); - final String selection = table + ".ignoreAllUpdates = 1 OR " + - table + ".ignoreThisUpdate >= " + table + ".suggestedVercode"; + final String selection = table + "." + Cols.IGNORE_ALLUPDATES + " = 1 OR " + + table + "." + Cols.IGNORE_THISUPDATE + " >= " + table + "." + Cols.SUGGESTED_VERSION_CODE; return new AppQuerySelection(selection); } @@ -632,19 +634,21 @@ public class AppProvider extends FDroidProvider { // fdroid_repo will have null fields if the LEFT JOIN didn't resolve, e.g. due to there // being no apks for the app in the result set. In that case, we can't tell if it is from // a swap repo or not. - final String selection = " fdroid_repo.isSwap = 0 OR fdroid_repo.isSwap is null "; + final String isSwap = RepoTable.NAME + "." + RepoTable.Cols.IS_SWAP; + final String selection = isSwap + " = 0 OR " + isSwap + " IS NULL"; return new AppQuerySelection(selection); } private AppQuerySelection queryNewlyAdded() { - final String selection = getTableName() + ".added > ?"; + final String selection = getTableName() + "." + Cols.ADDED + " > ?"; final String[] args = {Utils.formatDate(Preferences.get().calcMaxHistory(), "")}; return new AppQuerySelection(selection, args); } private AppQuerySelection queryRecentlyUpdated() { final String app = getTableName(); - final String selection = app + ".added != " + app + ".lastUpdated AND " + app + ".lastUpdated > ?"; + final String lastUpdated = app + "." + Cols.LAST_UPDATED; + final String selection = app + "." + Cols.ADDED + " != " + lastUpdated + " AND " + lastUpdated + " > ?"; final String[] args = {Utils.formatDate(Preferences.get().calcMaxHistory(), "")}; return new AppQuerySelection(selection, args); } @@ -652,11 +656,12 @@ public class AppProvider extends FDroidProvider { private AppQuerySelection queryCategory(String category) { // TODO: In the future, add a new table for categories, // so we can join onto it. + final String app = getTableName(); final String selection = - getTableName() + ".categories = ? OR " + // Only category e.g. "internet" - getTableName() + ".categories LIKE ? OR " + // First category e.g. "internet,%" - getTableName() + ".categories LIKE ? OR " + // Last category e.g. "%,internet" - getTableName() + ".categories LIKE ? "; // One of many categories e.g. "%,internet,%" + app + "." + Cols.CATEGORIES + " = ? OR " + // Only category e.g. "internet" + app + "." + Cols.CATEGORIES + " LIKE ? OR " + // First category e.g. "internet,%" + app + "." + Cols.CATEGORIES + " LIKE ? OR " + // Last category e.g. "%,internet" + app + "." + Cols.CATEGORIES + " LIKE ? "; // One of many categories e.g. "%,internet,%" final String[] args = { category, category + ",%", @@ -667,18 +672,20 @@ public class AppProvider extends FDroidProvider { } private AppQuerySelection queryNoApks() { - String selection = "(SELECT COUNT(*) FROM " + getApkTableName() + " WHERE " + getApkTableName() + ".id = " + getTableName() + ".id) = 0"; + final String apk = getApkTableName(); + final String app = getTableName(); + String selection = "(SELECT COUNT(*) FROM " + apk + " WHERE " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + ") = 0"; return new AppQuerySelection(selection); } - static AppQuerySelection queryApps(String packageNames, String idField) { + static AppQuerySelection queryApps(String packageNames, String packageNameField) { String[] args = packageNames.split(","); - String selection = idField + " IN (" + generateQuestionMarksForInClause(args.length) + ")"; + String selection = packageNameField + " IN (" + generateQuestionMarksForInClause(args.length) + ")"; return new AppQuerySelection(selection, args); } private AppQuerySelection queryApps(String packageNames) { - return queryApps(packageNames, getTableName() + ".id"); + return queryApps(packageNames, getTableName() + "." + Cols.PACKAGE_NAME); } @Override @@ -749,13 +756,13 @@ public class AppProvider extends FDroidProvider { break; case RECENTLY_UPDATED: - sortOrder = getTableName() + ".lastUpdated DESC"; + sortOrder = getTableName() + "." + Cols.LAST_UPDATED + " DESC"; selection = selection.add(queryRecentlyUpdated()); includeSwap = false; break; case NEWLY_ADDED: - sortOrder = getTableName() + ".added DESC"; + sortOrder = getTableName() + "." + Cols.ADDED + " DESC"; selection = selection.add(queryNewlyAdded()); includeSwap = false; break; @@ -846,26 +853,18 @@ public class AppProvider extends FDroidProvider { /** * For each app, we want to set the isCompatible flag to 1 if any of the apks we know * about are compatible, and 0 otherwise. - * - * Readable SQL code: - * - * UPDATE fdroid_app SET compatible = ( - * SELECT TOTAL( fdroid_apk.compatible ) > 0 - * FROM fdroid_apk - * WHERE fdroid_apk.id = fdroid_app.id ); */ private void updateCompatibleFlags() { - Utils.debugLog(TAG, "Calculating whether apps are compatible, based on whether any of their apks are compatible"); final String apk = getApkTableName(); final String app = getTableName(); String updateSql = - "UPDATE " + app + " SET compatible = ( " + - " SELECT TOTAL( " + apk + ".compatible ) > 0 " + + "UPDATE " + app + " SET " + Cols.IS_COMPATIBLE + " = ( " + + " SELECT TOTAL( " + apk + "." + ApkTable.Cols.IS_COMPATIBLE + ") > 0 " + " FROM " + apk + - " WHERE " + apk + ".id = " + app + ".id );"; + " WHERE " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " = " + app + "." + Cols.PACKAGE_NAME + " );"; db().execSQL(updateSql); } @@ -875,38 +874,24 @@ public class AppProvider extends FDroidProvider { * with the closest version code to that, without going over. * If the app is not compatible at all (i.e. no versions were compatible) * then we take the highest, otherwise we take the highest compatible version. - * - * Readable SQL code: - * - * UPDATE fdroid_app - * SET suggestedVercode = ( - * SELECT MAX(fdroid_apk.vercode) - * FROM fdroid_apk - * WHERE - * fdroid_app.id = fdroid_apk.id AND - * fdroid_apk.vercode <= fdroid_app.upstreamVercode AND - * ( fdroid_app.compatible = 0 OR fdroid_apk.compatible = 1 ) - * ) - * WHERE upstreamVercode > 0 */ private void updateSuggestedFromUpstream() { - Utils.debugLog(TAG, "Calculating suggested versions for all apps which specify an upstream version code."); final String apk = getApkTableName(); final String app = getTableName(); final boolean unstableUpdates = Preferences.get().getUnstableUpdates(); - String restrictToStable = unstableUpdates ? "" : (apk + ".vercode <= " + app + ".upstreamVercode AND "); + String restrictToStable = unstableUpdates ? "" : (apk + "." + ApkTable.Cols.VERSION_CODE + " <= " + app + "." + Cols.UPSTREAM_VERSION_CODE + " AND "); String updateSql = - "UPDATE " + app + " SET suggestedVercode = ( " + - " SELECT MAX( " + apk + ".vercode ) " + + "UPDATE " + app + " SET " + Cols.SUGGESTED_VERSION_CODE + " = ( " + + " SELECT MAX( " + apk + "." + ApkTable.Cols.VERSION_CODE + " ) " + " FROM " + apk + " WHERE " + - app + ".id = " + apk + ".id AND " + + app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " + restrictToStable + - " ( " + app + ".compatible = 0 OR " + apk + ".compatible = 1 ) ) " + - " WHERE upstreamVercode > 0 "; + " ( " + app + "." + Cols.IS_COMPATIBLE + " = 0 OR " + apk + "." + Cols.IS_COMPATIBLE + " = 1 ) ) " + + " WHERE " + Cols.UPSTREAM_VERSION_CODE + " > 0 "; db().execSQL(updateSql); } @@ -918,33 +903,21 @@ public class AppProvider extends FDroidProvider { * If the suggested version is null, it means that we could not figure it * out from the upstream vercode. In such a case, fall back to the simpler * algorithm as if upstreamVercode was 0. - * - * Readable SQL code: - * - * UPDATE fdroid_app SET suggestedVercode = ( - * SELECT MAX(fdroid_apk.vercode) - * FROM fdroid_apk - * WHERE - * fdroid_app.id = fdroid_apk.id AND - * ( fdroid_app.compatible = 0 OR fdroid_apk.compatible = 1 ) - * ) - * WHERE upstreamVercode = 0 OR upstreamVercode IS NULL OR suggestedVercode IS NULL; */ private void updateSuggestedFromLatest() { - Utils.debugLog(TAG, "Calculating suggested versions for all apps which don't specify an upstream version code."); final String apk = getApkTableName(); final String app = getTableName(); String updateSql = - "UPDATE " + app + " SET suggestedVercode = ( " + - " SELECT MAX( " + apk + ".vercode ) " + + "UPDATE " + app + " SET " + Cols.SUGGESTED_VERSION_CODE + " = ( " + + " SELECT MAX( " + apk + "." + ApkTable.Cols.VERSION_CODE + " ) " + " FROM " + apk + " WHERE " + - app + ".id = " + apk + ".id AND " + - " ( " + app + ".compatible = 0 OR " + apk + ".compatible = 1 ) ) " + - " WHERE upstreamVercode = 0 OR upstreamVercode IS NULL OR suggestedVercode IS NULL "; + app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " + + " ( " + app + "." + Cols.IS_COMPATIBLE + " = 0 OR " + apk + "." + ApkTable.Cols.IS_COMPATIBLE + " = 1 ) ) " + + " WHERE " + Cols.UPSTREAM_VERSION_CODE + " = 0 OR " + Cols.UPSTREAM_VERSION_CODE + " IS NULL OR " + Cols.SUGGESTED_VERSION_CODE + " IS NULL "; db().execSQL(updateSql); } @@ -958,8 +931,7 @@ public class AppProvider extends FDroidProvider { final String iconsDir = Utils.getIconsDir(context, 1.0); final String iconsDirLarge = Utils.getIconsDir(context, 1.5); String repoVersion = Integer.toString(Repo.VERSION_DENSITY_SPECIFIC_ICONS); - Utils.debugLog(TAG, "Updating icon paths for apps belonging to repos with version >= " - + repoVersion); + Utils.debugLog(TAG, "Updating icon paths for apps belonging to repos with version >= " + repoVersion); Utils.debugLog(TAG, "Using icons dir '" + iconsDir + "'"); Utils.debugLog(TAG, "Using large icons dir '" + iconsDirLarge + "'"); String query = getIconUpdateQuery(appTable, apkTable); @@ -980,38 +952,33 @@ public class AppProvider extends FDroidProvider { final String repo = RepoTable.NAME; final String iconUrlQuery = - " SELECT " + + "SELECT " + // Concatenate (using the "||" operator) the address, the // icons directory (bound to the ? as the second parameter // when executing the query) and the icon path. - " ( " + - repo + ".address " + + "( " + + repo + "." + RepoTable.Cols.ADDRESS + " || " + // If the repo has the relevant version, then use a more // intelligent icons dir, otherwise revert to the default // one - " CASE WHEN " + repo + ".version >= ? THEN ? ELSE ? END " + + " CASE WHEN " + repo + "." + RepoTable.Cols.VERSION + " >= ? THEN ? ELSE ? END " + " || " + - app + ".icon " + + app + "." + Cols.ICON + ") " + " FROM " + apk + - " JOIN " + repo + " ON (" + repo + "._id = " + apk + ".repo) " + + " JOIN " + repo + " ON (" + repo + "." + RepoTable.Cols._ID + " = " + apk + "." + ApkTable.Cols.REPO_ID + ") " + " WHERE " + - app + ".id = " + apk + ".id AND " + - apk + ".vercode = " + app + ".suggestedVercode "; + app + "." + Cols.PACKAGE_NAME + " = " + apk + "." + ApkTable.Cols.PACKAGE_NAME + " AND " + + apk + "." + ApkTable.Cols.VERSION_CODE + " = " + app + "." + Cols.SUGGESTED_VERSION_CODE; - return - " UPDATE " + app + " SET " + - " iconUrl = ( " + - iconUrlQuery + - " ), " + - " iconUrlLarge = ( " + - iconUrlQuery + - " ) "; + return "UPDATE " + app + " SET " + + Cols.ICON_URL + " = ( " + iconUrlQuery + " ), " + + Cols.ICON_URL_LARGE + " = ( " + iconUrlQuery + " )"; } } diff --git a/app/src/main/java/org/fdroid/fdroid/data/TempAppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/TempAppProvider.java index bd0a20ddc..3290dfb88 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/TempAppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/TempAppProvider.java @@ -131,9 +131,9 @@ public class TempAppProvider extends AppProvider { ensureTempTableDetached(db); db.execSQL("ATTACH DATABASE ':memory:' AS " + DB); db.execSQL("CREATE TABLE " + DB + "." + getTableName() + " AS SELECT * FROM main." + AppTable.NAME); - db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_id ON " + getTableName() + " (id);"); - db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_upstreamVercode ON " + getTableName() + " (upstreamVercode);"); - db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_compatible ON " + getTableName() + " (compatible);"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_id ON " + getTableName() + " (" + AppTable.Cols.PACKAGE_NAME + ");"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_upstreamVercode ON " + getTableName() + " (" + AppTable.Cols.UPSTREAM_VERSION_CODE + ");"); + db.execSQL("CREATE INDEX IF NOT EXISTS " + DB + ".app_compatible ON " + getTableName() + " (" + AppTable.Cols.IS_COMPATIBLE + ");"); } private void commitTable() { From 2ffd4ae4285be585a0a7a2f6ae20803517f0fcc2 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Thu, 30 Jun 2016 16:11:59 +1000 Subject: [PATCH 3/7] Ensure constants always used for fields in RepoProvider. --- .../main/java/org/fdroid/fdroid/data/RepoProvider.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java b/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java index 702d69ca6..c9e8b860a 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/RepoProvider.java @@ -141,8 +141,8 @@ public class RepoProvider extends FDroidProvider { } else if (!fingerprint.equals(calcedFingerprint)) { // TODO the UI should represent this error! Log.e(TAG, "The stored and calculated fingerprints do not match!"); - Log.e(TAG, "stored: " + fingerprint); - Log.e(TAG, "calced: " + calcedFingerprint); + Log.e(TAG, "Stored: " + fingerprint); + Log.e(TAG, "Calculated: " + calcedFingerprint); } } } else if (!TextUtils.isEmpty(publicKey)) { @@ -327,14 +327,14 @@ public class RepoProvider extends FDroidProvider { @Override public int delete(Uri uri, String where, String[] whereArgs) { + QuerySelection selection = new QuerySelection(where, whereArgs); switch (MATCHER.match(uri)) { case CODE_LIST: // Don't support deleting of multiple repos. return 0; case CODE_SINGLE: - where = (where == null ? "" : where + " AND ") + - "_ID = " + uri.getLastPathSegment(); + selection.add(Cols._ID + " = ?", new String[] {uri.getLastPathSegment()}); break; default: @@ -342,7 +342,7 @@ public class RepoProvider extends FDroidProvider { throw new UnsupportedOperationException("Invalid URI for repo content provider: " + uri); } - int rowsAffected = db().delete(getTableName(), where, whereArgs); + int rowsAffected = db().delete(getTableName(), selection.getSelection(), selection.getArgs()); Utils.debugLog(TAG, "Deleted repos. Notifying provider change: '" + uri + "'."); getContext().getContentResolver().notifyChange(uri, null); return rowsAffected; From 131978ad0244640901171dffa8101e1b42e4c5af Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Thu, 30 Jun 2016 16:58:41 +1000 Subject: [PATCH 4/7] Refactored create table statements to use constants from schema. --- .../java/org/fdroid/fdroid/data/DBHelper.java | 127 +++++++++--------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 294dee31c..4664e43dc 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -24,74 +24,81 @@ class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "fdroid"; private static final String CREATE_TABLE_REPO = "create table " - + RepoTable.NAME + " (_id integer primary key, " - + "address text not null, " - + "name text, description text, inuse integer not null, " - + "priority integer not null, pubkey text, fingerprint text, " - + "maxage integer not null default 0, " - + "version integer not null default 0, " - + "lastetag text, lastUpdated string," - + "isSwap integer boolean default 0," - + "username string, password string," - + "timestamp integer not null default 0" + + RepoTable.NAME + " (" + + RepoTable.Cols._ID + " integer primary key, " + + RepoTable.Cols.ADDRESS + " text not null, " + + RepoTable.Cols.NAME + " text, " + + RepoTable.Cols.DESCRIPTION + " text, " + + RepoTable.Cols.IN_USE + " integer not null, " + + RepoTable.Cols.PRIORITY + " integer not null, " + + RepoTable.Cols.SIGNING_CERT + " text, " + + RepoTable.Cols.FINGERPRINT + " text, " + + RepoTable.Cols.MAX_AGE + " integer not null default 0, " + + RepoTable.Cols.VERSION + " integer not null default 0, " + + RepoTable.Cols.LAST_ETAG + " text, " + + RepoTable.Cols.LAST_UPDATED + " string," + + RepoTable.Cols.IS_SWAP + " integer boolean default 0," + + RepoTable.Cols.USERNAME + " string, " + + RepoTable.Cols.PASSWORD + " string," + + RepoTable.Cols.TIMESTAMP + " integer not null default 0" + ");"; private static final String CREATE_TABLE_APK = "CREATE TABLE " + ApkTable.NAME + " ( " - + "id text not null, " - + "version text not null, " - + "repo integer not null, " - + "hash text not null, " - + "vercode int not null," - + "apkName text not null, " - + "size int not null, " - + "sig string, " - + "srcname string, " - + "minSdkVersion integer, " - + "targetSdkVersion integer, " - + "maxSdkVersion integer, " - + "permissions string, " - + "features string, " - + "nativecode string, " - + "hashType string, " - + "added string, " - + "compatible int not null, " - + "incompatibleReasons text, " - + "primary key(id, vercode)" + + ApkTable.Cols.PACKAGE_NAME + " text not null, " + + ApkTable.Cols.VERSION_NAME + " text not null, " + + ApkTable.Cols.REPO_ID + " integer not null, " + + ApkTable.Cols.HASH + " text not null, " + + ApkTable.Cols.VERSION_CODE + " int not null," + + ApkTable.Cols.NAME + " text not null, " + + ApkTable.Cols.SIZE + " int not null, " + + ApkTable.Cols.SIGNATURE + " string, " + + ApkTable.Cols.SOURCE_NAME + " string, " + + ApkTable.Cols.MIN_SDK_VERSION + " integer, " + + ApkTable.Cols.TARGET_SDK_VERSION + " integer, " + + ApkTable.Cols.MAX_SDK_VERSION + " integer, " + + ApkTable.Cols.PERMISSIONS + " string, " + + ApkTable.Cols.FEATURES + " string, " + + ApkTable.Cols.NATIVE_CODE + " string, " + + ApkTable.Cols.HASH_TYPE + " string, " + + ApkTable.Cols.ADDED_DATE + " string, " + + ApkTable.Cols.IS_COMPATIBLE + " int not null, " + + ApkTable.Cols.INCOMPATIBLE_REASONS + " text, " + + "primary key(" + ApkTable.Cols.PACKAGE_NAME + ", " + ApkTable.Cols.VERSION_CODE + ")" + ");"; private static final String CREATE_TABLE_APP = "CREATE TABLE " + AppTable.NAME + " ( " - + "id text not null, " - + "name text not null, " - + "summary text not null, " - + "icon text, " - + "description text not null, " - + "license text not null, " - + "author text, " - + "email text, " - + "webURL text, " - + "trackerURL text, " - + "sourceURL text, " - + "changelogURL text, " - + "suggestedVercode text," - + "upstreamVersion text," - + "upstreamVercode integer," - + "antiFeatures string," - + "donateURL string," - + "bitcoinAddr string," - + "litecoinAddr string," - + "flattrID string," - + "requirements string," - + "categories string," - + "added string," - + "lastUpdated string," - + "compatible int not null," - + "ignoreAllUpdates int not null," - + "ignoreThisUpdate int not null," - + "iconUrl text, " - + "iconUrlLarge text, " - + "primary key(id));"; + + AppTable.Cols.PACKAGE_NAME + "id text not null, " + + AppTable.Cols.NAME + "name text not null, " + + AppTable.Cols.SUMMARY + "summary text not null, " + + AppTable.Cols.ICON + "icon text, " + + AppTable.Cols.DESCRIPTION + "description text not null, " + + AppTable.Cols.LICENSE + "license text not null, " + + AppTable.Cols.AUTHOR + "author text, " + + AppTable.Cols.EMAIL + "email text, " + + AppTable.Cols.WEB_URL + "webURL text, " + + AppTable.Cols.TRACKER_URL + "trackerURL text, " + + AppTable.Cols.SOURCE_URL + "sourceURL text, " + + AppTable.Cols.CHANGELOG_URL + "changelogURL text, " + + AppTable.Cols.SUGGESTED_VERSION_CODE + "suggestedVercode text," + + AppTable.Cols.UPSTREAM_VERSION_NAME + "upstreamVersion text," + + AppTable.Cols.UPSTREAM_VERSION_CODE + "upstreamVercode integer," + + AppTable.Cols.ANTI_FEATURES + "antiFeatures string," + + AppTable.Cols.DONATE_URL + "donateURL string," + + AppTable.Cols.BITCOIN_ADDR + "bitcoinAddr string," + + AppTable.Cols.LITECOIN_ADDR + "litecoinAddr string," + + AppTable.Cols.FLATTR_ID + "flattrID string," + + AppTable.Cols.REQUIREMENTS + "requirements string," + + AppTable.Cols.CATEGORIES + "categories string," + + AppTable.Cols.ADDED + "added string," + + AppTable.Cols.LAST_UPDATED + "lastUpdated string," + + AppTable.Cols.IS_COMPATIBLE + "compatible int not null," + + AppTable.Cols.IGNORE_ALLUPDATES + "ignoreAllUpdates int not null," + + AppTable.Cols.IGNORE_THISUPDATE + "ignoreThisUpdate int not null," + + AppTable.Cols.ICON_URL + "iconUrl text, " + + AppTable.Cols.ICON_URL_LARGE + "iconUrlLarge text, " + + "primary key(" + AppTable.Cols.PACKAGE_NAME + "));"; private static final String CREATE_TABLE_INSTALLED_APP = "CREATE TABLE " + InstalledAppTable.NAME + " ( " From c55a53ec69ee79c7bcacae104da48c7b282a93da Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Sat, 2 Jul 2016 07:37:33 +1000 Subject: [PATCH 5/7] Ensure constants always used for fields in DBHelper. --- .../java/org/fdroid/fdroid/data/DBHelper.java | 216 +++++++++--------- 1 file changed, 114 insertions(+), 102 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java index 4664e43dc..3b682064e 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -5,6 +5,7 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.text.TextUtils; import android.util.Log; import org.fdroid.fdroid.R; @@ -69,35 +70,35 @@ class DBHelper extends SQLiteOpenHelper { private static final String CREATE_TABLE_APP = "CREATE TABLE " + AppTable.NAME + " ( " - + AppTable.Cols.PACKAGE_NAME + "id text not null, " - + AppTable.Cols.NAME + "name text not null, " - + AppTable.Cols.SUMMARY + "summary text not null, " - + AppTable.Cols.ICON + "icon text, " - + AppTable.Cols.DESCRIPTION + "description text not null, " - + AppTable.Cols.LICENSE + "license text not null, " - + AppTable.Cols.AUTHOR + "author text, " - + AppTable.Cols.EMAIL + "email text, " - + AppTable.Cols.WEB_URL + "webURL text, " - + AppTable.Cols.TRACKER_URL + "trackerURL text, " - + AppTable.Cols.SOURCE_URL + "sourceURL text, " - + AppTable.Cols.CHANGELOG_URL + "changelogURL text, " - + AppTable.Cols.SUGGESTED_VERSION_CODE + "suggestedVercode text," - + AppTable.Cols.UPSTREAM_VERSION_NAME + "upstreamVersion text," - + AppTable.Cols.UPSTREAM_VERSION_CODE + "upstreamVercode integer," - + AppTable.Cols.ANTI_FEATURES + "antiFeatures string," - + AppTable.Cols.DONATE_URL + "donateURL string," - + AppTable.Cols.BITCOIN_ADDR + "bitcoinAddr string," - + AppTable.Cols.LITECOIN_ADDR + "litecoinAddr string," - + AppTable.Cols.FLATTR_ID + "flattrID string," - + AppTable.Cols.REQUIREMENTS + "requirements string," - + AppTable.Cols.CATEGORIES + "categories string," - + AppTable.Cols.ADDED + "added string," - + AppTable.Cols.LAST_UPDATED + "lastUpdated string," - + AppTable.Cols.IS_COMPATIBLE + "compatible int not null," - + AppTable.Cols.IGNORE_ALLUPDATES + "ignoreAllUpdates int not null," - + AppTable.Cols.IGNORE_THISUPDATE + "ignoreThisUpdate int not null," - + AppTable.Cols.ICON_URL + "iconUrl text, " - + AppTable.Cols.ICON_URL_LARGE + "iconUrlLarge text, " + + AppTable.Cols.PACKAGE_NAME + " text not null, " + + AppTable.Cols.NAME + " text not null, " + + AppTable.Cols.SUMMARY + " text not null, " + + AppTable.Cols.ICON + " text, " + + AppTable.Cols.DESCRIPTION + " text not null, " + + AppTable.Cols.LICENSE + " text not null, " + + AppTable.Cols.AUTHOR + " text, " + + AppTable.Cols.EMAIL + " text, " + + AppTable.Cols.WEB_URL + " text, " + + AppTable.Cols.TRACKER_URL + " text, " + + AppTable.Cols.SOURCE_URL + " text, " + + AppTable.Cols.CHANGELOG_URL + " text, " + + AppTable.Cols.SUGGESTED_VERSION_CODE + " text," + + AppTable.Cols.UPSTREAM_VERSION_NAME + " text," + + AppTable.Cols.UPSTREAM_VERSION_CODE + " integer," + + AppTable.Cols.ANTI_FEATURES + " string," + + AppTable.Cols.DONATE_URL + " string," + + AppTable.Cols.BITCOIN_ADDR + " string," + + AppTable.Cols.LITECOIN_ADDR + " string," + + AppTable.Cols.FLATTR_ID + " string," + + AppTable.Cols.REQUIREMENTS + " string," + + AppTable.Cols.CATEGORIES + " string," + + AppTable.Cols.ADDED + " string," + + AppTable.Cols.LAST_UPDATED + " string," + + AppTable.Cols.IS_COMPATIBLE + " int not null," + + AppTable.Cols.IGNORE_ALLUPDATES + " int not null," + + AppTable.Cols.IGNORE_THISUPDATE + " int not null," + + AppTable.Cols.ICON_URL + " text, " + + AppTable.Cols.ICON_URL_LARGE + " text, " + "primary key(" + AppTable.Cols.PACKAGE_NAME + "));"; private static final String CREATE_TABLE_INSTALLED_APP = "CREATE TABLE " + InstalledAppTable.NAME @@ -127,9 +128,9 @@ class DBHelper extends SQLiteOpenHelper { return; } Utils.debugLog(TAG, "Populating repo names from the url"); - final String[] columns = {"address", "_id"}; + final String[] columns = {RepoTable.Cols.ADDRESS, RepoTable.Cols._ID}; Cursor cursor = db.query(RepoTable.NAME, columns, - "name IS NULL OR name = ''", null, null, null, null); + RepoTable.Cols.NAME + " IS NULL OR " + RepoTable.Cols.NAME + " = ''", null, null, null, null); if (cursor != null) { if (cursor.getCount() > 0) { cursor.moveToFirst(); @@ -138,10 +139,10 @@ class DBHelper extends SQLiteOpenHelper { long id = cursor.getInt(1); ContentValues values = new ContentValues(1); String name = Repo.addressToName(address); - values.put("name", name); + values.put(RepoTable.Cols.NAME, name); final String[] args = {Long.toString(id)}; Utils.debugLog(TAG, "Setting repo name to '" + name + "' for repo " + address); - db.update(RepoTable.NAME, values, "_id = ?", args); + db.update(RepoTable.NAME, values, RepoTable.Cols._ID + " = ?", args); cursor.moveToNext(); } } @@ -150,11 +151,11 @@ class DBHelper extends SQLiteOpenHelper { } private void renameRepoId(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 36 || columnExists(db, RepoTable.NAME, "_id")) { + if (oldVersion >= 36 || columnExists(db, RepoTable.NAME, RepoTable.Cols._ID)) { return; } - Utils.debugLog(TAG, "Renaming " + RepoTable.NAME + ".id to _id"); + Utils.debugLog(TAG, "Renaming " + RepoTable.NAME + ".id to " + RepoTable.Cols._ID); db.beginTransaction(); try { @@ -170,33 +171,44 @@ class DBHelper extends SQLiteOpenHelper { // statement. Therefore, I've put a copy of CREATE_TABLE_REPO // here that is the same as it was at DBVersion 36. String createTableDdl = "create table " + RepoTable.NAME + " (" - + "_id integer not null primary key, " - + "address text not null, " - + "name text, " - + "description text, " - + "inuse integer not null, " - + "priority integer not null, " - + "pubkey text, " - + "fingerprint text, " - + "maxage integer not null default 0, " - + "version integer not null default 0, " - + "lastetag text, " - + "lastUpdated string);"; + + RepoTable.Cols._ID + " integer not null primary key, " + + RepoTable.Cols.ADDRESS + " text not null, " + + RepoTable.Cols.NAME + " text, " + + RepoTable.Cols.DESCRIPTION + " text, " + + RepoTable.Cols.IN_USE + " integer not null, " + + RepoTable.Cols.PRIORITY + " integer not null, " + + RepoTable.Cols.SIGNING_CERT + " text, " + + RepoTable.Cols.FINGERPRINT + " text, " + + RepoTable.Cols.MAX_AGE + " integer not null default 0, " + + RepoTable.Cols.VERSION + " integer not null default 0, " + + RepoTable.Cols.LAST_ETAG + " text, " + + RepoTable.Cols.LAST_UPDATED + " string);"; db.execSQL(createTableDdl); - String nonIdFields = "address, name, description, inuse, priority, " + - "pubkey, fingerprint, maxage, version, lastetag, lastUpdated"; + String nonIdFields = TextUtils.join(", ", new String[] { + RepoTable.Cols.ADDRESS, + RepoTable.Cols.NAME, + RepoTable.Cols.DESCRIPTION, + RepoTable.Cols.IN_USE, + RepoTable.Cols.PRIORITY, + RepoTable.Cols.SIGNING_CERT, + RepoTable.Cols.FINGERPRINT, + RepoTable.Cols.MAX_AGE, + RepoTable.Cols.VERSION, + RepoTable.Cols.LAST_ETAG, + RepoTable.Cols.LAST_UPDATED, + }); String insertSql = "INSERT INTO " + RepoTable.NAME + - "(_id, " + nonIdFields + " ) " + + "(" + RepoTable.Cols._ID + ", " + nonIdFields + " ) " + "SELECT id, " + nonIdFields + " FROM " + tempTableName + ";"; db.execSQL(insertSql); db.execSQL("DROP TABLE " + tempTableName + ";"); db.setTransactionSuccessful(); } catch (Exception e) { - Log.e(TAG, "Error renaming id to _id", e); + Log.e(TAG, "Error renaming id to " + RepoTable.Cols._ID, e); } db.endTransaction(); } @@ -315,7 +327,7 @@ class DBHelper extends SQLiteOpenHelper { } List oldrepos = new ArrayList<>(); Cursor cursor = db.query(RepoTable.NAME, - new String[] {"address", "inuse", "pubkey"}, + new String[] {RepoTable.Cols.ADDRESS, RepoTable.Cols.IN_USE, RepoTable.Cols.SIGNING_CERT}, null, null, null, null, null); if (cursor != null) { if (cursor.getCount() > 0) { @@ -335,11 +347,11 @@ class DBHelper extends SQLiteOpenHelper { db.execSQL(CREATE_TABLE_REPO); for (final Repo repo : oldrepos) { ContentValues values = new ContentValues(); - values.put("address", repo.address); - values.put("inuse", repo.inuse); - values.put("priority", 10); - values.put("pubkey", repo.signingCertificate); - values.put("lastetag", (String) null); + values.put(RepoTable.Cols.ADDRESS, repo.address); + values.put(RepoTable.Cols.IN_USE, repo.inuse); + values.put(RepoTable.Cols.PRIORITY, 10); + values.put(RepoTable.Cols.SIGNING_CERT, repo.signingCertificate); + values.put(RepoTable.Cols.LAST_ETAG, (String) null); db.insert(RepoTable.NAME, null, values); } } @@ -348,9 +360,9 @@ class DBHelper extends SQLiteOpenHelper { int addressResId, int nameResId, int descriptionResId) { ContentValues values = new ContentValues(); values.clear(); - values.put("name", context.getString(nameResId)); - values.put("description", context.getString(descriptionResId)); - db.update(RepoTable.NAME, values, "address = ?", new String[] { + values.put(RepoTable.Cols.NAME, context.getString(nameResId)); + values.put(RepoTable.Cols.DESCRIPTION, context.getString(descriptionResId)); + db.update(RepoTable.NAME, values, RepoTable.Cols.ADDRESS + " = ?", new String[] { context.getString(addressResId), }); } @@ -360,16 +372,16 @@ class DBHelper extends SQLiteOpenHelper { * default repos with values from strings.xml. */ private void addNameAndDescriptionToRepo(SQLiteDatabase db, int oldVersion) { - boolean nameExists = columnExists(db, RepoTable.NAME, "name"); - boolean descriptionExists = columnExists(db, RepoTable.NAME, "description"); + boolean nameExists = columnExists(db, RepoTable.NAME, RepoTable.Cols.NAME); + boolean descriptionExists = columnExists(db, RepoTable.NAME, RepoTable.Cols.DESCRIPTION); if (oldVersion >= 21 || (nameExists && descriptionExists)) { return; } if (!nameExists) { - db.execSQL("alter table " + RepoTable.NAME + " add column name text"); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.NAME + " text"); } if (!descriptionExists) { - db.execSQL("alter table " + RepoTable.NAME + " add column description text"); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.DESCRIPTION + " text"); } insertNameAndDescription(db, R.string.fdroid_repo_address, R.string.fdroid_repo_name, R.string.fdroid_repo_description); @@ -390,12 +402,12 @@ class DBHelper extends SQLiteOpenHelper { if (oldVersion >= 44) { return; } - if (!columnExists(db, RepoTable.NAME, "fingerprint")) { - db.execSQL("alter table " + RepoTable.NAME + " add column fingerprint text"); + if (!columnExists(db, RepoTable.NAME, RepoTable.Cols.FINGERPRINT)) { + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.FINGERPRINT + " text"); } List oldrepos = new ArrayList<>(); Cursor cursor = db.query(RepoTable.NAME, - new String[] {"address", "pubkey"}, + new String[] {RepoTable.Cols.ADDRESS, RepoTable.Cols.SIGNING_CERT}, null, null, null, null, null); if (cursor != null) { if (cursor.getCount() > 0) { @@ -412,70 +424,70 @@ class DBHelper extends SQLiteOpenHelper { } for (final Repo repo : oldrepos) { ContentValues values = new ContentValues(); - values.put("fingerprint", Utils.calcFingerprint(repo.signingCertificate)); - db.update(RepoTable.NAME, values, "address = ?", new String[] {repo.address}); + values.put(RepoTable.Cols.FINGERPRINT, Utils.calcFingerprint(repo.signingCertificate)); + db.update(RepoTable.NAME, values, RepoTable.Cols.ADDRESS + " = ?", new String[] {repo.address}); } } private void addMaxAgeToRepo(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 30 || columnExists(db, RepoTable.NAME, "maxage")) { + if (oldVersion >= 30 || columnExists(db, RepoTable.NAME, RepoTable.Cols.MAX_AGE)) { return; } - db.execSQL("alter table " + RepoTable.NAME + " add column maxage integer not null default 0"); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.MAX_AGE + " integer not null default 0"); } private void addVersionToRepo(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 33 || columnExists(db, RepoTable.NAME, "version")) { + if (oldVersion >= 33 || columnExists(db, RepoTable.NAME, RepoTable.Cols.VERSION)) { return; } - db.execSQL("alter table " + RepoTable.NAME + " add column version integer not null default 0"); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.VERSION + " integer not null default 0"); } private void addLastUpdatedToRepo(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 35 || columnExists(db, RepoTable.NAME, "lastUpdated")) { + if (oldVersion >= 35 || columnExists(db, RepoTable.NAME, RepoTable.Cols.LAST_UPDATED)) { return; } - Utils.debugLog(TAG, "Adding lastUpdated column to " + RepoTable.NAME); - db.execSQL("Alter table " + RepoTable.NAME + " add column lastUpdated string"); + Utils.debugLog(TAG, "Adding " + RepoTable.Cols.LAST_UPDATED + " column to " + RepoTable.NAME); + db.execSQL("Alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.LAST_UPDATED + " string"); } private void addIsSwapToRepo(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 47 || columnExists(db, RepoTable.NAME, "isSwap")) { + if (oldVersion >= 47 || columnExists(db, RepoTable.NAME, RepoTable.Cols.IS_SWAP)) { return; } - Utils.debugLog(TAG, "Adding isSwap field to " + RepoTable.NAME + " table in db."); - db.execSQL("alter table " + RepoTable.NAME + " add column isSwap boolean default 0;"); + Utils.debugLog(TAG, "Adding " + RepoTable.Cols.IS_SWAP + " field to " + RepoTable.NAME + " table in db."); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.IS_SWAP + " boolean default 0;"); } private void addCredentialsToRepo(SQLiteDatabase db, int oldVersion) { if (oldVersion >= 52) { return; } - if (!columnExists(db, Schema.RepoTable.NAME, "username")) { - Utils.debugLog(TAG, "Adding username field to " + RepoTable.NAME + " table in db."); - db.execSQL("alter table " + RepoTable.NAME + " add column username string;"); + if (!columnExists(db, Schema.RepoTable.NAME, RepoTable.Cols.USERNAME)) { + Utils.debugLog(TAG, "Adding " + RepoTable.Cols.USERNAME + " field to " + RepoTable.NAME + " table in db."); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.USERNAME + " string;"); } - if (!columnExists(db, RepoTable.NAME, "password")) { - Utils.debugLog(TAG, "Adding password field to " + RepoTable.NAME + " table in db."); - db.execSQL("alter table " + RepoTable.NAME + " add column password string;"); + if (!columnExists(db, RepoTable.NAME, RepoTable.Cols.PASSWORD)) { + Utils.debugLog(TAG, "Adding " + RepoTable.Cols.PASSWORD + " field to " + RepoTable.NAME + " table in db."); + db.execSQL("alter table " + RepoTable.NAME + " add column " + RepoTable.Cols.PASSWORD + " string;"); } } private void addChangelogToApp(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 48 || columnExists(db, AppTable.NAME, "changelogURL")) { + if (oldVersion >= 48 || columnExists(db, AppTable.NAME, AppTable.Cols.CHANGELOG_URL)) { return; } - Utils.debugLog(TAG, "Adding changelogURL column to " + AppTable.NAME); - db.execSQL("alter table " + AppTable.NAME + " add column changelogURL text"); + Utils.debugLog(TAG, "Adding " + AppTable.Cols.CHANGELOG_URL + " column to " + AppTable.NAME); + db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.CHANGELOG_URL + " text"); } private void addIconUrlLargeToApp(SQLiteDatabase db, int oldVersion) { - if (oldVersion >= 49 || columnExists(db, AppTable.NAME, "iconUrlLarge")) { + if (oldVersion >= 49 || columnExists(db, AppTable.NAME, AppTable.Cols.ICON_URL_LARGE)) { return; } - Utils.debugLog(TAG, "Adding iconUrlLarge columns to " + AppTable.NAME); - db.execSQL("alter table " + AppTable.NAME + " add column iconUrlLarge text"); + Utils.debugLog(TAG, "Adding " + AppTable.Cols.ICON_URL_LARGE + " columns to " + AppTable.NAME); + db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.ICON_URL_LARGE + " text"); } private void updateIconUrlLarge(SQLiteDatabase db, int oldVersion) { @@ -491,13 +503,13 @@ class DBHelper extends SQLiteOpenHelper { if (oldVersion >= 53) { return; } - if (!columnExists(db, AppTable.NAME, "author")) { - Utils.debugLog(TAG, "Adding author column to " + AppTable.NAME); - db.execSQL("alter table " + AppTable.NAME + " add column author text"); + if (!columnExists(db, AppTable.NAME, AppTable.Cols.AUTHOR)) { + Utils.debugLog(TAG, "Adding " + AppTable.Cols.AUTHOR + " column to " + AppTable.NAME); + db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.AUTHOR + " text"); } - if (!columnExists(db, AppTable.NAME, "email")) { - Utils.debugLog(TAG, "Adding email column to " + AppTable.NAME); - db.execSQL("alter table " + AppTable.NAME + " add column email text"); + if (!columnExists(db, AppTable.NAME, AppTable.Cols.EMAIL)) { + Utils.debugLog(TAG, "Adding " + AppTable.Cols.EMAIL + " column to " + AppTable.NAME); + db.execSQL("alter table " + AppTable.NAME + " add column " + AppTable.Cols.EMAIL + " text"); } } @@ -505,7 +517,7 @@ class DBHelper extends SQLiteOpenHelper { if (oldVersion >= 54) { return; } - Utils.debugLog(TAG, "Converting maxSdkVersion value 0 to " + Byte.MAX_VALUE); + Utils.debugLog(TAG, "Converting " + ApkTable.Cols.MAX_SDK_VERSION + " value 0 to " + Byte.MAX_VALUE); ContentValues values = new ContentValues(); values.put(ApkTable.Cols.MAX_SDK_VERSION, Byte.MAX_VALUE); db.update(ApkTable.NAME, values, ApkTable.Cols.MAX_SDK_VERSION + " < 1", null); @@ -533,7 +545,7 @@ class DBHelper extends SQLiteOpenHelper { */ private void clearRepoEtags(SQLiteDatabase db) { Utils.debugLog(TAG, "Clearing repo etags, so next update will not be skipped with \"Repos up to date\"."); - db.execSQL("update " + RepoTable.NAME + " set lastetag = NULL"); + db.execSQL("update " + RepoTable.NAME + " set " + RepoTable.Cols.LAST_ETAG + " = NULL"); } private void resetTransient(SQLiteDatabase db, int oldVersion) { @@ -555,10 +567,10 @@ class DBHelper extends SQLiteOpenHelper { private static void createAppApk(SQLiteDatabase db) { db.execSQL(CREATE_TABLE_APP); - db.execSQL("create index app_id on " + AppTable.NAME + " (id);"); + db.execSQL("create index app_id on " + AppTable.NAME + " (" + AppTable.Cols.PACKAGE_NAME + ");"); db.execSQL(CREATE_TABLE_APK); - db.execSQL("create index apk_vercode on " + ApkTable.NAME + " (vercode);"); - db.execSQL("create index apk_id on " + ApkTable.NAME + " (id);"); + db.execSQL("create index apk_vercode on " + ApkTable.NAME + " (" + ApkTable.Cols.VERSION_CODE + ");"); + db.execSQL("create index apk_id on " + ApkTable.NAME + " (" + AppTable.Cols.PACKAGE_NAME + ");"); } /** From 9135026362585aa5fa31626ade8bc1dbbf876327 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Sat, 2 Jul 2016 07:58:23 +1000 Subject: [PATCH 6/7] Ensure constants always used for fields in InstalledAppProvider. --- .../java/org/fdroid/fdroid/data/InstalledAppProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java index 0bfeccee9..4e777a27f 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/InstalledAppProvider.java @@ -118,11 +118,11 @@ public class InstalledAppProvider extends FDroidProvider { } private QuerySelection queryApp(String packageName) { - return new QuerySelection("appId = ?", new String[]{packageName}); + return new QuerySelection(Cols.PACKAGE_NAME + " = ?", new String[]{packageName}); } private QuerySelection querySearch(String query) { - return new QuerySelection("applicationLabel LIKE ?", + return new QuerySelection(Cols.APPLICATION_LABEL + " LIKE ?", new String[]{"%" + query + "%"}); } From 88107cf94e7fe7406b8b277d0358f55121b40fc7 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Sat, 2 Jul 2016 07:58:36 +1000 Subject: [PATCH 7/7] Ensure constants always used for fields in remaining places. --- app/src/main/java/org/fdroid/fdroid/RepoUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java index f5ca2e6dc..3df518df1 100644 --- a/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java +++ b/app/src/main/java/org/fdroid/fdroid/RepoUpdater.java @@ -199,7 +199,7 @@ public class RepoUpdater { reader.setContentHandler(repoXMLHandler); reader.parse(new InputSource(indexInputStream)); - long timestamp = repoDetailsToSave.getAsLong("timestamp"); + long timestamp = repoDetailsToSave.getAsLong(RepoTable.Cols.TIMESTAMP); if (timestamp < repo.timestamp) { throw new UpdateException(repo, "index.jar is older that current index! " + timestamp + " < " + repo.timestamp);