mirror of
https://github.com/f-droid/fdroidclient.git
synced 2026-04-20 06:47:06 -04:00
[db] Add special queries for AppListItems
This commit is contained in:
committed by
Michael Pöhn
parent
97567a2057
commit
3cb7538fc8
@@ -5,7 +5,10 @@ import androidx.room.DatabaseView
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Ignore
|
||||
import androidx.room.Relation
|
||||
import org.fdroid.database.Converters.fromStringToLocalizedTextV2
|
||||
import org.fdroid.database.Converters.fromStringToMapOfLocalizedTextV2
|
||||
import org.fdroid.index.v2.Author
|
||||
import org.fdroid.index.v2.Donation
|
||||
import org.fdroid.index.v2.FileV2
|
||||
@@ -126,6 +129,48 @@ public data class AppOverviewItem(
|
||||
localizedIcon?.toLocalizedFileV2().getBestLocale(localeList)?.name
|
||||
}
|
||||
|
||||
public data class AppListItem @JvmOverloads constructor(
|
||||
public val repoId: Long,
|
||||
public val packageId: String,
|
||||
internal val name: String?,
|
||||
internal val summary: String?,
|
||||
internal val antiFeatures: String?,
|
||||
@Relation(
|
||||
parentColumn = "packageId",
|
||||
entityColumn = "packageId",
|
||||
)
|
||||
internal val localizedIcon: List<LocalizedIcon>?,
|
||||
/**
|
||||
* If true, this this app has at least one version that is compatible with this device.
|
||||
*/
|
||||
@Ignore // TODO actually get this from the DB (probably needs post-processing).
|
||||
public val isCompatible: Boolean = true,
|
||||
/**
|
||||
* The name of the installed version, null if this app is not installed.
|
||||
*/
|
||||
@Ignore
|
||||
public val installedVersionName: String? = null,
|
||||
@Ignore
|
||||
public val installedVersionCode: Long? = null,
|
||||
) {
|
||||
public fun getName(localeList: LocaleListCompat): String? {
|
||||
// queries for this class return a larger number, so we convert on demand
|
||||
return fromStringToLocalizedTextV2(name).getBestLocale(localeList)
|
||||
}
|
||||
|
||||
public fun getSummary(localeList: LocaleListCompat): String? {
|
||||
// queries for this class return a larger number, so we convert on demand
|
||||
return fromStringToLocalizedTextV2(summary).getBestLocale(localeList)
|
||||
}
|
||||
|
||||
public fun getAntiFeatureNames(): List<String> {
|
||||
return fromStringToMapOfLocalizedTextV2(antiFeatures)?.map { it.key } ?: emptyList()
|
||||
}
|
||||
|
||||
public fun getIcon(localeList: LocaleListCompat) =
|
||||
localizedIcon?.toLocalizedFileV2().getBestLocale(localeList)?.name
|
||||
}
|
||||
|
||||
public data class UpdatableApp(
|
||||
public val packageId: String,
|
||||
public val installedVersionCode: Long,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.fdroid.database
|
||||
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
@@ -11,6 +13,7 @@ import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.RoomWarnings.CURSOR_MISMATCH
|
||||
import androidx.room.Transaction
|
||||
import org.fdroid.database.FDroidDatabaseHolder.dispatcher
|
||||
import org.fdroid.index.v2.LocalizedFileListV2
|
||||
@@ -29,6 +32,14 @@ public interface AppDao {
|
||||
fun getApp(repoId: Long, packageId: String): App?
|
||||
fun getAppOverviewItems(limit: Int = 200): LiveData<List<AppOverviewItem>>
|
||||
fun getAppOverviewItems(category: String, limit: Int = 50): LiveData<List<AppOverviewItem>>
|
||||
fun getAppListItems(packageManager: PackageManager): LiveData<List<AppListItem>>
|
||||
fun getAppListItems(
|
||||
packageManager: PackageManager,
|
||||
category: String,
|
||||
): LiveData<List<AppListItem>>
|
||||
|
||||
fun getInstalledAppListItems(packageManager: PackageManager): LiveData<List<AppListItem>>
|
||||
|
||||
fun getNumberOfAppsInCategory(category: String): Int
|
||||
}
|
||||
|
||||
@@ -197,8 +208,69 @@ internal interface AppDaoInt : AppDao {
|
||||
LIMIT :limit""")
|
||||
override fun getAppOverviewItems(category: String, limit: Int): LiveData<List<AppOverviewItem>>
|
||||
|
||||
// FIXME don't over report the same app twice (e.g. in several repos)
|
||||
@Query("""SELECT COUNT(*) FROM AppMetadata
|
||||
override fun getAppListItems(packageManager: PackageManager): LiveData<List<AppListItem>> {
|
||||
return getAppListItems().map(packageManager)
|
||||
}
|
||||
|
||||
private fun LiveData<List<AppListItem>>.map(
|
||||
packageManager: PackageManager,
|
||||
installedPackages: Map<String, PackageInfo> = packageManager.getInstalledPackages(0)
|
||||
.associateBy { packageInfo -> packageInfo.packageName },
|
||||
) = map { items ->
|
||||
items.map { item ->
|
||||
val packageInfo = installedPackages[item.packageId]
|
||||
if (packageInfo == null) item else item.copy(
|
||||
installedVersionName = packageInfo.versionName,
|
||||
installedVersionCode = packageInfo.getVersionCode(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Transaction
|
||||
@Query("""SELECT repoId, packageId, app.name, summary, version.antiFeatures
|
||||
FROM AppMetadata AS app
|
||||
JOIN Version AS version USING (repoId, packageId)
|
||||
JOIN RepositoryPreferences AS pref USING (repoId)
|
||||
WHERE pref.enabled = 1
|
||||
GROUP BY packageId HAVING MAX(pref.weight) AND MAX(version.manifest_versionCode)
|
||||
ORDER BY app.lastUpdated DESC""")
|
||||
fun getAppListItems(): LiveData<List<AppListItem>>
|
||||
|
||||
override fun getAppListItems(
|
||||
packageManager: PackageManager,
|
||||
category: String,
|
||||
): LiveData<List<AppListItem>> {
|
||||
return getAppListItems(category).map(packageManager)
|
||||
}
|
||||
|
||||
// TODO maybe it makes sense to split categories into their own table for this?
|
||||
@Transaction
|
||||
@Query("""SELECT repoId, packageId, app.name, summary, version.antiFeatures
|
||||
FROM AppMetadata AS app
|
||||
JOIN Version AS version USING (repoId, packageId)
|
||||
JOIN RepositoryPreferences AS pref USING (repoId)
|
||||
WHERE pref.enabled = 1 AND categories LIKE '%' || :category || '%'
|
||||
GROUP BY packageId HAVING MAX(pref.weight) AND MAX(version.manifest_versionCode)
|
||||
ORDER BY app.lastUpdated DESC""")
|
||||
fun getAppListItems(category: String): LiveData<List<AppListItem>>
|
||||
|
||||
@Transaction
|
||||
@SuppressWarnings(CURSOR_MISMATCH) // no anti-features needed here
|
||||
@Query("""SELECT repoId, packageId, app.name, summary
|
||||
FROM AppMetadata AS app
|
||||
JOIN RepositoryPreferences AS pref USING (repoId)
|
||||
WHERE pref.enabled = 1 AND packageId IN (:packageNames)
|
||||
GROUP BY packageId HAVING MAX(pref.weight)""")
|
||||
fun getAppListItems(packageNames: List<String>): LiveData<List<AppListItem>>
|
||||
|
||||
override fun getInstalledAppListItems(packageManager: PackageManager): LiveData<List<AppListItem>> {
|
||||
val installedPackages = packageManager.getInstalledPackages(0)
|
||||
.associateBy { packageInfo -> packageInfo.packageName }
|
||||
val packageNames = installedPackages.keys.toList()
|
||||
return getAppListItems(packageNames).map(packageManager, installedPackages)
|
||||
}
|
||||
|
||||
@Query("""SELECT COUNT(DISTINCT packageId) FROM AppMetadata
|
||||
JOIN RepositoryPreferences AS pref USING (repoId)
|
||||
WHERE pref.enabled = 1 AND categories LIKE '%' || :category || '%'""")
|
||||
override fun getNumberOfAppsInCategory(category: String): Int
|
||||
|
||||
@@ -6,7 +6,7 @@ import kotlinx.serialization.builtins.serializer
|
||||
import org.fdroid.index.IndexParser.json
|
||||
import org.fdroid.index.v2.LocalizedTextV2
|
||||
|
||||
internal class Converters {
|
||||
internal object Converters {
|
||||
|
||||
private val localizedTextV2Serializer = MapSerializer(String.serializer(), String.serializer())
|
||||
private val mapOfLocalizedTextV2Serializer =
|
||||
|
||||
@@ -48,8 +48,6 @@ public interface RepositoryDao {
|
||||
fun updateUserMirrors(repoId: Long, mirrors: List<String>)
|
||||
fun updateUsernameAndPassword(repoId: Long, username: String?, password: String?)
|
||||
fun updateDisabledMirrors(repoId: Long, disabledMirrors: List<String>)
|
||||
|
||||
// FIXME: We probably want unique categories here flattened by repo weight
|
||||
fun getLiveCategories(): LiveData<List<Category>>
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user