mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-04-24 03:42:15 +00:00
Update: Migrate some of entity Product's fields to database.entity (and add some TODOs)
This commit is contained in:
parent
af611cb49a
commit
7694f3cade
@ -91,7 +91,7 @@ interface ProductDao : BaseDao<Product> {
|
|||||||
query: SupportSQLiteQuery
|
query: SupportSQLiteQuery
|
||||||
): Cursor
|
): Cursor
|
||||||
|
|
||||||
// TODO optimize and simplify
|
// TODO Remove
|
||||||
@Transaction
|
@Transaction
|
||||||
fun query(
|
fun query(
|
||||||
installed: Boolean, updates: Boolean, searchQuery: String,
|
installed: Boolean, updates: Boolean, searchQuery: String,
|
||||||
@ -175,6 +175,92 @@ interface ProductDao : BaseDao<Product> {
|
|||||||
return query(SimpleSQLiteQuery(builder.build()))
|
return query(SimpleSQLiteQuery(builder.build()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RawQuery
|
||||||
|
fun queryObject(query: SupportSQLiteQuery): List<Product>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
fun queryObject(
|
||||||
|
installed: Boolean, updates: Boolean, searchQuery: String,
|
||||||
|
section: Section, order: Order, numberOfItems: Int = 0
|
||||||
|
): List<Product> {
|
||||||
|
val builder = QueryBuilder()
|
||||||
|
|
||||||
|
val signatureMatches = """installed.${ROW_SIGNATURE} IS NOT NULL AND
|
||||||
|
product.${ROW_SIGNATURES} LIKE ('%.' || installed.${ROW_SIGNATURE} || '.%') AND
|
||||||
|
product.${ROW_SIGNATURES} != ''"""
|
||||||
|
|
||||||
|
builder += """SELECT product.rowid AS _id, product.${ROW_REPOSITORY_ID},
|
||||||
|
product.${ROW_PACKAGE_NAME}, product.${ROW_NAME},
|
||||||
|
product.${ROW_SUMMARY}, installed.${ROW_VERSION},
|
||||||
|
(COALESCE(lock.${ROW_VERSION_CODE}, -1) NOT IN (0, product.${ROW_VERSION_CODE}) AND
|
||||||
|
product.${ROW_COMPATIBLE} != 0 AND product.${ROW_VERSION_CODE} >
|
||||||
|
COALESCE(installed.${ROW_VERSION_CODE}, 0xffffffff) AND $signatureMatches)
|
||||||
|
AS ${ROW_CAN_UPDATE}, product.${ROW_COMPATIBLE},"""
|
||||||
|
|
||||||
|
if (searchQuery.isNotEmpty()) {
|
||||||
|
builder += """(((product.${ROW_NAME} LIKE ? OR
|
||||||
|
product.${ROW_SUMMARY} LIKE ?) * 7) |
|
||||||
|
((product.${ROW_PACKAGE_NAME} LIKE ?) * 3) |
|
||||||
|
(product.${ROW_DESCRIPTION} LIKE ?)) AS ${ROW_MATCH_RANK},"""
|
||||||
|
builder %= List(4) { "%$searchQuery%" }
|
||||||
|
} else {
|
||||||
|
builder += "0 AS ${ROW_MATCH_RANK},"
|
||||||
|
}
|
||||||
|
|
||||||
|
builder += """MAX((product.${ROW_COMPATIBLE} AND
|
||||||
|
(installed.${ROW_SIGNATURE} IS NULL OR $signatureMatches)) ||
|
||||||
|
PRINTF('%016X', product.${ROW_VERSION_CODE})) FROM $ROW_PRODUCT_NAME AS product"""
|
||||||
|
builder += """JOIN $ROW_REPOSITORY_NAME AS repository
|
||||||
|
ON product.${ROW_REPOSITORY_ID} = repository.${ROW_ID}"""
|
||||||
|
builder += """LEFT JOIN $ROW_LOCK_NAME AS lock
|
||||||
|
ON product.${ROW_PACKAGE_NAME} = lock.${ROW_PACKAGE_NAME}"""
|
||||||
|
|
||||||
|
if (!installed && !updates) {
|
||||||
|
builder += "LEFT"
|
||||||
|
}
|
||||||
|
builder += """JOIN $ROW_INSTALLED_NAME AS installed
|
||||||
|
ON product.${ROW_PACKAGE_NAME} = installed.${ROW_PACKAGE_NAME}"""
|
||||||
|
|
||||||
|
if (section is Section.Category) {
|
||||||
|
builder += """JOIN $ROW_CATEGORY_NAME AS category
|
||||||
|
ON product.${ROW_PACKAGE_NAME} = category.${ROW_PACKAGE_NAME}"""
|
||||||
|
}
|
||||||
|
|
||||||
|
builder += """WHERE repository.${ROW_ENABLED} != 0"""
|
||||||
|
|
||||||
|
if (section is Section.Category) {
|
||||||
|
builder += "AND category.${ROW_NAME} = ?"
|
||||||
|
builder %= section.name
|
||||||
|
} else if (section is Section.Repository) {
|
||||||
|
builder += "AND product.${ROW_REPOSITORY_ID} = ?"
|
||||||
|
builder %= section.id.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchQuery.isNotEmpty()) {
|
||||||
|
builder += """AND $ROW_MATCH_RANK > 0"""
|
||||||
|
}
|
||||||
|
|
||||||
|
builder += "GROUP BY product.${ROW_PACKAGE_NAME} HAVING 1"
|
||||||
|
|
||||||
|
if (updates) {
|
||||||
|
builder += "AND $ROW_CAN_UPDATE"
|
||||||
|
}
|
||||||
|
builder += "ORDER BY"
|
||||||
|
|
||||||
|
if (searchQuery.isNotEmpty()) {
|
||||||
|
builder += """$ROW_MATCH_RANK DESC,"""
|
||||||
|
}
|
||||||
|
|
||||||
|
when (order) {
|
||||||
|
Order.NAME -> Unit
|
||||||
|
Order.DATE_ADDED -> builder += "product.${ROW_ADDED} DESC,"
|
||||||
|
Order.LAST_UPDATE -> builder += "product.${ROW_UPDATED} DESC,"
|
||||||
|
}::class
|
||||||
|
builder += "product.${ROW_NAME} COLLATE LOCALIZED ASC${if (numberOfItems > 0) " LIMIT $numberOfItems" else ""}"
|
||||||
|
|
||||||
|
return queryObject(SimpleSQLiteQuery(builder.build()))
|
||||||
|
}
|
||||||
|
|
||||||
@RawQuery(observedEntities = [Product::class])
|
@RawQuery(observedEntities = [Product::class])
|
||||||
fun queryList(
|
fun queryList(
|
||||||
query: SupportSQLiteQuery
|
query: SupportSQLiteQuery
|
||||||
@ -332,6 +418,9 @@ interface ProductTempDao : BaseDao<ProductTemp> {
|
|||||||
this.signatures = signatures
|
this.signatures = signatures
|
||||||
compatible = if (it.compatible) 1 else 0
|
compatible = if (it.compatible) 1 else 0
|
||||||
data = it
|
data = it
|
||||||
|
icon = it.icon
|
||||||
|
metadataIcon = it.metadataIcon
|
||||||
|
releases = it.releases
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
it.categories.forEach { category ->
|
it.categories.forEach { category ->
|
||||||
|
@ -3,6 +3,7 @@ package com.looker.droidify.database.entity
|
|||||||
import androidx.room.ColumnInfo
|
import androidx.room.ColumnInfo
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import com.looker.droidify.entity.ProductItem
|
import com.looker.droidify.entity.ProductItem
|
||||||
|
import com.looker.droidify.entity.Release
|
||||||
|
|
||||||
@Entity(tableName = "product", primaryKeys = ["repository_id", "package_name"])
|
@Entity(tableName = "product", primaryKeys = ["repository_id", "package_name"])
|
||||||
open class Product {
|
open class Product {
|
||||||
@ -17,11 +18,39 @@ open class Product {
|
|||||||
var version_code = 0L
|
var version_code = 0L
|
||||||
var signatures = ""
|
var signatures = ""
|
||||||
var compatible = 0
|
var compatible = 0
|
||||||
|
var icon = ""
|
||||||
|
var metadataIcon = ""
|
||||||
|
var releases: List<Release> = emptyList()
|
||||||
|
|
||||||
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
|
@ColumnInfo(typeAffinity = ColumnInfo.BLOB)
|
||||||
var data: com.looker.droidify.entity.Product? = null
|
var data: com.looker.droidify.entity.Product? = null
|
||||||
|
|
||||||
fun item(): ProductItem? = data?.item()
|
val selectedReleases: List<Release>
|
||||||
|
get() = releases.filter { it.selected }
|
||||||
|
|
||||||
|
val displayRelease: Release?
|
||||||
|
get() = selectedReleases.firstOrNull() ?: releases.firstOrNull()
|
||||||
|
|
||||||
|
val version: String
|
||||||
|
get() = displayRelease?.version.orEmpty()
|
||||||
|
|
||||||
|
val versionCode: Long
|
||||||
|
get() = selectedReleases.firstOrNull()?.versionCode ?: 0L
|
||||||
|
|
||||||
|
val item: ProductItem
|
||||||
|
get() = ProductItem(
|
||||||
|
repository_id,
|
||||||
|
package_name,
|
||||||
|
name,
|
||||||
|
summary,
|
||||||
|
icon,
|
||||||
|
metadataIcon,
|
||||||
|
version,
|
||||||
|
"",
|
||||||
|
compatible != 0,
|
||||||
|
false,
|
||||||
|
0
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(tableName = "temporary_product")
|
@Entity(tableName = "temporary_product")
|
||||||
|
@ -7,6 +7,7 @@ import com.fasterxml.jackson.core.JsonToken
|
|||||||
import com.looker.droidify.database.entity.Repository
|
import com.looker.droidify.database.entity.Repository
|
||||||
import com.looker.droidify.utility.extension.json.*
|
import com.looker.droidify.utility.extension.json.*
|
||||||
|
|
||||||
|
// TODO make a Room entity
|
||||||
data class Release(
|
data class Release(
|
||||||
val selected: Boolean,
|
val selected: Boolean,
|
||||||
val version: String,
|
val version: String,
|
||||||
|
@ -24,11 +24,9 @@ import com.looker.droidify.ui.activities.MainActivityX
|
|||||||
import com.looker.droidify.utility.RxUtils
|
import com.looker.droidify.utility.RxUtils
|
||||||
import com.looker.droidify.utility.Utils
|
import com.looker.droidify.utility.Utils
|
||||||
import com.looker.droidify.utility.extension.android.Android
|
import com.looker.droidify.utility.extension.android.Android
|
||||||
import com.looker.droidify.utility.extension.android.asSequence
|
|
||||||
import com.looker.droidify.utility.extension.android.notificationManager
|
import com.looker.droidify.utility.extension.android.notificationManager
|
||||||
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
||||||
import com.looker.droidify.utility.extension.text.formatSize
|
import com.looker.droidify.utility.extension.text.formatSize
|
||||||
import com.looker.droidify.utility.getProduct
|
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.disposables.Disposable
|
import io.reactivex.rxjava3.disposables.Disposable
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
@ -390,18 +388,13 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
val disposable = RxUtils
|
val disposable = RxUtils
|
||||||
.querySingle { it ->
|
.querySingle { it ->
|
||||||
db.productDao
|
db.productDao
|
||||||
.query(
|
.queryObject(
|
||||||
installed = true,
|
installed = true,
|
||||||
updates = true,
|
updates = true,
|
||||||
searchQuery = "",
|
searchQuery = "",
|
||||||
section = Section.All,
|
section = Section.All,
|
||||||
order = Order.NAME,
|
order = Order.NAME
|
||||||
signal = it
|
).mapNotNull { it.item }
|
||||||
)
|
|
||||||
.use {
|
|
||||||
it.asSequence().map { it.getProduct().item() }
|
|
||||||
.toList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
@ -15,7 +15,7 @@ fun ProductsVerticalRecycler(productsList: List<Product>) {
|
|||||||
verticalArrangement = spacedBy(2.dp)
|
verticalArrangement = spacedBy(2.dp)
|
||||||
) {
|
) {
|
||||||
items(productsList) { product: Product ->
|
items(productsList) { product: Product ->
|
||||||
product.item()?.let { item ->
|
product.item?.let { item ->
|
||||||
ProductRow(item.name, item.version, item.summary, onUserClick = {
|
ProductRow(item.name, item.version, item.summary, onUserClick = {
|
||||||
Log.d(this.toString(), "You clicked $it")
|
Log.d(this.toString(), "You clicked $it")
|
||||||
})
|
})
|
||||||
@ -30,7 +30,7 @@ fun ProductsHorizontalRecycler(productsList: List<Product>) {
|
|||||||
horizontalArrangement = spacedBy(2.dp)
|
horizontalArrangement = spacedBy(2.dp)
|
||||||
) {
|
) {
|
||||||
items(productsList) { product: Product ->
|
items(productsList) { product: Product ->
|
||||||
product.item()?.let { item ->
|
product.item?.let { item ->
|
||||||
ProductColumn(item.name, item.version, onUserClick = {
|
ProductColumn(item.name, item.version, onUserClick = {
|
||||||
Log.d(this.toString(), "You clicked $it")
|
Log.d(this.toString(), "You clicked $it")
|
||||||
})
|
})
|
||||||
|
@ -52,7 +52,7 @@ class ExploreFragment : MainNavFragmentX() {
|
|||||||
|
|
||||||
override fun setupAdapters() {
|
override fun setupAdapters() {
|
||||||
appsItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
appsItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
||||||
it.item()?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
it.item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
||||||
}
|
}
|
||||||
appsFastAdapter = FastAdapter.with(appsItemAdapter)
|
appsFastAdapter = FastAdapter.with(appsItemAdapter)
|
||||||
appsFastAdapter?.setHasStableIds(true)
|
appsFastAdapter?.setHasStableIds(true)
|
||||||
|
@ -55,11 +55,11 @@ class InstalledFragment : MainNavFragmentX() {
|
|||||||
|
|
||||||
override fun setupAdapters() {
|
override fun setupAdapters() {
|
||||||
installedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
installedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
||||||
it.item()?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
it.item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
||||||
}
|
}
|
||||||
updatedItemAdapter = PagedModelAdapter<Product, HAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
updatedItemAdapter = PagedModelAdapter<Product, HAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
||||||
// TODO filter for only updated apps and add placeholder
|
// TODO filter for only updated apps and add placeholder
|
||||||
it.item()?.let { item -> HAppItem(item, repositories[it.repository_id]) }
|
it.item?.let { item -> HAppItem(item, repositories[it.repository_id]) }
|
||||||
}
|
}
|
||||||
installedFastAdapter = FastAdapter.with(installedItemAdapter)
|
installedFastAdapter = FastAdapter.with(installedItemAdapter)
|
||||||
installedFastAdapter?.setHasStableIds(true)
|
installedFastAdapter?.setHasStableIds(true)
|
||||||
|
@ -56,11 +56,11 @@ class LatestFragment : MainNavFragmentX() {
|
|||||||
|
|
||||||
override fun setupAdapters() {
|
override fun setupAdapters() {
|
||||||
updatedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
updatedItemAdapter = PagedModelAdapter<Product, VAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
||||||
it.item()?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
it.item?.let { item -> VAppItem(item, repositories[it.repository_id]) }
|
||||||
}
|
}
|
||||||
newItemAdapter = PagedModelAdapter<Product, HAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
newItemAdapter = PagedModelAdapter<Product, HAppItem>(PRODUCT_ASYNC_DIFFER_CONFIG) {
|
||||||
// TODO filter for only new apps and add placeholder
|
// TODO filter for only new apps and add placeholder
|
||||||
it.item()?.let { item -> HAppItem(item, repositories[it.repository_id]) }
|
it.item?.let { item -> HAppItem(item, repositories[it.repository_id]) }
|
||||||
}
|
}
|
||||||
updatedFastAdapter = FastAdapter.with(updatedItemAdapter)
|
updatedFastAdapter = FastAdapter.with(updatedItemAdapter)
|
||||||
updatedFastAdapter?.setHasStableIds(true)
|
updatedFastAdapter?.setHasStableIds(true)
|
||||||
|
@ -184,6 +184,7 @@ object Utils {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Remove
|
||||||
fun Cursor.getProduct(): Product = getBlob(getColumnIndex(ROW_DATA))
|
fun Cursor.getProduct(): Product = getBlob(getColumnIndex(ROW_DATA))
|
||||||
.jsonParse {
|
.jsonParse {
|
||||||
Product.deserialize(it).apply {
|
Product.deserialize(it).apply {
|
||||||
@ -192,7 +193,7 @@ fun Cursor.getProduct(): Product = getBlob(getColumnIndex(ROW_DATA))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Remove
|
||||||
fun Cursor.getProductItem(): ProductItem = getBlob(getColumnIndex(ROW_DATA_ITEM))
|
fun Cursor.getProductItem(): ProductItem = getBlob(getColumnIndex(ROW_DATA_ITEM))
|
||||||
.jsonParse {
|
.jsonParse {
|
||||||
ProductItem.deserialize(it).apply {
|
ProductItem.deserialize(it).apply {
|
||||||
@ -208,6 +209,7 @@ fun Cursor.getProductItem(): ProductItem = getBlob(getColumnIndex(ROW_DATA_ITEM)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Remove
|
||||||
fun Cursor.getRepository(): Repository = getBlob(getColumnIndex(ROW_DATA))
|
fun Cursor.getRepository(): Repository = getBlob(getColumnIndex(ROW_DATA))
|
||||||
.jsonParse {
|
.jsonParse {
|
||||||
Repository.deserialize(it).apply {
|
Repository.deserialize(it).apply {
|
||||||
@ -240,6 +242,6 @@ val PRODUCT_ASYNC_DIFFER_CONFIG
|
|||||||
oldItem: com.looker.droidify.database.entity.Product,
|
oldItem: com.looker.droidify.database.entity.Product,
|
||||||
newItem: com.looker.droidify.database.entity.Product
|
newItem: com.looker.droidify.database.entity.Product
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return oldItem.item() == newItem.item()
|
return oldItem.item == newItem.item
|
||||||
}
|
}
|
||||||
}).build()
|
}).build()
|
Loading…
x
Reference in New Issue
Block a user