Replace standard queries by a raw query to filter and sort the items list

This commit is contained in:
Shinokuni 2019-04-22 21:12:46 +02:00
parent b9a31d4652
commit 3f7a879993
4 changed files with 127 additions and 82 deletions

View File

@ -101,6 +101,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
viewModel.setShowReadItems(SharedPreferencesManager.readBoolean(this,
SharedPreferencesManager.SharedPrefKey.SHOW_READ_ARTICLES));
viewModel.invalidate();
viewModel.getItemsWithFeed().observe(this, itemWithFeeds -> {
allItems = itemWithFeeds;

View File

@ -0,0 +1,104 @@
package com.readrops.app.database;
import android.arch.persistence.db.SupportSQLiteQuery;
import android.arch.persistence.db.SupportSQLiteQueryBuilder;
import android.database.sqlite.SQLiteQuery;
import android.database.sqlite.SQLiteQueryBuilder;
import com.readrops.app.activities.MainActivity;
import com.readrops.app.viewmodels.MainViewModel;
public class ItemsListQueryBuilder {
private String [] columns = {"Item.id", "title", "clean_description", "image_link", "pub_date", "read",
"read_it_later", "Feed.name", "text_color", "background_color", "icon_url", "read_time",
"Feed.id as feedId", "Folder.id as folder_id", "Folder.name as folder_name"};
private String SELECT_ALL_JOIN = "Item Inner Join Feed, Folder on Item.feed_id = Feed.id And Folder.id = Feed.folder_id";
private String ORDER_BY_ASC = "Item.id DESC";
private String ORDER_BY_DESC = "pub_date ASC";
private SupportSQLiteQueryBuilder queryBuilder;
private boolean showReaditems;
private int filterFeedId;
private MainViewModel.FilterType filterType;
private MainActivity.ListSortType sortType;
public ItemsListQueryBuilder() {
queryBuilder = SupportSQLiteQueryBuilder.builder(SELECT_ALL_JOIN);
}
private String buildWhereClause() {
StringBuilder stringBuilder = new StringBuilder(50);
if (!showReaditems)
stringBuilder.append("read = 0 And ");
switch (filterType) {
case FEED_FILTER:
stringBuilder.append("feed_id = " + filterFeedId + " And read_it_later = 0");
break;
case READ_IT_LATER_FILTER:
stringBuilder.append("read_it_later = 1");
break;
case NO_FILTER:
stringBuilder.append("read_it_later = 0");
break;
default:
stringBuilder.append("read_it_later = 0");
break;
}
return stringBuilder.toString();
}
public SupportSQLiteQuery getQuery() {
queryBuilder.columns(columns);
queryBuilder.selection(buildWhereClause(), new String[0]);
if (sortType == MainActivity.ListSortType.NEWEST_TO_OLDEST)
queryBuilder.orderBy(ORDER_BY_ASC);
else
queryBuilder.orderBy(ORDER_BY_DESC);
return queryBuilder.create();
}
public boolean showReaditems() {
return showReaditems;
}
public void setShowReaditems(boolean showReaditems) {
this.showReaditems = showReaditems;
}
public int getFilterFeedId() {
return filterFeedId;
}
public void setFilterFeedId(int filterFeedId) {
this.filterFeedId = filterFeedId;
}
public MainViewModel.FilterType getFilterType() {
return filterType;
}
public void setFilterType(MainViewModel.FilterType filterType) {
this.filterType = filterType;
}
public MainActivity.ListSortType getSortType() {
return sortType;
}
public void setSortType(MainActivity.ListSortType sortType) {
this.sortType = sortType;
}
}

View File

@ -4,10 +4,14 @@ package com.readrops.app.database.dao;
import android.arch.lifecycle.LiveData;
import android.arch.paging.DataSource;
import android.arch.paging.PageKeyedDataSource;
import android.arch.persistence.db.SupportSQLiteQuery;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.RawQuery;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Folder;
import com.readrops.app.database.pojo.ItemWithFeed;
import com.readrops.app.database.entities.Item;
@ -16,45 +20,8 @@ import java.util.List;
@Dao
public interface ItemDao {
String SELECT_ALL_FIELDS = "Item.id, title, clean_description, image_link, pub_date, read, read_it_later, " +
"Feed.name, text_color, background_color, icon_url, read_time, Feed.id as feedId, Folder.id as folder_id, " +
"Folder.name as folder_name";
String SELECT_ALL_JOIN = "Item Inner Join Feed, Folder on Item.feed_id = Feed.id And Folder.id = Feed.folder_id";
String SELECT_ALL_ORDER_BY_ASC = "Order by Item.id DESC";
String SELECT_ALL_ORDER_BY_DESC = "Order By pub_date ASC";
@Query("Select " + SELECT_ALL_FIELDS + " from " + SELECT_ALL_JOIN + " Where feed_id = :feedId " +
"And read = :readState And read_it_later = 0 " + SELECT_ALL_ORDER_BY_ASC)
DataSource.Factory<Integer, ItemWithFeed> selectAllByFeedASC(int feedId, int readState);
@Query("Select " + SELECT_ALL_FIELDS + " from " + SELECT_ALL_JOIN + " Where feed_id = :feedId " +
"And read = :readState And read_it_later = 0 " + SELECT_ALL_ORDER_BY_DESC)
DataSource.Factory<Integer, ItemWithFeed> selectAllByFeedsDESC(int feedId, int readState);
@Query("Select " + SELECT_ALL_FIELDS + " from " + SELECT_ALL_JOIN + " Where read_it_later = 1 " +
"And read = :readState " + SELECT_ALL_ORDER_BY_ASC)
DataSource.Factory<Integer, ItemWithFeed> selectAllReadItLaterASC(int readState);
@Query("Select " + SELECT_ALL_FIELDS + " from " + SELECT_ALL_JOIN + " Where read_it_later = 1 " +
"And read = :readState " + SELECT_ALL_ORDER_BY_DESC)
DataSource.Factory<Integer, ItemWithFeed> selectAllReadItLaterDESC(int readState);
/**
* ASC means here from the newest (inserted) to the oldest
*/
@Query("Select " + SELECT_ALL_FIELDS + " From " + SELECT_ALL_JOIN + " Where read = :readState And " +
"read_it_later = 0 " + SELECT_ALL_ORDER_BY_ASC)
DataSource.Factory<Integer, ItemWithFeed> selectAllASC(int readState);
/**
* DESC means here from the oldest to the newest
*/
@Query("Select " + SELECT_ALL_FIELDS + " From " + SELECT_ALL_JOIN + " Where read = :readState And "
+ "read_it_later = 0 " + SELECT_ALL_ORDER_BY_DESC)
PageKeyedDataSource.Factory<Integer, ItemWithFeed> selectAllDESC(int readState);
@RawQuery(observedEntities = {Item.class, Folder.class, Feed.class})
PageKeyedDataSource.Factory<Integer, ItemWithFeed> selectAll(SupportSQLiteQuery query);
@Query("Select case When :guid In (Select guid from Item) Then 'true' else 'false' end")
String guidExist(String guid);
@ -62,9 +29,6 @@ public interface ItemDao {
@Insert
long insert(Item item);
@Insert
void insertAll(List<Item> items);
/**
* Set an item read or unread
* @param itemId if of the item to update

View File

@ -11,10 +11,12 @@ import android.arch.lifecycle.Transformations;
import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListBuilder;
import android.arch.paging.PagedList;
import android.arch.persistence.db.SupportSQLiteQuery;
import android.support.annotation.NonNull;
import com.readrops.app.activities.MainActivity;
import com.readrops.app.database.Database;
import com.readrops.app.database.ItemsListQueryBuilder;
import com.readrops.app.database.entities.Feed;
import com.readrops.app.database.entities.Folder;
import com.readrops.app.database.pojo.ItemWithFeed;
@ -36,54 +38,28 @@ public class MainViewModel extends AndroidViewModel {
private LocalFeedRepository repository;
private Database db;
private boolean showReadItems;
private FilterType filterType;
private MainActivity.ListSortType sortType;
private int filterFeedId;
private ItemsListQueryBuilder queryBuilder;
public MainViewModel(@NonNull Application application) {
super(application);
filterType = FilterType.NO_FILTER;
sortType = MainActivity.ListSortType.NEWEST_TO_OLDEST;
queryBuilder = new ItemsListQueryBuilder();
queryBuilder.setFilterType(FilterType.NO_FILTER);
queryBuilder.setSortType(MainActivity.ListSortType.NEWEST_TO_OLDEST);
repository = new LocalFeedRepository(application);
db = Database.getInstance(application);
itemsWithFeed = new MediatorLiveData<>();
buildPagedList();
}
private void buildPagedList() {
DataSource.Factory<Integer, ItemWithFeed> items;
int readState = showReadItems ? 1 : 0;
switch (filterType) {
case FEED_FILTER:
if (sortType == MainActivity.ListSortType.NEWEST_TO_OLDEST)
items = db.itemDao().selectAllByFeedASC(filterFeedId, readState);
else
items = db.itemDao().selectAllByFeedsDESC(filterFeedId, readState);
break;
case READ_IT_LATER_FILTER:
if (sortType == MainActivity.ListSortType.NEWEST_TO_OLDEST)
items = db.itemDao().selectAllReadItLaterASC(readState);
else
items = db.itemDao().selectAllReadItLaterDESC(readState);
break;
default:
if (sortType == MainActivity.ListSortType.NEWEST_TO_OLDEST)
items = db.itemDao().selectAllASC(readState);
else
items = db.itemDao().selectAllDESC(readState);
break;
}
if (lastFetch != null)
itemsWithFeed.removeSource(lastFetch);
lastFetch = new LivePagedListBuilder<>(items, new PagedList.Config.Builder()
lastFetch = new LivePagedListBuilder<>(db.itemDao().selectAll(queryBuilder.getQuery()),
new PagedList.Config.Builder()
.setPageSize(40)
.setPrefetchDistance(80)
.setEnablePlaceholders(false)
@ -98,31 +74,31 @@ public class MainViewModel extends AndroidViewModel {
}
public void setShowReadItems(boolean showReadItems) {
this.showReadItems = showReadItems;
queryBuilder.setShowReaditems(showReadItems);
}
public boolean showReadItems() {
return showReadItems;
return queryBuilder.showReaditems();
}
public void setFilterType(FilterType filterType) {
this.filterType = filterType;
queryBuilder.setFilterType(filterType);
}
public FilterType getFilterType() {
return filterType;
return queryBuilder.getFilterType();
}
public void setSortType(MainActivity.ListSortType sortType) {
this.sortType = sortType;
queryBuilder.setSortType(sortType);
}
public MainActivity.ListSortType getSortType() {
return sortType;
return queryBuilder.getSortType();
}
public void setFilterFeedId(int filterFeedId) {
this.filterFeedId = filterFeedId;
queryBuilder.setFilterFeedId(filterFeedId);
}
public MediatorLiveData<PagedList<ItemWithFeed>> getItemsWithFeed() {