Remove usage of StarredItem table in the main query

This commit is contained in:
Shinokuni 2021-07-01 21:40:16 +02:00
parent d9b31d4cfa
commit 15596e5fff
4 changed files with 92 additions and 105 deletions

View File

@ -11,8 +11,8 @@ import androidx.paging.PagedList;
import com.readrops.app.repositories.ARepository;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.db.Database;
import com.readrops.db.ItemsQueryBuilder;
import com.readrops.db.QueryFilters;
import com.readrops.db.queries.ItemsQueryBuilder;
import com.readrops.db.queries.QueryFilters;
import com.readrops.db.RoomFactoryWrapper;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
@ -70,16 +70,7 @@ public class MainViewModel extends ViewModel {
}
DataSource.Factory<Integer, ItemWithFeed> items;
/*
if (queryFilters.getFilterType() == FilterType.STARS_FILTER && currentAccount.getAccountType().getAccountConfig().useStarredItems()) {
items = database.starredItemDao().selectAll(ItemsQueryBuilder.buildStarredItemsQuery(queryFilters));
} else {
}
*/
items = database.itemDao().selectAll(ItemsQueryBuilder.buildItemsQuery(queryFilters));
items = database.itemDao().selectAll(ItemsQueryBuilder.buildItemsQuery(queryFilters, currentAccount.getConfig().useSeparateState()));
lastFetch = new LivePagedListBuilder<>(new RoomFactoryWrapper<>(items),
new PagedList.Config.Builder()

View File

@ -1,93 +0,0 @@
package com.readrops.db
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQueryBuilder
import com.readrops.db.filters.FilterType
import com.readrops.db.filters.ListSortType
object ItemsQueryBuilder {
private val COLUMNS = arrayOf("title", "clean_description", "image_link", "pub_date",
"read_it_later", "Feed.name", "text_color", "background_color", "icon_url", "read_time",
"Feed.id as feedId", "Feed.account_id", "Folder.id as folder_id", "Folder.name as folder_name",
"case When ItemState.remote_id is NULL Or ItemState.read = 1 Then 1 else 0 End read",
"case When ItemState.remote_id is NULL or ItemState.starred = 1 Then 1 else 0 End starred")
private val ITEM_COLUMNS = arrayOf(".id", ".remoteId")
private const val ORDER_BY_ASC = ".id DESC"
private const val ORDER_BY_DESC = "pub_date ASC"
@JvmStatic
fun buildItemsQuery(queryFilters: QueryFilters): SupportSQLiteQuery =
buildQuery(queryFilters, false)
@JvmStatic
fun buildStarredItemsQuery(queryFilters: QueryFilters): SupportSQLiteQuery =
buildQuery(queryFilters, true)
private fun buildQuery(queryFilters: QueryFilters, starQuery: Boolean): SupportSQLiteQuery = with(queryFilters) {
if (accountId == 0)
throw IllegalArgumentException("AccountId must be greater than 0")
if (filterType == FilterType.FEED_FILTER && filterFeedId == 0)
throw IllegalArgumentException("FeedId must be greater than 0 if current filter is FEED_FILTER")
val tableName = tableName(starQuery)
val selectAllJoin = buildSelectAllJoin(tableName)
SupportSQLiteQueryBuilder.builder(selectAllJoin).run {
columns(COLUMNS.plus(buildItemColumns(tableName)))
selection(buildWhereClause(this@with), null)
orderBy(if (sortType == ListSortType.NEWEST_TO_OLDEST) buildOrderByAsc(tableName) else ORDER_BY_DESC)
create()
}
}
private fun buildWhereClause(queryFilters: QueryFilters): String = StringBuilder(500).run {
append("Feed.account_id = ${queryFilters.accountId} And " +
"ItemState.account_id = ${queryFilters.accountId} Or ItemState.account_id is NULL And ")
//if (!queryFilters.showReadItems) append("read = 0 And ")
when (queryFilters.filterType) {
FilterType.FEED_FILTER -> append("feed_id = ${queryFilters.filterFeedId} And read_it_later = 0")
FilterType.READ_IT_LATER_FILTER -> append("read_it_later = 1")
FilterType.STARS_FILTER -> append("starred = 1 And read_it_later = 0")
else -> append("read_it_later = 0")
}
toString()
}
private fun tableName(starQuery: Boolean): String = if (starQuery) "StarredItem" else "Item"
private fun buildItemColumns(tableName: String): Array<String> {
val columns = arrayListOf<String>()
for (column in ITEM_COLUMNS) {
columns += tableName + column
}
return columns.toTypedArray()
}
private fun buildOrderByAsc(tableName: String): String = tableName + ORDER_BY_ASC
private fun buildSelectAllJoin(tableName: String): String = """
$tableName INNER JOIN Feed on $tableName.feed_id = Feed.id
LEFT JOIN Folder on Feed.folder_id = Folder.id LEFT JOIN ItemState On
$tableName.remoteId = ItemState.remote_id
""".trimIndent()
}
class QueryFilters(
var showReadItems: Boolean = true,
var filterFeedId: Int = 0,
var accountId: Int = 0,
var filterType: FilterType = FilterType.NO_FILTER,
var sortType: ListSortType = ListSortType.NEWEST_TO_OLDEST,
)

View File

@ -0,0 +1,87 @@
package com.readrops.db.queries
import androidx.sqlite.db.SupportSQLiteQuery
import androidx.sqlite.db.SupportSQLiteQueryBuilder
import com.readrops.db.filters.FilterType
import com.readrops.db.filters.ListSortType
object ItemsQueryBuilder {
private val COLUMNS = arrayOf("Item.id", "Item.remoteId", "title", "clean_description", "image_link", "pub_date",
"read_it_later", "Feed.name", "text_color", "background_color", "icon_url", "read_time",
"Feed.id as feedId", "Feed.account_id", "Folder.id as folder_id", "Folder.name as folder_name")
private val SEPARATE_STATE_COLUMNS = arrayOf("case When ItemState.remote_id is NULL Or ItemState.read = 1 Then 1 else 0 End read",
"case When ItemState.remote_id is NULL or ItemState.starred = 1 Then 1 else 0 End starred")
private val OTHER_COLUMNS = arrayOf("read", "starred")
private val SELECT_ALL_JOIN = """Item INNER JOIN Feed on Item.feed_id = Feed.id
LEFT JOIN Folder on Feed.folder_id = Folder.id """.trimIndent()
private const val SEPARATE_STATE_JOIN = "LEFT JOIN ItemState On Item.remoteId = ItemState.remote_id"
private const val ORDER_BY_ASC = "Item.id DESC"
private const val ORDER_BY_DESC = "pub_date ASC"
@JvmStatic
fun buildItemsQuery(queryFilters: QueryFilters, separateState: Boolean): SupportSQLiteQuery =
buildQuery(queryFilters, separateState)
@JvmStatic
fun buildItemsQuery(queryFilters: QueryFilters): SupportSQLiteQuery =
buildQuery(queryFilters, false)
private fun buildQuery(queryFilters: QueryFilters, separateState: Boolean): SupportSQLiteQuery = with(queryFilters) {
if (accountId == 0)
throw IllegalArgumentException("AccountId must be greater than 0")
if (filterType == FilterType.FEED_FILTER && filterFeedId == 0)
throw IllegalArgumentException("FeedId must be greater than 0 if current filter is FEED_FILTER")
val columns = if (separateState) COLUMNS.plus(SEPARATE_STATE_COLUMNS) else COLUMNS.plus(OTHER_COLUMNS)
val selectAllJoin = if (separateState) SELECT_ALL_JOIN + SEPARATE_STATE_JOIN else SELECT_ALL_JOIN
SupportSQLiteQueryBuilder.builder(selectAllJoin).run {
columns(columns)
selection(buildWhereClause(this@with, separateState), null)
orderBy(if (sortType == ListSortType.NEWEST_TO_OLDEST) ORDER_BY_ASC else ORDER_BY_DESC)
create()
}
}
private fun buildWhereClause(queryFilters: QueryFilters, separateState: Boolean): String = StringBuilder(500).run {
if (separateState)
append("ItemState.account_id = ${queryFilters.accountId} And ")
else
append("Feed.account_id = ${queryFilters.accountId} And ")
if (!queryFilters.showReadItems) append("ItemState.read = 0 And ")
when (queryFilters.filterType) {
FilterType.FEED_FILTER -> append("feed_id = ${queryFilters.filterFeedId} And read_it_later = 0")
FilterType.READ_IT_LATER_FILTER -> append("read_it_later = 1")
FilterType.STARS_FILTER -> {
if (separateState) {
append("ItemState.remote_id is NULL or ItemState.starred = 1 And read_it_later = 0")
} else {
append("starred = 1 And read_it_later = 0")
}
}
else -> append("read_it_later = 0")
}
toString()
}
}
class QueryFilters(
var showReadItems: Boolean = true,
var filterFeedId: Int = 0,
var accountId: Int = 0,
var filterType: FilterType = FilterType.NO_FILTER,
var sortType: ListSortType = ListSortType.NEWEST_TO_OLDEST,
)

View File

@ -2,6 +2,8 @@ package com.readrops.db
import com.readrops.db.filters.FilterType
import com.readrops.db.filters.ListSortType
import com.readrops.db.queries.ItemsQueryBuilder
import com.readrops.db.queries.QueryFilters
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertTrue
import org.junit.Test