[db] handle broken repos without certificate

On versions before 1.18.0, adding a repo would add it as "empty" to the DB without a certificate right away and if there was an issue with it (e.g. typo in URL), it would stay in the DB until manually removed.
Our migration code did not consider such repos.
This commit is contained in:
Torsten Grote 2024-04-05 15:28:28 -03:00 committed by Hans-Christoph Steiner
parent cc9ccb5e7f
commit ef4e72e6d4
2 changed files with 40 additions and 2 deletions

View File

@ -248,6 +248,44 @@ internal class MultiRepoMigrationTest {
}
}
@Test
fun repoWithoutCertificate() {
helper.createDatabase(TEST_DB, 1).use { db ->
// Database has schema version 1. Insert some data using SQL queries.
// We can't use DAO classes because they expect the latest schema.
val repoId = db.insert(CoreRepository.TABLE, CONFLICT_FAIL, ContentValues().apply {
put("name", localizedTextV2toString(mapOf("en-US" to fdroidRepo.name)))
put(
"description",
localizedTextV2toString(mapOf("en-US" to fdroidRepo.description))
)
put("address", fdroidRepo.address)
put("timestamp", -1)
})
db.insert(RepositoryPreferences.TABLE, CONFLICT_FAIL, ContentValues().apply {
put("repoId", repoId)
put("enabled", fdroidRepo.enabled)
put("weight", fdroidRepo.weight)
})
}
// Re-open the database with version 2, auto-migrations are applied automatically
helper.runMigrationsAndValidate(TEST_DB, 2, true).close()
// now get the Room DB, so we can use our DAOs for verifying the migration
databaseBuilder(getApplicationContext(), FDroidDatabaseInt::class.java, TEST_DB)
.allowMainThreadQueries()
.build().use { db ->
// repo without cert did not get migrated
assertEquals(1, db.getRepositoryDao().getRepositories().size)
val repo = db.getRepositoryDao().getRepositories()[0]
// cert is still null
assertNull(repo.certificate)
// address still the same
assertEquals(fdroidRepo.address, repo.address)
}
}
private fun runRepoMigration(
repos: List<InitialRepository>,
check: (FDroidDatabaseInt) -> Unit,

View File

@ -38,7 +38,7 @@ internal class MultiRepoMigration : AutoMigrationSpec {
while (cursor.moveToNext()) {
val repo = getRepo(cursor)
log.error { repo.toString() }
if (repo.isArchive()) {
if (repo.isArchive() && repo.certificate != null) {
if (archiveMap.containsKey(repo.certificate)) {
log.error { "More than two repos with certificate of ${repo.address}" }
// still migrating this as a normal repo then
@ -98,7 +98,7 @@ internal class MultiRepoMigration : AutoMigrationSpec {
private data class Repo(
val repoId: Long,
val address: String,
val certificate: String,
val certificate: String?,
val weight: Int,
) {
fun isArchive(): Boolean = address.trimEnd('/').endsWith("/archive")