Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
package com.keylesspalace.tusky.db
|
|
|
|
|
|
|
|
import androidx.room.Dao
|
|
|
|
import androidx.room.Insert
|
|
|
|
import androidx.room.OnConflictStrategy.IGNORE
|
|
|
|
import androidx.room.OnConflictStrategy.REPLACE
|
|
|
|
import androidx.room.Query
|
|
|
|
import androidx.room.Transaction
|
|
|
|
import io.reactivex.Single
|
|
|
|
|
|
|
|
@Dao
|
|
|
|
abstract class TimelineDao {
|
|
|
|
|
|
|
|
@Insert(onConflict = REPLACE)
|
|
|
|
abstract fun insertAccount(timelineAccountEntity: TimelineAccountEntity): Long
|
|
|
|
|
|
|
|
|
|
|
|
@Insert(onConflict = REPLACE)
|
|
|
|
abstract fun insertStatus(timelineAccountEntity: TimelineStatusEntity): Long
|
|
|
|
|
|
|
|
|
|
|
|
@Insert(onConflict = IGNORE)
|
|
|
|
abstract fun insertStatusIfNotThere(timelineAccountEntity: TimelineStatusEntity): Long
|
|
|
|
|
|
|
|
@Query("""
|
|
|
|
SELECT s.serverId, s.url, s.timelineUserId,
|
2019-02-13 19:20:31 +01:00
|
|
|
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt,
|
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.sensitive,
|
|
|
|
s.spoilerText, s.visibility, s.mentions, s.application, s.reblogServerId,s.reblogAccountId,
|
|
|
|
s.content, s.attachments,
|
2019-02-13 19:20:31 +01:00
|
|
|
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
|
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
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.emojis as 'a_emojis',
|
2019-02-13 19:20:31 +01:00
|
|
|
rb.serverId as 'rb_serverId', rb.timelineUserId 'rb_timelineUserId',
|
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
rb.localUsername as 'rb_localUsername', rb.username as 'rb_username',
|
|
|
|
rb.displayName as 'rb_displayName', rb.url as 'rb_url', rb.avatar as 'rb_avatar',
|
|
|
|
rb.emojis as'rb_emojis'
|
|
|
|
FROM TimelineStatusEntity s
|
|
|
|
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)
|
|
|
|
WHERE s.timelineUserId = :account
|
2019-01-31 19:03:34 +01:00
|
|
|
AND (CASE WHEN :maxId IS NOT NULL THEN
|
|
|
|
(LENGTH(s.serverId) < LENGTH(:maxId) OR LENGTH(s.serverId) == LENGTH(:maxId) AND s.serverId < :maxId)
|
|
|
|
ELSE 1 END)
|
|
|
|
AND (CASE WHEN :sinceId IS NOT NULL THEN
|
|
|
|
(LENGTH(s.serverId) > LENGTH(:sinceId) OR LENGTH(s.serverId) == LENGTH(:sinceId) AND s.serverId > :sinceId)
|
|
|
|
ELSE 1 END)
|
|
|
|
ORDER BY LENGTH(s.serverId) DESC, s.serverId DESC
|
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
LIMIT :limit""")
|
|
|
|
abstract fun getStatusesForAccount(account: Long, maxId: String?, sinceId: String?, limit: Int): Single<List<TimelineStatusWithAccount>>
|
|
|
|
|
|
|
|
|
|
|
|
@Transaction
|
|
|
|
open fun insertInTransaction(status: TimelineStatusEntity, account: TimelineAccountEntity,
|
|
|
|
reblogAccount: TimelineAccountEntity?) {
|
|
|
|
insertAccount(account)
|
|
|
|
reblogAccount?.let(this::insertAccount)
|
|
|
|
insertStatus(status)
|
|
|
|
}
|
|
|
|
|
|
|
|
@Query("""DELETE FROM TimelineStatusEntity WHERE authorServerId = null
|
2019-02-05 20:06:00 +01:00
|
|
|
AND timelineUserId = :acccount AND
|
|
|
|
(LENGTH(serverId) < LENGTH(:maxId) OR LENGTH(serverId) == LENGTH(:maxId) AND serverId < :maxId)
|
|
|
|
AND
|
|
|
|
(LENGTH(serverId) > LENGTH(:sinceId) OR LENGTH(serverId) == LENGTH(:sinceId) AND serverId > :sinceId)
|
|
|
|
""")
|
Caching toots (#809)
* Initial timeline cache implementation
* Fix build/DI errors for caching
* Rename timeline entities tables. Add migration. Add DB scheme file.
* Fix uniqueness problem, change offline strategy, improve mapping
* Try to merge in new statuses, fix bottom loading, fix saving spans.
* Fix reblogs IDs, fix inserting elements from top
* Send one more request to get latest timeline statuses
* Give Timeline placeholders string id. Rewrite Either in Kotlin
* Initial placeholder implementation for caching
* Fix crash on removing overlap statuses
* Migrate counters to long
* Remove unused counters. Add minimal TimelineDAOTest
* Fix bug with placeholder ID
* Update cache in response to events. Refactor TimelineCases
* Fix crash, reduce number of placeholders
* Fix crash, fix filtering, improve placeholder handling
* Fix migration, add 8-9 migration test
* Fix initial timeline update, remove more placeholders
* Add cleanup for old statuses
* Fix cleanup
* Delete ExampleInstrumentedTest
* Improve timeline UX regarding caching
* Fix typos
* Fix initial timeline update
* Cleanup/fix initial timeline update
* Workaround for weird behavior of first post on initial tl update.
* Change counter types back to int
* Clear timeline cache on logout
* Fix loading when timeline is completely empty
* Fix androidx migration issues
* Fix tests
* Apply caching feedback
* Save account emojis to cache
* Fix warnings and bugs
2019-01-14 22:05:08 +01:00
|
|
|
abstract fun removeAllPlaceholdersBetween(acccount: Long, maxId: String, sinceId: String)
|
|
|
|
|
|
|
|
@Query("""UPDATE TimelineStatusEntity SET favourited = :favourited
|
|
|
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId - :statusId)""")
|
|
|
|
abstract fun setFavourited(accountId: Long, statusId: String, favourited: Boolean)
|
|
|
|
|
|
|
|
|
|
|
|
@Query("""UPDATE TimelineStatusEntity SET reblogged = :reblogged
|
|
|
|
WHERE timelineUserId = :accountId AND (serverId = :statusId OR reblogServerId - :statusId)""")
|
|
|
|
abstract fun setReblogged(accountId: Long, statusId: String, reblogged: Boolean)
|
|
|
|
|
|
|
|
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId AND
|
|
|
|
(authorServerId = :userId OR reblogAccountId = :userId)""")
|
|
|
|
abstract fun removeAllByUser(accountId: Long, userId: String)
|
|
|
|
|
|
|
|
@Query("DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId")
|
|
|
|
abstract fun removeAllForAccount(accountId: Long)
|
|
|
|
|
|
|
|
@Query("DELETE FROM TimelineAccountEntity WHERE timelineUserId = :accountId")
|
|
|
|
abstract fun removeAllUsersForAccount(accountId: Long)
|
|
|
|
|
|
|
|
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
|
|
|
AND serverId = :statusId""")
|
|
|
|
abstract fun delete(accountId: Long, statusId: String)
|
|
|
|
|
|
|
|
@Query("""DELETE FROM TimelineStatusEntity WHERE timelineUserId = :accountId
|
|
|
|
AND authorServerId != :accountServerId AND createdAt < :olderThan""")
|
|
|
|
abstract fun cleanup(accountId: Long, accountServerId: String, olderThan: Long)
|
|
|
|
}
|