Update item state local management with new db requests

This commit is contained in:
Shinokuni 2021-04-16 21:42:25 +02:00
parent 2d6e798301
commit 2c2df55970
15 changed files with 163 additions and 160 deletions

View File

@ -136,9 +136,7 @@ public class ItemActivity extends AppCompatActivity {
}
item.setStarred(!item.isStarred());
item.setStarredChanged(!item.isStarredChanged());
viewModel.setStarState(item.getId(), item.isStarred(), item.isStarredChanged())
viewModel.setStarState(item)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Utils.showSnackbar(binding.itemRoot, throwable.getMessage()))

View File

@ -9,9 +9,13 @@ import androidx.core.content.FileProvider;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.readrops.app.repositories.ARepository;
import com.readrops.db.Database;
import com.readrops.db.entities.Item;
import com.readrops.db.pojo.ItemWithFeed;
import org.koin.java.KoinJavaComponent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@ -31,8 +35,8 @@ public class ItemViewModel extends ViewModel {
return database.itemDao().getItemById(id);
}
public Completable setStarState(int itemId, boolean starred, boolean starredChanged) {
return database.itemDao().setStarState(itemId, starred, starredChanged);
public Completable setStarState(Item item) {
return KoinJavaComponent.get(ARepository.class).setItemStarState(item);
}
public Uri saveImageInCache(Bitmap bitmap, Context context) throws IOException {

View File

@ -36,15 +36,16 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.readrops.app.R;
import com.readrops.app.account.AccountTypeListActivity;
import com.readrops.app.addfeed.AddFeedActivity;
import com.readrops.app.databinding.ActivityMainBinding;
import com.readrops.app.item.ItemActivity;
import com.readrops.app.settings.SettingsActivity;
import com.readrops.app.databinding.ActivityMainBinding;
import com.readrops.app.utils.GlideRequests;
import com.readrops.app.utils.customviews.ReadropsItemTouchCallback;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils;
import com.readrops.app.utils.customviews.ReadropsItemTouchCallback;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.db.filters.FilterType;
import com.readrops.db.filters.ListSortType;
@ -230,7 +231,11 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
startActivity(itemIntent);
viewModel.setItemReadState(intent.getIntExtra(ITEM_ID, 0), true, true)
Item item = new Item();
item.setId(intent.getIntExtra(ITEM_ID, 0));
item.setRead(true);
viewModel.setItemReadState(item)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Utils.showSnackbar(binding.mainRoot, throwable.getMessage()))
@ -314,13 +319,13 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
intent.putExtra(IMAGE_URL, itemWithFeed.getItem().getImageLink());
startActivityForResult(intent, ITEM_REQUEST);
viewModel.setItemReadState(itemWithFeed, true)
itemWithFeed.getItem().setRead(true);
viewModel.setItemReadState(itemWithFeed)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Utils.showSnackbar(binding.mainRoot, throwable.getMessage()))
.subscribe();
itemWithFeed.getItem().setRead(true);
adapter.notifyItemChanged(position, itemWithFeed);
updateDrawerFeeds();
} else {
@ -412,14 +417,13 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
if (direction == ItemTouchHelper.LEFT) { // set item read state
ItemWithFeed itemWithFeed = adapter.getItemWithFeed(viewHolder.getAdapterPosition());
viewModel.setItemReadState(itemWithFeed, !itemWithFeed.getItem().isRead())
itemWithFeed.getItem().setRead(!itemWithFeed.getItem().isRead());
viewModel.setItemReadState(itemWithFeed)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Utils.showSnackbar(binding.mainRoot, throwable.getMessage()))
.subscribe();
itemWithFeed.getItem().setRead(!itemWithFeed.getItem().isRead());
adapter.notifyItemChanged(viewHolder.getAdapterPosition());
} else { // add item to read it later section
viewModel.setItemReadItLater((int) adapter.getItemId(viewHolder.getAdapterPosition()))
@ -497,7 +501,7 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
allItemsSelected = false;
} else {
viewModel.setItemsReadState(adapter.getSelectedItems(), read)
viewModel.setItemsReadState(adapter.getSelectedItems())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> Utils.showSnackbar(binding.mainRoot, throwable.getMessage()))

View File

@ -16,6 +16,7 @@ import com.readrops.db.QueryFilters;
import com.readrops.db.RoomFactoryWrapper;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.account.Account;
import com.readrops.db.filters.FilterType;
import com.readrops.db.filters.ListSortType;
@ -223,19 +224,19 @@ public class MainViewModel extends ViewModel {
//region Item read state
public Completable setItemReadState(ItemWithFeed itemWithFeed, boolean read) {
return repository.setItemReadState(itemWithFeed.getItem(), read);
public Completable setItemReadState(ItemWithFeed itemWithFeed) {
return repository.setItemReadState(itemWithFeed.getItem());
}
public Completable setItemReadState(int itemId, boolean read, boolean readChanged) {
return repository.setItemReadState(itemId, read, readChanged);
public Completable setItemReadState(Item item) {
return repository.setItemReadState(item);
}
public Completable setItemsReadState(List<ItemWithFeed> items, boolean read) {
public Completable setItemsReadState(List<ItemWithFeed> items) {
List<Completable> completableList = new ArrayList<>();
for (ItemWithFeed itemWithFeed : items) {
completableList.add(setItemReadState(itemWithFeed, read));
completableList.add(setItemReadState(itemWithFeed));
}
return Completable.concat(completableList);

View File

@ -149,7 +149,7 @@ class SyncWorker(context: Context, parameters: WorkerParameters) : Worker(contex
val itemId = intent?.getIntExtra(ReadropsKeys.ITEM_ID, 0)!!
with(get<Database>()) {
itemDao().setReadState(itemId, true, true)
itemDao().setReadState(itemId, true)
.subscribeOn(Schedulers.io())
.subscribe()
}

View File

@ -17,6 +17,7 @@ import com.readrops.db.Database;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.ReadStarStateChange;
import com.readrops.db.entities.account.Account;
import org.koin.java.KoinJavaComponent;
@ -113,12 +114,10 @@ public abstract class ARepository {
return database.folderDao().delete(folder);
}
public Completable setItemReadState(Item item, boolean read) {
return setItemReadState(item.getId(), read, !item.isReadChanged());
}
public Completable setItemReadState(int itemId, boolean read, boolean readChanged) {
return database.itemDao().setReadState(itemId, read, readChanged);
public Completable setItemReadState(Item item) {
return database.itemDao().setReadState(item.getId(), item.isRead())
.andThen(database.itemsIdsDao().upsertReadStarStateChange(new ReadStarStateChange(item.getId(),
true, false, account.getId())));
}
public Completable setAllItemsReadState(boolean read) {
@ -129,6 +128,12 @@ public abstract class ARepository {
return database.itemDao().setAllFeedItemsReadState(feedId, read ? 1 : 0);
}
public Completable setItemStarState(Item item) {
return database.itemDao().setStarState(item.getId(), item.isStarred())
.andThen(database.itemsIdsDao().upsertReadStarStateChange(new ReadStarStateChange(item.getId(),
false, true, account.getId())));
}
public Single<Integer> getFeedCount(int accountId) {
return database.feedDao().getFeedCount(accountId);
}

View File

@ -124,11 +124,11 @@ public class NextNewsRepository extends ARepository {
database.accountDao().updateLastModified(account.getId(), lastModified);
if (!syncData.getReadItems().isEmpty() || !syncData.getUnreadItems().isEmpty()) {
database.itemDao().resetReadChanges(account.getId());
}
if (!syncData.getStarredItems().isEmpty() || !syncData.getUnstarredItems().isEmpty()) {
database.itemDao().resetStarChanges(account.getId());
}
emitter.onComplete();

View File

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "c5754bffea62bb91c7d79c091c61aca8",
"identityHash": "be089eb90d96a8582a76c667963886cc",
"entities": [
{
"tableName": "Feed",
@ -151,7 +151,7 @@
},
{
"tableName": "Item",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `read_changed` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `starred_changed` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
@ -231,24 +231,12 @@
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "readChanged",
"columnName": "read_changed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starredChanged",
"columnName": "starred_changed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "readItLater",
"columnName": "read_it_later",
@ -284,14 +272,6 @@
"guid"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_Item_guid` ON `${TABLE_NAME}` (`guid`)"
},
{
"name": "index_Item_starred_changed",
"unique": false,
"columnNames": [
"starred_changed"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_Item_starred_changed` ON `${TABLE_NAME}` (`starred_changed`)"
}
],
"foreignKeys": [
@ -504,7 +484,7 @@
},
{
"tableName": "ReadStarStateChange",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `read_change` INTEGER NOT NULL, `star_change` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `read_change` INTEGER NOT NULL, `star_change` INTEGER NOT NULL, `account_id` INTEGER NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
@ -523,6 +503,12 @@
"columnName": "star_change",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "accountId",
"columnName": "account_id",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
@ -536,7 +522,7 @@
},
{
"tableName": "StarredItem",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `read_changed` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `starred_changed` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
@ -616,24 +602,12 @@
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "readChanged",
"columnName": "read_changed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starredChanged",
"columnName": "starred_changed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "readItLater",
"columnName": "read_it_later",
@ -669,14 +643,6 @@
"guid"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_StarredItem_guid` ON `${TABLE_NAME}` (`guid`)"
},
{
"name": "index_StarredItem_starred_changed",
"unique": false,
"columnNames": [
"starred_changed"
],
"createSql": "CREATE INDEX IF NOT EXISTS `index_StarredItem_starred_changed` ON `${TABLE_NAME}` (`starred_changed`)"
}
],
"foreignKeys": [
@ -697,7 +663,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c5754bffea62bb91c7d79c091c61aca8')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'be089eb90d96a8582a76c667963886cc')"
]
}
}

View File

@ -7,14 +7,16 @@ import com.readrops.db.filters.ListSortType
object ItemsQueryBuilder {
private val COLUMNS = arrayOf("title", "clean_description", "image_link", "pub_date", "read",
"read_changed", "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 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 UnreadItemsIds.remote_id is NULL Then 1 else 0 End read")
private val ITEM_COLUMNS = arrayOf(".id", ".remoteId")
private const val SELECT_ALL_JOIN = "Item INNER JOIN Feed on Item.feed_id = Feed.id " +
"LEFT JOIN Folder on Feed.folder_id = Folder.id"
"LEFT JOIN Folder on Feed.folder_id = Folder.id LEFT JOIN UnreadItemsIds On " +
"Item.remoteId = UnreadItemsIds.remote_id"
private const val ORDER_BY_ASC = ".id DESC"
@ -44,21 +46,20 @@ object ItemsQueryBuilder {
}
}
private fun buildWhereClause(queryFilters: QueryFilters): String {
return StringBuilder(500).run {
append("Feed.account_id = ${queryFilters.accountId} And ")
private fun buildWhereClause(queryFilters: QueryFilters): String = StringBuilder(500).run {
append("Feed.account_id = ${queryFilters.accountId} And " +
"UnreadItemsIds.account_id = ${queryFilters.accountId} Or UnreadItemsIds.account_id is NULL And ")
if (!queryFilters.showReadItems) append("read = 0 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()
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 buildItemColumns(starQuery: Boolean): Array<String> {
@ -76,8 +77,10 @@ object ItemsQueryBuilder {
}
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)
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

@ -7,12 +7,12 @@ import androidx.room.Dao;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.room.RoomWarnings;
import androidx.room.Transaction;
import androidx.sqlite.db.SupportSQLiteQuery;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.Item;
import com.readrops.db.entities.UnreadItemsIds;
import com.readrops.db.pojo.ItemWithFeed;
import com.readrops.db.pojo.StarItem;
@ -23,7 +23,7 @@ import io.reactivex.Completable;
@Dao
public interface ItemDao extends BaseDao<Item> {
@RawQuery(observedEntities = {Item.class, Folder.class, Feed.class})
@RawQuery(observedEntities = {Item.class, Folder.class, Feed.class, UnreadItemsIds.class})
DataSource.Factory<Integer, ItemWithFeed> selectAll(SupportSQLiteQuery query);
@Query("Select * From Item Where id = :itemId")
@ -43,15 +43,14 @@ public interface ItemDao extends BaseDao<Item> {
*
* @param itemId id of the item to update
* @param read 1 for read, 0 for unread
* @param readChanged
*/
@Query("Update Item Set read_changed = :readChanged, read = :read Where id = :itemId")
Completable setReadState(int itemId, boolean read, boolean readChanged);
@Query("Update Item Set read = :read Where id = :itemId")
Completable setReadState(int itemId, boolean read);
@Query("Update Item set read_changed = 1, read = :readState Where feed_id In (Select id From Feed Where account_id = :accountId)")
@Query("Update Item set read = :readState Where feed_id In (Select id From Feed Where account_id = :accountId)")
Completable setAllItemsReadState(int readState, int accountId);
@Query("Update Item set read_changed = 1, read = :readState Where feed_id = :feedId")
@Query("Update Item set read = :readState Where feed_id = :feedId")
Completable setAllFeedItemsReadState(int feedId, int readState);
@Query("Update Item set read_it_later = 1 Where id = :itemId")
@ -66,41 +65,21 @@ public interface ItemDao extends BaseDao<Item> {
"Folder.name as folder_name from Item Inner Join Feed On Item.feed_id = Feed.id Left Join Folder on Folder.id = Feed.folder_id Where Item.id = :id")
LiveData<ItemWithFeed> getItemById(int id);
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where read_changed = 1 And read = 1 And account_id = :accountId")
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where read = 1 And account_id = :accountId")
List<String> getReadChanges(int accountId);
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where read_changed = 1 And read = 0 And account_id = :accountId")
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where read = 0 And account_id = :accountId")
List<String> getUnreadChanges(int accountId);
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 1 And account_id = :accountId")
List<String> getFreshRSSStarChanges(int accountId);
@Query("Select Item.remoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 0 And account_id = :accountId")
List<String> getFreshRSSUnstarChanges(int accountId);
@Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 1 And account_id = :accountId")
@Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred = 1 And account_id = :accountId")
List<StarItem> getStarChanges(int accountId);
@Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred_changed = 1 And starred = 0 And account_id = :accountId")
@Query("Select Item.guid, Feed.remoteId as feedRemoteId From Item Inner Join Feed On Item.feed_id = Feed.id Where starred = 0 And account_id = :accountId")
List<StarItem> getUnstarChanges(int accountId);
@Query("Update Item set read_changed = 0 Where feed_id in (Select id From Feed Where account_id = :accountId)")
void resetReadChanges(int accountId);
@Query("Update Item set starred_changed = 0 Where feed_id in (Select id From Feed Where account_id = :accountId)")
void resetStarChanges(int accountId);
@Query("Update Item set read = :read, starred = :starred Where remoteId = :remoteId")
void setReadAndStarState(String remoteId, boolean read, boolean starred);
@Query("Update Item set starred = :starred, starred_changed = :starredChanged Where id = :itemId")
Completable setStarState(int itemId, boolean starred, boolean starredChanged);
@Transaction
@Query("Update Item set read = 0 Where Item.remoteId In (Select remote_id From UnreadItemsIds) And feed_id In (Select id From Feed Where account_id = :accountId)")
void updateUnreadState(int accountId);
@Transaction
@Query("Update Item set read = 1 Where Item.remoteId Not In (Select remote_id From UnreadItemsIds) And feed_id In (Select id From Feed Where account_id = :accountId)")
void updateReadState(int accountId);
@Query("Update Item set starred = :starred Where id = :itemId")
Completable setStarState(int itemId, boolean starred);
}

View File

@ -1,10 +1,13 @@
package com.readrops.db.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import com.readrops.db.entities.ReadStarStateChange
import com.readrops.db.entities.UnreadItemsIds
import com.readrops.db.pojo.ItemReadStarState
import io.reactivex.Completable
@Dao
interface ItemsIdsDao {
@ -12,14 +15,63 @@ interface ItemsIdsDao {
@Insert
fun insertUnreadItemsIds(unreadItemsIds: List<UnreadItemsIds>)
@Insert
fun insertUnreadItemId(unreadItemId: UnreadItemsIds)
@Query("Delete From UnreadItemsIds Where remote_id = :remoteId And account_id = :accountId")
fun deleteUnreadItemId(remoteId: String, accountId: Int)
fun upsertUnreadItemId(unreadItemId: UnreadItemsIds) = Completable.create {
if (unreadItemIdExists(unreadItemId.remoteId, unreadItemId.accountId)) {
deleteUnreadItemId(unreadItemId.remoteId, unreadItemId.accountId)
} else {
insertUnreadItemId(unreadItemId)
}
it.onComplete()
}
@Query("Select case When Exists (Select remote_id, account_id From UnreadItemsIds Where remote_id = :remoteId And account_id = :accountId) Then 1 else 0 End")
fun unreadItemIdExists(remoteId: String, accountId: Int): Boolean
@Insert
fun insertReadStarStateChange(readStarStateChange: ReadStarStateChange)
@Delete
fun deleteReadStarStateChange(readStarStateChange: ReadStarStateChange)
@Query("Delete From UnreadItemsIds Where account_id = :accountId")
fun deleteUnreadItemsIds(accountId: Int)
@Query("Delete From ReadStarStateChange")
fun deleteReadStarStateChanges()
@Query("Delete From ReadStarStateChange Where account_id = :accountId")
fun deleteReadStarStateChanges(accountId: Int)
@Query("Delete From ReadStarStateChange Where account_id = :accountId")
fun deleteStateChanges(accountId: Int)
@Query("Select case When UnreadItemsIds.remote_id is NULL Then 1 else 0 End read, Item.remoteId, ReadStarStateChange.read_change, Item.starred, ReadStarStateChange.star_change " +
"From ReadStarStateChange Inner Join Item On ReadStarStateChange.id = Item.id " +
"Left Join UnreadItemsIds On UnreadItemsIds.remote_id = Item.remoteId Where ReadStarStateChange.account_id = :accountId")
fun getItemStateChanges(accountId: Int): List<ItemReadStarState>
@Query("Select StarredItem.remoteId, Case When StarredItem.read = 1 then 0 else 1 end read, StarredItem.starred, ReadStarStateChange.read_change, " +
"ReadStarStateChange.star_change From StarredItem Inner Join ReadStarStateChange On StarredItem.id = ReadStarStateChange.id Where account_id = :accountId")
fun getStarredItemStateChanges(accountId: Int): List<ItemReadStarState>
fun upsertReadStarStateChange(readStarStateChange: ReadStarStateChange) = Completable.create {
if (readStarStateChange.readChange && readStateChangeExists(readStarStateChange.id) ||
readStarStateChange.starChange && starStateChangeExists(readStarStateChange.id)) {
deleteReadStarStateChange(readStarStateChange)
} else {
insertReadStarStateChange(readStarStateChange)
}
it.onComplete()
}
@Query("Select Case When :itemId In (Select id From ReadStarStateChange Where read_change = 1) Then 1 Else 0 End")
fun readStateChangeExists(itemId: Int): Boolean
@Query("Select Case When :itemId In (Select id From ReadStarStateChange Where star_change = 1) Then 1 Else 0 End")
fun starStateChangeExists(itemId: Int): Boolean
}

View File

@ -47,14 +47,8 @@ public class Item implements Comparable<Item> {
private boolean read;
@ColumnInfo(name = "read_changed")
private boolean readChanged;
private boolean starred;
@ColumnInfo(name = "starred_changed", index = true)
private boolean starredChanged;
@ColumnInfo(name = "read_it_later")
private boolean readItLater;
@ -178,14 +172,6 @@ public class Item implements Comparable<Item> {
this.read = read;
}
public boolean isReadChanged() {
return readChanged;
}
public void setReadChanged(boolean readChanged) {
this.readChanged = readChanged;
}
public boolean isStarred() {
return starred;
}
@ -194,14 +180,6 @@ public class Item implements Comparable<Item> {
this.starred = starred;
}
public boolean isStarredChanged() {
return starredChanged;
}
public void setStarredChanged(boolean starredChanged) {
this.starredChanged = starredChanged;
}
public boolean isReadItLater() {
return readItLater;
}

View File

@ -8,10 +8,16 @@ import com.readrops.db.entities.account.Account
@Entity(foreignKeys = [ForeignKey(entity = Account::class, parentColumns = ["id"],
childColumns = ["account_id"], onDelete = ForeignKey.CASCADE)])
data class UnreadItemsIds(@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo(name = "remote_id", index = true) val remoteId: String,
@ColumnInfo(name = "account_id", index = true) val accountId: Int)
data class UnreadItemsIds(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
@ColumnInfo(name = "remote_id", index = true) val remoteId: String,
@ColumnInfo(name = "account_id", index = true) val accountId: Int,
)
@Entity
data class ReadStarStateChange(@PrimaryKey val id: Int = 0,
@ColumnInfo(name = "read_change") val readChange: Boolean = false,
@ColumnInfo(name = "star_change") val starChange: Boolean = false)
data class ReadStarStateChange(
@PrimaryKey val id: Int = 0,
@ColumnInfo(name = "read_change") val readChange: Boolean = false,
@ColumnInfo(name = "star_change") val starChange: Boolean = false,
@ColumnInfo(name = "account_id") val accountId: Int,
)

View File

@ -24,9 +24,7 @@ class StarredItem() : Item() {
guid = item.guid
readTime = item.readTime
isRead = item.isRead
isReadChanged = item.isReadChanged
isStarred = true // important here for the items query compatibility
isStarredChanged = item.isStarredChanged
isReadItLater = item.isReadItLater
remoteId = item.remoteId
feedRemoteId = item.feedRemoteId

View File

@ -0,0 +1,9 @@
package com.readrops.db.pojo
import androidx.room.ColumnInfo
data class ItemReadStarState(val remoteId: String,
val read: Boolean,
val starred: Boolean,
@ColumnInfo(name = "read_change") val readChange: Boolean,
@ColumnInfo(name = "star_change") val starChange: Boolean)