Skip to content

Commit 5dd8e6e

Browse files
folders for playlists
1 parent 0fc2d4c commit 5dd8e6e

14 files changed

Lines changed: 443 additions & 12 deletions

app/src/main/java/org/schabi/newpipe/NewPipeDatabase.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import org.schabi.newpipe.database.Migrations.MIGRATION_5_6
1717
import org.schabi.newpipe.database.Migrations.MIGRATION_6_7
1818
import org.schabi.newpipe.database.Migrations.MIGRATION_7_8
1919
import org.schabi.newpipe.database.Migrations.MIGRATION_8_9
20+
import org.schabi.newpipe.database.Migrations.MIGRATION_9_10
2021
import kotlin.concurrent.Volatile
2122

2223
object NewPipeDatabase {
@@ -27,8 +28,8 @@ object NewPipeDatabase {
2728
private fun getDatabase(context: Context): AppDatabase {
2829
return databaseBuilder(
2930
context.applicationContext,
30-
AppDatabase::class.java,
31-
AppDatabase.Companion.DATABASE_NAME
31+
AppDatabase::class.java,
32+
AppDatabase.Companion.DATABASE_NAME
3233
).addMigrations(
3334
MIGRATION_1_2,
3435
MIGRATION_2_3,
@@ -37,7 +38,8 @@ object NewPipeDatabase {
3738
MIGRATION_5_6,
3839
MIGRATION_6_7,
3940
MIGRATION_7_8,
40-
MIGRATION_8_9
41+
MIGRATION_8_9,
42+
MIGRATION_9_10
4143
).build()
4244
}
4345

app/src/main/java/org/schabi/newpipe/database/AppDatabase.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
3434

3535
@TypeConverters(Converters::class)
3636
@Database(
37-
version = Migrations.DB_VER_9,
37+
version = Migrations.DB_VER_10,
3838
entities = [
3939
SubscriptionEntity::class,
4040
SearchHistoryEntry::class,
@@ -44,6 +44,7 @@ import org.schabi.newpipe.database.subscription.SubscriptionEntity
4444
PlaylistEntity::class,
4545
PlaylistStreamEntity::class,
4646
PlaylistRemoteEntity::class,
47+
org.schabi.newpipe.database.playlist.model.PlaylistFolderEntity::class,
4748
FeedEntity::class,
4849
FeedGroupEntity::class,
4950
FeedGroupSubscriptionEntity::class,
@@ -56,6 +57,7 @@ abstract class AppDatabase : RoomDatabase() {
5657
abstract fun playlistDAO(): PlaylistDAO
5758
abstract fun playlistRemoteDAO(): PlaylistRemoteDAO
5859
abstract fun playlistStreamDAO(): PlaylistStreamDAO
60+
abstract fun playlistFolderDAO(): org.schabi.newpipe.database.playlist.dao.PlaylistFolderDAO
5961
abstract fun searchHistoryDAO(): SearchHistoryDAO
6062
abstract fun streamDAO(): StreamDAO
6163
abstract fun streamHistoryDAO(): StreamHistoryDAO

app/src/main/java/org/schabi/newpipe/database/Migrations.kt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ object Migrations {
3030
const val DB_VER_7 = 7
3131
const val DB_VER_8 = 8
3232
const val DB_VER_9 = 9
33+
const val DB_VER_10 = 10
3334

3435
private val TAG = Migrations::class.java.getName()
3536
private val isDebug = MainActivity.DEBUG
@@ -365,4 +366,33 @@ object Migrations {
365366
}
366367
}
367368
}
369+
370+
val MIGRATION_9_10 = object : Migration(DB_VER_9, DB_VER_10) {
371+
override fun migrate(db: SupportSQLiteDatabase) {
372+
// Add folder table and folder_id column to playlists
373+
db.execSQL(
374+
"CREATE TABLE IF NOT EXISTS `playlist_folders` (" +
375+
"`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +
376+
"`name` TEXT NOT NULL, " +
377+
"`sort_order` INTEGER NOT NULL DEFAULT 0)"
378+
)
379+
380+
// Add nullable folder_id column to playlists
381+
db.execSQL(
382+
"ALTER TABLE `playlists` ADD COLUMN `folder_id` INTEGER"
383+
)
384+
}
385+
}
386+
387+
val ALL_MIGRATIONS = arrayOf(
388+
MIGRATION_1_2,
389+
MIGRATION_2_3,
390+
MIGRATION_3_4,
391+
MIGRATION_4_5,
392+
MIGRATION_5_6,
393+
MIGRATION_6_7,
394+
MIGRATION_7_8,
395+
MIGRATION_8_9,
396+
MIGRATION_9_10
397+
)
368398
}

app/src/main/java/org/schabi/newpipe/database/playlist/PlaylistMetadataEntry.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ open class PlaylistMetadataEntry(
2929
@ColumnInfo(name = PlaylistEntity.PLAYLIST_THUMBNAIL_STREAM_ID)
3030
open val thumbnailStreamId: Long?,
3131

32+
@ColumnInfo(name = PlaylistEntity.PLAYLIST_FOLDER_ID)
33+
open val folderId: Long?,
34+
3235
@ColumnInfo(name = PLAYLIST_STREAM_COUNT)
3336
open val streamCount: Long
3437
) : PlaylistLocalItem {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.schabi.newpipe.database.playlist.dao
2+
3+
import androidx.room.Dao
4+
import androidx.room.Query
5+
import androidx.room.Update
6+
import androidx.room.Insert
7+
import io.reactivex.rxjava3.core.Flowable
8+
import io.reactivex.rxjava3.core.Maybe
9+
import org.schabi.newpipe.database.playlist.model.PlaylistFolderEntity
10+
11+
@Dao
12+
interface PlaylistFolderDAO {
13+
@Query("SELECT * FROM playlist_folders ORDER BY sort_order ASC")
14+
fun getAll(): Flowable<List<PlaylistFolderEntity>>
15+
16+
@Insert
17+
fun insert(folder: PlaylistFolderEntity): Long
18+
19+
@Update
20+
fun update(folder: PlaylistFolderEntity): Int
21+
22+
@Query("DELETE FROM playlist_folders WHERE uid = :folderId")
23+
fun delete(folderId: Long): Int
24+
25+
@Query("SELECT * FROM playlist_folders WHERE uid = :folderId LIMIT 1")
26+
fun get(folderId: Long): Maybe<PlaylistFolderEntity>
27+
}

app/src/main/java/org/schabi/newpipe/database/playlist/dao/PlaylistStreamDAO.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ interface PlaylistStreamDAO : BasicDAO<PlaylistStreamEntity> {
7171
@Transaction
7272
@Query(
7373
"""
74-
SELECT uid, name, is_thumbnail_permanent, thumbnail_stream_id, display_index,
74+
SELECT uid, name,
7575
(SELECT thumbnail_url FROM streams WHERE streams.uid = thumbnail_stream_id) AS thumbnail_url,
76-
76+
display_index, is_thumbnail_permanent, thumbnail_stream_id, folder_id,
7777
COALESCE(COUNT(playlist_id), 0) AS streamCount FROM playlists
7878
7979
LEFT JOIN playlist_stream_join
@@ -106,8 +106,9 @@ interface PlaylistStreamDAO : BasicDAO<PlaylistStreamEntity> {
106106
@Transaction
107107
@Query(
108108
"""
109-
SELECT playlists.uid, name, is_thumbnail_permanent, thumbnail_stream_id, display_index,
109+
SELECT playlists.uid, name,
110110
(SELECT thumbnail_url FROM streams WHERE streams.uid = thumbnail_stream_id) AS thumbnail_url,
111+
display_index, is_thumbnail_permanent, thumbnail_stream_id, folder_id,
111112
112113
COALESCE(COUNT(playlist_id), 0) AS streamCount,
113114
COALESCE(SUM(url = :streamUrl), 0) AS timesStreamIsContained FROM playlists

app/src/main/java/org/schabi/newpipe/database/playlist/model/PlaylistEntity.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ data class PlaylistEntity @JvmOverloads constructor(
2626

2727
@ColumnInfo(name = PLAYLIST_THUMBNAIL_STREAM_ID)
2828
var thumbnailStreamId: Long,
29-
29+
30+
@ColumnInfo(name = PLAYLIST_FOLDER_ID)
3031
@ColumnInfo(name = PLAYLIST_DISPLAY_INDEX)
31-
var displayIndex: Long
32+
var displayIndex: Long,
33+
34+
@ColumnInfo(name = PLAYLIST_FOLDER_ID)
35+
var folderId: Long? = null,
3236
) {
3337

3438
@Ignore
@@ -46,6 +50,7 @@ data class PlaylistEntity @JvmOverloads constructor(
4650
const val PLAYLIST_TABLE = "playlists"
4751
const val PLAYLIST_ID = "uid"
4852
const val PLAYLIST_NAME = "name"
53+
const val PLAYLIST_FOLDER_ID = "folder_id"
4954
const val PLAYLIST_THUMBNAIL_URL = "thumbnail_url"
5055
const val PLAYLIST_DISPLAY_INDEX = "display_index"
5156
const val PLAYLIST_THUMBNAIL_PERMANENT = "is_thumbnail_permanent"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 NewPipe contributors
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
package org.schabi.newpipe.database.playlist.model
7+
8+
import androidx.room.ColumnInfo
9+
import androidx.room.Entity
10+
import androidx.room.PrimaryKey
11+
12+
@Entity(tableName = PlaylistFolderEntity.FOLDER_TABLE)
13+
data class PlaylistFolderEntity(
14+
@PrimaryKey(autoGenerate = true)
15+
@ColumnInfo(name = FOLDER_ID)
16+
var uid: Long = 0,
17+
18+
@ColumnInfo(name = FOLDER_NAME)
19+
var name: String,
20+
21+
@ColumnInfo(name = FOLDER_SORT_ORDER)
22+
var sortOrder: Long = 0
23+
){
24+
companion object {
25+
const val FOLDER_TABLE = "playlist_folders"
26+
const val FOLDER_ID = "uid"
27+
const val FOLDER_NAME = "name"
28+
const val FOLDER_SORT_ORDER = "sort_order"
29+
}
30+
}

0 commit comments

Comments
 (0)