Deduplicate SQL queries to get feed streams

This commit is contained in:
Stypox 2022-07-13 11:37:46 +02:00
parent b96c8a0c2f
commit e8669d4ab5
No known key found for this signature in database
GPG key ID: 4BDF1B40A49FDD23
3 changed files with 37 additions and 104 deletions

View file

@ -9,6 +9,7 @@ import androidx.room.Update
import io.reactivex.rxjava3.core.Flowable import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe import io.reactivex.rxjava3.core.Maybe
import org.schabi.newpipe.database.feed.model.FeedEntity import org.schabi.newpipe.database.feed.model.FeedEntity
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity import org.schabi.newpipe.database.feed.model.FeedLastUpdatedEntity
import org.schabi.newpipe.database.stream.StreamWithState import org.schabi.newpipe.database.stream.StreamWithState
import org.schabi.newpipe.database.stream.model.StreamStateEntity import org.schabi.newpipe.database.stream.model.StreamStateEntity
@ -21,56 +22,16 @@ abstract class FeedDAO {
@Query("DELETE FROM feed") @Query("DELETE FROM feed")
abstract fun deleteAll(): Int abstract fun deleteAll(): Int
@Query(
"""
SELECT s.*, sst.progress_time
FROM streams s
LEFT JOIN stream_state sst
ON s.uid = sst.stream_id
LEFT JOIN stream_history sh
ON s.uid = sh.stream_id
INNER JOIN feed f
ON s.uid = f.stream_id
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500
"""
)
abstract fun getAllStreams(): Maybe<List<StreamWithState>>
@Query(
"""
SELECT s.*, sst.progress_time
FROM streams s
LEFT JOIN stream_state sst
ON s.uid = sst.stream_id
LEFT JOIN stream_history sh
ON s.uid = sh.stream_id
INNER JOIN feed f
ON s.uid = f.stream_id
INNER JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = f.subscription_id
WHERE fgs.group_id = :groupId
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500
"""
)
abstract fun getAllStreamsForGroup(groupId: Long): Maybe<List<StreamWithState>>
/** /**
* @param groupId the group id to get feed streams of; use
* [FeedGroupEntity.GROUP_ALL_ID] to not filter by group
* @param includePlayed if false, only return all of the live, never-played or non-finished
* feed streams (see `@see` items); if true no filter is applied
* @param uploadDateBefore get only streams uploaded before this date (useful to filter out
* future streams); use null to not filter by upload date
* @return the feed streams filtered according to the conditions provided in the parameters
* @see StreamStateEntity.isFinished() * @see StreamStateEntity.isFinished()
* @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS * @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS
* @return all of the non-live, never-played and non-finished streams in the feed
* (all of the cited conditions must hold for a stream to be in the returned list)
*/ */
@Query( @Query(
""" """
@ -79,67 +40,44 @@ abstract class FeedDAO {
LEFT JOIN stream_state sst LEFT JOIN stream_state sst
ON s.uid = sst.stream_id ON s.uid = sst.stream_id
LEFT JOIN stream_history sh LEFT JOIN stream_history sh
ON s.uid = sh.stream_id ON s.uid = sh.stream_id
INNER JOIN feed f INNER JOIN feed f
ON s.uid = f.stream_id ON s.uid = f.stream_id
LEFT JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = f.subscription_id
WHERE ( WHERE (
sh.stream_id IS NULL :groupId = ${FeedGroupEntity.GROUP_ALL_ID}
OR sst.stream_id IS NULL OR fgs.group_id = :groupId
OR sst.progress_time < s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS}
OR sst.progress_time < s.duration * 1000 * 3 / 4
OR s.stream_type = 'LIVE_STREAM'
OR s.stream_type = 'AUDIO_LIVE_STREAM'
) )
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500
"""
)
abstract fun getLiveOrNotPlayedStreams(): Maybe<List<StreamWithState>>
/**
* @see StreamStateEntity.isFinished()
* @see StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS
* @param groupId the group id to get streams of
* @return all of the non-live, never-played and non-finished streams for the given feed group
* (all of the cited conditions must hold for a stream to be in the returned list)
*/
@Query(
"""
SELECT s.*, sst.progress_time
FROM streams s
LEFT JOIN stream_state sst
ON s.uid = sst.stream_id
LEFT JOIN stream_history sh
ON s.uid = sh.stream_id
INNER JOIN feed f
ON s.uid = f.stream_id
INNER JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = f.subscription_id
WHERE fgs.group_id = :groupId
AND ( AND (
sh.stream_id IS NULL :includePlayed
OR sh.stream_id IS NULL
OR sst.stream_id IS NULL OR sst.stream_id IS NULL
OR sst.progress_time < s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS} OR sst.progress_time < s.duration * 1000 - ${StreamStateEntity.PLAYBACK_FINISHED_END_MILLISECONDS}
OR sst.progress_time < s.duration * 1000 * 3 / 4 OR sst.progress_time < s.duration * 1000 * 3 / 4
OR s.stream_type = 'LIVE_STREAM' OR s.stream_type = 'LIVE_STREAM'
OR s.stream_type = 'AUDIO_LIVE_STREAM' OR s.stream_type = 'AUDIO_LIVE_STREAM'
) )
AND (
:uploadDateBefore IS NULL
OR s.upload_date IS NULL
OR s.upload_date < :uploadDateBefore
)
ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC ORDER BY s.upload_date IS NULL DESC, s.upload_date DESC, s.uploader ASC
LIMIT 500 LIMIT 500
""" """
) )
abstract fun getLiveOrNotPlayedStreamsForGroup(groupId: Long): Maybe<List<StreamWithState>> abstract fun getStreams(
groupId: Long,
includePlayed: Boolean,
uploadDateBefore: OffsetDateTime?
): Maybe<List<StreamWithState>>
@Query( @Query(
""" """

View file

@ -41,19 +41,15 @@ class FeedDatabaseManager(context: Context) {
fun database() = database fun database() = database
fun getStreams( fun getStreams(
groupId: Long = FeedGroupEntity.GROUP_ALL_ID, groupId: Long,
getPlayedStreams: Boolean = true includePlayedStreams: Boolean,
includeFutureStreams: Boolean
): Maybe<List<StreamWithState>> { ): Maybe<List<StreamWithState>> {
return when (groupId) { return feedTable.getStreams(
FeedGroupEntity.GROUP_ALL_ID -> { groupId,
if (getPlayedStreams) feedTable.getAllStreams() includePlayedStreams,
else feedTable.getLiveOrNotPlayedStreams() if (includeFutureStreams) null else OffsetDateTime.now()
} )
else -> {
if (getPlayedStreams) feedTable.getAllStreamsForGroup(groupId)
else feedTable.getLiveOrNotPlayedStreamsForGroup(groupId)
}
}
} }
fun outdatedSubscriptions(outdatedThreshold: OffsetDateTime) = feedTable.getAllOutdated(outdatedThreshold) fun outdatedSubscriptions(outdatedThreshold: OffsetDateTime) = feedTable.getAllOutdated(outdatedThreshold)

View file

@ -65,9 +65,8 @@ class FeedViewModel(
.map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) -> .map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
val streamItems = if (event is SuccessResultEvent || event is IdleEvent) val streamItems = if (event is SuccessResultEvent || event is IdleEvent)
feedDatabaseManager feedDatabaseManager
.getStreams(groupId, showPlayedItems) .getStreams(groupId, showPlayedItems, showFutureItems)
.blockingGet(arrayListOf()) .blockingGet(arrayListOf())
.filter { s -> showFutureItems || s.stream.uploadDate?.isBefore(OffsetDateTime.now()) ?: true }
else else
arrayListOf() arrayListOf()