diff --git a/F-Droid/src/org/fdroid/fdroid/RepoUpdater.java b/F-Droid/src/org/fdroid/fdroid/RepoUpdater.java index 1fe11220e..1d36baee5 100644 --- a/F-Droid/src/org/fdroid/fdroid/RepoUpdater.java +++ b/F-Droid/src/org/fdroid/fdroid/RepoUpdater.java @@ -173,14 +173,6 @@ public class RepoUpdater { if (downloadedFile == null || !downloadedFile.exists()) throw new UpdateException(repo, downloadedFile + " does not exist!"); - // This is where we will store all of the metadata before commiting at the - // end of the process. This is due to the fact that we can't verify the cert - // the index was signed with until we've finished reading it - and we don't - // want to put stuff in the real database until we are sure it is from a - // trusted source. - TempAppProvider.Helper.init(context); - TempApkProvider.Helper.init(context); - // Due to a bug in Android 5.0 Lollipop, the inclusion of spongycastle causes // breakage when verifying the signature of the downloaded .jar. For more // details, check out https://gitlab.com/fdroid/fdroidclient/issues/111. diff --git a/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java b/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java index 804fd1db2..b56616f0e 100644 --- a/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java +++ b/F-Droid/src/org/fdroid/fdroid/data/AppProvider.java @@ -24,8 +24,6 @@ public class AppProvider extends FDroidProvider { private static final String TAG = "AppProvider"; - public static final int MAX_APPS_TO_QUERY = 900; - public static final class Helper { private Helper() { } @@ -165,7 +163,7 @@ public class AppProvider extends FDroidProvider { static final class UpgradeHelper { public static void updateIconUrls(Context context, SQLiteDatabase db) { - AppProvider.updateIconUrls(context, db); + AppProvider.updateIconUrls(context, db, DBHelper.TABLE_APP, DBHelper.TABLE_APK); } } @@ -295,8 +293,8 @@ public class AppProvider extends FDroidProvider { @Override protected String getRequiredTables() { - final String app = DBHelper.TABLE_APP; - final String apk = DBHelper.TABLE_APK; + final String app = getTableName(); + final String apk = getApkTableName(); final String repo = DBHelper.TABLE_REPO; return app + @@ -312,7 +310,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 : DBHelper.TABLE_APP + ".id"; + return countFieldAppended ? null : getTableName() + ".id"; } public void addSelection(AppQuerySelection selection) { @@ -329,7 +327,7 @@ public class AppProvider extends FDroidProvider { join( DBHelper.TABLE_INSTALLED_APP, "installed", - "installed." + InstalledAppProvider.DataColumns.APP_ID + " = " + DBHelper.TABLE_APP + ".id"); + "installed." + InstalledAppProvider.DataColumns.APP_ID + " = " + getTableName() + ".id"); requiresInstalledTable = true; } } @@ -339,7 +337,7 @@ public class AppProvider extends FDroidProvider { leftJoin( DBHelper.TABLE_INSTALLED_APP, "installed", - "installed." + InstalledAppProvider.DataColumns.APP_ID + " = " + DBHelper.TABLE_APP + ".id"); + "installed." + InstalledAppProvider.DataColumns.APP_ID + " = " + getTableName() + ".id"); requiresInstalledTable = true; } } @@ -378,15 +376,15 @@ public class AppProvider extends FDroidProvider { private void addSuggestedApkVersionField() { addSuggestedApkField( - ApkProvider.DataColumns.VERSION, - DataColumns.SuggestedApk.VERSION); + ApkProvider.DataColumns.VERSION, + DataColumns.SuggestedApk.VERSION); } private void addSuggestedApkField(String fieldName, String alias) { if (!isSuggestedApkTableAdded) { isSuggestedApkTableAdded = true; leftJoin( - DBHelper.TABLE_APK, + getApkTableName(), "suggestedApk", getTableName() + ".suggestedVercode = suggestedApk.vercode AND " + getTableName() + ".id = suggestedApk.id"); } @@ -395,8 +393,8 @@ public class AppProvider extends FDroidProvider { private void addInstalledAppVersionName() { addInstalledAppField( - InstalledAppProvider.DataColumns.VERSION_NAME, - DataColumns.InstalledApp.VERSION_NAME + InstalledAppProvider.DataColumns.VERSION_NAME, + DataColumns.InstalledApp.VERSION_NAME ); } @@ -555,6 +553,10 @@ public class AppProvider extends FDroidProvider { return DBHelper.TABLE_APP; } + protected String getApkTableName() { + return DBHelper.TABLE_APK; + } + @Override protected String getProviderName() { return "AppProvider"; @@ -578,7 +580,7 @@ public class AppProvider extends FDroidProvider { } private AppQuerySelection queryRepo(long repoId) { - final String selection = DBHelper.TABLE_APK + ".repo = ? "; + final String selection = getApkTableName() + ".repo = ? "; final String[] args = {String.valueOf(repoId)}; return new AppQuerySelection(selection, args); } @@ -660,7 +662,8 @@ public class AppProvider extends FDroidProvider { } private AppQuerySelection queryRecentlyUpdated() { - final String selection = getTableName() + ".added != fdroid_app.lastUpdated AND fdroid_app.lastUpdated > ?"; + final String app = getTableName(); + final String selection = app + ".added != " + app + ".lastUpdated AND " + app + ".lastUpdated > ?"; final String[] args = {Utils.formatDate(Preferences.get().calcMaxHistory(), "")}; return new AppQuerySelection(selection, args); } @@ -683,7 +686,7 @@ public class AppProvider extends FDroidProvider { } private AppQuerySelection queryNoApks() { - String selection = "(SELECT COUNT(*) FROM " + DBHelper.TABLE_APK + " WHERE " + DBHelper.TABLE_APK + ".id = " + getTableName() + ".id) = 0"; + String selection = "(SELECT COUNT(*) FROM " + getApkTableName() + " WHERE " + getApkTableName() + ".id = " + getTableName() + ".id) = 0"; return new AppQuerySelection(selection); } @@ -843,11 +846,11 @@ public class AppProvider extends FDroidProvider { return count; } - private void updateAppDetails() { + protected void updateAppDetails() { updateCompatibleFlags(); updateSuggestedFromUpstream(); updateSuggestedFromLatest(); - updateIconUrls(getContext(), write()); + updateIconUrls(getContext(), write(), getTableName(), getApkTableName()); } /** @@ -865,8 +868,8 @@ public class AppProvider extends FDroidProvider { Utils.debugLog(TAG, "Calculating whether apps are compatible, based on whether any of their apks are compatible"); - final String apk = DBHelper.TABLE_APK; - final String app = DBHelper.TABLE_APP; + final String apk = getApkTableName(); + final String app = getTableName(); String updateSql = "UPDATE " + app + " SET compatible = ( " + @@ -900,8 +903,8 @@ public class AppProvider extends FDroidProvider { Utils.debugLog(TAG, "Calculating suggested versions for all apps which specify an upstream version code."); - final String apk = DBHelper.TABLE_APK; - final String app = DBHelper.TABLE_APP; + final String apk = getApkTableName(); + final String app = getTableName(); final boolean unstableUpdates = Preferences.get().getUnstableUpdates(); String restrictToStable = unstableUpdates ? "" : (apk + ".vercode <= " + app + ".upstreamVercode AND "); @@ -941,8 +944,8 @@ public class AppProvider extends FDroidProvider { Utils.debugLog(TAG, "Calculating suggested versions for all apps which don't specify an upstream version code."); - final String apk = DBHelper.TABLE_APK; - final String app = DBHelper.TABLE_APP; + final String apk = getApkTableName(); + final String app = getTableName(); String updateSql = "UPDATE " + app + " SET suggestedVercode = ( " + @@ -961,7 +964,7 @@ public class AppProvider extends FDroidProvider { * it without instantiating an {@link AppProvider}. This is also the reason it needs to accept * the context and database as arguments. */ - private static void updateIconUrls(Context context, SQLiteDatabase db) { + private static void updateIconUrls(Context context, SQLiteDatabase db, String appTable, String apkTable) { 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); @@ -969,7 +972,7 @@ public class AppProvider extends FDroidProvider { + repoVersion); Utils.debugLog(TAG, "Using icons dir '" + iconsDir + "'"); Utils.debugLog(TAG, "Using large icons dir '" + iconsDirLarge + "'"); - String query = getIconUpdateQuery(); + String query = getIconUpdateQuery(appTable, apkTable); final String[] params = { repoVersion, iconsDir, Utils.FALLBACK_ICONS_DIR, repoVersion, iconsDirLarge, Utils.FALLBACK_ICONS_DIR, @@ -982,10 +985,8 @@ public class AppProvider extends FDroidProvider { * 1) The repo version that introduced density specific icons * 2) The dir to density specific icons for the current device. */ - private static String getIconUpdateQuery() { + private static String getIconUpdateQuery(String app, String apk) { - final String apk = DBHelper.TABLE_APK; - final String app = DBHelper.TABLE_APP; final String repo = DBHelper.TABLE_REPO; final String iconUrlQuery = @@ -1022,9 +1023,9 @@ public class AppProvider extends FDroidProvider { // then join onto that instead. This will save from doing // a futher sub query for each app. " SELECT MAX(inner_apk.vercode) " + - " FROM fdroid_apk as inner_apk " + - " WHERE inner_apk.id = fdroid_apk.id ) " + - " AND fdroid_apk.repo = fdroid_repo._id "; + " FROM " + apk + " as inner_apk " + + " WHERE inner_apk.id = " + apk + ".id ) " + + " AND " + apk + ".repo = fdroid_repo._id "; return " UPDATE " + app + " SET " + diff --git a/F-Droid/src/org/fdroid/fdroid/data/RepoPersister.java b/F-Droid/src/org/fdroid/fdroid/data/RepoPersister.java index f1166b20a..858746e07 100644 --- a/F-Droid/src/org/fdroid/fdroid/data/RepoPersister.java +++ b/F-Droid/src/org/fdroid/fdroid/data/RepoPersister.java @@ -51,6 +51,8 @@ public class RepoPersister { @NonNull private final Repo repo; + private boolean hasBeenInitialized; + @NonNull private final Context context; @@ -82,6 +84,17 @@ public class RepoPersister { } private void flushBufferToDb() throws RepoUpdater.UpdateException { + if (!hasBeenInitialized) { + // This is where we will store all of the metadata before commiting at the + // end of the process. This is due to the fact that we can't verify the cert + // the index was signed with until we've finished reading it - and we don't + // want to put stuff in the real database until we are sure it is from a + // trusted source. + TempAppProvider.Helper.init(context); + TempApkProvider.Helper.init(context); + hasBeenInitialized = true; + } + if (apksToSave.size() > 0 || appsToSave.size() > 0) { Log.d(TAG, "Flushing details of up to " + MAX_APP_BUFFER + " apps and their packages to the database."); flushAppsToDbInBatch(); diff --git a/F-Droid/src/org/fdroid/fdroid/data/TempApkProvider.java b/F-Droid/src/org/fdroid/fdroid/data/TempApkProvider.java index 0079487b7..66148704f 100644 --- a/F-Droid/src/org/fdroid/fdroid/data/TempApkProvider.java +++ b/F-Droid/src/org/fdroid/fdroid/data/TempApkProvider.java @@ -17,6 +17,8 @@ public class TempApkProvider extends ApkProvider { private static final String PROVIDER_NAME = "TempApkProvider"; + static final String TABLE_TEMP_APK = "temp_fdroid_apk"; + private static final String PATH_INIT = "init"; private static final String PATH_COMMIT = "commit"; @@ -135,7 +137,7 @@ public class TempApkProvider extends ApkProvider { private void initTable() { write().execSQL("DROP TABLE IF EXISTS " + getTableName()); - write().execSQL("CREATE TEMPORARY TABLE " + getTableName() + " AS SELECT * FROM " + DBHelper.TABLE_APK); + write().execSQL("CREATE TABLE " + getTableName() + " AS SELECT * FROM " + DBHelper.TABLE_APK); } private void commitTable() { diff --git a/F-Droid/src/org/fdroid/fdroid/data/TempAppProvider.java b/F-Droid/src/org/fdroid/fdroid/data/TempAppProvider.java index 2e6737ac9..a307a08f5 100644 --- a/F-Droid/src/org/fdroid/fdroid/data/TempAppProvider.java +++ b/F-Droid/src/org/fdroid/fdroid/data/TempAppProvider.java @@ -15,6 +15,8 @@ public class TempAppProvider extends AppProvider { private static final String PROVIDER_NAME = "TempAppProvider"; + private static final String TABLE_TEMP_APP = "temp_fdroid_app"; + private static final String PATH_INIT = "init"; private static final String PATH_COMMIT = "commit"; @@ -31,7 +33,7 @@ public class TempAppProvider extends AppProvider { @Override protected String getTableName() { - return "temp_" + super.getTableName(); + return TABLE_TEMP_APP; } public static String getAuthority() { @@ -68,6 +70,11 @@ public class TempAppProvider extends AppProvider { } + @Override + protected String getApkTableName() { + return TempApkProvider.TABLE_TEMP_APK; + } + @Override public Uri insert(Uri uri, ContentValues values) { int code = matcher.match(uri); @@ -76,6 +83,7 @@ public class TempAppProvider extends AppProvider { initTable(); return null; } else if (code == CODE_COMMIT) { + updateAppDetails(); commitTable(); return null; } else { @@ -104,7 +112,7 @@ public class TempAppProvider extends AppProvider { private void initTable() { write().execSQL("DROP TABLE IF EXISTS " + getTableName()); - write().execSQL("CREATE TEMPORARY TABLE " + getTableName() + " AS SELECT * FROM " + DBHelper.TABLE_APP); + write().execSQL("CREATE TABLE " + getTableName() + " AS SELECT * FROM " + DBHelper.TABLE_APP); } private void commitTable() {