make sure all timeline database operations run on a background thread (#3391)
This commit is contained in:
parent
b8c77a795c
commit
816dc0cbbc
2 changed files with 44 additions and 37 deletions
|
@ -3,45 +3,52 @@ 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.disposables.Disposable
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.rx3.asFlow
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CacheUpdater @Inject constructor(
|
class CacheUpdater @Inject constructor(
|
||||||
eventHub: EventHub,
|
eventHub: EventHub,
|
||||||
private val accountManager: AccountManager,
|
accountManager: AccountManager,
|
||||||
appDatabase: AppDatabase,
|
appDatabase: AppDatabase,
|
||||||
gson: Gson
|
gson: Gson
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val disposable: Disposable
|
private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val timelineDao = appDatabase.timelineDao()
|
val timelineDao = appDatabase.timelineDao()
|
||||||
|
|
||||||
disposable = eventHub.events.subscribe { event ->
|
scope.launch {
|
||||||
val accountId = accountManager.activeAccount?.id ?: return@subscribe
|
eventHub.events.asFlow().collect { event ->
|
||||||
when (event) {
|
val accountId = accountManager.activeAccount?.id ?: return@collect
|
||||||
is FavoriteEvent ->
|
when (event) {
|
||||||
timelineDao.setFavourited(accountId, event.statusId, event.favourite)
|
is FavoriteEvent ->
|
||||||
is ReblogEvent ->
|
timelineDao.setFavourited(accountId, event.statusId, event.favourite)
|
||||||
timelineDao.setReblogged(accountId, event.statusId, event.reblog)
|
is ReblogEvent ->
|
||||||
is BookmarkEvent ->
|
timelineDao.setReblogged(accountId, event.statusId, event.reblog)
|
||||||
timelineDao.setBookmarked(accountId, event.statusId, event.bookmark)
|
is BookmarkEvent ->
|
||||||
is UnfollowEvent ->
|
timelineDao.setBookmarked(accountId, event.statusId, event.bookmark)
|
||||||
timelineDao.removeAllByUser(accountId, event.accountId)
|
is UnfollowEvent ->
|
||||||
is StatusDeletedEvent ->
|
timelineDao.removeAllByUser(accountId, event.accountId)
|
||||||
timelineDao.delete(accountId, event.statusId)
|
is StatusDeletedEvent ->
|
||||||
is PollVoteEvent -> {
|
timelineDao.delete(accountId, event.statusId)
|
||||||
val pollString = gson.toJson(event.poll)
|
is PollVoteEvent -> {
|
||||||
timelineDao.setVoted(accountId, event.statusId, pollString)
|
val pollString = gson.toJson(event.poll)
|
||||||
|
timelineDao.setVoted(accountId, event.statusId, pollString)
|
||||||
|
}
|
||||||
|
is PinEvent ->
|
||||||
|
timelineDao.setPinned(accountId, event.statusId, event.pinned)
|
||||||
}
|
}
|
||||||
is PinEvent ->
|
|
||||||
timelineDao.setPinned(accountId, event.statusId, event.pinned)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
this.disposable.dispose()
|
this.scope.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ SELECT s.serverId, s.url, s.timelineUserId,
|
||||||
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.editedAt,
|
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.editedAt,
|
||||||
s.emojis, s.reblogsCount, s.favouritesCount, s.repliesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
|
s.emojis, s.reblogsCount, s.favouritesCount, s.repliesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
|
||||||
s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId,
|
s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId,
|
||||||
s.content, s.attachments, s.poll, s.card, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, s.language,
|
s.content, s.attachments, s.poll, s.card, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, s.language,
|
||||||
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
|
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
|
||||||
a.localUsername as 'a_localUsername', a.username as 'a_username',
|
a.localUsername as 'a_localUsername', a.username as 'a_username',
|
||||||
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar',
|
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar',
|
||||||
|
@ -59,7 +59,7 @@ SELECT s.serverId, s.url, s.timelineUserId,
|
||||||
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.editedAt,
|
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt, s.editedAt,
|
||||||
s.emojis, s.reblogsCount, s.favouritesCount, s.repliesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
|
s.emojis, s.reblogsCount, s.favouritesCount, s.repliesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
|
||||||
s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId,
|
s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId,
|
||||||
s.content, s.attachments, s.poll, s.card, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, s.language,
|
s.content, s.attachments, s.poll, s.card, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned, s.language,
|
||||||
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
|
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
|
||||||
a.localUsername as 'a_localUsername', a.username as 'a_username',
|
a.localUsername as 'a_localUsername', a.username as 'a_username',
|
||||||
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar',
|
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar',
|
||||||
|
@ -71,7 +71,7 @@ rb.emojis as 'rb_emojis', rb.bot as 'rb_bot'
|
||||||
FROM TimelineStatusEntity s
|
FROM TimelineStatusEntity s
|
||||||
LEFT JOIN TimelineAccountEntity a ON (s.timelineUserId = a.timelineUserId AND s.authorServerId = a.serverId)
|
LEFT JOIN TimelineAccountEntity a ON (s.timelineUserId = a.timelineUserId AND s.authorServerId = a.serverId)
|
||||||
LEFT JOIN TimelineAccountEntity rb ON (s.timelineUserId = rb.timelineUserId AND s.reblogAccountId = rb.serverId)
|
LEFT JOIN TimelineAccountEntity rb ON (s.timelineUserId = rb.timelineUserId AND s.reblogAccountId = rb.serverId)
|
||||||
WHERE (s.serverId = :statusId OR s.reblogServerId = :statusId)
|
WHERE (s.serverId = :statusId OR s.reblogServerId = :statusId)
|
||||||
AND s.authorServerId IS NOT NULL"""
|
AND s.authorServerId IS NOT NULL"""
|
||||||
)
|
)
|
||||||
abstract suspend fun getStatus(statusId: String): TimelineStatusWithAccount?
|
abstract suspend fun getStatus(statusId: String): TimelineStatusWithAccount?
|
||||||
|
@ -89,25 +89,25 @@ AND
|
||||||
"""UPDATE TimelineStatusEntity SET favourited = :favourited
|
"""UPDATE TimelineStatusEntity SET favourited = :favourited
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setFavourited(accountId: Long, statusId: String, favourited: Boolean)
|
abstract suspend fun setFavourited(accountId: Long, statusId: String, favourited: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET bookmarked = :bookmarked
|
"""UPDATE TimelineStatusEntity SET bookmarked = :bookmarked
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setBookmarked(accountId: Long, statusId: String, bookmarked: Boolean)
|
abstract suspend fun setBookmarked(accountId: Long, statusId: String, bookmarked: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET reblogged = :reblogged
|
"""UPDATE TimelineStatusEntity SET reblogged = :reblogged
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setReblogged(accountId: Long, statusId: String, reblogged: Boolean)
|
abstract suspend fun setReblogged(accountId: Long, statusId: String, reblogged: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
|
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
|
||||||
(authorServerId = :userId OR reblogAccountId = :userId)"""
|
(authorServerId = :userId OR reblogAccountId = :userId)"""
|
||||||
)
|
)
|
||||||
abstract fun removeAllByUser(accountId: Long, userId: String)
|
abstract suspend fun removeAllByUser(accountId: Long, userId: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes everything in the TimelineStatusEntity and TimelineAccountEntity tables for one user account
|
* Removes everything in the TimelineStatusEntity and TimelineAccountEntity tables for one user account
|
||||||
|
@ -128,7 +128,7 @@ WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId =
|
||||||
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
"""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
||||||
AND serverId = :statusId"""
|
AND serverId = :statusId"""
|
||||||
)
|
)
|
||||||
abstract fun delete(accountId: Long, statusId: String)
|
abstract suspend fun delete(accountId: Long, statusId: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans the TimelineStatusEntity and TimelineAccountEntity tables from old entries.
|
* Cleans the TimelineStatusEntity and TimelineAccountEntity tables from old entries.
|
||||||
|
@ -158,8 +158,8 @@ AND serverId = :statusId"""
|
||||||
*/
|
*/
|
||||||
@Query(
|
@Query(
|
||||||
"""DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId AND serverId NOT IN
|
"""DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId AND serverId NOT IN
|
||||||
(SELECT authorServerId FROM TimelineStatusEntity WHERE timelineUserId = :accountId)
|
(SELECT authorServerId FROM TimelineStatusEntity WHERE timelineUserId = :accountId)
|
||||||
AND serverId NOT IN
|
AND serverId NOT IN
|
||||||
(SELECT reblogAccountId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND reblogAccountId IS NOT NULL)"""
|
(SELECT reblogAccountId FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND reblogAccountId IS NOT NULL)"""
|
||||||
)
|
)
|
||||||
abstract suspend fun cleanupAccounts(accountId: Long)
|
abstract suspend fun cleanupAccounts(accountId: Long)
|
||||||
|
@ -168,31 +168,31 @@ AND serverId = :statusId"""
|
||||||
"""UPDATE TimelineStatusEntity SET poll = :poll
|
"""UPDATE TimelineStatusEntity SET poll = :poll
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setVoted(accountId: Long, statusId: String, poll: String)
|
abstract suspend fun setVoted(accountId: Long, statusId: String, poll: String)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET expanded = :expanded
|
"""UPDATE TimelineStatusEntity SET expanded = :expanded
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setExpanded(accountId: Long, statusId: String, expanded: Boolean)
|
abstract suspend fun setExpanded(accountId: Long, statusId: String, expanded: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET contentShowing = :contentShowing
|
"""UPDATE TimelineStatusEntity SET contentShowing = :contentShowing
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setContentShowing(accountId: Long, statusId: String, contentShowing: Boolean)
|
abstract suspend fun setContentShowing(accountId: Long, statusId: String, contentShowing: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET contentCollapsed = :contentCollapsed
|
"""UPDATE TimelineStatusEntity SET contentCollapsed = :contentCollapsed
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setContentCollapsed(accountId: Long, statusId: String, contentCollapsed: Boolean)
|
abstract suspend fun setContentCollapsed(accountId: Long, statusId: String, contentCollapsed: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""UPDATE TimelineStatusEntity SET pinned = :pinned
|
"""UPDATE TimelineStatusEntity SET pinned = :pinned
|
||||||
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId = :statusId)"""
|
||||||
)
|
)
|
||||||
abstract fun setPinned(accountId: Long, statusId: String, pinned: Boolean)
|
abstract suspend fun setPinned(accountId: Long, statusId: String, pinned: Boolean)
|
||||||
|
|
||||||
@Query(
|
@Query(
|
||||||
"""DELETE FROM TimelineStatusEntity
|
"""DELETE FROM TimelineStatusEntity
|
||||||
|
|
Loading…
Reference in a new issue