Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deduplicate SQL queries to get feed streams #8621

Merged
merged 1 commit into from
Jul 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 25 additions & 87 deletions app/src/main/java/org/schabi/newpipe/database/feed/dao/FeedDAO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.room.Update
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
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.stream.StreamWithState
import org.schabi.newpipe.database.stream.model.StreamStateEntity
Expand All @@ -21,92 +22,16 @@ abstract class FeedDAO {
@Query("DELETE FROM feed")
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>>

/**
* @see StreamStateEntity.isFinished()
* @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(
"""
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

WHERE (
sh.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 * 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>>

/**
* @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.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(
"""
Expand All @@ -122,24 +47,37 @@ abstract class FeedDAO {
INNER JOIN feed f
ON s.uid = f.stream_id

INNER JOIN feed_group_subscription_join fgs
LEFT JOIN feed_group_subscription_join fgs
ON fgs.subscription_id = f.subscription_id

WHERE fgs.group_id = :groupId
WHERE (
:groupId = ${FeedGroupEntity.GROUP_ALL_ID}
OR fgs.group_id = :groupId
)
AND (
sh.stream_id IS NULL
:includePlayed
OR sh.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 * 3 / 4
OR s.stream_type = '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
LIMIT 500
"""
)
abstract fun getLiveOrNotPlayedStreamsForGroup(groupId: Long): Maybe<List<StreamWithState>>
abstract fun getStreams(
groupId: Long,
includePlayed: Boolean,
uploadDateBefore: OffsetDateTime?
): Maybe<List<StreamWithState>>

@Query(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,15 @@ class FeedDatabaseManager(context: Context) {
fun database() = database

fun getStreams(
groupId: Long = FeedGroupEntity.GROUP_ALL_ID,
getPlayedStreams: Boolean = true
groupId: Long,
includePlayedStreams: Boolean,
includeFutureStreams: Boolean
): Maybe<List<StreamWithState>> {
return when (groupId) {
FeedGroupEntity.GROUP_ALL_ID -> {
if (getPlayedStreams) feedTable.getAllStreams()
else feedTable.getLiveOrNotPlayedStreams()
}
else -> {
if (getPlayedStreams) feedTable.getAllStreamsForGroup(groupId)
else feedTable.getLiveOrNotPlayedStreamsForGroup(groupId)
}
}
return feedTable.getStreams(
groupId,
includePlayedStreams,
if (includeFutureStreams) null else OffsetDateTime.now()
)
}

fun outdatedSubscriptions(outdatedThreshold: OffsetDateTime) = feedTable.getAllOutdated(outdatedThreshold)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ class FeedViewModel(
.map { (event, showPlayedItems, showFutureItems, notLoadedCount, oldestUpdate) ->
val streamItems = if (event is SuccessResultEvent || event is IdleEvent)
feedDatabaseManager
.getStreams(groupId, showPlayedItems)
.getStreams(groupId, showPlayedItems, showFutureItems)
.blockingGet(arrayListOf())
.filter { s -> showFutureItems || s.stream.uploadDate?.isBefore(OffsetDateTime.now()) ?: true }
else
arrayListOf()

Expand Down