diff --git a/libs/database/src/main/java/org/fdroid/database/App.kt b/libs/database/src/main/java/org/fdroid/database/App.kt index 127d50eec..ae6a1cbf1 100644 --- a/libs/database/src/main/java/org/fdroid/database/App.kt +++ b/libs/database/src/main/java/org/fdroid/database/App.kt @@ -34,6 +34,7 @@ public interface MinimalApp { * This largely represents [MetadataV2] in a database table. */ @Entity( + tableName = AppMetadata.TABLE, primaryKeys = ["repoId", "packageName"], foreignKeys = [ForeignKey( entity = CoreRepository::class, @@ -79,7 +80,11 @@ public data class AppMetadata( * that adds the [AppMetadata]. */ public val isCompatible: Boolean, -) +) { + internal companion object { + const val TABLE = "AppMetadata" + } +} internal fun MetadataV2.toAppMetadata( repoId: Long, @@ -119,7 +124,7 @@ internal fun MetadataV2.toAppMetadata( isCompatible = isCompatible, ) -@Entity +@Entity(tableName = AppMetadataFts.TABLE) @Fts4(contentEntity = AppMetadata::class) internal data class AppMetadataFts( val repoId: Long, @@ -128,7 +133,11 @@ internal data class AppMetadataFts( val name: String? = null, @ColumnInfo(name = "localizedSummary") val summary: String? = null, -) +) { + internal companion object { + const val TABLE = "AppMetadataFts" + } +} /** * A class to represent all data of an App. @@ -340,6 +349,7 @@ internal interface IFile { } @Entity( + tableName = LocalizedFile.TABLE, primaryKeys = ["repoId", "packageName", "type", "locale"], foreignKeys = [ForeignKey( entity = AppMetadata::class, @@ -356,7 +366,11 @@ internal data class LocalizedFile( override val name: String, override val sha256: String? = null, override val size: Long? = null, -) : IFile +) : IFile { + internal companion object { + const val TABLE = "LocalizedFile" + } +} internal fun LocalizedFileV2.toLocalizedFile( repoId: Long, @@ -385,7 +399,8 @@ internal fun List.toLocalizedFileV2(): LocalizedFileV2? = associate { fil // We can't restrict this query further (e.g. only from enabled repos or max weight), // because we are using this via @Relation on packageName for specific repos. // When filtering the result for only the repoId we are interested in, we'd get no icons. -@DatabaseView("SELECT * FROM LocalizedFile WHERE type='icon'") +@DatabaseView(viewName = LocalizedIcon.TABLE, + value = "SELECT * FROM ${LocalizedFile.TABLE} WHERE type='icon'") internal data class LocalizedIcon( val repoId: Long, val packageName: String, @@ -394,9 +409,14 @@ internal data class LocalizedIcon( override val name: String, override val sha256: String? = null, override val size: Long? = null, -) : IFile +) : IFile { + internal companion object { + const val TABLE = "LocalizedIcon" + } +} @Entity( + tableName = LocalizedFileList.TABLE, primaryKeys = ["repoId", "packageName", "type", "locale", "name"], foreignKeys = [ForeignKey( entity = AppMetadata::class, @@ -413,7 +433,11 @@ internal data class LocalizedFileList( val name: String, val sha256: String? = null, val size: Long? = null, -) +) { + internal companion object { + const val TABLE = "LocalizedFileList" + } +} internal fun LocalizedFileListV2.toLocalizedFileList( repoId: Long, diff --git a/libs/database/src/main/java/org/fdroid/database/AppDao.kt b/libs/database/src/main/java/org/fdroid/database/AppDao.kt index 7cefc0632..211980706 100644 --- a/libs/database/src/main/java/org/fdroid/database/AppDao.kt +++ b/libs/database/src/main/java/org/fdroid/database/AppDao.kt @@ -271,19 +271,19 @@ internal interface AppDaoInt : AppDao { * This is needed to support v1 streaming and shouldn't be used for something else. */ @Deprecated("Only for v1 index") - @Query("""UPDATE AppMetadata SET preferredSigner = :preferredSigner + @Query("""UPDATE ${AppMetadata.TABLE} SET preferredSigner = :preferredSigner WHERE repoId = :repoId AND packageName = :packageName""") fun updatePreferredSigner(repoId: Long, packageName: String, preferredSigner: String?) - @Query("""UPDATE AppMetadata + @Query("""UPDATE ${AppMetadata.TABLE} SET isCompatible = ( - SELECT TOTAL(isCompatible) > 0 FROM Version - WHERE repoId = :repoId AND AppMetadata.packageName = Version.packageName + SELECT TOTAL(isCompatible) > 0 FROM ${Version.TABLE} + WHERE repoId = :repoId AND ${AppMetadata.TABLE}.packageName = ${Version.TABLE}.packageName ) WHERE repoId = :repoId""") override fun updateCompatibility(repoId: Long) - @Query("""UPDATE AppMetadata SET localizedName = :name, localizedSummary = :summary + @Query("""UPDATE ${AppMetadata.TABLE} SET localizedName = :name, localizedSummary = :summary WHERE repoId = :repoId AND packageName = :packageName""") fun updateAppMetadata(repoId: Long, packageName: String, name: String?, summary: String?) @@ -291,42 +291,44 @@ internal interface AppDaoInt : AppDao { fun updateAppMetadata(appMetadata: AppMetadata): Int @Transaction - @Query("""SELECT AppMetadata.* FROM AppMetadata + @Query("""SELECT ${AppMetadata.TABLE}.* FROM ${AppMetadata.TABLE} JOIN RepositoryPreferences AS pref USING (repoId) WHERE packageName = :packageName ORDER BY pref.weight DESC LIMIT 1""") override fun getApp(packageName: String): LiveData @Transaction - @Query("""SELECT * FROM AppMetadata + @Query("""SELECT * FROM ${AppMetadata.TABLE} WHERE repoId = :repoId AND packageName = :packageName""") override fun getApp(repoId: Long, packageName: String): App? /** * Used for diffing. */ - @Query("SELECT * FROM AppMetadata WHERE repoId = :repoId AND packageName = :packageName") + @Query("""SELECT * FROM ${AppMetadata.TABLE} + WHERE repoId = :repoId AND packageName = :packageName""") fun getAppMetadata(repoId: Long, packageName: String): AppMetadata? /** * Used for updating best locales. */ - @Query("SELECT * FROM AppMetadata") + @Query("SELECT * FROM ${AppMetadata.TABLE}") fun getAppMetadata(): List /** * used for diffing */ - @Query("SELECT * FROM LocalizedFile WHERE repoId = :repoId AND packageName = :packageName") + @Query("""SELECT * FROM ${LocalizedFile.TABLE} + WHERE repoId = :repoId AND packageName = :packageName""") fun getLocalizedFiles(repoId: Long, packageName: String): List @Transaction @Query("""SELECT repoId, packageName, app.added, app.lastUpdated, localizedName, localizedSummary, version.antiFeatures - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) - LEFT JOIN LocalizedIcon AS icon USING (repoId, packageName) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) + LEFT JOIN ${LocalizedIcon.TABLE} AS icon USING (repoId, packageName) WHERE pref.enabled = 1 GROUP BY packageName HAVING MAX(pref.weight) ORDER BY localizedName IS NULL ASC, icon.packageName IS NULL ASC, @@ -337,10 +339,10 @@ internal interface AppDaoInt : AppDao { @Transaction @Query("""SELECT repoId, packageName, app.added, app.lastUpdated, localizedName, localizedSummary, version.antiFeatures - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) - LEFT JOIN LocalizedIcon AS icon USING (repoId, packageName) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) + LEFT JOIN ${LocalizedIcon.TABLE} AS icon USING (repoId, packageName) WHERE pref.enabled = 1 AND categories LIKE '%,' || :category || ',%' GROUP BY packageName HAVING MAX(pref.weight) ORDER BY localizedName IS NULL ASC, icon.packageName IS NULL ASC, @@ -355,7 +357,7 @@ internal interface AppDaoInt : AppDao { @SuppressWarnings(CURSOR_MISMATCH) // no anti-features needed here @Query("""SELECT repoId, packageName, added, app.lastUpdated, localizedName, localizedSummary - FROM AppMetadata AS app WHERE repoId = :repoId AND packageName = :packageName""") + FROM ${AppMetadata.TABLE} AS app WHERE repoId = :repoId AND packageName = :packageName""") fun getAppOverviewItem(repoId: Long, packageName: String): AppOverviewItem? // @@ -403,11 +405,11 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, app.localizedName, app.localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - JOIN AppMetadataFts USING (repoId, packageName) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) - JOIN RepositoryPreferences AS pref USING (repoId) - WHERE pref.enabled = 1 AND AppMetadataFts MATCH '"*' || :searchQuery || '*"' + FROM ${AppMetadata.TABLE} AS app + JOIN ${AppMetadataFts.TABLE} USING (repoId, packageName) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + WHERE pref.enabled = 1 AND ${AppMetadataFts.TABLE} MATCH '"*' || :searchQuery || '*"' GROUP BY packageName HAVING MAX(pref.weight)""") fun getAppListItems(searchQuery: String): LiveData> @@ -415,12 +417,12 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, app.localizedName, app.localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - JOIN AppMetadataFts USING (repoId, packageName) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) - JOIN RepositoryPreferences AS pref USING (repoId) + FROM ${AppMetadata.TABLE} AS app + JOIN ${AppMetadataFts.TABLE} USING (repoId, packageName) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 AND categories LIKE '%,' || :category || ',%' AND - AppMetadataFts MATCH '"*' || :searchQuery || '*"' + ${AppMetadataFts.TABLE} MATCH '"*' || :searchQuery || '*"' GROUP BY packageName HAVING MAX(pref.weight)""") fun getAppListItems(category: String, searchQuery: String): LiveData> @@ -428,9 +430,9 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, localizedName, localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - LEFT JOIN HighestVersion AS version USING (repoId, packageName) - JOIN RepositoryPreferences AS pref USING (repoId) + FROM ${AppMetadata.TABLE} AS app + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 GROUP BY packageName HAVING MAX(pref.weight) ORDER BY localizedName COLLATE NOCASE ASC""") @@ -440,9 +442,9 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, localizedName, localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) WHERE pref.enabled = 1 GROUP BY packageName HAVING MAX(pref.weight) ORDER BY app.lastUpdated DESC""") @@ -452,9 +454,9 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, localizedName, localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) WHERE pref.enabled = 1 AND categories LIKE '%,' || :category || ',%' GROUP BY packageName HAVING MAX(pref.weight) ORDER BY app.lastUpdated DESC""") @@ -464,9 +466,9 @@ internal interface AppDaoInt : AppDao { @Query(""" SELECT repoId, packageName, localizedName, localizedSummary, version.antiFeatures, app.isCompatible - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN HighestVersion AS version USING (repoId, packageName) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${HighestVersion.TABLE} AS version USING (repoId, packageName) WHERE pref.enabled = 1 AND categories LIKE '%,' || :category || ',%' GROUP BY packageName HAVING MAX(pref.weight) ORDER BY localizedName COLLATE NOCASE ASC""") @@ -475,8 +477,8 @@ internal interface AppDaoInt : AppDao { @Transaction @SuppressWarnings(CURSOR_MISMATCH) // no anti-features needed here @Query("""SELECT repoId, packageName, localizedName, localizedSummary, app.isCompatible - FROM AppMetadata AS app - JOIN RepositoryPreferences AS pref USING (repoId) + FROM ${AppMetadata.TABLE} AS app + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 AND packageName IN (:packageNames) GROUP BY packageName HAVING MAX(pref.weight) ORDER BY localizedName COLLATE NOCASE ASC""") @@ -491,49 +493,49 @@ internal interface AppDaoInt : AppDao { return getAppListItems(packageNames).map(packageManager, installedPackages) } - @Query("""SELECT COUNT(DISTINCT packageName) FROM AppMetadata - JOIN RepositoryPreferences AS pref USING (repoId) + @Query("""SELECT COUNT(DISTINCT packageName) FROM ${AppMetadata.TABLE} + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 AND categories LIKE '%,' || :category || ',%'""") override fun getNumberOfAppsInCategory(category: String): Int - @Query("SELECT COUNT(*) FROM AppMetadata WHERE repoId = :repoId") + @Query("SELECT COUNT(*) FROM ${AppMetadata.TABLE} WHERE repoId = :repoId") override fun getNumberOfAppsInRepository(repoId: Long): Int - @Query("DELETE FROM AppMetadata WHERE repoId = :repoId AND packageName = :packageName") + @Query("DELETE FROM ${AppMetadata.TABLE} WHERE repoId = :repoId AND packageName = :packageName") fun deleteAppMetadata(repoId: Long, packageName: String) - @Query("""DELETE FROM LocalizedFile + @Query("""DELETE FROM ${LocalizedFile.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND type = :type""") fun deleteLocalizedFiles(repoId: Long, packageName: String, type: String) - @Query("""DELETE FROM LocalizedFile + @Query("""DELETE FROM ${LocalizedFile.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND type = :type AND locale = :locale""") fun deleteLocalizedFile(repoId: Long, packageName: String, type: String, locale: String) - @Query("""DELETE FROM LocalizedFileList + @Query("""DELETE FROM ${LocalizedFileList.TABLE} WHERE repoId = :repoId AND packageName = :packageName""") fun deleteLocalizedFileLists(repoId: Long, packageName: String) - @Query("""DELETE FROM LocalizedFileList + @Query("""DELETE FROM ${LocalizedFileList.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND type = :type""") fun deleteLocalizedFileLists(repoId: Long, packageName: String, type: String) - @Query("""DELETE FROM LocalizedFileList + @Query("""DELETE FROM ${LocalizedFileList.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND type = :type AND locale = :locale""") fun deleteLocalizedFileList(repoId: Long, packageName: String, type: String, locale: String) @VisibleForTesting - @Query("SELECT COUNT(*) FROM AppMetadata") + @Query("SELECT COUNT(*) FROM ${AppMetadata.TABLE}") fun countApps(): Int @VisibleForTesting - @Query("SELECT COUNT(*) FROM LocalizedFile") + @Query("SELECT COUNT(*) FROM ${LocalizedFile.TABLE}") fun countLocalizedFiles(): Int @VisibleForTesting - @Query("SELECT COUNT(*) FROM LocalizedFileList") + @Query("SELECT COUNT(*) FROM ${LocalizedFileList.TABLE}") fun countLocalizedFileLists(): Int } diff --git a/libs/database/src/main/java/org/fdroid/database/AppPrefs.kt b/libs/database/src/main/java/org/fdroid/database/AppPrefs.kt index ba54de720..3b08bdc09 100644 --- a/libs/database/src/main/java/org/fdroid/database/AppPrefs.kt +++ b/libs/database/src/main/java/org/fdroid/database/AppPrefs.kt @@ -8,7 +8,7 @@ import org.fdroid.PackagePreference * User-defined preferences related to [App]s that get stored in the database, * so they can be used for queries. */ -@Entity +@Entity(tableName = AppPrefs.TABLE) public data class AppPrefs( @PrimaryKey val packageName: String, @@ -17,6 +17,10 @@ public data class AppPrefs( // which had exactly the same field. internal val appPrefReleaseChannels: List? = null, ) : PackagePreference { + internal companion object { + const val TABLE = "AppPrefs" + } + public val ignoreAllUpdates: Boolean get() = ignoreVersionCodeUpdate == Long.MAX_VALUE public override val releaseChannels: List get() = appPrefReleaseChannels ?: emptyList() public fun shouldIgnoreUpdate(versionCode: Long): Boolean = diff --git a/libs/database/src/main/java/org/fdroid/database/AppPrefsDao.kt b/libs/database/src/main/java/org/fdroid/database/AppPrefsDao.kt index aa8fe0b4b..137a6dd7d 100644 --- a/libs/database/src/main/java/org/fdroid/database/AppPrefsDao.kt +++ b/libs/database/src/main/java/org/fdroid/database/AppPrefsDao.kt @@ -22,10 +22,10 @@ internal interface AppPrefsDaoInt : AppPrefsDao { } } - @Query("SELECT * FROM AppPrefs WHERE packageName = :packageName") + @Query("SELECT * FROM ${AppPrefs.TABLE} WHERE packageName = :packageName") fun getLiveAppPrefs(packageName: String): LiveData - @Query("SELECT * FROM AppPrefs WHERE packageName = :packageName") + @Query("SELECT * FROM ${AppPrefs.TABLE} WHERE packageName = :packageName") fun getAppPrefsOrNull(packageName: String): AppPrefs? @Insert(onConflict = REPLACE) diff --git a/libs/database/src/main/java/org/fdroid/database/Repository.kt b/libs/database/src/main/java/org/fdroid/database/Repository.kt index 586466a2f..c585d7bf0 100644 --- a/libs/database/src/main/java/org/fdroid/database/Repository.kt +++ b/libs/database/src/main/java/org/fdroid/database/Repository.kt @@ -19,7 +19,7 @@ import org.fdroid.index.v2.MirrorV2 import org.fdroid.index.v2.ReleaseChannelV2 import org.fdroid.index.v2.RepoV2 -@Entity +@Entity(tableName = CoreRepository.TABLE) internal data class CoreRepository( @PrimaryKey(autoGenerate = true) val repoId: Long = 0, val name: LocalizedTextV2 = emptyMap(), @@ -32,7 +32,11 @@ internal data class CoreRepository( val maxAge: Int?, val description: LocalizedTextV2 = emptyMap(), val certificate: String?, -) +) { + internal companion object { + const val TABLE = "CoreRepository" + } +} internal fun RepoV2.toCoreRepository( repoId: Long = 0, @@ -199,6 +203,7 @@ public data class Repository internal constructor( * A database table to store repository mirror information. */ @Entity( + tableName = Mirror.TABLE, primaryKeys = ["repoId", "url"], foreignKeys = [ForeignKey( entity = CoreRepository::class, @@ -212,6 +217,10 @@ internal data class Mirror( val url: String, val location: String? = null, ) { + internal companion object { + const val TABLE = "Mirror" + } + fun toDownloadMirror(): org.fdroid.download.Mirror = org.fdroid.download.Mirror( baseUrl = url, location = location, @@ -243,6 +252,7 @@ public abstract class RepoAttribute { * An anti-feature belonging to a [Repository]. */ @Entity( + tableName = AntiFeature.TABLE, primaryKeys = ["repoId", "id"], foreignKeys = [ForeignKey( entity = CoreRepository::class, @@ -257,7 +267,11 @@ public data class AntiFeature internal constructor( @Embedded(prefix = "icon_") public override val icon: FileV2? = null, override val name: LocalizedTextV2, override val description: LocalizedTextV2, -) : RepoAttribute() +) : RepoAttribute() { + internal companion object { + const val TABLE = "AntiFeature" + } +} internal fun Map.toRepoAntiFeatures(repoId: Long) = map { AntiFeature( @@ -273,6 +287,7 @@ internal fun Map.toRepoAntiFeatures(repoId: Long) = map { * A category of apps belonging to a [Repository]. */ @Entity( + tableName = Category.TABLE, primaryKeys = ["repoId", "id"], foreignKeys = [ForeignKey( entity = CoreRepository::class, @@ -287,7 +302,11 @@ public data class Category internal constructor( @Embedded(prefix = "icon_") public override val icon: FileV2? = null, override val name: LocalizedTextV2, override val description: LocalizedTextV2, -) : RepoAttribute() +) : RepoAttribute() { + internal companion object { + const val TABLE = "Category" + } +} internal fun Map.toRepoCategories(repoId: Long) = map { Category( @@ -303,6 +322,7 @@ internal fun Map.toRepoCategories(repoId: Long) = map { * A release-channel for apps belonging to a [Repository]. */ @Entity( + tableName = ReleaseChannel.TABLE, primaryKeys = ["repoId", "id"], foreignKeys = [ForeignKey( entity = CoreRepository::class, @@ -317,7 +337,11 @@ public data class ReleaseChannel( @Embedded(prefix = "icon_") public override val icon: FileV2? = null, override val name: LocalizedTextV2, override val description: LocalizedTextV2, -) : RepoAttribute() +) : RepoAttribute() { + internal companion object { + const val TABLE = "ReleaseChannel" + } +} internal fun Map.toRepoReleaseChannel(repoId: Long) = map { ReleaseChannel( @@ -328,7 +352,7 @@ internal fun Map.toRepoReleaseChannel(repoId: Long) = ) } -@Entity +@Entity(tableName = RepositoryPreferences.TABLE) internal data class RepositoryPreferences( @PrimaryKey internal val repoId: Long, val weight: Int, @@ -339,7 +363,11 @@ internal data class RepositoryPreferences( val disabledMirrors: List? = null, val username: String? = null, val password: String? = null, -) +) { + internal companion object { + const val TABLE = "RepositoryPreferences" + } +} /** * A reduced version of [Repository] used to pre-populate the [FDroidDatabase]. diff --git a/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt b/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt index a6e080803..e096256cf 100644 --- a/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt +++ b/libs/database/src/main/java/org/fdroid/database/RepositoryDao.kt @@ -182,27 +182,27 @@ internal interface RepositoryDaoInt : RepositoryDao { return repoId } - @Query("SELECT MAX(weight) FROM RepositoryPreferences") + @Query("SELECT MAX(weight) FROM ${RepositoryPreferences.TABLE}") fun getMaxRepositoryWeight(): Int @Transaction - @Query("SELECT * FROM CoreRepository WHERE repoId = :repoId") + @Query("SELECT * FROM ${CoreRepository.TABLE} WHERE repoId = :repoId") override fun getRepository(repoId: Long): Repository? @Transaction - @Query("SELECT * FROM CoreRepository") + @Query("SELECT * FROM ${CoreRepository.TABLE}") override fun getRepositories(): List @Transaction - @Query("SELECT * FROM CoreRepository") + @Query("SELECT * FROM ${CoreRepository.TABLE}") override fun getLiveRepositories(): LiveData> - @Query("SELECT * FROM RepositoryPreferences WHERE repoId = :repoId") + @Query("SELECT * FROM ${RepositoryPreferences.TABLE} WHERE repoId = :repoId") fun getRepositoryPreferences(repoId: Long): RepositoryPreferences? @RewriteQueriesToDropUnusedColumns - @Query("""SELECT * FROM Category - JOIN RepositoryPreferences AS pref USING (repoId) + @Query("""SELECT * FROM ${Category.TABLE} + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 GROUP BY id HAVING MAX(pref.weight)""") override fun getLiveCategories(): LiveData> @@ -239,7 +239,7 @@ internal interface RepositoryDaoInt : RepositoryDao { * V2 index should use [update] instead as there the certificate is known * before reading full index. */ - @Query("UPDATE CoreRepository SET certificate = :certificate WHERE repoId = :repoId") + @Query("UPDATE ${CoreRepository.TABLE} SET certificate = :certificate WHERE repoId = :repoId") fun updateRepository(repoId: Long, certificate: String) @Update @@ -301,17 +301,18 @@ internal interface RepositoryDaoInt : RepositoryDao { ) } - @Query("UPDATE RepositoryPreferences SET enabled = :enabled WHERE repoId = :repoId") + @Query("UPDATE ${RepositoryPreferences.TABLE} SET enabled = :enabled WHERE repoId = :repoId") override fun setRepositoryEnabled(repoId: Long, enabled: Boolean) - @Query("UPDATE RepositoryPreferences SET userMirrors = :mirrors WHERE repoId = :repoId") + @Query("""UPDATE ${RepositoryPreferences.TABLE} SET userMirrors = :mirrors + WHERE repoId = :repoId""") override fun updateUserMirrors(repoId: Long, mirrors: List) - @Query("""UPDATE RepositoryPreferences SET username = :username, password = :password + @Query("""UPDATE ${RepositoryPreferences.TABLE} SET username = :username, password = :password WHERE repoId = :repoId""") override fun updateUsernameAndPassword(repoId: Long, username: String?, password: String?) - @Query("""UPDATE RepositoryPreferences SET disabledMirrors = :disabledMirrors + @Query("""UPDATE ${RepositoryPreferences.TABLE} SET disabledMirrors = :disabledMirrors WHERE repoId = :repoId""") override fun updateDisabledMirrors(repoId: Long, disabledMirrors: List) @@ -323,58 +324,58 @@ internal interface RepositoryDaoInt : RepositoryDao { deleteRepositoryPreferences(repoId) } - @Query("DELETE FROM CoreRepository WHERE repoId = :repoId") + @Query("DELETE FROM ${CoreRepository.TABLE} WHERE repoId = :repoId") fun deleteCoreRepository(repoId: Long) - @Query("DELETE FROM RepositoryPreferences WHERE repoId = :repoId") + @Query("DELETE FROM ${RepositoryPreferences.TABLE} WHERE repoId = :repoId") fun deleteRepositoryPreferences(repoId: Long) - @Query("DELETE FROM CoreRepository") + @Query("DELETE FROM ${CoreRepository.TABLE}") fun deleteAllCoreRepositories() - @Query("DELETE FROM RepositoryPreferences") + @Query("DELETE FROM ${RepositoryPreferences.TABLE}") fun deleteAllRepositoryPreferences() /** * Used for diffing. */ - @Query("DELETE FROM Mirror WHERE repoId = :repoId") + @Query("DELETE FROM ${Mirror.TABLE} WHERE repoId = :repoId") fun deleteMirrors(repoId: Long) /** * Used for diffing. */ - @Query("DELETE FROM AntiFeature WHERE repoId = :repoId") + @Query("DELETE FROM ${AntiFeature.TABLE} WHERE repoId = :repoId") fun deleteAntiFeatures(repoId: Long) /** * Used for diffing. */ - @Query("DELETE FROM AntiFeature WHERE repoId = :repoId AND id = :id") + @Query("DELETE FROM ${AntiFeature.TABLE} WHERE repoId = :repoId AND id = :id") fun deleteAntiFeature(repoId: Long, id: String) /** * Used for diffing. */ - @Query("DELETE FROM Category WHERE repoId = :repoId") + @Query("DELETE FROM ${Category.TABLE} WHERE repoId = :repoId") fun deleteCategories(repoId: Long) /** * Used for diffing. */ - @Query("DELETE FROM Category WHERE repoId = :repoId AND id = :id") + @Query("DELETE FROM ${Category.TABLE} WHERE repoId = :repoId AND id = :id") fun deleteCategory(repoId: Long, id: String) /** * Used for diffing. */ - @Query("DELETE FROM ReleaseChannel WHERE repoId = :repoId") + @Query("DELETE FROM ${ReleaseChannel.TABLE} WHERE repoId = :repoId") fun deleteReleaseChannels(repoId: Long) /** * Used for diffing. */ - @Query("DELETE FROM ReleaseChannel WHERE repoId = :repoId AND id = :id") + @Query("DELETE FROM ${ReleaseChannel.TABLE} WHERE repoId = :repoId AND id = :id") fun deleteReleaseChannel(repoId: Long, id: String) /** @@ -397,19 +398,19 @@ internal interface RepositoryDaoInt : RepositoryDao { } @VisibleForTesting - @Query("SELECT COUNT(*) FROM Mirror") + @Query("SELECT COUNT(*) FROM ${Mirror.TABLE}") fun countMirrors(): Int @VisibleForTesting - @Query("SELECT COUNT(*) FROM AntiFeature") + @Query("SELECT COUNT(*) FROM ${AntiFeature.TABLE}") fun countAntiFeatures(): Int @VisibleForTesting - @Query("SELECT COUNT(*) FROM Category") + @Query("SELECT COUNT(*) FROM ${Category.TABLE}") fun countCategories(): Int @VisibleForTesting - @Query("SELECT COUNT(*) FROM ReleaseChannel") + @Query("SELECT COUNT(*) FROM ${ReleaseChannel.TABLE}") fun countReleaseChannels(): Int } diff --git a/libs/database/src/main/java/org/fdroid/database/Version.kt b/libs/database/src/main/java/org/fdroid/database/Version.kt index 3e2ad9d11..3b1227572 100644 --- a/libs/database/src/main/java/org/fdroid/database/Version.kt +++ b/libs/database/src/main/java/org/fdroid/database/Version.kt @@ -27,6 +27,7 @@ import org.fdroid.index.v2.UsesSdkV2 * This holds the data of [PackageVersionV2]. */ @Entity( + tableName = Version.TABLE, primaryKeys = ["repoId", "packageName", "versionId"], foreignKeys = [ForeignKey( entity = AppMetadata::class, @@ -48,6 +49,10 @@ internal data class Version( val whatsNew: LocalizedTextV2? = null, val isCompatible: Boolean, ) : PackageVersion { + internal companion object { + const val TABLE = "Version" + } + override val versionCode: Long get() = manifest.versionCode override val signer: SignerV2? get() = manifest.signer override val packageManifest: PackageManifest get() = manifest @@ -141,13 +146,18 @@ internal fun ManifestV2.toManifest() = AppManifest( features = features.map { it.name }, ) -@DatabaseView("""SELECT repoId, packageName, antiFeatures FROM Version +@DatabaseView(viewName = HighestVersion.TABLE, + value = """SELECT repoId, packageName, antiFeatures FROM ${Version.TABLE} GROUP BY repoId, packageName HAVING MAX(manifest_versionCode)""") internal class HighestVersion( val repoId: Long, val packageName: String, val antiFeatures: Map? = null, -) +) { + internal companion object { + const val TABLE = "HighestVersion" + } +} internal enum class VersionedStringType { PERMISSION, @@ -155,6 +165,7 @@ internal enum class VersionedStringType { } @Entity( + tableName = VersionedString.TABLE, primaryKeys = ["repoId", "packageName", "versionId", "type", "name"], foreignKeys = [ForeignKey( entity = Version::class, @@ -170,7 +181,11 @@ internal data class VersionedString( val type: VersionedStringType, val name: String, val version: Int? = null, -) +) { + internal companion object { + const val TABLE = "VersionedString" + } +} internal fun List.toVersionedString( version: Version, diff --git a/libs/database/src/main/java/org/fdroid/database/VersionDao.kt b/libs/database/src/main/java/org/fdroid/database/VersionDao.kt index 4890ddfa9..dd5369aeb 100644 --- a/libs/database/src/main/java/org/fdroid/database/VersionDao.kt +++ b/libs/database/src/main/java/org/fdroid/database/VersionDao.kt @@ -155,8 +155,8 @@ internal interface VersionDaoInt : VersionDao { @Transaction @RewriteQueriesToDropUnusedColumns - @Query("""SELECT * FROM Version - JOIN RepositoryPreferences AS pref USING (repoId) + @Query("""SELECT * FROM ${Version.TABLE} + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) WHERE pref.enabled = 1 AND packageName = :packageName ORDER BY manifest_versionCode DESC, pref.weight DESC""") override fun getAppVersions(packageName: String): LiveData> @@ -165,11 +165,11 @@ internal interface VersionDaoInt : VersionDao { * Only use for testing, not sorted, does take disabled repos into account. */ @Transaction - @Query("""SELECT * FROM Version + @Query("""SELECT * FROM ${Version.TABLE} WHERE repoId = :repoId AND packageName = :packageName""") fun getAppVersions(repoId: Long, packageName: String): List - @Query("""SELECT * FROM Version + @Query("""SELECT * FROM ${Version.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND versionId = :versionId""") fun getVersion(repoId: Long, packageName: String, versionId: String): Version? @@ -178,19 +178,20 @@ internal interface VersionDaoInt : VersionDao { * so takes [AppPrefs.ignoreVersionCodeUpdate] into account. */ @RewriteQueriesToDropUnusedColumns - @Query("""SELECT * FROM Version - JOIN RepositoryPreferences AS pref USING (repoId) - LEFT JOIN AppPrefs USING (packageName) + @Query("""SELECT * FROM ${Version.TABLE} + JOIN ${RepositoryPreferences.TABLE} AS pref USING (repoId) + LEFT JOIN ${AppPrefs.TABLE} AS appPrefs USING (packageName) WHERE pref.enabled = 1 AND - manifest_versionCode > COALESCE(AppPrefs.ignoreVersionCodeUpdate, 0) AND + manifest_versionCode > COALESCE(appPrefs.ignoreVersionCodeUpdate, 0) AND packageName IN (:packageNames) ORDER BY manifest_versionCode DESC, pref.weight DESC""") fun getVersions(packageNames: List): List - @Query("SELECT * FROM VersionedString WHERE repoId = :repoId AND packageName = :packageName") + @Query("""SELECT * FROM ${VersionedString.TABLE} + WHERE repoId = :repoId AND packageName = :packageName""") fun getVersionedStrings(repoId: Long, packageName: String): List - @Query("""SELECT * FROM VersionedString + @Query("""SELECT * FROM ${VersionedString.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND versionId = :versionId""") fun getVersionedStrings( repoId: Long, @@ -198,18 +199,18 @@ internal interface VersionDaoInt : VersionDao { versionId: String, ): List - @Query("""DELETE FROM Version WHERE repoId = :repoId AND packageName = :packageName""") + @Query("""DELETE FROM ${Version.TABLE} WHERE repoId = :repoId AND packageName = :packageName""") fun deleteAppVersion(repoId: Long, packageName: String) - @Query("""DELETE FROM Version + @Query("""DELETE FROM ${Version.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND versionId = :versionId""") fun deleteAppVersion(repoId: Long, packageName: String, versionId: String) - @Query("""DELETE FROM VersionedString + @Query("""DELETE FROM ${VersionedString.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND versionId = :versionId""") fun deleteVersionedStrings(repoId: Long, packageName: String, versionId: String) - @Query("""DELETE FROM VersionedString WHERE repoId = :repoId + @Query("""DELETE FROM ${VersionedString.TABLE} WHERE repoId = :repoId AND packageName = :packageName AND versionId = :versionId AND type = :type""") fun deleteVersionedStrings( repoId: Long, @@ -218,10 +219,10 @@ internal interface VersionDaoInt : VersionDao { type: VersionedStringType, ) - @Query("SELECT COUNT(*) FROM Version") + @Query("SELECT COUNT(*) FROM ${Version.TABLE}") fun countAppVersions(): Int - @Query("SELECT COUNT(*) FROM VersionedString") + @Query("SELECT COUNT(*) FROM ${VersionedString.TABLE}") fun countVersionedStrings(): Int }