diff --git a/app/src/main/java/org/fdroid/fdroid/data/ContentProviderMigrator.java b/app/src/main/java/org/fdroid/fdroid/data/ContentProviderMigrator.java index fd8ff02d0..08a41ffb4 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/ContentProviderMigrator.java +++ b/app/src/main/java/org/fdroid/fdroid/data/ContentProviderMigrator.java @@ -9,6 +9,8 @@ import android.util.Log; import androidx.core.util.ObjectsCompat; +import org.fdroid.database.AppPrefs; +import org.fdroid.database.AppPrefsDao; import org.fdroid.database.FDroidDatabase; import org.fdroid.database.InitialRepository; import org.fdroid.database.Repository; @@ -29,67 +31,90 @@ final class ContentProviderMigrator { return false; } - void migrateOldRepos(Context context, FDroidDatabase db) { + void runMigrations(Context context, FDroidDatabase db) { + try (ContentProviderDbHelper helper = new ContentProviderDbHelper(context)) { + SQLiteDatabase oldDb = helper.getReadableDatabase(); + migrateOldRepos(db, oldDb); + migrateIgnoredUpdates(db, oldDb); + } + } + + private void migrateOldRepos(FDroidDatabase db, SQLiteDatabase oldDb) { RepositoryDao repoDao = db.getRepositoryDao(); List repos = repoDao.getRepositories(); int weight = repos.isEmpty() ? 0 : repos.get(repos.size() - 1).getWeight(); - try (ContentProviderDbHelper helper = new ContentProviderDbHelper(context)) { - String[] projection = new String[]{"name", "address", "pubkey", "inuse", "userMirrors", "disabledMirrors", - "username", "password"}; - SQLiteDatabase oldDb = helper.getReadableDatabase(); - try (Cursor c = oldDb.query("fdroid_repo", projection, null, null, null, null, null)) { - while (c.moveToNext()) { - String name = c.getString(c.getColumnIndexOrThrow("name")); - String address = c.getString(c.getColumnIndexOrThrow("address")); - String certificateDb = c.getString(c.getColumnIndexOrThrow("pubkey")); - if (certificateDb == null) continue; - String certificate = certificateDb.toLowerCase(Locale.ROOT); - boolean enabled = c.getInt(c.getColumnIndexOrThrow("inuse")) == 1; - String userMirrorsDb = c.getString(c.getColumnIndexOrThrow("userMirrors")); - List userMirrors = userMirrorsDb == null ? null : Arrays.asList(userMirrorsDb.split(",")); - String disabledMirrorsDb = c.getString(c.getColumnIndexOrThrow("disabledMirrors")); - List disabledMirrors = disabledMirrorsDb == null ? - null : Arrays.asList(disabledMirrorsDb.split(",")); - String username = c.getString(c.getColumnIndexOrThrow("username")); - String password = c.getString(c.getColumnIndexOrThrow("password")); - // find existing repos by address, because F-Droid archive re-uses certificate - Repository repo = null; - for (Repository r : repos) { - if (r.getAddress().equals(address)) { - repo = r; - break; - } - } - // add new repo if not existing - if (repo == null) { // new repo to be added to new DB - InitialRepository newRepo = new InitialRepository(name, address, "", certificate, - 0, enabled, ++weight); - long repoId = repoDao.insert(newRepo); - repo = ObjectsCompat.requireNonNull(repoDao.getRepository(repoId)); - } else { // old repo that may need an update for the new DB - if (!certificate.equals(repo.getCertificate())) { - continue; // don't update if certificate does not match - } - } - // update settings of new or existing repo - if (repo.getEnabled() != enabled) { - repoDao.setRepositoryEnabled(repo.getRepoId(), enabled); - } - if (userMirrors != null && !userMirrors.isEmpty()) { - repoDao.updateUserMirrors(repo.getRepoId(), userMirrors); - } - if (disabledMirrors != null && !disabledMirrors.isEmpty()) { - repoDao.updateDisabledMirrors(repo.getRepoId(), disabledMirrors); - } - if (username != null || password != null) { - repoDao.updateUsernameAndPassword(repo.getRepoId(), username, password); + String[] projection = new String[]{"name", "address", "pubkey", "inuse", "userMirrors", "disabledMirrors", + "username", "password"}; + try (Cursor c = oldDb.query("fdroid_repo", projection, null, null, null, null, null)) { + while (c.moveToNext()) { + String name = c.getString(c.getColumnIndexOrThrow("name")); + String address = c.getString(c.getColumnIndexOrThrow("address")); + String certificateDb = c.getString(c.getColumnIndexOrThrow("pubkey")); + if (certificateDb == null) continue; + String certificate = certificateDb.toLowerCase(Locale.ROOT); + boolean enabled = c.getInt(c.getColumnIndexOrThrow("inuse")) == 1; + String userMirrorsDb = c.getString(c.getColumnIndexOrThrow("userMirrors")); + List userMirrors = userMirrorsDb == null ? null : Arrays.asList(userMirrorsDb.split(",")); + String disabledMirrorsDb = c.getString(c.getColumnIndexOrThrow("disabledMirrors")); + List disabledMirrors = disabledMirrorsDb == null ? + null : Arrays.asList(disabledMirrorsDb.split(",")); + String username = c.getString(c.getColumnIndexOrThrow("username")); + String password = c.getString(c.getColumnIndexOrThrow("password")); + // find existing repos by address, because F-Droid archive re-uses certificate + Repository repo = null; + for (Repository r : repos) { + if (r.getAddress().equals(address)) { + repo = r; + break; } } - } catch (SQLiteException e) { - if (e.getMessage() != null && e.getMessage().contains("disabledMirrors")) { - Log.e("DbHelper", "disabledMirrors column missing. Can't migrate. ", e); - } else throw e; + // add new repo if not existing + if (repo == null) { // new repo to be added to new DB + InitialRepository newRepo = new InitialRepository(name, address, "", certificate, + 0, enabled, ++weight); + long repoId = repoDao.insert(newRepo); + repo = ObjectsCompat.requireNonNull(repoDao.getRepository(repoId)); + } else { // old repo that may need an update for the new DB + if (!certificate.equals(repo.getCertificate())) { + continue; // don't update if certificate does not match + } + } + // update settings of new or existing repo + if (repo.getEnabled() != enabled) { + repoDao.setRepositoryEnabled(repo.getRepoId(), enabled); + } + if (userMirrors != null && !userMirrors.isEmpty()) { + repoDao.updateUserMirrors(repo.getRepoId(), userMirrors); + } + if (disabledMirrors != null && !disabledMirrors.isEmpty()) { + repoDao.updateDisabledMirrors(repo.getRepoId(), disabledMirrors); + } + if (username != null || password != null) { + repoDao.updateUsernameAndPassword(repo.getRepoId(), username, password); + } + } + } catch (SQLiteException e) { + if (e.getMessage() != null && e.getMessage().contains("disabledMirrors")) { + Log.e("DbHelper", "disabledMirrors column missing. Can't migrate. ", e); + } else throw e; + } + } + + private void migrateIgnoredUpdates(FDroidDatabase db, SQLiteDatabase oldDb) { + AppPrefsDao appPrefsDao = db.getAppPrefsDao(); + + String[] projection = new String[]{"packageName", "ignoreThisUpdate", "ignoreAllUpdates"}; + try (Cursor c = oldDb.query("fdroid_appPrefs", projection, null, null, null, null, null)) { + while (c.moveToNext()) { + String packageName = c.getString(c.getColumnIndexOrThrow("packageName")); + long ignoreVersionCode = c.getLong(c.getColumnIndexOrThrow("ignoreThisUpdate")); + boolean ignoreAllUpdates = c.getInt(c.getColumnIndexOrThrow("ignoreAllUpdates")) == 1; + + // ignored version code is max code to ignore all updates, or a specific one to ignore + long v = ignoreAllUpdates ? Long.MAX_VALUE : ignoreVersionCode; + // this is a new DB, so we can just start to insert new AppPrefs + appPrefsDao.update(new AppPrefs(packageName, v, null)); } } } 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 501785ed4..d8fa3ed3d 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/data/DBHelper.java @@ -89,7 +89,7 @@ public class DBHelper { ContentProviderMigrator migrator = new ContentProviderMigrator(); if (migrator.needsMigration(context)) { Log.d(TAG, "Migrating DB..."); - migrator.migrateOldRepos(context, db); + migrator.runMigrations(context, db); migrator.removeOldDb(context); // force update on UiThread in case we need to show Toasts new Handler(Looper.getMainLooper()).post(() -> UpdateService.forceUpdateRepo(context));