From b1f1d031f735a4e5d210cd026b02d7cdb1cd6649 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 16 Mar 2022 15:51:58 -0300 Subject: [PATCH] [db] Add simple IndexV1Updater (not in final form) just to be able to get a real DB into the app for further testing --- database/build.gradle | 1 + .../org/fdroid/database/IndexV1InsertTest.kt | 7 +-- .../org/fdroid/database/RepositoryTest.kt | 4 +- .../src/main/java/org/fdroid/database/App.kt | 2 +- .../java/org/fdroid/database/RepositoryDao.kt | 22 +++++++-- .../org/fdroid/index/v1/IndexV1Updater.kt | 49 +++++++++++++++++++ 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 database/src/main/java/org/fdroid/index/v1/IndexV1Updater.kt diff --git a/database/build.gradle b/database/build.gradle index 354e68e58..e4f7cb887 100644 --- a/database/build.gradle +++ b/database/build.gradle @@ -41,6 +41,7 @@ android { } dependencies { + implementation project(":download") implementation project(":index") def room_version = "2.4.2" diff --git a/database/src/androidTest/java/org/fdroid/database/IndexV1InsertTest.kt b/database/src/androidTest/java/org/fdroid/database/IndexV1InsertTest.kt index 4907ec479..c9a154f82 100644 --- a/database/src/androidTest/java/org/fdroid/database/IndexV1InsertTest.kt +++ b/database/src/androidTest/java/org/fdroid/database/IndexV1InsertTest.kt @@ -6,14 +6,15 @@ import androidx.test.core.app.ApplicationProvider.getApplicationContext import androidx.test.ext.junit.runners.AndroidJUnit4 import kotlinx.serialization.SerializationException import org.apache.commons.io.input.CountingInputStream -import org.fdroid.index.v2.IndexStreamProcessor import org.fdroid.index.IndexV1StreamProcessor +import org.fdroid.index.v2.IndexStreamProcessor import org.junit.Test import org.junit.runner.RunWith import kotlin.math.roundToInt import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertTrue +import kotlin.test.fail @RunWith(AndroidJUnit4::class) class IndexV1InsertTest : DbTest() { @@ -58,8 +59,8 @@ class IndexV1InsertTest : DbTest() { insertV2ForComparison(2) - val repo1 = repoDao.getRepository(1) - val repo2 = repoDao.getRepository(2) + val repo1 = repoDao.getRepository(1) ?: fail() + val repo2 = repoDao.getRepository(2) ?: fail() assertEquals(repo1.repository, repo2.repository.copy(repoId = 1)) assertEquals(repo1.mirrors, repo2.mirrors.map { it.copy(repoId = 1) }) assertEquals(repo1.antiFeatures, repo2.antiFeatures) diff --git a/database/src/androidTest/java/org/fdroid/database/RepositoryTest.kt b/database/src/androidTest/java/org/fdroid/database/RepositoryTest.kt index c79d037c5..72c038611 100644 --- a/database/src/androidTest/java/org/fdroid/database/RepositoryTest.kt +++ b/database/src/androidTest/java/org/fdroid/database/RepositoryTest.kt @@ -36,11 +36,11 @@ class RepositoryTest : DbTest() { assertRepoEquals(repo2, repos[1]) // remove first repo and check that the database only returns one - repoDao.removeRepository(repos[0].repository) + repoDao.deleteRepository(repos[0].repository) assertEquals(1, repoDao.getRepositories().size) // remove second repo as well and check that all associated data got removed as well - repoDao.removeRepository(repos[1].repository) + repoDao.deleteRepository(repos[1].repository) assertEquals(0, repoDao.getRepositories().size) assertEquals(0, repoDao.getMirrors().size) assertEquals(0, repoDao.getAntiFeatures().size) diff --git a/database/src/main/java/org/fdroid/database/App.kt b/database/src/main/java/org/fdroid/database/App.kt index 5021de5f3..0897ec93f 100644 --- a/database/src/main/java/org/fdroid/database/App.kt +++ b/database/src/main/java/org/fdroid/database/App.kt @@ -35,7 +35,7 @@ data class AppMetadata( val sourceCode: String? = null, val issueTracker: String? = null, val translation: String? = null, - val preferredSigner: String? = null, + val preferredSigner: String? = null, // TODO use platformSig if an APK matches it val video: LocalizedTextV2? = null, @Embedded(prefix = "author_") val author: Author? = Author(), @Embedded(prefix = "donation_") val donation: Donation? = Donation(), diff --git a/database/src/main/java/org/fdroid/database/RepositoryDao.kt b/database/src/main/java/org/fdroid/database/RepositoryDao.kt index 373636880..e22cf9ff6 100644 --- a/database/src/main/java/org/fdroid/database/RepositoryDao.kt +++ b/database/src/main/java/org/fdroid/database/RepositoryDao.kt @@ -13,9 +13,9 @@ import kotlinx.serialization.json.JsonNull import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.jsonObject -import org.fdroid.index.v2.ReflectionDiffer.applyDiff import org.fdroid.index.IndexParser.json import org.fdroid.index.v2.MirrorV2 +import org.fdroid.index.v2.ReflectionDiffer.applyDiff import org.fdroid.index.v2.RepoV2 public interface RepositoryDao { @@ -49,6 +49,17 @@ internal interface RepositoryDaoInt : RepositoryDao { @Insert(onConflict = REPLACE) fun insertReleaseChannels(repoFeature: List) + @Transaction + fun insertEmptyRepo(address: String): Long { + val repo = CoreRepository( + name = "", + icon = null, + address = address, + timestamp = System.currentTimeMillis(), + ) + return insert(repo) + } + @Transaction override fun insert(repository: RepoV2): Long { val repoId = insert(repository.toCoreRepository()) @@ -72,12 +83,12 @@ internal interface RepositoryDaoInt : RepositoryDao { @Transaction @Query("SELECT * FROM CoreRepository WHERE repoId = :repoId") - fun getRepository(repoId: Long): Repository + fun getRepository(repoId: Long): Repository? @Transaction fun updateRepository(repoId: Long, jsonObject: JsonObject) { // get existing repo - val repo = getRepository(repoId) + val repo = getRepository(repoId) ?: error("Repo $repoId does not exist") // update repo with JSON diff updateRepository(applyDiff(repo.repository, jsonObject)) // replace mirror list, if it is in the diff @@ -217,6 +228,9 @@ internal interface RepositoryDaoInt : RepositoryDao { fun deleteReleaseChannel(repoId: Long, name: String) @Delete - fun removeRepository(repository: CoreRepository) + fun deleteRepository(repository: CoreRepository) + + @Query("DELETE FROM CoreRepository WHERE repoId = :repoId") + fun deleteRepository(repoId: Long) } diff --git a/database/src/main/java/org/fdroid/index/v1/IndexV1Updater.kt b/database/src/main/java/org/fdroid/index/v1/IndexV1Updater.kt new file mode 100644 index 000000000..036ed7209 --- /dev/null +++ b/database/src/main/java/org/fdroid/index/v1/IndexV1Updater.kt @@ -0,0 +1,49 @@ +package org.fdroid.index.v1 + +import android.content.Context +import org.fdroid.database.DbV1StreamReceiver +import org.fdroid.database.FDroidDatabase +import org.fdroid.download.Downloader +import org.fdroid.index.IndexV1StreamProcessor +import java.io.File +import java.io.IOException + +// TODO should this live here and cause a dependency on download lib or in dedicated module? +public class IndexV1Updater( + context: Context, + private val file: File, + private val downloader: Downloader, + ) { + + private val db: FDroidDatabase = FDroidDatabase.getDb(context, "test") // TODO final name + + @Throws(IOException::class, InterruptedException::class) + fun update(address: String, expectedSigningFingerprint: String?) { + val repoId = db.getRepositoryDaoInt().insertEmptyRepo(address) + try { + update(repoId, null, expectedSigningFingerprint) + } catch (e: Throwable) { + db.getRepositoryDaoInt().deleteRepository(repoId) + throw e + } + db.getRepositoryDaoInt().getRepositories().forEach { println(it) } + } + + @Throws(IOException::class, InterruptedException::class) + fun update(repoId: Long, certificate: String) { + update(repoId, certificate, null) + } + + @Throws(IOException::class, InterruptedException::class) + private fun update(repoId: Long, certificate: String?, fingerprint: String?) { + downloader.download() + val verifier = IndexV1Verifier(file, certificate, fingerprint) + db.runInTransaction { + verifier.getStreamAndVerify { inputStream -> + val streamProcessor = IndexV1StreamProcessor(DbV1StreamReceiver(db)) + streamProcessor.process(repoId, inputStream) + } + } + } + +}