fix: Only insert repo and app if not duplicate

This commit is contained in:
LooKeR 2025-05-24 22:17:50 +05:30
parent 4d80956806
commit d1d65a3aeb
No known key found for this signature in database
GPG Key ID: 6B59369FDB608FB9
2 changed files with 52 additions and 16 deletions

View File

@ -22,7 +22,6 @@ import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule

View File

@ -5,8 +5,9 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.Transaction import androidx.room.Transaction
import com.looker.droidify.data.local.model.AntiFeatureEntity import androidx.room.Update
import com.looker.droidify.data.local.model.AntiFeatureAppRelation import com.looker.droidify.data.local.model.AntiFeatureAppRelation
import com.looker.droidify.data.local.model.AntiFeatureEntity
import com.looker.droidify.data.local.model.AntiFeatureRepoRelation import com.looker.droidify.data.local.model.AntiFeatureRepoRelation
import com.looker.droidify.data.local.model.AppEntity import com.looker.droidify.data.local.model.AppEntity
import com.looker.droidify.data.local.model.AuthorEntity import com.looker.droidify.data.local.model.AuthorEntity
@ -43,12 +44,12 @@ interface IndexDao {
index: IndexV2, index: IndexV2,
expectedRepoId: Int = 0, expectedRepoId: Int = 0,
) { ) {
val repoId = insertRepo( val repoId = upsertRepo(
index.repo.repoEntity( index.repo.repoEntity(
id = expectedRepoId, id = expectedRepoId,
fingerprint = fingerprint, fingerprint = fingerprint,
), ),
).toInt() )
val antiFeatures = index.repo.antiFeatures.flatMap { (tag, feature) -> val antiFeatures = index.repo.antiFeatures.flatMap { (tag, feature) ->
feature.antiFeatureEntity(tag) feature.antiFeatureEntity(tag)
} }
@ -66,18 +67,14 @@ interface IndexDao {
index.packages.forEach { (packageName, packages) -> index.packages.forEach { (packageName, packages) ->
val metadata = packages.metadata val metadata = packages.metadata
val author = metadata.authorEntity() val author = metadata.authorEntity()
val authorId = insertAuthor(author).toInt().takeIf { it > 0 } ?: authorId( val authorId = upsertAuthor(author)
email = author.email, val appId = appIdByPackageName(repoId, packageName) ?: insertApp(
name = author.name,
website = author.website,
)
val appId = insertApp(
appEntity = metadata.appEntity( appEntity = metadata.appEntity(
packageName = packageName, packageName = packageName,
repoId = repoId, repoId = repoId,
authorId = authorId, authorId = authorId,
), ),
).toInt().takeIf { it > 0 } ?: appIdByPackageName(packageName) ).toInt()
val versions = packages.versionEntities(appId) val versions = packages.versionEntities(appId)
insertVersions(versions.keys.toList()) insertVersions(versions.keys.toList())
insertAntiFeatureAppRelation(versions.values.flatten()) insertAntiFeatureAppRelation(versions.values.flatten())
@ -90,9 +87,22 @@ interface IndexDao {
} }
} }
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertRepo(repoEntity: RepoEntity): Long suspend fun insertRepo(repoEntity: RepoEntity): Long
@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateRepo(repoEntity: RepoEntity): Int
@Transaction
suspend fun upsertRepo(repoEntity: RepoEntity): Int {
val id = insertRepo(repoEntity)
return if (id == -1L) {
updateRepo(repoEntity)
} else {
id.toInt()
}
}
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMirror(mirrors: List<MirrorEntity>) suspend fun insertMirror(mirrors: List<MirrorEntity>)
@ -111,14 +121,41 @@ interface IndexDao {
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertApp(appEntity: AppEntity): Long suspend fun insertApp(appEntity: AppEntity): Long
@Query("SELECT id FROM app WHERE packageName = :packageName") @Query("SELECT id FROM app WHERE packageName = :packageName AND repoId = :repoId LIMIT 1")
suspend fun appIdByPackageName(packageName: String): Int suspend fun appIdByPackageName(repoId: Int, packageName: String): Int?
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertAuthor(authorEntity: AuthorEntity): Long suspend fun insertAuthor(authorEntity: AuthorEntity): Long
@Query("SELECT id FROM author WHERE email = :email AND name = :name AND website = :website") @Query(
suspend fun authorId(email: String?, name: String?, website: String?): Int """
SELECT id FROM author
WHERE
(:email IS NULL AND email IS NULL OR email = :email) AND
(:name IS NULL AND name IS NULL OR name = :name COLLATE NOCASE) AND
(:website IS NULL AND website IS NULL OR website = :website COLLATE NOCASE)
LIMIT 1
""",
)
suspend fun authorId(
email: String?,
name: String?,
website: String?,
): Int?
@Transaction
suspend fun upsertAuthor(authorEntity: AuthorEntity): Int {
val id = insertAuthor(authorEntity)
return if (id == -1L) {
authorId(
email = authorEntity.email,
name = authorEntity.name,
website = authorEntity.website,
)!!.toInt()
} else {
id.toInt()
}
}
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertScreenshots(screenshotEntity: List<ScreenshotEntity>) suspend fun insertScreenshots(screenshotEntity: List<ScreenshotEntity>)