Improve timeline dao (#2353)
* improve TimelineDao methods * remove @Transaction from cleanup methods
This commit is contained in:
parent
a6335e6bcd
commit
497b434663
5 changed files with 35 additions and 26 deletions
|
@ -3,9 +3,7 @@ package com.keylesspalace.tusky.appstore
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.keylesspalace.tusky.db.AccountManager
|
import com.keylesspalace.tusky.db.AccountManager
|
||||||
import com.keylesspalace.tusky.db.AppDatabase
|
import com.keylesspalace.tusky.db.AppDatabase
|
||||||
import io.reactivex.rxjava3.core.Single
|
|
||||||
import io.reactivex.rxjava3.disposables.Disposable
|
import io.reactivex.rxjava3.disposables.Disposable
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CacheUpdater @Inject constructor(
|
class CacheUpdater @Inject constructor(
|
||||||
|
@ -47,12 +45,7 @@ class CacheUpdater @Inject constructor(
|
||||||
this.disposable.dispose()
|
this.disposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearForUser(accountId: Long) {
|
suspend fun clearForUser(accountId: Long) {
|
||||||
Single.fromCallable {
|
appDatabase.timelineDao().removeAll(accountId)
|
||||||
appDatabase.timelineDao().removeAllForAccount(accountId)
|
|
||||||
appDatabase.timelineDao().removeAllUsersForAccount(accountId)
|
|
||||||
}
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.subscribe()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ class CachedTimelineViewModel @Inject constructor(
|
||||||
override val statuses = Pager(
|
override val statuses = Pager(
|
||||||
config = PagingConfig(pageSize = LOAD_AT_ONCE),
|
config = PagingConfig(pageSize = LOAD_AT_ONCE),
|
||||||
remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db, gson),
|
remoteMediator = CachedTimelineRemoteMediator(accountManager, api, db, gson),
|
||||||
pagingSourceFactory = { db.timelineDao().getStatusesForAccount(accountManager.activeAccount!!.id) }
|
pagingSourceFactory = { db.timelineDao().getStatuses(accountManager.activeAccount!!.id) }
|
||||||
).flow
|
).flow
|
||||||
.map { pagingData ->
|
.map { pagingData ->
|
||||||
pagingData.map { timelineStatus ->
|
pagingData.map { timelineStatus ->
|
||||||
|
@ -214,10 +214,7 @@ class CachedTimelineViewModel @Inject constructor(
|
||||||
override fun fullReload() {
|
override fun fullReload() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val activeAccount = accountManager.activeAccount!!
|
val activeAccount = accountManager.activeAccount!!
|
||||||
db.runInTransaction {
|
db.timelineDao().removeAll(activeAccount.id)
|
||||||
db.timelineDao().removeAllForAccount(activeAccount.id)
|
|
||||||
db.timelineDao().removeAllUsersForAccount(activeAccount.id)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ LEFT JOIN TimelineAccountEntity rb ON (s.timelineUserId = rb.timelineUserId AND
|
||||||
WHERE s.timelineUserId = :account
|
WHERE s.timelineUserId = :account
|
||||||
ORDER BY LENGTH(s.serverId) DESC, s.serverId DESC"""
|
ORDER BY LENGTH(s.serverId) DESC, s.serverId DESC"""
|
||||||
)
|
)
|
||||||
abstract fun getStatusesForAccount(account: Long): PagingSource<Int, TimelineStatusWithAccount>
|
abstract fun getStatuses(account: Long): PagingSource<Int, TimelineStatusWithAccount>
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
|
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
|
||||||
|
@ -86,11 +86,20 @@ WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId =
|
||||||
)
|
)
|
||||||
abstract fun removeAllByUser(accountId: Long, userId: String)
|
abstract fun removeAllByUser(accountId: Long, userId: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes everything in the TimelineStatusEntity and TimelineAccountEntity tables for one user account
|
||||||
|
* @param accountId id of the account for which to clean tables
|
||||||
|
*/
|
||||||
|
suspend fun removeAll(accountId: Long) {
|
||||||
|
removeAllStatuses(accountId)
|
||||||
|
removeAllAccounts(accountId)
|
||||||
|
}
|
||||||
|
|
||||||
@Query("DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId")
|
@Query("DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId")
|
||||||
abstract fun removeAllForAccount(accountId: Long)
|
abstract suspend fun removeAllStatuses(accountId: Long)
|
||||||
|
|
||||||
@Query("DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId")
|
@Query("DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId")
|
||||||
abstract fun removeAllUsersForAccount(accountId: Long)
|
abstract suspend fun removeAllAccounts(accountId: Long)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
||||||
|
@ -98,6 +107,16 @@ AND serverId = :statusId"""
|
||||||
)
|
)
|
||||||
abstract fun delete(accountId: Long, statusId: String)
|
abstract fun delete(accountId: Long, statusId: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans the TimelineStatusEntity and TimelineAccountEntity tables from old entries.
|
||||||
|
* @param accountId id of the account for which to clean tables
|
||||||
|
* @param limit how many statuses to keep
|
||||||
|
*/
|
||||||
|
suspend fun cleanup(accountId: Long, limit: Int) {
|
||||||
|
cleanupStatuses(accountId, limit)
|
||||||
|
cleanupAccounts(accountId)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans the TimelineStatusEntity table from old status entries.
|
* Cleans the TimelineStatusEntity table from old status entries.
|
||||||
* @param accountId id of the account for which to clean statuses
|
* @param accountId id of the account for which to clean statuses
|
||||||
|
@ -108,7 +127,7 @@ AND serverId = :statusId"""
|
||||||
(SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT :limit)
|
(SELECT serverId FROM TimelineStatusEntity WHERE timelineUserId = :accountId ORDER BY LENGTH(serverId) DESC, serverId DESC LIMIT :limit)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
abstract suspend fun cleanup(accountId: Long, limit: Int)
|
abstract suspend fun cleanupStatuses(accountId: Long, limit: Int)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans the TimelineAccountEntity table from accounts that are no longer referenced in the TimelineStatusEntity table
|
* Cleans the TimelineAccountEntity table from accounts that are no longer referenced in the TimelineStatusEntity table
|
||||||
|
|
|
@ -514,7 +514,7 @@ class CachedTimelineRemoteMediatorTest {
|
||||||
expected: List<TimelineStatusWithAccount>,
|
expected: List<TimelineStatusWithAccount>,
|
||||||
forAccount: Long = 1
|
forAccount: Long = 1
|
||||||
) {
|
) {
|
||||||
val pagingSource = timelineDao().getStatusesForAccount(forAccount)
|
val pagingSource = timelineDao().getStatuses(forAccount)
|
||||||
|
|
||||||
val loadResult = runBlocking {
|
val loadResult = runBlocking {
|
||||||
pagingSource.load(PagingSource.LoadParams.Refresh(null, 100, false))
|
pagingSource.load(PagingSource.LoadParams.Refresh(null, 100, false))
|
||||||
|
|
|
@ -53,7 +53,7 @@ class TimelineDaoTest {
|
||||||
timelineDao.insertStatus(status)
|
timelineDao.insertStatus(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
val pagingSource = timelineDao.getStatusesForAccount(setOne.first.timelineUserId)
|
val pagingSource = timelineDao.getStatuses(setOne.first.timelineUserId)
|
||||||
|
|
||||||
val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 2, false))
|
val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 2, false))
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class TimelineDaoTest {
|
||||||
|
|
||||||
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
||||||
|
|
||||||
val loadedStatuses = (timelineDao.getStatusesForAccount(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
val loadedStatuses = (timelineDao.getStatuses(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
||||||
|
|
||||||
assertStatuses(statusesAfterCleanup, loadedStatuses)
|
assertStatuses(statusesAfterCleanup, loadedStatuses)
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ class TimelineDaoTest {
|
||||||
|
|
||||||
// make sure status 2 is no longer in db
|
// make sure status 2 is no longer in db
|
||||||
|
|
||||||
val pagingSource = timelineDao.getStatusesForAccount(1)
|
val pagingSource = timelineDao.getStatuses(1)
|
||||||
|
|
||||||
val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 100, false))
|
val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 100, false))
|
||||||
|
|
||||||
|
@ -197,8 +197,8 @@ class TimelineDaoTest {
|
||||||
|
|
||||||
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
||||||
|
|
||||||
val statusesAccount1 = (timelineDao.getStatusesForAccount(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
val statusesAccount1 = (timelineDao.getStatuses(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
||||||
val statusesAccount2 = (timelineDao.getStatusesForAccount(2).load(loadParams) as PagingSource.LoadResult.Page).data
|
val statusesAccount2 = (timelineDao.getStatuses(2).load(loadParams) as PagingSource.LoadResult.Page).data
|
||||||
|
|
||||||
val remainingStatusesAccount1 = listOf(
|
val remainingStatusesAccount1 = listOf(
|
||||||
makeStatus(statusId = 100),
|
makeStatus(statusId = 100),
|
||||||
|
@ -269,8 +269,8 @@ class TimelineDaoTest {
|
||||||
|
|
||||||
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
|
||||||
|
|
||||||
val statusesAccount1 = (timelineDao.getStatusesForAccount(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
val statusesAccount1 = (timelineDao.getStatuses(1).load(loadParams) as PagingSource.LoadResult.Page).data
|
||||||
val statusesAccount2 = (timelineDao.getStatusesForAccount(2).load(loadParams) as PagingSource.LoadResult.Page).data
|
val statusesAccount2 = (timelineDao.getStatuses(2).load(loadParams) as PagingSource.LoadResult.Page).data
|
||||||
|
|
||||||
assertStatuses(listOf(statusWithBlueDomain, statusWithGreenDomain), statusesAccount1)
|
assertStatuses(listOf(statusWithBlueDomain, statusWithGreenDomain), statusesAccount1)
|
||||||
assertStatuses(listOf(statusWithRedDomainOtherAccount, statusWithBlueDomainOtherAccount), statusesAccount2)
|
assertStatuses(listOf(statusWithRedDomainOtherAccount, statusWithBlueDomainOtherAccount), statusesAccount2)
|
||||||
|
|
Loading…
Reference in a new issue